有了想法,回測卻選不出股票

  •   355 
  • 最後發表   Ryan103325  2025 五月 06
Ryan103325 發文於   2025/05/04

if BarFreq <> "1" then begin
    return;
    raiseRunTimeError("頻率錯誤");
end;

//===========================================進場===========================================

input: mintime(090100,"最早進場時間"),maxtime(091500,"最晚進場時間");

if {GetField("買賣現沖", "D")} GetSymbolInfo("買賣現沖") = true     //確定該個股可以當沖
 and currenttime>= mintime and currenttime< maxtime then begin    //確定進場時間(9:01-9:15)

    input:minprice(10,"最低價格"), maxprice(100,"最高價格");
    input:minV(5000,"昨日成交量");

    value1 = GetBarOffset(CurrentDate,090000);  //抓當天第一根1分K棒位子

    if Date <> CurrentDate then return;

    condition11 = close>= minprice and close <= maxprice and getfield("volume","D")[1]>minV;       //確定股價跟昨日成交量
    CONdition12 = c[value1] > o[value1];     //第一根1分K為紅K

    if condition11 and condition12 then begin

        input: Capital(100,"每檔資金(萬)");

        var: OrderQuantity(0); 

        condition21 = value1 < 5 and c[1] > l[value1] and c[1] < h[value1] and v[1] = lowest(v, value1) and c>h[value1] and v<v[value1];
                      {距離第一根K棒不超過5根,且前一根K棒位於第一根K棒的K棒範圍內,且為當日最小量(抓凹洞量),當根K棒過高,且不爆量}

        condition22 = (value1 = 1 and c>h[value1] and v<v[value1]);       {第2根K棒就過高不爆量}

        condition20 =   lowest(l, value1-1) > low[value1]        //第2根以後的K棒低點都不低於第一根的低點
                        and low[value1] > closeD(1)*1.01     //跳空開高,且最低點不填補開高的缺口
                        and (c-closeD(1))/closeD(1)*100 < 7      //當日漲幅小於7趴
                        and (condition21 or condition22);


        if condition20[1]
        and Position = 0 and filled=0  then begin         

            OrderQuantity=round(Capital*10000/Close/1000,0);  
            SetPosition(OrderQuantity,Market);

        end;

    end;

end;

//===========================================出場===========================================

input: PT(3,"停利%"), SL(1, "停損%") ;

if (position>0 and filled>0 and time>=filledRecordDate(FilledRecordCount)  )  
and (
        {( SL > 0 and Close <= FilledAvgPrice*(1-(0.01*SL)) )
        or  ( PT > 0 and Close >= FilledAvgPrice*(1+(0.01*PT)) )
        or  }c[1] < average(c,5)[1] or c < l[value1] or c<closeD(1) or c = GetField("漲停價", "D") or c < GetField("均價") or time > 130000
            {收盤破五均}         {跌破第1根K棒低點} {破平盤}         {碰漲停}                      {破均價線}             {時間到13:00}
    )
then SetPosition(0);

下面這邊是我突然想到的當沖想法,但是不知道是不是條件太多,反而導致選不出股票,不知道這種時候應該怎麼去做試驗或除錯,希望能在這邊獲得一些方法或意見~

 

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

你用前一期的condition20判斷進場,進場的機率很低。問題出在condition21及condition22條件太嚴。

condition21的value1<5,限制只有090100、090200、090300、090400,這4根K棒符合條件,接著又用c[1]與第一根K的最高價與最低價比較,所以090100又被排除掉,只剩下090200、090300、090400這三根K棒有機會。

condition22更嚴格,value1 = 1,限制只有090100這根K棒,價要過第一根高點,量要小於第一根的量。

然後最嚴重的是condition20加了[1],它會讓condition20及condition21裡面的運算元都被加上[1],這裡會有邏輯運算問題,而且又讓條件更嚴格,condition21又少了090200,只剩090300及090400兩根K棒有機會,而condition22永遠不可能成立。

 

Ryan103325 發文於   2025/05/05

input: mintime(0901,"最早進場時間"),maxtime(0915,"最晚進場時間");

if date<>date[1] then
value1 = getBarOffset(date,090000)  //抓當天第一根1分K棒位子
else value1=0;

if GetSymbolInfo("買賣現沖") = true     //確定該個股可以當沖
 and currenttime>= mintime*100 and currenttime< maxtime*100 then begin    //確定進場時間(9:01-9:15)

    input:minprice(10,"最低價格"), maxprice(100,"最高價格");
    input:minV(5000,"昨日成交量");

    condition11 = close>= minprice and close <= maxprice and getfield("volume","D")[1]>minV;       //確定股價跟昨日成交量
    CONdition12 = c[value1] > o[value1];     //第一根1分K為紅K

    if condition11 and condition12 then begin

        input: Capital(100,"每檔資金(萬)");
        var: OrderQuantity(0);      

        if  Position = 0 and filled=0  then begin         

            OrderQuantity=floor(Capital*10000/Close/1000);  
            SetPosition(OrderQuantity,Market);

        end;

    end;

end;
if GetSymbolInfo("買賣現沖") = true //確定該個股可以當沖 then begin input:minprice(10,"最低價格"), maxprice(100,"最高價格"); input:minV(5000,"昨日成交量"); value1 = timevalue(CurrentTime, "H")*60+timevalue(CurrentTime, "M") -540; //抓當天第一根1分K棒位子(這邊根原本的想法是一樣的) condition11 = close>= minprice and close <= maxprice and getfield("volume","D")[1]>minV; //確定股價跟昨日成交量 if condition11 then begin input: Capital(100,"每檔資金(萬)"); var: OrderQuantity(0); if Position = 0 and filled=0 then begin OrderQuantity=floor(Capital*10000/Close/1000); SetPosition(OrderQuantity,Market); end; end; end;

