XS函數「isfirstcall」說明
選擇單元...
XS語法進階應用
單元目錄
單元目錄
進階功能介紹
1-1 SetTotalBar資料讀取範圍與腳本執行的關係
1-2 SetBackBar指定頻率設定資料筆數
1-3 探討變數序列的觀念:幾天前黃金交叉商品為例
1-4 如何運用Print指令來抓程式的臭蟲
1-5 談OutputField跟GetFieldDate這兩個函數
1-6 計算區間漲跌幅的自訂函數
1-7 盤中即時資料欄位的應用
1-8 Tick欄位的應用
1-9 台股逐筆撮合的連續成交Tick序列
1-10 選股中心創掛牌新高與大單欄位的應用
1-11 集保相關欄位調整
1-12 如何使用函數取得商品的實際庫存數量
1-13 XS在可轉債的應用
1-14 XS函數「isfirstcall」說明
1-15 XScript 編輯器已支援 *.xs 副檔名的檔案
isfirstcall 能迅速解決腳本撰寫的負擔,它最重要的作用就是:在特定事件下的第一次觸發。這麼說可能有些抽象,舉凡變數重置、在 K 棒內限制觸發次數等等,都是腳本撰寫上常會用到的邏輯。如果你曾經遇過「實際執行腳本時,並不如想像中在達成條件後僅觸發一次,而是瘋狂觸發」、「每次都要為了限制觸發,而花不少時間空間設計腳本」或是「明明條件沒有符合,卻還是觸發了(因為沒有重置條件 or 變數)」,那 isfirstcall 能解決很多這方面的困擾。isfirstcall 要傳入字串形式的事件代碼,回 true / false,以下便來說明幾種 isfirstcall 目前支援的使用情境。 以下是文章目錄:一、isfirstcall(" "):此次執行的第一次洗價二、isfirstcall("Bar"):此根 Bar 的第一次洗價三、isfirstcall("Date"):此交易日的第一次洗價四、isfirstcall("Realtime"):進入即時洗價區間的第一次洗價補充:isfirstcall的底層邏輯
一、isfirstcall(" "):此次執行的第一次洗價
只會 true 一次,後續洗價維持 false。會用到這個事件,通常是為了在腳本啟動後,處理需要引用的資料或變數,而且只需要在一開始執行一次,之後不再需要。只在第一次洗價時判斷條件,之後都不需再次判斷。- 不用 isfirstcall 的寫法:
{先宣告變數_firstTime,來限制觸發一次} var:_firstTime(0); condition1 = ……; if _firstTime = 0 then begin if condition1 then …… ; _firstTime = 1; //第一次洗價後_firstTime就會持續=1,此後不會再=0了 end;
- isfirstcall(" ") 的寫法:
condition1 = ……; if isfirstcall(" ") then condition1 then ……;
二、isfirstcall("Bar"):此根 Bar 的第一次洗價
換 Bar 就會更新為 true 一次,其餘洗價維持 false。這些應該是 XS 玩家最常用到的情境了:(一) 逐筆洗價時,援引「上一根 Bar 最後一次的洗價結果」,做 Bar 內單次觸發- 不用 isfirstcall 的寫法:
{宣告一個intrabarpersist性質的變數_Bar,來限制Bar內觸發一次} var: intrabarpersist _Bar(0); condition1 = ......; if _Bar <> currentbar then begin if condition1[1] then ......; _Bar = currentbar; //更新 _Bar的數值 end;
- isfirstcall("Bar") 的寫法:
condition1 = ......; if isfirstcall("Bar") and condition1[1] then ......;(二) Bar 內 N 次觸發,使用最新洗價的結果來判斷
- 不用 isfirstcall 的寫法:
input:N(3,"限制觸發次數"); var: intrabarpersist _Bar(0), intraBarPersist counts(0); {將累積觸發次數counts,在Bar內第一次洗價時歸0} if _Bar <> currentbar then begin counts = 0; _Bar = currentbar; end; {Bar內最多累積N次觸發} condition1 = ......; if condition1 and counts < N then begin ......; counts += 1; end;
- isfirstcall ("Bar") 的寫法:
input:N(3,"限制觸發次數"); var:intraBarPersist counts(0); {將累積觸發次數counts,在Bar內第一次洗價時歸0} if isfirstcall("Bar") then counts = 0; {Bar內最多累積N次觸發} if condition1 and counts < N then begin ......; counts += 1; end;
三、isfirstcall("Date"):此交易日的第一次洗價
依照執行商品的交易日來決定何時換日,例如:- 股票會在 09:00 時換日
- 期貨(一般)會在 08:45 時換日
- 期貨(全日)會在 15:00 時換日
- 若是股票、期貨(一般),不用 isfirstcall 的寫法:
if date<>date[1] and Position > 0 then SetPosition(0, label:="換日開盤清倉");
- 若是期貨(全日),不用 isfirstcall 的寫法(通用於全部商品):
{用isSessionFirstBar來鎖定交易日的第一根Bar,再加上單根Bar內限制觸發一次的邏輯} var:intraBarPersist _Bar; if isSessionFirstBar and _Bar <> currentBar and Position > 0 then begin SetPosition(0, label:="換日開盤清倉"); _Bar = currentBar; end;
- isfirstcall("Date") 的寫法(通用於全部商品):
if IsFirstCall("Date") and Position > 0 then SetPosition(0, label:="換日開盤清倉");
四、isfirstcall("Realtime"):進入即時洗價區間的第一次洗價
從資料歷史區間轉進即時區間後,就會更新為 true 一次,其餘洗價維持 false。如題,只有在即時洗價區間才會成立,洗價區間分為歷史與即時,歷史洗價區間就是所謂「資料讀取筆數(totalbar)」或「自動交易的策略部位計算」的範圍;即時洗價區間則是在資料讀取完成後,進入盤中即時行情的範圍。策略進入即時洗價後 N 分鐘,停止策略- 不用 isfirstcall 的寫法:
input:N(60,"幾分鐘後停止策略"); var:_firstTime(0), _startTime(0); if _firstTime = 0 then begin _startTime = currentTime; _firstTime = 1; end; if currentTime >= TimeAdd(_startTime,"MM",N) then raiseRunTimeError("時間到停止策略");
- isfirstcall("Date") 的寫法:
input:N(60,"幾分鐘後停止策略"); var: _startTime(0); if isfirstcall("Realtime") then _startTime = currentTime; if currentTime >= TimeAdd(_startTime,"MM",N) then raiseRunTimeError("時間到停止策略");