交易策略包含特大單時,回測選逐筆搓合會報minTA錯誤

  •   228 
  • 最後發表   iker  2022 七月 15
iker 發文於   2022/06/25

我在交易腳本裡設置了兩個參數想自己根據1分K統計特大單數量,寫了下述這段:

if date<>date[1] then begin
    _buyLargeBidCount = 0;
    _sellLargeBidCount = 0;
end;

// 初始化特大單量 if (GetField("買進特大單量","1") > 1 and _buyLargeBidCount = 0) or GetField("買進特大單量","1") > _buyLargeBidCount then begin _buyLargeBidCount = GetField("買進特大單量","1"); end; if (GetField("賣出特大單量","1") > 1 and _sellLargeBidCount = 0) or GetField("賣出特大單量","1") > _sellLargeBidCount then begin _sellLargeBidCount = GetField("賣出特大單量","1"); end;

但這段在我透過自動交易回測時,選擇模擬洗價會報錯誤:
(取消模擬洗價就不會報錯,但也無法觸發我的進出場條件)

假如我想要在1分K根據敲進特大單觸發進場做空的話,該如何抓取特大單做判斷呢?

 

 

排序方式: 標準 | 最新
XQ小幫手 發文於   2022/06/29

Hello iker,

 

買進特大單量 和 賣出特大單量 欄位不支援1分鐘逐筆洗價,所以您只能使用1分鐘頻率,或其他頻率的逐筆洗價。

就您腳本的內容來看,您的 _buyLargeBidCount 和 _sellLargeBidCount 紀錄的是當日最大的特大單量。

您的腳本可以簡化成

if date <> date[1] then begin

    _buyLargeBidCount = 0;

    _sellLargeBidCount = 0;

    end;

if GetField("買進特大單量","1") > _buyLargeBidCount then _buyLargeBidCount  = GetField("買進特大單量","1");

if GetField("賣出特大單量","1") > _sellLargeBidCount then _sellLargeBidCount  = GetField("賣出特大單量","1");

 

就可以達到於您上述腳本相同的效果。

另外,您可以使用 print 函數來確認條件相關運算是否會觸發進出場條件。

 

如果您還有疑慮的話,麻煩提供 交易腳本、回測的設定(截圖或回測報告) 以及您覺得應該要交易但沒有的商品與日期時間 來檢驗。

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

感謝。

iker 發文於   2022/06/29

了解

另想請問如果無法逐筆洗價回測的話,有辦法可以在下實單前驗證「逐筆遇到特大單敲進時,且1分K的特大單量又創日新高,就進場做同向」的邏輯嗎?

還是這種情況只能寫成策略雷達,出訊號後做個記錄,回頭人工檢查該策略是否有效呢?

iker 發文於   2022/06/29

請問如果要找大戶買轉賣,可以這樣寫嗎?

value99 = GetField("賣出特大單量","1")-GetField("買進特大單量","1");

condition1 = value99 > 0 and  value99[1] < 0;


還是必須要設置兩個參數才行?

value98 = GetField("賣出特大單量","1")-GetField("買進特大單量","1");
value99 = GetField("賣出特大單量","1")[1]-GetField("買進特大單量","1")[1];

condition1 = value98 > 0 and  value99 < 0;

XQ小幫手 發文於   2022/07/05

Hello iker,

 

回測終究只是一種模擬過去的狀況,就算您使用1分鐘逐筆洗價,在運算時也只是1分鐘Bar洗價四次 (OHLC)。

所以您如果要測試逐筆洗價下發生的狀況,還是需要在即時的策略雷達或自動交易上作測試。

 

兩者寫法在1分鐘頻率上會相同,但其他頻率就會有差別。

因為 value99[1] 取得的是上一根Bar的資訊,而 value98 取得是上一分鐘的資訊。

如果您使用非1分鐘頻率的話,第二種應該才是符合您需求的寫法。

iker 發文於   2022/07/05

Hi 小幫手

請問上述的兩種寫法如果用在 5 分鐘頻率的話,第一種 value99 會是目前最後一根 1 分K的資訊嗎?(例如5分鐘已經跑完3分鐘,而這個value99運算的是剛剛跑完的第3分鐘的1分K的大單狀況嗎?)

另外還是不明白為什麼 value99[1] 取得的是上一根Bar的資訊,而 value98 取得是上一分鐘的資訊

無論在什麼頻率,GetField("賣出特大單量", "1") 跟 GetField("賣出特大單量", "1")[1] 指的不應該是相同的東西嗎?

只是加上 [1] 用來選擇要取該目標的前幾個目標值,這樣的話為什麼會第一個是取上一根Bar?另一個是取上一分鐘的資訊?

還請小幫手幫忙說明一下,感激不盡

