2013年12月31日 星期二

籌碼分析-法人期貨未平倉

 

籌碼分析是期權交易方法中的一種,其中最常聽到的是由期交所每日公布法人期貨未平倉資料,用以判斷法人的方向,這算是一個顯學吧,每日期貨商的分析報告和分析師幾乎都會引用這項資料,也有許多書籍、程式交易、甚至一些論文都在研究法人未平倉部位和台指走勢的相關性,不過,L不覺得能夠盡信或使用,可能要換個方式說,L還未找到能夠應用它的並可認同的策略,即使它回測是會獲利的。

 

最初的認識是由程式回測而來,曾有試過外資未平倉部位加上均線邏輯,最讓人疑惑的就是大跌段2008年時,外資期貨多單從五千多點抱到四千點,這怎麼能用呢? 有多少人可以承受這樣的回檔? 就算抱過那兩三個月後開始大賺,也是一場空,因為都被抬出場了。這是其一,再來看看以今日(2013/12/30)為例。

 

前一個交易日(2013/12/27)的外資期貨未平倉如圖

 

1227期

 

今日(2013/12/30)的外資期貨未平倉如圖

 

1230期

 

這一陣子外資一路是空單,慢慢降低,指數則是由盤整區8400震盪到今日收盤8625,但如果說外資是被軋空的話就太不負責任了,因為那是錯的今日的行情是上漲82點,價位如圖。

 

1230期行情

 

假設27日的期貨留倉-881口在今日全數未動,那今日損益則是82點*200*-881口=-14,448,400,但是選擇權呢,是賺的。

 

前一個交易日(2013/12/27)的外資選擇權未平倉如圖

 

1227選

 

今日(2013/12/30)的外資選擇權未平倉如圖

 

1230選

 

買權最後一欄契約金額464,689,000 減前日金額389,659,000再加今日權利金收回的金額5,490,000 = 80,520,000

 

而賣權最後一欄契約金額201,020,000 減前日金額226,178,000再減今日權利金繼續投入的金額18,304,000 = -43,462,000

 

則買賣權合計80,520,000 – 43,462,000 =權利金今日獲利 35,410,000

 

期貨與選擇權合計則是 -14,448,400 + 35,410,000 = 20,961,600

 

所以,今日台指上漲82點,外資部位是獲利約2100萬,反過來說,如果作期貨在今天要賺到這個獲利需要作多幾口台指呢? 20961600 / 82 / 200 = 約 1278 口,這是一個可以拿來約當期貨總部位的DELTA,BUT,只在這個盤後時間點有效,因為明天一開盤,選擇權部位會因為THETA變化、會隨著行情變化GAMMA和DELTA、權利金變化更跟著VEGA變化,所以也不曉得會變到哪裡去。

 

若是想要很粗估選擇權的DELTA,就繼續來算算,首先粗估,買權總付出權利金464,689,000 / 口數92,743 = 每口平均是5010.5 元,也就是約100點的CALL,那現在市場上100點的CALL最接近的是8500(148點)和8600(79點)之間,對應的DELTA約是8500(0.795)和8600(0.576),已經是價平靠價內了,目標是100點,那再插補法算一下對應的DETLA位置,然後再乘92743口,得到粗估的買權DELTA…然後再算賣權的…以下省略

 

這個東西已經非常粗略的估計,不知能代表多少真實狀況,因為完全不曉得履約價的分配,而且還有不同月份,除非那麼厲害再把今日總權利金變化對應行情和各履約價的OI變化量這兩個因素再加進去好好算一算,或許,只是或許能夠得到比較接近的部位狀況。

 

問題是,期貨有了,假設選擇權也能算的出來粗估的,還是沒辦法知道法人部位偏空還是偏多,因為摩台是不需揭露的,而且以未平倉部位來看,台指現在才58465口,但摩台是219033口,就算合約價值比除下去也有約12萬多口,這比台指還大的太多了,怎能知摩台在外資部位是什麼比例? 什麼部位? 所以當然不知外資總期權部位是偏多偏空呢?

 

摩台OI

 

小結論:

  1. 期貨偏多不代表作多,至少加看選擇權部位

  2. 期貨加選擇權總共偏多也不代表作多,因為摩台部位不知道

  3. 以不知道的假設方向作回測的結果,即使是可獲利的也難以信服

  4. 分析師和研究員的未平倉參考分析其實是作報告而已,有時準有時不準,不過至少有東西寫


 

以上,紀錄目前的心得,或許有更好的方式判斷這些資料,只是目前還未有好方法,繼續觀察囉~

 

 

 

2013年12月29日 星期日

大陸滬深300選擇權商品明年上市

 

兩岸金融交流越趨緊密,我們雖然無法直接交易對岸商品,但也許哪天當政策開放,大陸商品也將成為我們的投資組合之一,因此隨時保持關注是必要的。

 

自從大連商品交易所、鄭州商品交易所與上海期貨交易所自一年多前開始期權(選擇權)仿真交易後,今年11月8號大陸中國金融交易所(簡稱中金所),公布 股指期權仿真交易業務規則,形同宣布明年中國衍生性交易市場將全面性進入下一個階段-選擇權的時代來臨,未來也許中國再上市更多選擇權交易商品後,結合既有的大連、鄭州與上海三個商品交易所將成為亞洲衍生性商品交易的重鎮。

 

