2016年1月7日 星期四

函數(_DailyProfit):取得過去第N日的當日損益


程式交易小學堂─期貨投機事業的王道
MultiCharts 內建函數中已經有當日賺賠的次數,也有當日已經進場、出場的次數,還沒看到取得某日損益變化的函數。而對我來說,我很關心每天的權益值變化... 這很重要。

所以,我們自己做個函數來取得以日為單位的損益數值。
函數名稱:_DailyProfit,參數 為 daysAgo。參數輸入 0 可取得今天的損益變化,輸入 1 則是昨天,2 則是前天... and so on。

函數(數值、序列) Code 如下。我使用一個動態陣列,透過輸入的參數值來決定陣列的大小,在每天的換日的那根K棒把用來儲存每日損益的陣列往前偏移一格後,再把昨日的 equity 記錄在陣列的第 1 格...(陣列偏移函數,點我),得到記錄每天 equity 的陣列。再把陣列中的指定格的數值減去前一格就可得到指定第前 daysAgo 日的損益了。
input: daysAgo(Numeric);
var: equity(0);
array: dayEquity[](0);


equity= i_OpenEquity;
array_setmaxindex(dayEquity, daysAgo+1);

if D>D[1] then
begin
  _arrayShift(dayEquity);
  dayEquity[1]= equity[1];
end;

if daysAgo=0 then
  _DailyProfit = equity - dayEquity[1]
else
  _DailyProfit = dayEquity[daysAgo] - dayEquity[daysAgo+1];


寫個簡單的指標來引用這個函數,在圖表上顯示今天(0)的損益、昨天(1)的損益、前天(2)及大前天(3)的損益。

把指標放上圖表,顯示出 4個數值,我們怎麼知道這是不是對的呢?你可以自行計算來驗證,或者像這樣對照一下回測報表中的日權益。It works。

2015年10月23日 星期五

MultiCharts的 點數K棒 有Bug


程式交易小學堂─期貨投機事業的王道
起源於日前 樸格交易團隊 發表了一篇利用 RangeBar 來避開盤整的方法,文章連結:https://goo.gl/OtO0P0。該文章中,我從樸格所帶上的圖去推測,應該就是 MultiCharts 上的,"點"圖。在圖表上,商品這部份的設定如下,試試看吧。


雖然,之前我曾經發過文章說到,這類 tick base Bar 很有回測與實際交易上的問題存在,文章可見:http://goo.gl/R3wLDt。而 Range Bar 的概念,經過朋友給我解釋,我想了一下,的確是不大受 tick 資料遺漏所大幅影響 K棒呈現的,應該可用。只是,就在我想把這個想法應用到 個股期貨時,意外發現了 MultiCharts 在 點K棒(也就是 range bar)的 BUG了。

我們先很普通的把圖表設定好,開起來就可以看到一如預期的,每根 K棒的長度是一樣的。


不過,在我打開回測報表的時候,卻發現了奇怪的現象,你注意到了嗎?這些訊號的進出場價位,都是不存在於真實世界的!因為,在聯發科200多元這價位,是每 0.5 一跳的,怎麼會有這樣的進出場價位呢?


看到了以上的回測報表,我立刻懷疑是凱衛給我的歷史資料有問題,畢竟...,咱們就不多說了 XD  可是,我打開 QM 看了一下歷史資料,看起來卻很正常,沒有那些奇怪的價位啊~


這下我就很疑惑了。接著想到,該不會 點數K棒 也來 Ranko 或是 Heikin-Ashi 那一招吧?但你只要把商品切到 TXF 卻又沒有這個問題,所以,這應該不是一貫的作弊方法。但是,這回測報表很顯然已經成了垃圾。我繼續檢查圖表上的 K棒,這下可妙了,從 K棒的開、高、低、收就是錯的了, Data Window 直接可視。


猜想著會不會是因為股票有不同價位帶而有不同的 miniMove,而價位高了實際上報價的每一跳,超過 miniMove ,blah blah... 如果是這個問題的話,那應該會影響所有的圖表,於是開啟傳統的時間週期 K棒來看看,卻是正常的很!


這樣的測試比較,我在 8.5 x64 與 9.1 x32 都試了,一模一樣的情形。到了這裡,我們幾乎可以推斷,目前來說,要在 MultiCharts 上使用 Range bar,恐怕是有 bug 存在的,如果你有打算使用 Range bar 的話,最好多多小心。因為,我還看到了一個更妙的狀況,如下。或許這根 K棒的結束 tick 價格真的就是直接跳很大,但我沒有去仔細檢查了,


2015年7月31日 星期五

收盤前平倉_當沖專用(訊號)


