回測和實盤交易結果不同

  •   2.2K 
  • 最後發表   龍槍  2024 六月 18
龍槍 發文於   2021/10/19

Hi 小幫手您好

最近利用撰寫好的交易腳本進行實盤交易時發現實盤交易的賣出時機點,跟回測的時間點不同。

回測的所賣出的時間點是獲利的,但實盤卻是比較早的時候並且是虧損的,因此實盤希望得到的效果跟回測的時候不一樣

想請問這是為甚麼?若要讓實盤和回測賣出的時間點一致或是接近,腳本該怎麼處理?

 

謝謝!!

排序方式: 標準 | 最新
XQ小幫手 發文於   2021/10/21

Hello 龍槍,

 

首先您需要了解回測跟即時運作的流程,以及逐筆洗價的差異。

小幫手這邊簡單講解。

 

回測非逐筆:

每筆K棒結束後運算,條件符合下一筆K棒進場(雷達可選下筆開盤或當筆收盤,交易中心目前為下筆開盤)。

 

回測逐筆1分鐘頻率:

將每筆K棒拆分成四根,並以OHLC四個價格模擬四根Tick。

回測逐筆1分鐘以上的頻率:

將每筆K棒改由1分鐘K棒來模擬進出場。

 

即時非逐筆:

每根Bar結束時運算,符合條件就下單。

 

即時逐筆:

每次洗價運算,符合條件就下單。

 

需注意若沒有成交就不會運算。

 

您遇到的情況可能是回測時沒有勾選逐筆,或是勾選逐筆但由於回測的限制無法像即時一樣每筆Tick都運算。

所以進出場時間會略有不同。

要讓兩者相近的話,最簡單的方法是兩者都勾選非逐筆,這樣的話進場時間和價格會較為接近。

 

若您還有其他的問題,需要麻煩您提供 交易中心匯出檔勾選(包含)腳本 (或策略雷達匯出檔,視您使用哪個)、XQ Log 來檢驗。

Log資料夾(預設路徑:C:\SysJust\XQLite\LOG)直接壓縮後提供即可。

您可以直接將檔案上傳,如果檔案過大的話也可以Mail至客服信箱 XQservice@XQ.com.tw且附上 討論文章連結網址(小幫手才能盡早處理)。

感謝。

 

龍槍 發文於   2021/10/21

Hi 小幫手您好,

謝謝回答,想再問一下 OHLC的洗價時間差是多少? 我是否能夠在實盤的時候用delay來達到回測的洗價方式

另外自動交易腳本似乎都是default 逐筆洗價,無法取消

XQ小幫手 發文於   2021/10/26

Hello 龍槍,

 

回測1分鐘頻率以上時逐筆洗價會是1分鐘洗價一次。

1分鐘頻率是15秒(1分鐘拆成4等分)洗價一次。

小幫手認為您應該無法在實盤時用延遲來達到逼近回測的洗價方式。

因為實際上該根Bar有多少交易,高點低點發生在什麼時候,先高後低還是先低後高都有可能會與回測假設的不同。

自動交易腳本在您使用日頻率的時候會強制逐筆洗價,因為日頻率非逐筆的話腳本運算時都是當天(當根Bar)結束,也就不會進場。

如果您使用分鐘頻率的話就不會強制逐筆。

 

Hello pure4321,

 

您的用法得到的就是該1分鐘對應的日頻率value1。

日頻率回測逐筆時雖然會1分鐘洗價一次,但使用的資料頻率還是日。

所以每次腳本洗價運算時買進特大單量和買進大單量會是以日頻率來呼叫。

需注意的是買進特大單量和買進大單量不支援日頻率回測。

您如果想看到類似的效果,可以將:

value1 = GetField("買進特大單量", "D") + GetField("買進大單量", "D");

畫在1分鐘圖上。

小散戶 發文於   2021/10/26

 

小幫手

我有用一個日線5分鐘的警示腳本,然後逐筆洗價去回測,用print 逐行看輸出的時間

發現系統是一分鐘跑執行一次,5分鐘裡面有5根1分K棒,每根都有OHLCV