musashi 發文於   2022/07/05

value99[1] 這個中括號是指定括號前面value99頻率的前一根K棒,例如在五分頻率下,value99[1]就是前一根5分K棒的value99值。
而GetField("賣出特大單量", "1")[1]是因為中括號前面是指定1分頻率,所以會抓前一根1分K棒的GetField("賣出特大單量", "1")值。

以下舉例在資料區間大頻率讀取小頻率
例如在5分頻率10點05分K棒,執行以下腳本
    getfield("close","1");          = 5分頻率目前K棒(10:05),讀取1分頻率的10點09分收盤價
    getfield("close","1")[1];       = 5分頻率目前K棒(10:05),讀取1分頻率的10點08分收盤價
    getfield("close","1")[2];       = 5分頻率目前K棒(10:05),讀取1分頻率的10點07分收盤價
    getfield("close","1")[3];       = 5分頻率目前K棒(10:05),讀取1分頻率的10點06分收盤價

    value99=getfield("close","1");  = 5分頻率目前K棒(10:05),讀取1分頻率的10點09分收盤價
    value99[1];                     = 5分頻率往前1根(10:00),讀取1分頻率的10點04分收盤價
    value99[2];                     = 5分頻率往前2根(09:55),讀取1分頻率的09點59分收盤價
    value99[3];                     = 5分頻率往前3根(09:50),讀取1分頻率的09點54分收盤價

iker 發文於   2022/07/06

感謝 mussahi 解說,不過我還是有幾個地方不明白想請益:

1. 

範例是 在5分頻率10點05分K棒,執行以下腳本,為什麼這時候getfield("close","1")會取到1分頻率的10點09分收盤價呢?還是您的意思是用戶是在10點09分的時候執行腳本?如果用戶是在10點06分的時候執行腳本,這樣一樣是嘗試取1分頻率的10點09分收盤價,只是值為0嗎?

 

2. 

不太理解為什麼單純跑getfield("close","1")跟把值塞給一個變數value99之後代表的意義會不同,範例裡關於塞值給value99之後,直觀會以為是單純不想重複寫getfield("close","1"),所以採用一個變數去取代他。還是XQ所有跨頻率取值的情況下,這種塞值給指定參數的邏輯就會變成範例裡的情境呢?

XQ小幫手 發文於   2022/07/11

Hello iker,

 

1.XQ標示的時間是K棒開始的時間。

所以5分鐘頻率下10:05的K棒代表的時10:05~10:10的資料。

而您在10:10的時候取用1分鐘頻率K棒的話,此時對應的1分鐘資料會是 10:09 ~ 10:10 的資料,也就是10:09的1分鐘K棒。

小幫手建議您可以使用 print 將 getfield("Time", "1") 印出,或許會比較容易理解。

 

2.小幫手試著用更容易理解的方式講解。

getfield("Close", "1")  ==>  執行頻率為1分鐘的close

value1 = getfield("Close", "1")  ==> 變數value1,裡面儲存了執行頻率為1分鐘的close

這裡要注意的是,變數本身的頻率是執行頻率,並不會因為裡面儲存了不同的頻率資料而有所改變。

所以在執行頻率為5分鐘頻率下的狀況,value1[1] 會是前一根5分鐘K棒的資訊,而 getfield("Close", "1")[1] 會是前一根1分鐘Bar的資訊。

 

iker 發文於   2022/07/11

感謝小幫手回覆

第一點之前是想反了,以為10:05的K棒代表的是10:01-10:05才覺得怪。

第二點這樣解釋可以聽懂,困惑的點是混和頻率這個概念後,導致XQ跟一般程式邏輯不同,一般程式寫法在塞值給一個變數通常是希望透過該變數更輕鬆的去管理一個重複出現的值,修改時也只需要修改變數值即可。但遇到跨頻率值的問題時,反而造成用XQ語法的用戶需要知道這個時候變數是跟著回測的頻率運作,而不是根據塞進去的值的頻率運作,這點有點 tricky...寫過其他程式語言的使用者在寫 XScript的時候反而容易被誤導...

如果能將變數本身也做 跨頻率/當前頻率 的區分,或許會讓使用者更好理解一點。例如跨頻率取值都是 xf_ 開頭,那默認除了提供 value1-valueXXX 的變數以外,也可以另外提供一組 xf_value1-xf_valueXXX,只有帶 xf_ 這組前綴時,該變數才會跟著塞進去的跨頻率內容運作。

XQ小幫手 發文於   2022/07/15

Hello iker,

 

變數會跟著執行頻率,如果要取得該變數在其他頻率的資訊,可以使用 xfMin_GetValue

小幫手會將您的建議轉告相關人員。

顯示更多回應 發表回覆
Close