然而一般台灣人對指數類選擇權的商品最為熟悉,因此對於滬深300指數推出的選擇權關注度也較其他商品選擇權更為高出許多,下圖即為中金所公布的商品合約規格表。

 

圖片 2

 

看完上圖,可能很直觀的了解到每跳種一點大約10人民幣,也差不多相當於台指選擇權1點的價值,而比較特別的是,規則中並沒有如同台灣在不同價格的時候跳動點跟隨改變,例如台指選擇權在50點時,往上跳一ticks是1點,而往下跳一點則是0.5點。讀者可以從下圖仿真交易的畫面中更看出這點的差異。

 

圖片 3

 

比較兩岸交易規則差異時,其中有一點差異特別讓J注意到,並可推演到交易策略上,而這交易規則是「履約價的上市規則」。讀者可先行閱讀下圖。

 

圖片 5

 

比較早參與台指選擇權交易市場的讀者可能會有印象,以前台灣履約價上市的交易規則跟現在(2010/10/19後)是不同的,可先參考下圖紅框處。

 

圖片 4

 

現行的規則修改如下。

 

圖片 6

 

現在讀者有沒有發現,中金所目前規劃的交易規則就像以前台灣的交易規則,而這其中隱藏了很好的交易機會與策略,我想經歷過以前08年大波動的時候的讀者可能會想起,當年我們在作交易的時候會出現PUT履約價不足的問題,就算想買便宜的權利金,因為只多開5檔履約價而導致行情大幅變動的時候連最遠的履約價都超級貴,讓許多人無法狠下心去買這保險或利用選擇權作空,而眼睜睜看著行情繼續快速往下而錯失大好賺錢機會。

 

現在再去看看大陸的交易規則與J的仿真交易截圖,讀者可以發現中金所只多開到當時指數的價外3檔(150點),而其指數的漲跌停還比台灣7%大(滬深指數10%),我們簡單計算一下,如果滬深指數在3000點,若出現稍微大一點的波動例如5%的幅度,就已經讓指數變動150點,因此只要指數高一點或波動再大一點,是非常容易超過3檔價外,所以散戶與法人的行為就可能再次出現與台灣過去一樣的極端狀況,例如昨天的便宜價外,開盤後突然變成很貴的價平,法人大量買進避險,散戶買不下手,而收盤時已經變成深度價內,最後回頭一看,這種讓你貴到買不下手(例如BUY PUT),最後就是眼睜睜看著行情繼續大幅同向波動, 錯失一次賺大錢的機會。

 

本篇除了簡單的提及了大陸選擇權市場的發展現況外,主要期望提醒讀者,交易制度的研究也是相當重要的,對於每個合約設計的環節都是會影響到交易策略的設計與市場的波動,本篇J的小想法,僅是站在歷史可能重演的角度發想,也許之後其選擇權上市前交易規則有可能再作調整,讀者可持續關注明年的正式上線。

 

2013年12月26日 星期四

Trend Following 趨勢追隨策略類型

 

Trend Following趨勢追隨是 期權交易分類 裡最基本的一個策略,這也是每個人都知曉的策略。目前(2013/12)在 isag 裡列出的611檔CTA中,有311檔的策略類型完全或部份是Trend Following,是所有列出的策略類型中最多的一種。

 

Trend Following基本的邏輯就是利用技術指標判斷趨勢方向,然後持有跟隨,這些指標都是一般常見的例如moving average、MACD、breakout X days等等,它的特性就是在趨勢市場獲利,不論是漲勢或跌勢,而在震盪盤整期虧損,因為常常碰到停損或轉向

 

在這些Trend Following類型的CTA裡要找表現很好的有很多,要找到表現很差甚至破了MaxDD的也不少。可見要作的好也不是容易的事,就像我們大家一群人,就算用同一條線作為主要邏輯,最後結果也會是天差地遠。

 

isag Maxdd

 

L記得朋友說過程式交易不就可以解決這些問題了,一樣的策略給誰作都一樣,其實L心裡想的是,不論誰作都會不一樣,但要解釋很花時間。會變成這樣的原因非常多,資金不同、環境不同、個性不同、容忍風險程度不同、執行能力、保持紀律的能力等等,不適合的人用策略兩三次交易就用不下去,兩三天就想換了,那這樣就算策略在中長期可以獲利根本就不重要了。

 

程式交易可以解決一部份問題,但設計的策略、資金運用、風險控制等等還是離不開交易策略的本質這些都是關於 交易心理與經驗 的影響,這也是交易員不會停止的課題,而且它的重要性是比其它分類(交易方法、系統建置、程式交易策略)還更重要,畢竟你設計出來的東西是來自於你怎麼想的。

 

回到Trend Following的特性,需要再特別強調當行情出現時絕對、必須要能獲利。不論你是自己作單、幫親友操作、在公司作交易員,都一樣,假設操作台指期碰到一波400~800點行情時,你的策略卻賺不到錢,那是很糟糕的事情,不管你有什麼理由,別人都會認為你的策略不行,如果小漲小跌沒賺錢,大漲大跌又賺不到錢,那還要作什麼交易?

 

當然不是說策略只有Trend Following這一種,只是在對應盤勢上,當有行情出現時,一般人會給予更高的期望,這可能也是普遍把Trend Following作為基本策略的原因之一。

 