程式交易小學堂─期貨投機事業的王道
最近又看到人家在問,想要在收盤時平倉。在 MultiCharts 上,實際上是做不到收盤"時"平倉的,因為當真的收盤的時間一到,不管你的下單機有多快,委託單送出得到的回報必然只有一個:拒絕委託,非交易時間。

而在 MultiCharts 用來作為每天的收盤清倉的指令:SetExitOnClose,實際上是個僅供"回測"的指令,這個指令是無法用在盤中驅動買賣動作的。只要花點時間去觀察就知道,盤中報價持續跳著,即使你在訊號程式碼中下了 SetExitOnClose,但到了 13:45(TXF為例),它就是不會產生平倉訊號,我們得把圖表關掉重開,才會看到平倉訊號出現。

那麼,實際上我要在臨收盤前把部位清掉的話,該怎麼做呢?得獨立做一個訊號,專門來幹這件事,它必須開啟 IntrabarOrderGeneration 模式,只下平倉命令,沒有進場命令,訊號程式碼如下:
[IntrabarOrderGeneration = True]


input:exitTime( 134457 );
var:cleanTime(0), now(0), realTiming(false), toClean(false);

if LastBarOnChart then begin

  now= currentTime_s;
  cleanTime= iff( _Checkday, exitTime-1500, exitTime );
  realTiming= now>=cleanTime and now<=134500;
  toClean= realTiming and Time_s>=cleanTime;

  if toClean then begin
    if marketposition>0 then Sell (" clean ") next bar market;
    if marketposition<0 then Buytocover ("clean") next bar market;
  end;

end;

RecalcLastBarAfter(1);

訊號的參數是到秒格式的指定時間,時間一到要做平倉出場動作,以上 code 預設值是 13:44:57 。通常來說以國內的下單機速度,3 秒鐘應該足夠用來委託的送達了,如果你擔心這樣的時間太緊迫或有個人喜好的話,自行調整參數去控制出場的指定時間。另外,因為結算日當天會提早 15分鐘收盤,所以我把執行出場時間在結算日當天自動減去 1500。

基於通常對盤中特定時間控制用 Q_time_s 來做,有可能因為臨收盤前各種原因沒有收到任何報價的 tick,因而無從發生 event 推動出場動作。所以,我特意採用 currentTime_s 並且搭配 ReCalcLastBarAfter ,直接讀取本端電腦時間去產生出場訊號,相對來說適應性更高。

在你做好了這個專門用來給當沖程式的指定時間到就強迫清倉出場的訊號後,需要把這個訊號跟你的當沖程式放在同一個圖表上,並作設定如下圖:



2015年7月18日 星期六

函數:讀取文字檔_利用ELCollections.dll


程式交易小學堂─期貨投機事業的王道
在 MultiCharts 中要把一些所需的資訊輸出出去,存成文字檔(.txt)的形式,內建於 MultiCharts 的 fileappend 與 print 指令都能順利辦到。另外,國內有凌波大分享的 outputfile.dll 與 下單大師的 omSignTXT.dll 可供使用,更能提供比內建指令更好的穩定性,避免檔案讀取權限被鎖住的問題。

但是從外部文字檔讀取資訊進來給 MultiCharts 使用,就沒有內建的指令可以使用了,在凱衛官方網站上,有網友 bodrigs 分享自製工具,我有使用一段時日,但是如果欲讀取文字檔不存在的話,會導致整個 MultiCharts 整個 crash 掉,算是使用該資源的一項風險。其後,又有網友 swwang1999 分享相同功能的資源,說是即使讀取文字檔失敗,也不會造成 MultiCharts 當掉。不過,幾經實驗,我依然不得要領。

經過一番 Google 後發現,原來安裝了 ADE 就會得到的 ELCollections.dll ,也可以用來讀取文字檔(資訊來源)。經過測試後,這個功能就算讀取文字檔失敗也不會造成 MultiCharts 當掉,只會出現個錯誤訊息,並且讓引用這功能的指標或訊號 OFF 掉而已,不會影響其他的圖表運作,相對安全。

由於要讀取文字檔內容,需要經過 ADE 套件中的三個函數依序協做,我乾脆把這幾個需要用到的函數內容複製出來做一些修改,合併成一個好方便使用,函數(_readFile,數值型)程式碼如下:
[LegacyColorValue = TRUE];

external method: "C:\AutoTrading\ELCollections_x64.dll", double, "ListN_New";
external method: "C:\AutoTrading\ELCollections_x64.dll", int, "ListN_ReadFile", double, LPSTR;
external method: "C:\AutoTrading\ELCollections_x64.dll", double, "ListN_Get", double, int;
external: "C:\AutoTrading\ELCollections_x64.dll", int, "_OnDestroyHandler", IEasyLanguageObject;

