XQ安控失效

  •   340 
  • 最後發表   allen_XQ  4 週前
allen_XQ 發文於   2025/04/30

目前打期貨全日盤遇到每日最多進場次數設定一次 , 實際上每天會打超過一單 造成額外損失的問題

爬文之後有先在程式內用條件嘗試做一天只打一單的安控,回測時有發揮作用
(回測選擇每次進場次數不限,確實一個交易日只會打一單,我寫的安控邏輯在下面 請參考)
但實際上還是每天會打超過一次

想請問
1.請問系統安控失效的原因是什麼?有辦法改善嗎?
2.若只能自己用程式實現安控 , 請問還有什麼建議寫法? 要如何驗證是否有效呢 ? 

以下是成交紀錄時間軸 ,附檔也有紀錄
1.4/29 早上進場 4/29下午出場 (這邊換日 所以不算一天進場一次限制)
2.4/29下午進場  4/29下午出場(這邊以全日盤來看算是今天第一次進場)
3.4/30早上進場  4/30早上出場(這邊以全日盤來看算是今天第二次進場 -> 安控失效)
4.4/30下午進場  4/30下午出場(這邊以全日盤來看算是今天第一次進場)

另外這是我的虛擬程式碼(在程式內條件嘗試過濾,頻率為60分k ) 
洗價設定為逐筆洗價+自動洗價 洗價間隔一秒,自訂洗價時段為00:00-00:00
有開啟排程 時間為08:46-05:15
策略部位與庫存同步,並只啟用 庫存異動時自動同步數值

var: CurrentSec(0);
CurrentSec =  mod(CurrentTime, 100);  
condition1 = CurrentSec>=59 ; //在每個分K快收K時進場  
var: intraBarPersist OnOff(0);
if  currenttime >=150000 and currenttime <=150050  then OnOff=0; // 每次換日 reset 只下一筆單的flag

IF Position = 0  and OnOff=0  and condition1 THEN BEGIN  
    SetPosition(1,MARKET,label:="多單"); 
    OnOff=1;
End;

if position > 0 and condition1  and  Close >= FilledAvgPrice + 100 THEN BEGIN  
    SetPosition(0,MARKET,label:="多單停利"); 
End;

if position > 0 and condition1  and  Close <= FilledAvgPrice - 100 THEN BEGIN  
    SetPosition(0,MARKET,label:="多單停損"); 
End;


 再麻煩協助解決 感謝幫忙 


附加文件

排序方式: 標準 | 最新
allen_XQ 發文於   2025/05/05

再麻煩協助解決  謝謝  

虎科大許教授 發文於   2025/05/05

雖然台指期全日盤在4/29下午三點的交易日期是4/30,但4/30早上5點結束第一盤,8:15左右會清盤,這代表原本的設定都重新來過,所以4/30早上的進場,安控並沒有失效。

allen_XQ 發文於   2025/05/05

感謝回復 但請教下面問題 

8:15左右會清盤,這代表原本的設定都重新來過  
->這意思是假設 
4/29下午三點進出場後 , 4/30早上8:45後還是會打一口單 ,
而這代表實際上XQ的安控機制是"一個交易日會打兩口單對吧" 因為原本的設定都重新來過了 , 就像我遇到的情況一樣 


但回測是"一個交易日只會打一口單" 所以我認為是安控失效 , 因為我想實現的是和回測一樣"一個交易日只會打一口單"

而回測設定的策略安控也是指一天(一個交易日)進場一次 , 所以這樣對我來說等同於失效  

問題是發生在8:15清盤 這時把變數初始化了導致下該交易日第二口單對嗎?

全日盤為什麼在這時間點變數初始化呢? 

再麻煩協助解決 謝謝

虎科大許教授 發文於   2025/05/06

(1)4/29下午三點進出場後 , 4/30早上8:45後還是會打一口單

你可以這樣想,真實情況下,夜盤下的委託單若沒有成交,券商是不會保留該委託單到早盤,道理是一樣的。台指期的兩個盤,任何一盤結束,一切都恢復原本設定。

(2)回測是"一個交易日只會打一口單"

全日盤的回測,若安控設定只進場一次,確實昨天下午夜盤進場且平倉之後,今天的日盤就不會再進場。實戰時,你若希望與回測一樣,建議使用變數控制,若昨天下午的夜盤已進場一次,則今天的日盤不再進場。這樣就可以達到與回測的情境一樣。

(3)系統安控有其限制,除了整體策略的安控之外,我都會建議自己用程式安控。

allen_XQ 發文於   2025/05/06

感謝 虎大 回覆 , 我的程式裡面確實有用變數控制了,但是問題就如您所說的,卡進場條件被XQ 初始化了

 

我理解是這樣的

 

4/29 下午三點進出場後 ->  OnOff =1 ;

4/30 8:15左右會清盤 這代表原本的設定都重新來過  -> OnOff 被 initial成0  ->OnOff =0 ;

 

4/30 早上8:45後還是會打一口單 ->因為OnOff =0  所以滿足進場條件

 

 

var: CurrentSec(0);

CurrentSec =  mod(CurrentTime, 100);  

condition1 = CurrentSec>=59 ; //在每個分K快收K時進場  

var: intraBarPersist OnOff(0);

