如何寫出10秒內委買委賣互換3次的雷達?

  •   294 
  • 最後發表   無情卻慈悲  2022 五月 03
無情卻慈悲 發文於   2022/03/29

你好,

如題我的寫法在跑盤中時,會出現有無窮迴圈的錯誤,可否指導一下?謝

 

var: intrabarpersist last_seqno(0); // 上次洗價時最後一筆Tick的SeqNo

var: curr_seqno(0); // 這次洗價時最後一筆Tick的SeqNo

 

if Date <> CurrentDate then return; // 只跑今日的資料

 

curr_seqno = GetField("SeqNo", "Tick"); // 最新一筆Tick編號

 

if last_seqno = 0 then last_seqno = curr_seqno - 1; // 第一次洗價時只洗當時那一筆

 

var: seq_no(0), offset(0);

seq_no = curr_seqno;

offset = 0;

 

var:intraBarPersist b1(0),intraBarPersist s1(0);

var:intraBarPersist CountBS(0),intraBarPersist Count0(0),intraBarPersist Event_time1(0);

 

while seq_no > last_seqno begin

 

  // 讀取Tick資料

  value1 = GetField("Time", "Tick")[offset];

  value4 = GetField("BidAskFlag", "Tick")[offset];

  b1 =GetField("BidPrice", "Tick")[offset];//買1

  s1 =GetField("AskPrice", "Tick")[offset];//賣1

 

if b1[4] = b1[6] then  Event_time1 = time;

if b1 = b1[2] and b1[2] = b1[4] and b1[4] = b1[6]

and time - Event_time1 <=7

then 

begin

ret = 1 ;

retmsg ="委買委賣互換3次(6秒內)";

print(date,time,"委買委賣互換3次(6秒內)","此時買1",b1);

end;

 

end; {end while}

 

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

Hello 無情卻慈悲,

 

您的while條件 seq_no 永遠會大於 last_seq_no,所以會是無窮迴圈。

推測您應該是想用 seq_no[value1] 的方式,但須注意也有可能發生取前一根的時候直接取到昨日的收盤的 seq_no 一樣發生無窮迴圈的狀況,這邊的[1]取的會是上一根Bar的資訊,而不是上一個tick。

另外時間的計算小幫手會建議您使用 TimeDiff

不然像是 090100 和 090059 相減就會是41而不是1秒。

您目前的寫法會讓迴圈跑當下到開盤間的tick消耗大量效能,小幫手會建議您用像是:

value1 = 1;

while timeDiff(getfield("Time", "Tick"), getfield("Time", "Tick")[value1], "S") < 10 begin  //讓迴圈指抓取近10秒的tick

    ...判斷條件...

    value1 += 1;

    end;

這樣就可以有效的降低所需抓取判斷的資料數量。

無情卻慈悲 發文於   2022/04/06

感謝小幫手,

我目前修改如下,但還是會出現無窮迴圈,可否請您幫我看一下經您指導後的寫法, 是否可行呢?

謝。

if Date <> CurrentDate then return;   // 只跑今日的資料

var:intraBarPersist b1(0),intraBarPersist s1(0);

value1 = 1;

while timeDiff(getfield("Time", "Tick"), getfield("Time", "Tick")[value1], "S") <= 6 begin  //讓迴圈指抓取近6秒的tick
    b1 =GetField("BidPrice", "Tick")[value1];//買1
    s1 =GetField("AskPrice", "Tick")[value1];//賣1

    if  value1 >1 and b1[4] = b1[6] then begin
        if b1[2]  = b1[4] 
        then begin
            if b1[4] = b1[6]
            ret = 1 ;
            retmsg ="委買委賣互換3次(6秒內)";
            print(date,time,"委買委賣互換3次(6秒內)","此時買1",b1);
            end;
        end;    
    end;

    value1 += 1;

end;{end while}

 

 

 

musashi 發文於   2022/04/07

我也想了解如何判斷相同價格在委買1委賣1之間跳動次數

XQ小幫手 發文於   2022/04/13

Hello 無情卻慈悲,

 

小幫手這邊測試是沒有發生類似的情況。

但您可以嘗試以下的做法看是否有辦法解決:

while absvalue(timeDiff(getfield("Time", "Tick"), getfield("Time", "Tick")[value1], "S")) <= 6 begin   //加上absvalue確保如果抓到昨日的tick時會中斷

以及在 value1 += 1; 下面多加一行

if value1 > 100 then break;    //如果迴圈執行超過100次就中斷

 