如果其中有一分鐘是完全沒成交量的,那一分鐘就不會跑腳本

所以open在五分鐘K一開始就固定不變,

但是最新的high, low, close, 會在這五分鐘內隨著一分k的值變化 volume則是每分鐘累增

如果這時取用前一期  open[1]   high[1]   low[1]   close[1]   volume[1]

取到的並不是上根1分K的值,而是上一根5分K的值,因為腳本主要頻率設定是5分鐘

我說的對不對?

但我沒有做過1分鐘警示腳本,然後逐筆回測結果。

也許跟小幫手說的會是每25秒 4 筆tick,分別是 OHLC,那每根tick的V應該是多少呢?

 

 

 

 

 

Hello 龍槍,

 

回測1分鐘頻率以上時逐筆洗價會是1分鐘洗價一次。

1分鐘頻率是15秒(1分鐘拆成4等分)洗價一次。

小幫手認為您應該無法在實盤時用延遲來達到逼近回測的洗價方式。

因為實際上該根Bar有多少交易,高點低點發生在什麼時候,先高後低還是先低後高都有可能會與回測假設的不同。

自動交易腳本在您使用日頻率的時候會強制逐筆洗價,因為日頻率非逐筆的話腳本運算時都是當天(當根Bar)結束,也就不會進場。

如果您使用分鐘頻率的話就不會強制逐筆。

 

Hello pure4321,

 

您的用法得到的就是該1分鐘對應的日頻率value1。

日頻率回測逐筆時雖然會1分鐘洗價一次,但使用的資料頻率還是日。

所以每次腳本洗價運算時買進特大單量和買進大單量會是以日頻率來呼叫。

需注意的是買進特大單量和買進大單量不支援日頻率回測。

您如果想看到類似的效果,可以將:

value1 = GetField("買進特大單量", "D") + GetField("買進大單量", "D");

畫在1分鐘圖上。

XQ小幫手 發文於   2021/10/28

Hello 小散戶,

 

正確來說不單是5根1分鐘Bar,而是這5根1分鐘Bar模擬這根5分鐘Bar的轉變。

舉例來說09:00 ~ 09:05這根5分Bar是由 09:00, 09:01, 09:02, 09:03, 09:04 這四根1分鐘Bar所組成。

簡單假設 09:00 O=100, H=105, L=95, C=102

09:01 O=103, H=106, L=102, C=103 好了。

那麼在第一分鐘的時候,5分鐘Bar為 O=100, H=105, L=95, C=102,但是到第二分鐘的時候會變成 O=100, H=106, L=95, C=103。

可以看出 H 跟 C 被第二根1分鐘Bar給取代。

雖然是用1分鐘Bar來模擬,但是您使用的始終是5分鐘頻率,[1]取到的自然會是上一根5分鐘Bar的資訊。

在1分鐘逐筆的狀況下,會是該根1分鐘Bar的成交量處以4累加上去。

假設是80的話,就會是20, 40, 60, 80。

您可以嘗試實際print出來就可得知。

 

Hello pure4321,

 

是的,您可以將1分鐘的累加起來,就可得出日頻率的值。

value1 = GetField("買進特大單量", "D") + GetField("買進大單量", "D");

if getfielddate("Date") <> getfieldDate("Date")[1] then value2 = 0;

value2 = value2 + GetField("買進特大單量", "1") + GetField("買進大單量", "1");

plot1(value1);

plot2(value2);

將這指標腳本畫在1分鐘圖上,value1會等於value2。

XQ小幫手 發文於   2021/11/02

Hello pure4321,

 

如同小幫手上面有註明的,該腳本的邏輯是使用在一分鐘頻率上,為了取得特大單和大單的當日累計值(或著是分鐘頻率,只要將value2 getfield裡的頻率作調整即可)。

如果您要用在日頻率上的話,只能使用在日頻率逐筆。

邏輯上和上面相同,都是使用1分鐘作累加的動作:

var: intraBarPersist count(0);