if  currenttime >=150000 and currenttime <=150050  then OnOff=0; // 每次換日 reset 只下一筆單的flag

 

IF Position = 0  and OnOff=0  and condition1 THEN BEGIN  

    SetPosition(1,MARKET,label:="多單"); 

    OnOff=1;

End;

 

 

或是虎大有推薦的寫法嗎? 感謝 

虎科大許教授 發文於   2025/05/06

只要重新啟動策略,變數都會被恢復預設值。這種情況,你可以考慮使用參數處理。在夜盤已進場,將參數設為1,亦即選擇“是”。

input: OnOff(0,"是否已進場?",inputkind:=dict(["否",0],["是",1]));

你上面寫的程式,在早盤時,並沒有辦法判斷昨天夜盤是否有進場。若昨天夜盤有庫存且策略部位選擇延續前次執行,則還可以通過filledEntryDate判斷庫存的日期,以確認夜盤是否有進場;但若夜盤沒有留下庫存,就無從得知夜盤是否有進場,除非在跑歷史K棒時,用變數記錄,模擬是否進場。

allen_XQ 發文於   2025/05/06

感謝回覆 但我想釐清一件事 謝謝 
如果把本交易日已進場的flag
定義成input input: OnOff(0,"是否已進場?",inputkind:=dict(["否",0],["是",1]));

那麼下次重啟策略(早上8:15清盤 重啟變數)時 
OnOff 是否會繼承上一次的值呢? 
如果不會的話 那麼這樣還是會重複進場對吧? 
如果會的話 我這樣寫是否可以達到我預期效果? 

 

 


input: OnOff(0,"是否已進場?",inputkind:=dict(["否",0],["是",1]));

var: CurrentSec(0);

CurrentSec =  mod(CurrentTime, 100);  

condition1 = CurrentSec>=59 ; //在每個分K快收K時進場  

 

//var: intraBarPersist OnOff(0);

if date = filledEntryDate then OnOff=1; // 如果是庫存進場日是同一天(今日已進場過),則OnOff=1

if  currenttime >=150000 and currenttime <=150050  then OnOff=0; // 每次換日 reset 只下一筆單的flag

IF Position = 0  and OnOff=0  and condition1 THEN BEGIN  

    SetPosition(1,MARKET,label:="多單");

    OnOff=1;

End;

虎科大許教授 發文於   2025/05/06

(1)下次重啟策略(早上8:15清盤 重啟變數)時 OnOff 是否會繼承上一次的值呢? 

參數一樣會保留你原先設定的值。若之前設定OnOff為1,它就一直是1,除非你啟動之前把它更改為0,才會接受進場。

(2)參數在程式執行期間是固定不變的數值,不可被改變,你這樣寫會出錯。

(3)用下面的程式碼,在下午三點前啟動策略,符合條件會進場,並監控出場。隔天早盤開盤前再根據第一盤是否有進場來設定OnOff。若已進場過,則設定OnOff為是(亦即1),這樣早盤就不會再進場。若夜盤沒進場,則改設為否(亦即0),符合條件就會進場並監控出場。

allen_XQ 發文於   2025/05/06

Hi 虎大 還是有點疑問

如果OnOff 從input 進來後就是read only ,不可更改的話,然後變數又會被Reset的話 
我用input進來的值當flag就沒有必要了

需要的是能夠取得前一次進場的日期資料 ,且是不會被Reset的參數對吧?
我想到的是FilledRecordDate(FilledRecordCount)


策略部位設定為 與庫存同步,並只啟用 庫存異動時自動同步數值

->請問這樣是否能實現一個交易日只進場一次?

程式如下

 

//input: OnOff(0,"是否已進場?",inputkind:=dict(["否",0],["是",1]));

var: CurrentSec(0);

CurrentSec =  mod(CurrentTime, 100);  

condition1 = CurrentSec>=59 ; //在每個分K快收K時進場  

 

var: intraBarPersist OnOff(0);

 

if date = FilledRecordDate(FilledRecordCount) then OnOff=1; // 如果進場日期是同一天(今日已進場過),則OnOff=1

 

if  currenttime >=150000 and currenttime <=150050  then OnOff=0; // 每次換日 reset 只下一筆單的flag

 

IF Position = 0  and OnOff=0  and condition1 THEN BEGIN  

    SetPosition(1,MARKET,label:="多單");

    OnOff=1;

End;


虎科大許教授 發文於   2025/05/06

(1)OnOff已宣告為參數,不能再宣告為變數。

(2)設定它是參數,就需要啟動策略前,人工判斷是否要修改參數,不會自動偵測。

(3)前面已經講過,若之前的策略部位選擇延續前次執行且第一盤有留下庫存,則你還可以透過filledEntryDate抓到庫存的進場日期,但若沒有留下庫存,則無從判斷第一盤是否有進場。

(4)策略部位選擇與庫存同步,並無法抓到第一盤建立庫存的日期,而是啟動部位時候的日期。

(5)用我最後提供的程式碼,每次開盤前(不管第一盤或是第二盤)都設定參數,就可滿足你的需求。

(6)我發覺你並沒有將寫好的程式先行編譯。應該是先編譯看看哪裡有問題,沒問題之後,試著用虛擬帳號演練一下,就可以知道策略是否如預期地運作

顯示更多回應 發表回覆
Close