但是我把這兩個條件刪去用{}刮起來去執行的時候,一樣都沒有交易資料耶,有點找不太到原因,這邊是我把大部分條件移除後,想說只抓第一根1分K紅K就進場,但依就沒有資料

虎科大許教授 發文於   2025/05/05

下列的程式碼區塊有問題,date<>date[1]就是第一根K棒,你只有在第一根K棒才讓value1抓第一根K的相對位置,所以value1永遠等於0。date<>date[1]應該改成date=date[1]。

if date<>date[1] then

value1 = getBarOffset(date,090000)  //抓當天第一根1分K棒位子

else value1=0;

Ryan103325 發文於   2025/05/06

目前的策略是這樣,但依然沒有辦法篩選出結果,是不是其實問題很多呀,看過好多次依然沒有頭緒

if BarFreq <> "1" then begin
    return;
    raiseRunTimeError("頻率錯誤");
end;

//===========================================進場===========================================

input: mintime(085500,"最早進場時間"),maxtime(091500,"最晚進場時間");
input:minprice(10,"最低價格"), maxprice(100,"最高價格");
input:minV(5000,"昨日成交量");

if date=date[1] then
value1 = getBarOffset(date,090000)                                                  //抓當天第一根1分K棒位子
else value1=0;

if GetSymbolInfo("買賣現沖") = true                                                 //確定該個股可以當沖
 and currenttime>= mintime and currenttime< maxtime                                   //確定進場時間(9:01-9:15)
 and close>= minprice and close <= maxprice and getfield("volume","D")[1]>minV     //確定股價跟昨日成交量
 then begin

    CONdition12 = c[value1] > o[value1];                                         //第一根1分K為紅K
    input: Capital(100,"每檔資金(萬)");
    var: OrderQuantity(0); 

    if condition12[1] and Position = 0 and filled=0 then begin

        OrderQuantity=floor(Capital*10000/Close/1000);  
        SetPosition(OrderQuantity,Market);

    end;

end;

//===========================================出場===========================================

input: PT(3,"停利%"), SL(1, "停損%") ;

if (position>0 and filled>0 and time>=filledRecordDate(FilledRecordCount)  )  
and (
    c[1] < average(c,5)[1]       //收盤破五均
or  c < l[value1]                //跌破第1根K棒低點
or  c<closeD(1)                  //破平盤
or  c = GetField("漲停價", "D") //碰漲停
or  c < GetField("均價")       //破均價線
or  time > 130000                //時間到13:00                                                              
    )
then SetPosition(0);

...

附加文件

虎科大許教授 發文於   2025/05/06

(1)控制使用1分鐘頻率,盡量不要只使用barinterval<>1,最好結合barfreq<>"Min",不然使用日頻率一樣可以執行程式。

if barinterval<>1 or barfreq<>"Min" then raiseRunTimeError("限用1分鐘");

(2)若交易的是台指期,則抓第一根K的相對位置要用084500,而非090000。

(3)既然用第一根K是否收紅當作條件,又使用condition12[1],它代表昨天最後一根K收紅,這樣很奇怪,是否不要加[1]才合理?

(4)不清楚你在出場這邊,使用time>=filledRecordDate(FilledRecordCount)是做什麼用的,把這兩個進行比較,是很奇怪的事。一個是時間,一個是日期,時間不可能大於等於日期。

(5)破平盤使用c<GetField("參考價","D"),會比用CloseD(1)周延。

if barinterval<>1 or barfreq<>"Min" then raiseRunTimeError("限用1分鐘");
//===========================================進場===========================================
input: mintime(085500,"最早進場時間"),maxtime(091500,"最晚進場時間");
input:minprice(10,"最低價格"), maxprice(100,"最高價格");
input:minV(5000,"昨日成交量");
input: Capital(100,"每檔資金(萬)");

if date=date[1] then
value1 = getBarOffset(date,084500)                                                  //抓當天第一根1分K棒位子
else value1=0;

if GetSymbolInfo("買賣現沖") = true                                                 //確定該個股可以當沖
 and currenttime>= mintime and currenttime< maxtime                                   //確定進場時間(9:01-9:15)
 and close>= minprice and close <= maxprice and getfield("volume","D")[1]>minV     //確定股價跟昨日成交量
then begin
    condition12 = c[value1] > o[value1];                                         //第一根1分K為紅K
    if condition12 and Position = 0 and filled=0 then
        SetPosition(Capital*10/Close,Market);
end;
//===========================================出場===========================================
input: PT(3,"停利%"), SL(1, "停損%") ;

if position>0 and filled>0
and (
    c[1] < average(c,5)[1]       //收盤破五均
or  c < l[value1]                //跌破第1根K棒低點
or  c<closeD(1)                  //破平盤
or  c = GetField("漲停價", "D") //碰漲停
or  c < GetField("均價")       //破均價線
or  time > 130000                //時間到13:00                                                              
    )
then SetPosition(0);

Ryan103325 發文於   2025/05/06

第三點的部分,我的想法是:既然要符合date=date[1]才會跑出VALUE1,那就是必得第2跟K棒之後才會開始執行,所以才會這樣寫;
第四點是我沒注意到,這邊是參考別的程式碼寫的,所以有一些地方可能沒注意到;
有了,看來是出場條件的關係,謝謝您的回答~

發表回覆
Close