if getfieldDate("Date", "1") <> getfielddate("Date", "1")[1] then count = 0;

count = count +  GetField("買進特大單量", "1") + GetField("買進大單量", "1");

print(date, currentTime, count);

 

value2 為系統保留字,所以無法再度宣告此變數,您需要另外宣告其他變數。

在日頻率下,換日歸0的寫法需要稍作更動,指定頻率為1分鐘才可以對應到日頻率逐筆。

XQ小幫手 發文於   2021/11/09

Hello pure4321,

 

如果您是使用日頻率逐筆的話,這些指令都是得到該1分鐘對應的日頻率值,而不是盤後日頻率值。

因為他們計算都是使用close,而在日頻率逐筆的狀況下close會對應到該1分鐘頻率的close,而不會取到當日收盤(從那時來看是未來)的值。

 

回測無法使用日頻率 買進特大單量 和 買進大單量。

不過如果您將其用在即時的話,得到的會是今天累加到該1分鐘頻率的單量資訊。

如同小幫手上面的指標腳本範例:

value1 = GetField("買進特大單量", "D") + GetField("買進大單量", "D");

if getfielddate("Date") <> getfieldDate("Date")[1] then value2 = 0;

value2 = value2 + GetField("買進特大單量", "1") + GetField("買進大單量", "1");

plot1(value1);

plot2(value2);

您只要將其畫在1分鐘頻率的圖上就會看到 value1 (GetField("買進特大單量", "D") + GetField("買進大單量", "D")) 和 value2 (value2 + GetField("買進特大單量", "1") + GetField("買進大單量", "1")) 會相等。

相關人士已經有在規劃讓單量資訊可以使用日頻率回測,預計在 .07.01 以後的版本中更新。

XQ小幫手 發文於   2021/11/17

Hello pure4321,

 

當日沖銷張數 並沒有限定無法使用日頻率回測。

但需注意此資料為盤後才更新,所以建議您回測使用時要逼近實際狀況的話要取用前期值 GetField("當日沖銷張數")[1]。

 

回測和實際操作的差別會隨著您的腳本與策略的設定不同而有所差別,但核心觀念都是一樣的:

回測無法作到實際逐筆洗價的狀況,最短就是1分鐘洗價。

這點導致了回測和實際執行的差別。

您理解了這一點,在設定策略參數、撰寫腳本和閱讀回測報表時就可以考量進去。

 

感謝您的建議,小幫手會轉告相關人士您的建議。

pure4321 發文於   2021/11/22

6457.TW紘康等少部分幾檔,上述問題日頻率回測不行,

又,GetField("Volume","D"),日頻率回測是得到該分對應日量,

則,GetField("Volume","D")[1],日頻率回測是得到上一分對應日量?還是上一天日量?

是否能做一個回測完整教學?

XQ小幫手 發文於   2021/11/24

Hello pure4321,

 

在日頻率逐筆回測的時候 GetField("Volume","D") 會取得模擬當下那個1分鐘Bar的當日累積量。

GetField("Volume","D")[1] 則是取得前一日的成交量。

 

如果您使用1分鐘頻率來回測的話,GetField("Volume","D") 會取得模擬當下那個1分鐘Bar的當日累積量。

GetField("Volume","D")[1] 是取得前一日的成交量。

需注意的是,如果您用變數存取的話,如 value1 = GetField("Volume","D"),value1會取得模擬當下那個1分鐘Bar的當日累積量。

但 value1[1] 會取得前1分鐘頻率的當日累積量。(在1分鐘頻率下)

 

簡單來說:

Getfield("Volume", "D")[1] 會取得 GetField 指定頻率的前一根Bar資訊。

value1 = Getfield("Volume", "D");

value1[1] 則會取得您當下商品使用頻率的前一根Bar資訊。

 

關於回測的設定,您可以參考XS教學裡面的 策略雷達回測相關說明 以及 自動交易回測相關說明

 

6457.TW 小幫手測試是可以回測,但是print出來的資訊都是0有誤。

會再和工程師確認問題為何。

感謝。

顯示更多回應 發表回覆
Close