設計Trend Following類型的交易策略有幾個主題

  1. 要選用什麼指標作判斷? 前述的moving average、MACD、breakout X days會一一測試介紹。

  2. 要選用多長的期間? 其實也等於你的目標波段要多少點?

  3. 如何有效避免震盪洗刷的次數?

  4. 對應程式交易策略的標準如何?


 

以上,再慢慢紀錄了

 

2013年12月20日 星期五

台指2013年12月份結算

 

台指2013年12月份結算,來檢視一下行情走勢和對應的策略表現。

 

12

 

 

開倉的價格約在8100,也是這個月的低檔了,盤勢一直延續著從十月初以來的區間震盪,直到12月開始後是一連串的區間洗刷,開高走低、開低走高及上下影線,本月程式單非常難熬,如果操作部位僅使用台指期貨的話,這個月幾乎就是慘。

 

另外一提,18號結算壓低後碰到12/19這天的跳空,是可以預防的,如同之前 美元與FOMC會議 文章中所紀錄的原則,在會議公布的日子少作多看或是利用這個特性來設計策略。實際上18號的波動率提升不少,在19號開盤後又降低回去,就是一個常見的狀況。

 

選擇權策略中有紀錄的一種,台指選擇權結算買賣方損益 在8100履約價作的跨式買方部位,成本230點,結算238點,表現普通。2014年1月的合約波動率依然很低,照策略走持續作買方。

 

op

 

這一個沒行情又小區間震盪的月份肯定難熬,這也是磨練交易心理的時候。策略虧損是一定會發生的,如果讀者和L一樣在這個月操作不順的話也別緊張,只要虧損是在容忍的正常範圍內,控制好資金的比例,穩定好自己的心態,然後就加緊檢視和設計不同策略和不同商品吧

 

以策略來說,再設計的策略特性要不很長,要不很短,長的長到這種一兩百點的區間震盪刷不出來,短的就研究極短線和TICK Trade,將策略的特性區分開來。另一方面就是選擇權策略的研究,難以預期如此小的波動率會再持續多久,可以想想投資組合加上賣方策略是否合適,也可以嘗試從現有程式訊號轉成賣方部位來測試。此外就是測試不同的商品,開發國外期貨的策略。趁著這個月虧損,加倍研究的動力吧。

 

 

2013年12月17日 星期二

臺指期、臺指選擇權2014年5月15日歐洲掛牌上市

 

期交所發布了新聞稿,可到期交所網站看全文。其中有重點說明:

 

一、掛牌商品:期交所授權 EUREX 推出新臺幣計價,以 TX 及TXO 為標的之一天期期貨契約

 

二、交易時段:限於期交所與 EUREX 均為交易日之期交所盤後時段。本商品規劃在 EUREX 之交易時間為德國時間 7:45~21:00 (日光節約時間 8:45~21:00),即臺灣時間 14:45~4:00 (日光節約時間14:45~3:00)。

 

三、不影響我國期貨市場正常交易時段之交易人部位:因該商品之最後結算價為當日臺股期貨契約及臺指選擇權之每日結算價,不會造成臺股期貨及臺指選擇權之盤後價格波動風險,故對我國期貨市場正常交易時段之交易人部位風險並無影響

 

四、在 EUREX 交易時,遵循 EUREX 相關規範:本商品在 EUREX交易,視同國外期貨商品,應遵循 EUREX 交易、結算、市場監視等規範。

 

五、每日未沖銷部位處理方式:每日 EUREX 交易時段結束,期交所次日開盤前,期交所帳戶最終受益人(交易人)於 EUREX 之未沖銷部位將實物交割為 TX 及 TXO 部位,並移轉回期交所,併入該交易人於期交所之 TX 及 TXO 未沖銷部位,該交易人部位應依我國期貨市場交易、結算、市場監視及保證金等相關規範,由期貨商完成相關檢核後,始完成部位移轉之程序。

 

以上五個重點是新聞內容,以下是L的一些觀察和想法。

 

既然是台灣盤後時間的台指期權交易,那很自然就要跟摩台比一比了

 

從投資人的角度來看交易和避險需求,

一、Eurex台指交易時段很長,會到台灣時間凌晨4點,比摩台長。

二、新台幣計價,標的就是台指期,而摩台期是美元計價,標的是摩台指數。Eurex台指對於台灣投資人當然是比較直觀方便。

 

從商品本身的設計來看影響,

一、摩台和台指是近似但不同,再加上摩台和台指交易時段白天是重疊的,使得流動性分散。

二、Eurex台指和台指是完全一樣的標的,晚上的交易部位到了白天會直接轉換成台指。時段是區隔的,不會影響現有台指流動性,反而在晚上的部位轉回台指會增加台指的流動性。

 

從投資人和商品的角度來想,Eurex台指都比摩台的優勢多,只要看到時候Eurex台指的成本多少,量是不是夠大。如果量夠大,或許以後晚上就是看它而不再是摩台了,然後就繼續開發盤後的台指交易策略。

 

當然重點是量會不會夠,在Eurex看到有前例可尋,Eurex KOSPI Product (OKS2)

 

