一個交易策略的熟成

By | 2017-04-11

很多程式交易的前輩,都一再的提醒我們,在建構交易策略時,如果能夠使用彼此沒有啥相關性的因子,往往比用同類型可能彼此相互影響的因子要有用的多。這兩日,我在建構一個從籌碼面出發的程式時,深深地體會了前輩們的用心良苦,在一直用籌碼面的欄位撰寫交易策略,但回測效果都不夠好之後,我索興加入震盪型均值回復概念下的指標,然後又把外資的大盤多空方向考量進去,結果反而得到一個很理想的回測效果,今天想要跟大家來分享的,就是這一段心路歷程。

 

這些日,我試著想把每天的交易量,扣除現股當沖之外的部份,再看看法人及主力佔的比重有多大,我的理論是,當每天的成交張數是從散戶流向法人及大戶,後市應該是看好的,我試了寫了很多的腳本來測試這個理論,但效果都不好,以下的這個腳本勝率甚至不到四成。

value1=GetField("現股當沖張數","D");
value2=GetField("外資買賣超","D");
value3=GetField("投信買賣超","D");
value4=GetField("自營商買賣超","D");
value5=GetField("主力買賣超張數","D");
value6=GetField("融資增減張數","D");
value7=GetField("融券增減張數","D");
value8=volume-value1;//當日淨交易張數
value9=value2+value3+value4+value5-value6+value7;
//籌碼收集張數
if value8<>0
then 
value10=value9/value8*100
else
value10=value10[1];
value11=average(value10,5);
if value11 crosses over 10
then  ret=1;

後來我決定不再籌碼裡繞圈圈,我試著加上股價短中期都處於震盪的谷底向上翻的情況,我加上雙KD向上的條件,我把上述的籌碼腳本設成condition1,然後在腳本中加上如下的雙KD向上的條件

input: Length_D(9, "日KD期間");
input: Length_W(5, "周KD期間");

variable:rsv_d(0),kk_d(0),dd_d(0);
variable:rsv_w(0),kk_w(0),dd_w(0);

stochastic(Length_D, 3, 3, rsv_d, kk_d, dd_d);
xf_stochastic("W", Length_W, 3, 3, rsv_w, kk_w, dd_w);

condition2 = kk_d crosses above dd_d; // 日KD crosses over
condition3 = xf_crossover("W", kk_w, dd_w); // 周KD crosses over
condition4 = kk_d[1] <= 30; // 日K 低檔
condition5 = xf_getvalue("W", kk_w, 1) <= 50; // 周K 低檔

ret = condition1 and condition2 and condition3 and condition4 and condition5;
end;

加上這一段之後回測從2010年底到現在的資料,跑所有的股票,回測的結果如下:

17041001

這樣的回測結果非常的好,但七年的時間裡出現576次的交易機會似乎多了一點,所以我用公司連續十年都賺超過一億的股票下去跑,符合條件的股票有260檔,回測的結果如下圖

17041002

結果勝率更高,風險更低。

最後我考慮了大盤的因素,只有在過去十個交易日裡外資有五天以上是買超的情況下,才觸發,這樣的腳本,回測的結果如下

17041003

勝率達到2/3

這樣的結果,出乎我預期。

 

在沒有程式交易之前,我們手動下單的時候,也是會看看大盤的多空方向,會挑自己覺得OK的股票,會找合適的價格時點,會觀察籌碼的變化,最後才形成交易的決策。

因此,沒有道理反而在程式交易的時候,只憑價量的數據就擬定出交易策略。

以上是我最近在寫交易策略時的小小心得,野人獻曝,在尋找聖杯的路上,大家一起努力囉。

最後附上完整的腳本,當中有用了一個我自訂的函數叫tselsindex,這個函數有兩個參數,第一個是計算的天數,第二個是外資買超的最低天數,如果符合條件,會回傳 1,如果不符合則會回傳-1。

condition1=false;
value1=GetField("現股當沖張數","D");
value2=GetField("外資買賣超","D");
value3=GetField("投信買賣超","D");
value4=GetField("自營商買賣超","D");
value5=GetField("主力買賣超張數","D");
value6=GetField("融資增減張數","D");
value7=GetField("融券增減張數","D");
value8=volume-value1;//當日淨交易張數
value9=value2+value3+value4+value5-value6+value7;
//籌碼收集張數
if tselsindex(10,5)=1
then begin
if value8<>0
then 
value10=value9/value8*100
else
value10=value10[1];
value11=average(value10,5);
if value11 crosses over 10
then condition1=true;

input: Length_D(9, "日KD期間");
input: Length_W(5, "周KD期間");

variable:rsv_d(0),kk_d(0),dd_d(0);
variable:rsv_w(0),kk_w(0),dd_w(0);

stochastic(Length_D, 3, 3, rsv_d, kk_d, dd_d);
xf_stochastic("W", Length_W, 3, 3, rsv_w, kk_w, dd_w);

condition2 = kk_d crosses above dd_d; // 日KD crosses over
condition3 = xf_crossover("W", kk_w, dd_w); // 周KD crosses over
condition4 = kk_d[1] <= 30; // 日K 低檔
condition5 = xf_getvalue("W", kk_w, 1) <= 50; // 周K 低檔

ret = condition1 and condition2 and condition3 and condition4 and condition5;
end;

我回測是設五天後出場。

 

你可能會有興趣的文章

回應