另外,小幫手不是很懂您判斷的條件,但如果要檢查迴圈內的買1的話,您裡面應該是用value1 + n 來判斷,而不是寫死。

寫死的話每次檢查的都會是相同的tick。

且您的條件實際上並不需要用那麼多層 if,可以都寫在同一層:

if value1 >1 and b1[value1 + 4] = b1[value1 + 6] and b1[value1 + 2]  = b1[value1 + 4] and b1[value1 + 4] = b1[value1 + 6]

 

如果您是用在即時且設為逐筆洗價的話,其實可以不用迴圈,因為逐筆洗價會在每次洗價時運算。

雖然不能保證每筆Tick都運算,但大多時候也很接近。

這樣運算時您只要判斷 timeDiff(getfield("Time", "Tick"), getfield("Time", "Tick")[6], "S") <= 6 符合的話,就代表你條件中用的tick都在6秒鐘內。

無情卻慈悲 發文於   2022/04/16

非常感謝小幫手的提點,

我目前把迴圈拿掉,修改如下,不知這樣是否與您指導的方向一致呢

if Date <> CurrentDate then return;
var:intraBarPersist b1(0),intraBarPersist s1(0);
b1 =GetField("BidPrice", "Tick");//買1
s1 =GetField("AskPrice", "Tick");//賣1
value1 = 1;
if timeDiff(getfield("Time", "Tick"), getfield("Time", "Tick")[6], "S") <= 6
then begin
    value1 += 1;
    if value1 >1 
    and b1[value1 + 4] = b1[value1 + 6] 
    and b1[value1 + 2]  = b1[value1 + 4] 
    and b1[value1 + 4] = b1[value1 + 6]
    then begin
        ret = 1 ;
    end;
end;

XQ小幫手 發文於   2022/04/22

Hello 無情卻慈悲,

 

小幫手要更正一部分:

b1 = GetField("BidPrice", "Tick");

b1[1]會取得上一根Bar的最後一筆Tick,不是前一筆Tick。

所以應該要直接用 GetField("BidPrice", "Tick")[1] 才會是前一筆Tick。

 

if timeDiff(getfield("Time", "Tick"), getfield("Time", "Tick")[6], "S") <= 6

then begin

    value1 += 1;

    if value1 >1 

    and b1[value1 + 4] = b1[value1 + 6] 

    and b1[value1 + 2]  = b1[value1 + 4] 

    and b1[value1 + 4] = b1[value1 + 6]   //跟前兩行重複了

    then begin

        ret = 1 ;

    end;

end;

由於您改為不使用迴圈,那麼就只要檢查固定數值即可,這部分可以修改為:

if timeDiff(getfield("Time", "Tick"), getfield("Time", "Tick")[6], "S") <= 6 then begin

    if  GetField("BidPrice", "Tick")[4] = GetField("BidPrice", "Tick")[6] 

    and GetField("BidPrice", "Tick")[2]  = GetField("BidPrice", "Tick")[4] 

    then begin

        ret = 1 ;

        end;

    end;

無情卻慈悲 發文於   2022/04/25

謝謝小幫手的指教,我再研究一下。

另我突然有一個邏輯上的問題想請教,

如同上面指導的或我原本的想法,都是對「買價」的前偶數tick若相同,則可以視為是買價賣價的互換,但我的新的困惑是,

假加

  if  GetField("BidPrice", "Tick")[4] = GetField("BidPrice", "Tick")[6]    .....

在前[4]=[6]時,萬一那時候的[5]也剛好是與[4]與[6]相同的數字,那不就表現[4]、[5]、[6]這三筆tick是連續同一個買價成交,那麼是否就不能把[4]=[6]視為買價與賣價互換,對嗎?

 

 

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

Hello 無情卻慈悲,

 

就您的描述來看,若[4]、[5]、[6]這三筆tick是連續相同價格,那麼應該不能把[4]=[6]視為買價與賣價互換。

小幫手建議您可以搭判 GetField("Close", "Tick") 和  GetField("AskPrice", "Tick") 來比較使用,或許會比較接近您想要的狀況。

您可以實際pirnt出來觀察這3個數值的變化。

(ex. print(date, currentTime, GetField("Close", "Tick"), GetField("Close", "Tick")[1], GetField("Close", "Tick")[2], GetField("BidPrice", "Tick"), GetField("BidPrice", "Tick")[1], GetField("BidPrice", "Tick")[2], GetField("AskPrice", "Tick"), GetField("AskPrice", "Tick")[1], GetField("AskPrice", "Tick")[2]);)

發表回覆
Close