這個商品是韓國交易所的KOSPI 200 指數選擇權在Eurex交易,時段區隔,韓元計價。我們期交所應該就是參考他們的模式來設計Eurex台指。他們的產品是成功的,L看近期成交量在7萬口以上,有時會到15萬口以上,所以Eurex台指應該也是蠻看好的。

 

 

2013年12月14日 星期六

秒K應用

 

一般多數交易者在使用或觀看K棒的時候,通常從1分、5分、10分線開始著手,稍微想做些差異化的時候可能使用2分線、3分線、7分線等較少見的K棒周期,然而若跳脫分線框架,當科技進步,電腦效能日新月異,秒線的使用在MC上也已經完全不是問題,也許現今交易的戰場已經不是分線可因應?為了證明這個想法或差異化我們既有的策略,我們開始思考使用秒k來作交易,至於該要設定多少秒呢?

 

J這邊可以提供讀者一個方向,首先看一個例子,3分線表示180秒,若設定為177秒,則因為177/(180-177)=59,所以表示當一般的3分線走了59根K棒之後,因為每一根省下3秒的時間,導致在177秒的K棒設定下,圖上已經畫出了60根K,反之設定成183秒則比原本分線少1根K棒。

 

透過多或少製造1根K棒,也許能讓我們減少一些在整分時敲單的滑價(因一般程式單若是用指標型撰寫將在00秒時敲單),而本篇將延續海龜通道突破策略的精神,稍微小改程式碼成為利用close價突破來進單的指標型策略,以反映秒k收盤價的微小差異在近年來的影響。

 

程式碼修改如下圖。

 

1

 

建立用close所創造的高低區間,回取K棒數(HL)參數讀者可自行嘗試。

進場與出場也以最簡單的方式修改如下圖。

 

2

 

須注意,在撰寫秒線以下層級時,TIME要改為TIME_S才不會錯誤喔!另外本篇利用之前提及的尾盤出場策略1-建立日期表,作最後進場與出場時間調整,以及漲跌幅超過6%的進場限制。

 

在參數相同的情況下,本篇利用最多加碼5口來突顯出3分線與177秒的差異,首先我們先來看3分線的表現如何,回測時間為2007年至今,來回成本單筆設定800元。

 

3

 

再看看177秒的績效圖如下。

 

4

 

可以發現兩者在同樣狀況下,177秒K的回檔略小於3分線,而且獲利大約多了快100萬。再來觀察近年來表現,如下圖所示。

 

5

 

上方的圖是3分線,可以看出近年來已經無法再創新高(上次新高點大約為2011年2月),而下圖177秒K的在2013年9月還有再創新高。

 

經過本篇的實驗證實,也許過往的簡單模型在近年來無法表現得令人滿意,但透過細微的變化,許多邏輯仍然是持續有效的,只是現在交易的戰場或許已經拉到秒K上了,讀者可以再延伸思考透過不同的以往的K棒計算,可能也會有更好的表現。

 

 

2013年12月13日 星期五

QuoteManager 回補期交所行情資料(C#)

 

下單系統有時候難免會出狀況,行情漏接是偶爾會碰到的問題,這時事後就要處理行情的回補。如果是有訂閱行情資料的可以線上回補即可,但沒有的呢? 可能要請別人匯出文字檔來回補,但就是有點麻煩。其實偶爾漏個一兩天,還是有簡便方法可以自己處理的,就是直接拿期交所行情來回補。

 

期交所的網站有過去三十日的行情資料提供下載,如圖。

 

download

 

我們下載之後可以得到一個ZIP檔,解壓縮後得到RPT檔,其實就是文字檔,裡面包含當日所有期貨商品的TICK資料,不過我們僅需要台指期的資料而已,這時就要作些小小處理,先看RPT檔的格式。

 

rpt

 

格式為日期,商品,月份,時間,價位,成交量,還有跨月價差用的欄位。而我們想要轉資料進的QuoteManager,要求的TICK檔格式為日期,時間,價位,成交量,如下圖。

 

tick format

 

所以可以利用一個小程式,將格式轉換輸出文字檔就OK了,如下圖,一個來源的RPT和一個輸出的TXT,兩個檔案的路徑和一個執行按鈕。

 

form

 

程式很短,我們只需要兩個輸出入串流,

FileInfo source = new FileInfo(textBox1.Text);
StreamReader sr = source.OpenText();

FileInfo destination = new FileInfo(textBox2.Text);
StreamWriter sw = destination.CreateText();

 

設定來源及目的的檔案路徑,然後處理來源的期交所資料,

其中要處理的部分有:

1. 只要台指期近月

2.成交量要除以2

3.處理成QM的TICK格式(有符號/、: 這個)

 

關於期交所資料每日下載的排程設定可以參考前文,取得期交所每日行情資料 。

程式碼如下,歡迎參考指教。

 
namespace RPTtoQM
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{

FileInfo source = new FileInfo(textBox1.Text);
StreamReader sr = source.OpenText();

FileInfo destination = new FileInfo(textBox2.Text);
StreamWriter sw = destination.CreateText();

String tmps = "";
String month = "";
int qty=0;

while( sr.Peek()>=0 )
{
tmps = sr.ReadLine();

if ( tmps.Length>=10 && tmps.Substring(9, 2) == "TX")
{
if (month == "") { month = tmps.Substring(17, 6); }

if (tmps.Substring(17, 6) == month && tmps.Substring(23, 4)==" ")
{
if (tmps.Length == 50) { qty = Int32.Parse(tmps.Substring(41, 3)) /2 ; }
else if (tmps.Length == 49) { qty = Int32.Parse(tmps.Substring(41, 2)) / 2; }
else if (tmps.Length == 48) { qty = Int32.Parse(tmps.Substring(41, 1)) / 2; }

sw.Write(tmps.Substring(0, 4) + @"/" + tmps.Substring(4, 2) + @"/" + tmps.Substring(6, 2) +","
+ tmps.Substring(29, 2) + @":" + tmps.Substring(31, 2) + @":" + tmps.Substring(33, 2) + ","
+ tmps.Substring(36, 4) + "," + qty.ToString() +
"\r\n");
}
}

}

sw.Flush();
sw.Close();
sr.Close();

}
}
}

 

 

 