#Events
    OnDestroy = _OnDestroyHandler;
#End;



Inputs:FileName(string),Index(Numeric);
Vars:ID(ListN_New);


ListN_ReadFile(ID, FileName);

_readFile = ListN_Get(ID, Index);


要使用這個函數的時候需要兩個參數,_readFile(A, B)。A:文字檔的名稱,需包含路徑、B:讀取文字檔中的第幾行。使用範例如下,我用一個指標做這件事情,請自行參考。


因為這個 _readFile 函數需要使用到 ELCollections.dll,而 ADE 有分 x64、x32 的版本不同,我自己使用 x64 的,如果你不想為了這個功能就去做整個 ADE 的安裝工程的話,我把 ELCollections.dll 複製出來,跟函數 _readFile 的 pla 檔及 sef 檔(8.5_x64),一同打包在一起提供下載。下載點:download from GoogleDrive

解壓縮開後,需要把 ELCollections_x64.dll 放到 C:\AutoTrading\ 之下,因為函數 readFile 的程式碼已經指向了這個路徑。或者你得修改程式碼內容(參照上方程式碼中藍色字)去對應好,看你把 ELCollections_x64.dll 放在哪邊去了。

注意:本函數的調用,被讀取的文字檔內容中,必須全部內容都是數字,不可含有字母、空格或是其他符號,可分多行,一如上圖中的 123.txt 那樣。另外,被讀取的文字檔,不可以用 FileAppend 去寫,會發生權限打架而導致失敗。

2015年7月10日 星期五

分散交易是為了什麼?


程式交易小學堂─期貨投機事業的王道
今年的台指也許是跳空方向的關係,也也許是走勢的來回,總之讓有掛在台指期上的策略大多數表現不佳,因為這項商品本身的走勢,似乎對一般大家使用的順勢交易策略,並不友善。

分散到不同的商品,為的應該是更多的機會可供選擇,因為只交易一種商品就只有一種機會,不管這個商品是不是 TXF,至少不同的策略掛在相同商品上只會有同一種 GAP。


等待交易的商品清單,在任意時間區段中,總是會有比較好做與比較難做的,而所謂的比較好做或難做,其實不是商品本身的走勢乾淨與否,其實是直接跟掛在其上的策略一併表現的。我相信今年的台指,還是有人的策略績效表現得很好。所以,什麼叫做好做或不好做?

畢竟,透過不管什麼面相去評估商品走勢本身是否好做,都是在預期商品會讓某個策略有比較好的績效表現。如果在投入資金之前的商品 ranking 得到 IF300 是該優先交易的商品,但策略掛在其上之後,卻是表現不佳,那是策略的錯嗎?又或者是給商品做 ranking 的指標的錯?

因此,直接去對商品做 ranking 似乎就怪怪的了。難道,我們不該直接對圖表(某商品掛上某策略)的績效做 ranking 嗎?

不過,直接對圖表績效做 ranking 的話,就得有個前提必須成立:圖表的績效不會是隨機表現。而這個假設是正確的嗎?

2015年6月10日 星期三

函數 _ChartSleepDetect:圖表睡著的通報


程式交易小學堂─期貨投機事業的王道
每每在課程中講到程式交易的一般障礙自動自我救援的時候,我說出 MultiCharts 其實時不時還是會有圖表報價"睡著"的意外發生時,同學幾乎都是一副不可思議的表情。是的,圖表會睡著!是睡著,不是死掉,不是當掉,也不是斷線...

一般來說,如果報價中斷或是網路斷線,在 MultiCharts 上所有圖表的報價就不會跳了。但是,在我多年的使用經驗上,實際上多次發生好幾個圖接收同一個商品報價,卻只有其中某一個圖的報價不會跳,而其他圖表的報價依然在跳動,這證明了網路沒斷、報價有進來,僅僅只有那個不跳報價的圖表昏過去了(難道是賠太多嗎 XD)。這狀況其實很嚴重啊!因為不是報價中斷,不會觸發 Multicharts 本身的自動重連或是自動回補機制,只有那個圖表遺世獨立而已...

在我的自動救援機制中,自有其應對之道。但我還想進一步知道到底是哪一個圖表睡著呢?

2015年5月16日 星期六

函數 _bankerRound:四捨六入五成雙


程式交易小學堂─期貨投機事業的王道
MultiCharts 內建函數的 Round 是大家所熟知的四捨五入去到小數點以下幾位。但是,Round 這個幾乎所有程式語言都有的內建函數,卻不見得在每個語言中都是四捨五入喔。至於,什麼是"四捨六入五成雙"?可以查一下 banker's rounding。這裡有些不同 round 方式的介紹:http://goo.gl/gTpp9b

熱門文章