關於除息的商品回測試遇到的問題

  •   37 
  • 最後發表   菜鳥  2025 八月 29
菜鳥 發文於   2025/08/26

小編你好

今天遇到新纖被打到停損,因為新纖今天除息,所以我有一些疑惑,我的腳本出場部分如下,

這個條件在還原後是成立的:(closeD(1)=lowest(closeD(1),4) and low<=lowest(lowD(1),4) and date<>filledEntryDate)

我的問題是,盤後回測,如果勾選"還原值"則出場會落在8/25 9:01而非今天,如果不勾選"還原值",就不會觸發停損(停損點若還原應該在15.65),我該如何做才能讓回測在預期的點位出場?

var:intraBarPersist dayentry(0);

if date<>date[1] and (currenttime=090000 or currenttime=133000) then dayentry=0; //控制當天出場後,不會當天又再進場

condition1= close <> getField("漲停價") ;//排除漲停價做多,因為不一定買的到

condition2= open <= GetField("Close", "D")[1]*(1+10/100) and open >= GetField("Close", "D")[1]*(1-10/100);//開盤介於

if date<>date[1] and position=0  and dayentry=0 and condition1 and condition2 

then begin

setposition(1,AddSpread(Close,+2));

end;

if  filled>0 and close <> getField("跌停價", "D")  and

    (  close>=filledAvgPrice*(1+100*0.01)

or close<=filledAvgPrice*(1-15*0.01)

    or (closeD(1)=lowest(closeD(1),4) and low<=lowest(lowD(1),4) and date<>filledEntryDate)

)

then begin

dayentry=1;

setposition(0,AddSpread(Close,-10));

end;

排序方式: 標準 | 最新
虎科大許教授 發文於   2025/08/26

除權息當天的價格是還原的價格,回測時應該使用還原值,自動交易中心腳本設定時,也應勾選還原值。

菜鳥 發文於   2025/08/27

許教授你好

我盤後回測,如果勾選"還原值"則出場會落在8/25 9:01而非8/26,以出場條件來看,回測的出場點也不對

8/25未除息,出場價格是15.3,當日及前五日最低都比15.3還高,怎麼看都奇怪~

虎科大許教授 發文於   2025/08/27

使用還原價格本來就是這樣。以前的價格經過還原,大部分情況,價格都會比原始價格低。確認回測的進、出場價格及損益是否正確,應該使用還原的價格,而非原始價格。

菜鳥 發文於   2025/08/28

許教授你好

我還是覺得不通,如果8/25出廠前的原始值扣減股息0.6,那麼最低是15,也不會在15.3觸發停損,況且8/25的最低點就沒破前4日最低點...不論原始值還是還原值就不應該觸發停損,所以有沒有可能是程式在做還原計算的時候出錯了?

虎科大許教授 發文於   2025/08/28

你的問題來自兩個邏輯錯誤:

(1)從你使用date<>date[1],我猜測你的主頻率應該是分鐘頻率。CloseD及LowD等函數,雖然是計算日頻率的收盤價及最低價,但在分鐘頻率下,若使用函數計算,例如average、lowest...,則會以主頻率的方式計算並傳回結果。假設你用5分鐘頻率,則lowest(lowD(1),4)會傳回4根5分K的前一個交易日的最低價,它只會傳回前一個交易日的最低價,而非過去4天的最低價。

(2)最糟糕的是,CloseD及LowD等函數傳回的是原始的日資料,無法傳回還原的日資料,亦即你若使用還原資料,則 low<=lowest(lowD(1),4) 不等式的左邊是還原最低價,右邊是原始最低價。新纖8/25的還原最低價是15.06低於前一個交易日原始最低價15.65;8/22原始的收盤價15.75,亦即closeD(1)也等於lowest(closeD(1),4),所以觸發出場訊號。

在使用還原資料的情況下,若你將CloseD及LowD等函數改成GetField("Close","AD")及GetField("Low","AD")就可解決問題。

closeD(1)=lowest(closeD(1),4)改成GetField("Close","AD")[1]=lowest(GetField("Close","AD")[1],4)

low<=lowest(lowD(1),4)改成Low<=lowest(GetField("Low","AD")[1],4)

菜鳥 發文於   2025/08/29

感謝許教授的詳細解析!!!

發表回覆
Close