2013年12月11日 星期三

選擇權GREEKS實作(C#)

 

在能夠計算 選擇權評價-BS MODEL (with Excel) 及 隱含波動率 (with EXCEL VBA、C#) 之後,再來剩GREEKS了,要計算四個影響價格的變數是Delta、Gamma、 Vega、Theta,完成這部份就可以得出目前選擇權部位組合的各項數值。關於這些希臘字母的定義和作用,都需要深入瞭解後才能對選擇權策略有所掌握,進而設計出選擇權策略。

 

此篇要紀錄的僅是關於系統開發,雖說大部份的交易軟體都會提供GREEKS資料,但總要是自己寫的才能確定正確性,因為券商軟體算的不一定對。當然也有許多人不在意些微差距,或根本沒在觀察GREEKS,但那樣操作選擇權是無法進步的,再說若要自己建立策略模組,這些也只是第一步而已。

 

大部份設計選擇權監視程式的軟體是EXCEL,因為最簡便,直接利用公式和一些函數設計就可以完成,若要即時串接部位的話,大部份是寫VBA程式和券商API串接,而行情的部份可以用DDE或API來接收。

 

但是EXCEL會有效能問題,如果接受行情多,再加上運算邏輯複雜,EXCEL很可能會有延遲的狀況,因此比較好的方式還是自己寫程式,可以先由券商API所提供的範例程式來測試,可能是VB、C#、C++或Delphi等等,選一個好寫的來測試收行情、回報、部位。此篇L要紀錄的是以C#來實作選擇權GREEKS。

 

整段範例程式碼貼在最後面,需要先說明一下前因後果,先有一個DataTable是用來紀錄未平倉的選擇權部位,這個副程式所要處理的是計算目前所有未平倉選擇權部位的GREEKS並寫進DataTable,這個DataTable再與DataGridView串接,就可以顯示在FORM上

 

這個DataTable,取名dtOI,至少有以下的欄位:

 

dtOI.Columns.Add(new DataColumn("SettleM", typeof(string))); //月份

dtOI.Columns.Add(new DataColumn("Strike", typeof(double))); //履約價

dtOI.Columns.Add(new DataColumn("CP", typeof(string))); //Call or Put

dtOI.Columns.Add(new DataColumn("BS", typeof(string))); //Buy or Short

dtOI.Columns.Add(new DataColumn("Qty", typeof(string))); //口數

dtOI.Columns.Add(new DataColumn("Match", typeof(double))); //成交價

dtOI.Columns.Add(new DataColumn("Market", typeof(double))); //市價

dtOI.Columns.Add(new DataColumn("VOL(%)", typeof(double))); //隱含波動率

dtOI.Columns.Add(new DataColumn("DELTA", typeof(double))); //DELTA

dtOI.Columns.Add(new DataColumn("GAMMA", typeof(double)));//GAMMA

dtOI.Columns.Add(new DataColumn("THETA", typeof(double))); //THETA

dtOI.Columns.Add(new DataColumn("VEGA", typeof(double))); //VEGA

 

在執行副程式之前,除了最後五欄之外都是準備好的,然後有一些變數要準備

AssetPrice 期貨價格

Strike 履約價

InterestRate 利率

Expiry 到期因子

Target 選擇權的市價

 

還有之前紀錄隱含波動率的類別,一開始要NEW一下。

Option op = new Option();

 

然後就開始了,看片段來說明一下

 

圖片 1

 

圖片 3

 

圖片 4

 

以下PUT的部份就依此類推。程式碼如後所貼,有一些使用到的參數及關聯FORM的變數沒有仔細說明,不過整個架構已經是可以瞭解的了。以前 L 設計時找不到完整的參考資料,一步步的自己設計,現在若有同樣需求的朋友看到這邊可以自由取用,歡迎參考及指正

 
private void Greeks()
{
int i = 0;
AssetPrice = double.Parse(label16.Text);

while (i < dtOI.Rows.Count)
{
Strike = double.Parse(dtOI.Rows[i]["Strike"].ToString());
Target = double.Parse(dtOI.Rows[i]["Market"].ToString());
Qty = double.Parse(dtOI.Rows[i]["Qty"].ToString());

//期貨
if (dtOI.Rows[i]["CP"].ToString() == "")
{
if (dtOI.Rows[i]["BS"].ToString().Trim() == "B")
{
dtOI.Rows[i].SetField("DELTA", 200 * Qty );
}
if (dtOI.Rows[i]["BS"].ToString().Trim() == "S")
{
dtOI.Rows[i].SetField("DELTA", -200 * Qty );
}
}

//CALL civ(double AssetPrice, double Strike, double InterestRate, double Expiry, double Target)
if ((dtOI.Rows[i]["CP"].ToString().Trim()) == "C")
{
if (dtOI.Rows[i]["PId"].ToString().Trim() == "TXO")
{
if (dtOI.Rows[i]["SettleM"].ToString().Trim() == label10.Text.Substring(0, 6)) //近月
{
AssetPrice = double.Parse(label16.Text);
Expiry = Expirynear;
}

if (dtOI.Rows[i]["SettleM"].ToString().Trim() == label11.Text.Substring(0, 6)) //遠月
{
if (label22.Text != "")
{
AssetPrice = double.Parse(label22.Text);
}
else { AssetPrice = double.Parse(label16.Text); }
Expiry = Expiryfar;
}
}
else //週選
{
if (wnFid != "MX")
{
if (dtOI.Rows[i]["PId"].ToString().Trim().Substring(1, 2) == wnFid.Substring(1, 2)) //近週
{
AssetPrice = double.Parse(label23.Text);
Expiry = Expirywn;
}
}

if (wfFid != "MX")
{
if (dtOI.Rows[i]["PId"].ToString().Trim().Substring(1, 2) == wfFid.Substring(1, 2)) //遠週
{
AssetPrice = double.Parse(label22.Text);
Expiry = Expirywf;
}
}
}

civ = op.civ(AssetPrice, Strike, InterestRate, Expiry, Target);
d1 = op.d1(AssetPrice, Strike, InterestRate, Expiry, civ);
nd1 = Math.Exp(-0.5 * d1 * d1) / Math.Sqrt(2 * Math.PI);
nd2 = op.NormsDist(d1 - civ * Math.Sqrt(Expiry));

//DELTA NormsDist(double x) d1(double AssetPrice, double Strike, double InterestRate, double Expiry, double Volatility)
DELTA = op.NormsDist(d1);
GAMMA = nd1 / (AssetPrice * civ * Math.Sqrt(Expiry));
THETA = (-(AssetPrice * nd1 * civ / (2 * Math.Sqrt(Expiry))) - InterestRate * Strike * Math.Exp(-InterestRate * Expiry) * nd2) / 365;
VEGA = (AssetPrice * (Math.Sqrt(Expiry)) * nd1) / 100;

dtOI.Rows[i].SetField("VOL(%)", Math.Round(civ * 100, 4));

if (dtOI.Rows[i]["BS"].ToString().Trim() == "B")
{
dtOI.Rows[i].SetField("DELTA", Math.Round(DELTA * 50 * Qty , 0));
dtOI.Rows[i].SetField("GAMMA", Math.Round(GAMMA * 50 * Qty * AssetPrice / 100, 0));
dtOI.Rows[i].SetField("THETA", Math.Round(THETA * 50 * Qty, 0));
dtOI.Rows[i].SetField("VEGA", Math.Round(VEGA * 50 * Qty, 0));
}
else if (dtOI.Rows[i]["BS"].ToString().Trim() == "S")
{
dtOI.Rows[i].SetField("DELTA", Math.Round(-DELTA * 50 * Qty , 0));
dtOI.Rows[i].SetField("GAMMA", Math.Round(-GAMMA * 50 * Qty * AssetPrice / 100, 0));
dtOI.Rows[i].SetField("THETA", Math.Round(-THETA * 50 * Qty, 0));
dtOI.Rows[i].SetField("VEGA", Math.Round(-VEGA * 50 * Qty, 0));
}
}

//PUT piv(double AssetPrice, double Strike, double InterestRate, double Expiry, double Target)
if ((dtOI.Rows[i]["CP"].ToString().Trim()) == "P")
{
if (dtOI.Rows[i]["PId"].ToString().Trim() == "TXO")
{
if (dtOI.Rows[i]["SettleM"].ToString().Trim() == label10.Text.Substring(0, 6)) //近月
{
AssetPrice = double.Parse(label16.Text);
Expiry = Expirynear;
}

if (dtOI.Rows[i]["SettleM"].ToString().Trim() == label11.Text.Substring(0, 6)) //遠月
{
if (label22.Text != "")
{
AssetPrice = double.Parse(label22.Text);
}
else { AssetPrice = double.Parse(label16.Text); }
Expiry = Expiryfar;
}
}
else //週選
{

if (wnFid != "MX")
{
if (dtOI.Rows[i]["PId"].ToString().Trim().Substring(1, 2) == wnFid.Substring(1, 2)) //近週
{
AssetPrice = double.Parse(label23.Text);
Expiry = Expirywn;
}
}

if (wfFid != "MX")
{
if (dtOI.Rows[i]["PId"].ToString().Trim().Substring(1, 2) == wfFid.Substring(1, 2)) //遠週
{
AssetPrice = double.Parse(label22.Text);
Expiry = Expirywf;
}
}
}

piv = op.piv(AssetPrice, Strike, InterestRate, Expiry, Target);
d1 = op.d1(AssetPrice, Strike, InterestRate, Expiry, piv);
nd1 = Math.Exp(-0.5 * d1 * d1) / Math.Sqrt(2 * Math.PI);
nd2 = op.NormsDist(d1 - piv * Math.Sqrt(Expiry));

//DELTA NormsDist(double x) d1(double AssetPrice, double Strike, double InterestRate, double Expiry, double Volatility)
DELTA = op.NormsDist(d1) - 1;
GAMMA = nd1 / (AssetPrice * piv * Math.Sqrt(Expiry));
THETA = (-(AssetPrice * nd1 * piv / (2 * Math.Sqrt(Expiry))) + InterestRate * Strike * Math.Exp(-InterestRate * Expiry) * nd2) / 365;
VEGA = (AssetPrice * (Math.Sqrt(Expiry)) * nd1) / 100;

dtOI.Rows[i].SetField("VOL(%)", Math.Round(piv * 100, 4));

if (dtOI.Rows[i]["BS"].ToString().Trim() == "B")
{
dtOI.Rows[i].SetField("DELTA", Math.Round(DELTA * 50 * Qty , 0));
dtOI.Rows[i].SetField("GAMMA", Math.Round(GAMMA * 50 * Qty * AssetPrice / 100, 0));
dtOI.Rows[i].SetField("THETA", Math.Round(THETA * 50 * Qty, 0));
dtOI.Rows[i].SetField("VEGA", Math.Round(VEGA * 50 * Qty, 0));
}
else if (dtOI.Rows[i]["BS"].ToString().Trim() == "S")
{
dtOI.Rows[i].SetField("DELTA", Math.Round(-DELTA * 50 * Qty , 0));
dtOI.Rows[i].SetField("GAMMA", Math.Round(-GAMMA * 50 * Qty * AssetPrice / 100, 0));
dtOI.Rows[i].SetField("THETA", Math.Round(-THETA * 50 * Qty, 0));
dtOI.Rows[i].SetField("VEGA", Math.Round(-VEGA * 50 * Qty, 0));
}
}

//dtOI.Rows[i].SetField("VOL(%)", i);
i = i + 1;
}

}

 

 

 

2013年12月6日 星期五

波段突破策略(with ATR)

 

紀錄一個常用也好用的邏輯,突破策略。區間突破最常使用在當沖程式裡,不過波段的程式使用起來也不差,基本邏輯就是由開盤向上漲多少要突破作多,向下跌多少要突破做空,很單純,最主要的因素只有這個突破的臨界點是如何決定?

 

先前曾經紀錄過簡單當沖突破的測試 - 當沖逆勢單進場。其中提到開盤點為準,漲50點作多,跌50點作空,如果沒翻就擺到收盤,這樣的邏輯在近年是無法獲利的。但是波段程式就不一樣了,能獲利。只是突破的區間要思考,不是單純點數或比例就能適用的。

 

這時 Average True Range(ATR) 平均真實範圍 就是個好用的指標,當行情波動大時,這個區間確認也應該放大,波動小時,則區間也小,因此加上波動性的指標有用處,ATR比其它波動性指標直接方便的是它本身就是價格的表示,而不是比例或無法對應的數字。例如ATR 100點,就是近期日高低點數平均在100點,而開盤後往上50點或往下50點的區間內都很正常,而我們設定的突破邏輯就是市價漲超過50點作多,跌超過50點作空。

 

搭配觀察指標和策略訊號的程式碼範例如下。

 

id

 

bkatr

 

在策略設計的部份只有一個參數,是要決定ATR用多少期間,其中變數TRX是每日的TR值,ATR用來紀錄…ATR,TR的陣列和其中註記//replace AverageArray的部份是因為Multicharts內建的AverageArray用起來不對勁,就自己再寫進策略裡,內容就是把TRX一個個放進TR陣列裡,放到最後一個時順便算一下裡面那些TR的平均值紀錄到ATR。

 

再詳細一點的紀錄程式,因為ATR在這個例子中使用的是日線層級,但實際運用的K線可能是10min、5min、8min之類的,會要再搭配其它的指標,所以才使用這種Array的方式將TR記錄下來,在新的一天開始時計算一次( date <> date[1] ),然後看是要多少個TR的平均,一個一個放進去,另外特別注意Array第一個位置是0起始,所以for迴圈裡目標值減一,這樣個數才對。

 

這個Array+For迴圈的方法在使用不同k線層級的指標時蠻好用的,可以多加利用,如果是常coding的朋友可能會覺得一個地方怪怪的,平常都是for i=0 to X,這邊因為i是 Multicharts 的關鍵字所以不能用,常常都要再改成 j….,是特別的習慣。

 

回到突破邏輯,以ATR所計算的近日高低作為區間,它近期的進出及績效(2005~2013,10min)如下。

 

chart

 

performance

 

trade

 

以一個不加濾網、不加出場邏輯、未設停損停利的邏輯來說,這樣的績效是蠻不錯的,值得繼續研究開發。

 

延伸一點的說,區間可以使用其它的波動性指標來調整、或直接用N日高低區間、或布林通道的區間、或參考CDP之類的,都可嘗試看看。這樣的突破邏輯應該是每個人都會測試過的基本款,不過應用時如何決定區間指標和如何搭配濾網就是深入的工夫了。

 

 

2013年12月5日 星期四

尾盤出場策略2-加強判斷

 

一支交易策略可簡單分成進場主邏輯、出場主邏輯,而當沖策略在尾盤必須出場的特性,使得其重要性在出場設計上不容小覷,然而根據 J 幾年來的觀察,似乎許多交易者並不太在乎這點,大多專心於進場與一般停損的設計,而最後出場僅使用指定時間出場,因此本篇延續 尾盤出場策略1-建立日期表,來簡單介紹一些尾盤現象對績效的影響性,提供讀者思考更多在尾盤邏輯設計的一些想法。

 

本篇測試的策略在進場主邏輯部分延續 通道突破策略  一文中所使用的程式碼,讀者可先行參考,然而為了增加交易次數以突顯出尾盤的影響性,本篇改用台指期1分線交易,參數也稍微修改,並配合尾盤出場策略1-建立日期表 所使用的最終出場時間作為初始設計,其出場設計如下圖,讀者可先回憶一下。

 

圖片 1

 

2007年至今交易績效如下(手續費來回共800元)

圖片 2

 

現在,開始進入本篇的尾盤出場邏輯,主要新增的想法是,交易時間以及賺賠對於出場快慢的影響,以及是否該逆勢找好的點出場(例如作多拉高出),或順勢出場(例如下跌後多單出場),讓我們直接看程式碼與績效得到簡單結論。

 

圖片 3

 

從上圖中可發現,若策略處於虧損狀態,且12點50分至13點時是上漲的,則於13點後就盡快出場,如同虧損時找有利的點出場,其改善的績效如下圖。

 

圖片 4

 

獲利增加約10萬,MDD幾乎不變,效果不錯,然而若是條件相反,當策略賺錢早點出場則會如何呢?直接看下圖績效來得到結論。

 

圖片 5

 

可發現獲利明顯減少23萬,MDD幾乎不變,符合虧損時早點讓部位出場,賺錢時讓獲利奔馳的精神,然而讓賺錢的部位一直持有到尾盤就是最好的嗎? J用同樣的手法找到稍微能繼續改善績效的方法,一樣直接來看程式碼。

 

圖片 6

 

其想法主要在思考,若是賺錢的時候,大多數當沖順勢策略應該也是賺錢,而假定多數策略與K棒周期的影響大約都在13:10至13:20分左右出場,因此若行情在此時間轉為與今日當沖走勢反向,也許顯示法人在尾盤作價上並不積極,持有過久也不一定能吃到13:30當沖強制平倉以及現貨收盤後期貨的順勢行情,使得順短期的勢先出場較有優勢,其績效如下。

 

圖片 7

 

獲利上升6萬,MDD續減少,反之此時若改為逆勢出場(即條件3與4對調),績效如下。

 

圖片 8

 

顯示若尾盤趨勢持續順勢,不該提早出場,將大幅減少獲利與增加MDD。

 

最後,透過尾盤簡單的上漲與下跌現象,與交易時間的特色,將有助於進一步改善交易績效,而本篇並非特別要研究其成因為何,只是挑出可能相對有意義的時間去做測試,得出符合一般賺錢精神的結論,賠錢快出,而且逆勢找好機會出效果不錯;賺錢要等轉弱再出,否則持有久一點較有優勢再了解簡單的尾盤狀況後,更進階讀者則可思考如何精進賠錢逆勢出的方法,賺錢順勢出的方法,也許可以找到更明顯改善績效的交易邏輯。

 

 

2013年12月3日 星期二

Average True Range(ATR) 平均真實範圍

 

之前紀錄過觀察行情波動的技術指標,有 歷史波動率 及 動能指標-ADX與Momentum ,此外常見的另一個指標是Average True Range(ATR) 平均真實範圍。目的都是由波動程度來輔助策略,應用在合適的盤勢及避開不合適的盤勢。而不同的計算方法則是各有其依據,每個人能領略並應用的程度也不同,但多認識一下總是好的。

 

定義的連結如 Average True Range - ATR,先計算其中的TR,取以下三者的最大值

  1. 今高-今低

  2. (今高-昨收)的絕對值

  3. (今低-昨收)的絕對值


然後再計算N個TR的簡易平均值

 

ATR定義

 

在說明中有簡單提到,高的行情波動會有高的ATR值,低的行情波動會有低的ATR值。

 

ATR值的計算很簡單,在MULTICHARTS裡也有內建了這個函數可以直接使用,例如下圖,使用AvgTrueRange,一個參數是要多少期間的平均數。

 

mc_atr

 

直接套用指標觀察圖形

 

mc_atr_pic

 

ATR如同其他波動性指標,在很多方面都可以應用,例如

 

  1. 單一指標的高低比較,由設定的門檻判斷波動的高低值。

  2. 長短期的ATR互相比較,判斷近期相對的波動率程度走向。

  3. 將ATR應用在帶狀指標的範圍決定上。

  4. 應用在出場的條件,例如遇上K棒遠大於ATR的區間時,是否適合停損停利。

  5. 也可以應用在停損的設定上,ATR小讓停損小,ATR大讓停損大。

  6. 某些基於K棒強弱度的策略邏輯可以應用ATR過濾不具代表性的K棒。


 

以上提到的各項都各自有測試應用的價值,L自己也有應用到的部份,不過以目前的應用程度來說,還不及ADX的順手,在有不同想法時仍會想到測試使用看看,或許有更多的好用之處,就請朋友們動手使用看看囉~