自訂函數問題

  •   75 
  • 最後發表   PHOT-196  2025 八月 07
PHOT-196 發文於   2025/08/03

XQ小編您好
我有寫一個專門類似dateadd的函數,但只會判斷工作日(一~五),不過後來發現程式效率似乎很差,請問以下還有哪些地方可以優化嗎?目前我想到的方法是,只要在最新的k棒跑迴圈就好。
此外我這個函數腳本是放在選股中心選股,然後用交易中心套用選股中心做回測用,因此會有日k模擬逐筆洗價的地方需要注意。


SetBarMode(1);

if not IsLastBar then return;

input:start_date(numericsimple,"起始天數");

input:days(numericsimple,"工作日");

var:i(0);

var:end_date(0);

i=0;

end_date = start_date;

if days >= 0 then

begin

   while i < days

   Begin

   end_date = dateAdd(end_date,"D",1);

   if dayofWeek(end_date) <> 6 and dayofWeek(end_date) <> 0  then i = i +1 ;

   end;

end ;

 

if end_date > 0 then dateadd_work_1 = end_date else dateadd_work_1=0;

排序方式: 標準 | 最新
PHOT-196 發文於   2025/08/03

此外,我發現在函數腳本中放print,似乎沒什麼作用,完全沒有輸出運算過程。
例如在上面程式碼i=0;以下放PRINT(DATE,end_date,i);
雖然有勾print輸出,但還是都沒反應。

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

你思考一下,若颱風來,台北股市休市,這樣的函數是否能傳回你要的數值。

PHOT-196 發文於   2025/08/03

我知道,我先簡單判斷六日而已,先求有,後續再慢慢求好。

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

我的意思是提醒你,思考的方向錯了。

PHOT-196 發文於   2025/08/03

感謝,那可以請教一下哪個方向比較正確嗎?

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

善用XS序列語言會逐一在準備的資料,從第一筆資料一直跑到最後一筆的特性,在跑每筆資料的時候判斷哪筆資料是你的日期資料,然後按照第二個參數往後加計幾筆。這裡需要判斷加計之後是否會超過最後一筆。另外,也要注意,讀取的資料筆數是否足夠,亦即你要加計的日期是否在讀取資料筆數裡面。若是跨頻率處理這個問題,例如,5分鐘頻率的策略,想要持有5天就出場,也需要注意讀取的分鐘筆數是否涵蓋你的日期。

PHOT-196 發文於   2025/08/03

不過,我就是不想去考慮資料讀取筆數的問題,因為若不足涵蓋則值不正確,以及讀取筆數只能比較過去日期,無法使用在未來日期。否則用GetBarOffset應該就很容易解決問題,但GetBarOffset無法去讀取未來日期。

例如,我想於今日8/3 + 6個工作日的日期進場,也就是8/11,就無法用讀取筆數去回推,因為讀取筆數只有過去的資料而已。

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

若8/1出現訊號,則再過6個工作日進場,可否反過來思考成為每天判斷出現訊號那天距離今天是否有6個工作日?若剛好6個工作日,亦即在8/11那天,就進場。這樣的思考比較符合時序語言的程式邏輯。

PHOT-196 發文於   2025/08/03

了解,謝謝教授。不過還是請XQ小編方便的話,看一下原本的程式碼建議修改的地方,謝謝。

XS小編 發文於   2025/08/07

Hello PHOT-196,

 

自動交易策略串接選股策略並不會讓選股策略變成逐筆洗價,所以您在選股中心執行這個函數的話不需要擔心會逐筆洗價運算。

選股中心只會用收盤後的日 (以上) 頻率作運算。

 

一般來說因為未來的日期無法確定是否會開盤 (ex. 颱風假),故不會特別計算向後幾個工作天。

不過如果您目前只要剃除週末的話,建議可以將 days 除以5來得到向後幾個禮拜(整數部分)和幾天(餘數部分),計算會向後幾個禮拜 (也就是要多加幾天),再使用新的數值放入adddate中。

舉例來說,days = 23,然後起始日是20250807的話:

value1 = floor(days / 5);  //記錄過了幾週 (會是4)

value2 = mod(days, 5);   //紀錄多過幾天 (會是3)

value3 = dayofweek(20250807);  //會是4

if (value3 + value2) > 5 then value1 += 1;  //如果多過了幾天的部分會導致換週的話,value1 要多加1 (多過一週)

 

value4 = days + (value1 * 2);    //計算days只算工作日的話要多幾天

 

所以最後新的日期就會是 dateadd(20250807, "D", value4) => 20250909。

顯示更多回應 發表回覆
Close