做了一個自動交易計畫買賣連鎖,控制買賣間交易的策略用範本,
讓當日能夠在不同的情況下,在一個策略下進行,
相關的控制是否有遺漏不足之處或消耗資源
若有高手大神請不吝指教,也請小幫手幫忙!

範本轉換為交易程式碼如下
賣賣之間多加了Else。
異常如:
回測安控最大部位1張沒問題,2張會連續買進2張,3張會連續有連買6張的情況。
模擬交易也不太在預期內,會多買超過安控、委託超過設定時間沒刪單、當日達獲利時沒賣出。
Input:
P103(1.03), //獲利3%
P098(0.98), //回跌2%
T60(60), //逾時60
T300(300), //逾時300
C1(1), //1日均線
C2(2), //2日均線
C5(5), //5日均線
E12(12), //EMA 12日均線
E26(26); //EMA 26日均線
Var:
IntraBarPersist B1Pod(False), //尚未委買
IntraBarPersist B1P(FilledAvgPrice), //預設委買價格
IntraBarPersist B1T(0), //委買時間
IntraBarPersist B1PF(False), //委買尚未成交 復歸False
IntraBarPersist S1Pod(False), //尚未委賣
IntraBarPersist S1P(FilledAvgPrice*1.03), //預設委賣價格
IntraBarPersist S1T(0), //當沖委賣時間
IntraBarPersist S1PF(False), //當沖委賣尚未成交 復歸False
IntraBarPersist S2Pod(False), //庫存股尚未委賣
IntraBarPersist S2P(FilledAvgPrice*1.03), //庫存股委賣價格
IntraBarPersist S2T(0), //庫存股委賣時間
IntraBarPersist S2PF(False), //庫存股委賣尚未成交 復歸False
IntraBarPersist B2Pod(False), //庫存股賣出尚未當沖買回
IntraBarPersist B2P(FilledAvgPrice*0.98),//庫存股賣出後當沖委買價格
IntraBarPersist B2T(0), //庫存股賣出後當沖委買時間
IntraBarPersist B2PF(False); //庫存股賣出後當沖委買尚未成交 復歸False
value1 = average(close, C1);
// 計算 C1 週期的簡單移動平均 (SMA)
value2 = average(close, C2);
// 計算 C2 週期的簡單移動平均 (SMA)
value3 = average(close, C5);
// 計算 C5 週期的簡單移動平均 (SMA)
value4 = ema(close, E12);
// 計算 E12 週期的指數移動平均 (EMA)
value5 = ema(GetField("Close"), E26);
// 計算 E26 週期的指數移動平均 (EMA)
value11 = BarsLast(xf_EMA("D", Close, 12) cross over xf_EMA("D", Close, 26));
// 計算 12 週期 EMA 上穿 26 週期 EMA 到現在的天數
value12 = BarsLast(xf_EMA("D", Close, 12) cross under xf_EMA("D", Close, 26));
// 計算 12 週期 EMA 下穿 26 週期 EMA 到現在的天數
value13 = minlist(value11, value12);
// 取上述兩者較小的數值,代表最近一次金叉或死叉發生的時間
Value14 = highest(high, value13);
// 取得最近金叉/死叉期間的最高價
Value15 = lowest(low, value13);
// 取得最近金叉/死叉期間的最低價
//當日觸發訊號買進
B1P=FilledAvgPrice; //先指定委買初始值
B1Pod=False; //先指定初始值尚未委賣
Condition1 = trueAll(Value15 >= Value15[1], 3) AND trueAll(Value14 >= Value14[1], 3)
AND (Value14 - Value15) / Value15 >= 0.05;
// 條件1: 最近的低點和高點連續 3 個週期上升,且高低差距超過 5%
if FilledAtBroker <=2 // 檢查庫存數量,最多允許兩筆庫存
and B1Pod=False //尚未委買
and Position >=0 //目標部位非放空部位
//and Filled >=0 //實際部位非放空部位
and value2 cross Over value3 // 當短期均線 (C2) 上穿中期均線 (C3)
and Value11 < Value12 // 當前屬於 EMA 金叉階段
and Condition1 // 符合支撐與上漲條件
then
Begin
SetPosition(Position+1,Market,label:="訊號觸發買進");
B1P=GetField("收盤價", "Tick"); //紀錄委買價格
B1T=Getfield("時間","Tick"); //紀錄委買時間
B1Pod=True; //已經委買
end else
//未成交單逾時取消
if Position > filled //目標 > 實際部位
and B1Pod=True //已經有委買單
Then
Begin
If currentTime < 093000 //當下時間 < 09:30
and GetField("時間", "Tick") >= TimeAdd(B1T, "S", T60) //現洗價時間 > 委買時間+60秒
then
Begin
CancelAllOrders(label:="未成交逾時60取消買進委託"); //取消委買單
B1T=0; //委買時間復歸
end else
If currentTime >= 093000 //當下時間 >= 09:30
and GetField("時間", "Tick") >= TimeAdd(B1T, "S", T300) //現洗價時間 > 委買時間+300秒
then
Begin
CancelAllOrders(label:="未成交逾時300取消買進委託"); //取消委買單
B1T=0; //委買時間復歸
end else
if Filled > Filled[1] //沒有刪單而成交
then
Begin
B1PF=True; //確認委買成交
if date <> date[1] then B1Pod=False; // 復歸尚未委買 (可以進行下一次委買)
end;
end else
//當日買進當沖賣出
S1P=FilledAvgPrice*P103; //指定賣出佳價格初始值成本*P103
S1Pod=False; //指定尚未委賣
Condition2= GetField("收盤價", "Tick") > FilledAvgPrice * P103 //現在價格高於 (庫存+當日買進)平均成本的3% 獲利
or (B1P > 10 and GetField("收盤價", "Tick") > B1P * P103); //高於當日買進價位上漲3%(只可賣買入的數量)
if B1PF=true //委買已經成交
and S1Pod=False //尚未委賣
and Position >=1 //目標部位>=1
and Filled >=1 //實際部位 >=1
and condition2 //獲利條件
Then
Begin
SetPosition(Position-1,Market,label:="當日股獲利當沖賣出");
S1P=GetField("收盤價", "Tick"); //紀錄委賣價格
S1T=Getfield("時間","Tick"); //紀錄委賣時間
S1Pod=True; //已經委賣
if Filled < Filled[1] //已經賣出
then S1PF=True ; //確認委賣成交
if date <> date[1] then S1Pod=False; //復歸當沖尚未委賣 (可以進行下一次委賣)
end else
//庫存股獲利賣出
S2P=FilledAvgPrice*P103; //預設委賣初始價格
S2Pod=False; //尚未委賣庫存股
condition3=GetField("收盤價", "Tick") > FilledAvgPrice * P103; //庫存股獲利3%
if S2Pod=False //尚未委賣
and Position>=1 //庫存有量
and Filled >=1 //庫存有量
and condition3 //庫存股委賣條件
Then
Begin
SetPosition(Position-1 ,Market,label:="庫存股獲利後賣出");
S2P=GetField("收盤價", "Tick"); //紀錄庫存委賣價格
S2T=Getfield("時間","Tick"); //紀錄庫存委賣時間
S2Pod=True; //庫存股已委賣
if Filled < Filled[1] then S2PF=True; //庫存股已委賣成交
if date <> date[1] then S2Pod=False; //復歸庫股尚未委賣 (可以進行下一次庫股委賣)
end else
//庫存股賣出後回跌當沖買回
B2P=FilledAvgPrice*P098; //指定賣出當沖買回價格獲利2%
B2Pod=False; //庫股賣出尚未買回
Condition4= S2P >10 and GetField("收盤價", "Tick") < S2P * P098 ;//賣出的價位回跌2%獲利當沖
If S2PF=True //庫存股已委賣成交
and Position >= 0 //庫股存量0以上
and Filled >= 0 //庫股存量0以上
and condition4 //回跌獲利條件
Then
Begin
SetPosition(Position+1,Market,label:="賣出後獲利當沖買進");
B2P=GetField("收盤價", "Tick"); //紀錄賣出當沖買回的價格
B2T=Getfield("時間","Tick"); //紀錄賣出當沖買回的時間
B2Pod=True; //已下單買回賣出的庫股
if Filled > Filled[1] then B2PF=True;//已成交買回賣出的庫股 //庫存股已當沖買回
if date <> date[1] then B2Pod=False; //復歸庫股尚未買回 (可進行下一次庫股賣出後當沖買回)
end;
Hi xqyi,
不好意思,由於您的自動交易程式碼較複雜,故需要您提供
自動交易策略匯出檔案,匯出時記得勾選包含選股策略與引用函數,以便小幫手搭配您的自動交易策略設定變數來釐清問題的原因,
煩請您將上述檔案,Mail至客服信箱:XQservice@XQ.com.tw,並貼上此討論串連結,請小幫手收,以便小幫手安排釐清問題的原因,
以上,感激不盡。
已mail,請查收
Hi xqyi,
感謝,
若小幫手這邊收到後,會再安排釐清此題,
再次感謝您撥冗提供相關資訊。
Hi xqyi,
小幫手已收到您提供的相關資訊,
查看您的自動交易回測報告

在安控:單一商品最大部位:3,回測出來的結果,小幫手查看是符合交易安控的,單一商品最大部份控制在 3 個單位內,
因為 09/30 在 4971.TW 這檔商品,交易序號(簡稱 #)都有符合出場先前的部分後,才進場:
#1)進場時間是 09:00,出場時間是 09:23 → 此時單一商品部位是 1(#1 的部位)
#2)進場時間是 09:01,出場時間是 12:18 → 此時單一商品部位是 2(#1、#2 的部位)
#3)進場時間是 09:02,出場時間是 12:20 → 此時單一商品部位是 3(#1、#2、#3 的部位)
#4)進場時間是 09:24,出場時間是 12:22 → 此時單一商品部位是 3(#2、#3、#4 的部位,因為 #1 的部位在 09:23 出場)
#5)進場時間是 12:19,出場時間是 12:43 → 此時單一商品部位是 3(#3、#4、#5 的部位,因為 #2 的部位在 12:18 出場)
#6)進場時間是 12:21,出場是 隔日 09:00→ 此時單一商品部位是 3(#4、#5、#6 的部位,因為 #3 的部位在 12:20 出場)
#7)進場時間是 12:23,出場是 隔日 09:13→ 此時單一商品部位是 3(#5、#6、#7 的部位,因為 #4 的部位在 12:22 出場)
#8)進場時間是 12:44,出場是 隔日 09:27→ 此時單一商品部位是 3(#6、#7、#8 的部位,因為 #5 的部位在 12:43 出場)

以上說明,謝謝。
恩恩有觀察到安控部位3
可設定是
每日最大進場次數為1,但當日進場多次了 !
Hi xqyi,
您好,小幫手這邊用最新的 3.15.02 250102 版本,執行回測是正常的
單一商品每日最多進場次數:1

交易分析結果,證實每日的進場次數為 1

小幫手猜測您的版本可能是比較舊的版本,猜測應該是舊版本的問題,此問題已經修正在 3.15.02 250102 以後的版本,
您可以在官網下載並用完整安裝,覆蓋更新至最新的版本後,再試試看,應該就不會有您所述的問題,謝謝。
按設定>版本更新,顯示 目前為最新版本
3.15.02 241217
但手動下載個人版完整安裝後為
3.15.02 250102
沒有提示需更新版本!
若單一商品最多進場次數設為1。只要部位的方向不變,例如一直加碼,都符合進場次數為1。直到部位變0,才無法再進場。
這樣的設計,感覺有點特別,難怪連續買了多次,雖然中間也有賣出但未出清,也還繼續買。
這樣的情況下,最大部位的安控一定要設!
似乎失去了文章所提
這個安控的設計目的也是用來避免過多的交易,例如不斷的買進/賣出。
14 評論