有關移動停利,停損點變低

  •   292 
  • 最後發表   算算有幾個六  2024 九月 13
算算有幾個六 發文於   2024/07/09

嘗試用網路上找的移動停利寫法,看了print數據後發現是移動停利的語法問題,開始移動停利後按理來說停損點就會取最高的那個數字,但現在收盤價一更新 停損點也跟著變了

按理說移動停利的停損點只會變高不會變低
不知移動停利區的語法可以加上甚麼條件,讓停損點只會往上更新呢?

input: satisfy_percent(8, "滿足啟動(%)");
input: loss_percent(6, "初始防守(%)");

var:BOut(0);

//====================進場區=================================
if Position = 0 and getField("最高價","W")>=getField("開盤價","W")*1.02 then 
 SetPosition(1,market); { 買進1張 } 
 BOut=filledavgPrice*(1-loss_percent*0.01);

//=====================移動停利區=============================
if getField("close","D")[1]*(1-(satisfy_percent+loss_percent)*0.01) > BOut then 
 BOut = getField("close","D")[1]*(1-loss_percent*0.01);
//=========================出場區============================
if position = 1 and getField("close","D") < BOut then { 啟動停利後最大獲利點 }
  SetPosition(0,market);

print("Date=",date,"部位",position,"收盤價",getField("close","D")[1],"現價",getField("close","D"),"進場點",filledavgPrice,"停損點",BOut);

附加文件

排序方式: 標準 | 最新
虎科大許教授 發文於   2024/07/09

//=====================移動停利區=============================

if getField("close","D")[1]*(1-(satisfy_percent+loss_percent)*0.01) > BOut then 

 BOut = IFF(getField("close","D")[1]>filledavgPrice,getField("close","D")[1]*(1-loss_percent*0.01),filledavgPrice*(1-loss_percent*0.01));

 

算算有幾個六 發文於   2024/07/09

成功了!太感謝許教授了!
另外想請問此語法是用在自動交易日頻率,配合的選股是一週選一次的,
目前回測結果發現當周出場後仍會再進場,要如何避免這個問題?
舉例來說 
週開盤價100,故進場點在102
漲到120後回落6% 故移動停利出場112.8
但112.8仍然符合進場條件(週開盤價+2%時進場)
所以系統就又進場了
要如何限制同一週只能進場一次呢? 避免當週重複進場的情況
謝謝。
另要限制同一週是因為,有可能同一檔,下周選股又選到可能要再進場

以波若威為例,附上回測結果 在同一週6/26進場後 6/27出場 6/28又進場

虎科大許教授 發文於   2024/07/10

input: satisfy_percent(8, "滿足啟動(%)");
input: loss_percent(6, "初始防守(%)");
var: BOut(0);
var: intraBarPersist WeekOut(0);
//====================進場區=================================
if Position = 0 
    and getField("最高價","W")>=getField("開盤價","W")*1.02 
    and  WeekOut<>xf_GetDTValue("W",Date) then SetPosition(1,market); { 買進1張 } 
BOut=filledavgPrice*(1-loss_percent*0.01);
//=====================移動停利區=============================
if getField("close","D")[1]*(1-(satisfy_percent+loss_percent)*0.01) > BOut then
 BOut = IFF(getField("close","D")[1]>filledavgPrice,getField("close","D")[1]*(1-loss_percent*0.01),filledavgPrice*(1-loss_percent*0.01));
//=========================出場區============================
if position = 1 and getField("close","D") < BOut then { 啟動停利後最大獲利點 }
    begin
        SetPosition(0,market);
        WeekOut=xf_GetDTValue("W",Date);
    end;
print("Date=",date,"部位",position,"收盤價",getField("close","D")[1],"現價",getField("close","D"),"進場點",filledavgPrice,"停損點",BOut);

算算有幾個六 發文於   2024/07/10

許教授好:

改用您說的這段IFF的條件式之後,仍然有遇到問題,IFF的第二個值getField("close","D")[1]*(1-loss_percent*0.01)仍然是變動的,底下是print資料佐證

 

原先移動停利點是收盤價前一天收盤價59.4*0.94 = 55.836,但5/10時一樣符合IFF寫的條件式,所以導致移動停利點也跟著變動了,該怎麼修改呢?謝謝

 

附加文件

算算有幾個六 發文於   2024/07/10

目前的語法入下,有使用教授的 xf_GetDTValue 語法來讓一周只進場一次有成功!
目前問題僅剩移動停利點仍然是會上下浮動,
而不是只往上更新

再請不吝指教~

input: satisfy_percent(8, "滿足啟動(%)");
input: loss_percent(6, "初始防守(%)");

var: BOut(0); //移動停損點
var: BOut0(0); //起始停損點
var: intraBarPersist weekout(0);
//======================================進場區=====================================================
if  Position = 0 
        and getField("收盤價","D")>=getField("開盤價","W")*1.02 
        and Weekout<>xf_GetDTValue("W",Date) then
    begin 
    SetPosition(1,market);  { 買進1張 }
    end;
BOut0= filledavgPrice*(1-loss_percent*0.01);
//======================================移動停利區=====================================================
if getField("收盤價","D")[1]*(1-(satisfy_percent+loss_percent)*0.01) > BOut0 and BOut0 <> 0 then
BOut = IFF(getField("收盤價","D")[1] > filledavgPrice,getField("收盤價","D")[1]*(1-loss_percent*0.01),
           BOut0);
//======================================出場區=====================================================
if position = 1 and getField("收盤價","D") < BOut or getField("收盤價","D") < BOut0 then { 啟動停利後最大獲利點 }
    begin
        SetPosition(0,market);
        Weekout = xf_GetDTValue("W",Date);
        end;
if position = 0 then BOut = 0;

print("Date=",Date,"部位",position,"收盤價",getField("收盤價","D")[1],"週開盤價",getField("開盤價", "W"),
      "現價",getField("收盤價","D"),"進場點",filledavgPrice,"初停點",BOut0,"移停點",BOut,
      "出場週數",weekout,"當前週數",xf_GetDTValue("W",Date));

虎科大許教授 發文於   2024/07/10

if barfreq<>"D" then raiseRunTimeError("限用日頻率");
input: satisfy_percent(8, "滿足啟動(%)");
input: loss_percent(6, "初始防守(%)");
var: intraBarPersist BOut(0);
var: intraBarPersist WeekOut(0);
//====================進場區=================================
if Position = 0 
    and getField("最高價","W")>=getField("開盤價","W")*1.02 
    and  WeekOut<>xf_GetDTValue("W",Date) then SetPosition(1,market); { 買進1張 } 
BOut=filledavgPrice*(1-loss_percent*0.01);
//=====================移動停利區=============================
if getField("close","D")[1]*(1-(satisfy_percent+loss_percent)*0.01) > BOut then
    begin
        BOut = IFF(getField("close","D")[1]>filledavgPrice,
        getField("close","D")[1]*(1-loss_percent*0.01),
        filledavgPrice*(1-loss_percent*0.01));
        if BOut<BOut[1] then BOut=BOut[1];
    end;
//=========================出場區============================
if position = 1 and getField("close","D") < BOut then { 啟動停利後最大獲利點 }
    begin
        SetPosition(0,market);
        WeekOut=xf_GetDTValue("W",Date);
    end;
print("Date=",date,"部位",position,"收盤價",getField("close","D")[1],
"現價",getField("close","D"),"進場點",filledavgPrice,"停損點",BOut);

算算有幾個六 發文於   2024/07/12

教授好:

目前已修正語法如下,但觀察回測及print有發現到些許進場錯誤,想請教

觀察1732毛寶這檔,2021年5月19日跳買進訊號,但其實20210518附件反白這個時間點就應該要買入了,請問為何沒有在這個點買入呢?是語法有那些問題嗎?

附上目前語法供參

input: satisfy_percent(10, "滿足啟動(%)");
input: loss_percent(6, "初始防守(%)");
input: drawback_percent(10,"移利回檔(%)");
input: right_percent(2,"追價(%)");
input: position_size(160000,"部位金額(元)");

var: BOut(0);
var: BOut0(0);
var: intraBarPersist weekout(0);
var: shares_to_buy(0);
//======================================計算買入數量===============================================
if floor(position_size / (getField("收盤價","D")*1000)) <> 0 then 
        shares_to_buy = floor(position_size / (getField("收盤價","D")*1000)) else shares_to_buy = 1;
//======================================進場區=====================================================
if  Position = 0 
        and getField("收盤價","D")>=getField("開盤價","W")*(1+right_percent*0.01)
        and Weekout<>xf_GetDTValue("W",Date) then
    begin 
        SetPosition(shares_to_buy,market);  { 買進N張 }
    end;
BOut0= filledavgPrice*(1-loss_percent*0.01);
//======================================移動停利區=====================================================
if getField("收盤價","D")[1]*(1-(satisfy_percent+loss_percent)*0.01) > BOut0 and BOut0 <> 0 then
BOut = maxList(BOut,getField("收盤價","D")[1]*(1-drawback_percent*0.01),BOut0);
//======================================出場區=====================================================
if position <> 0 and getField("收盤價","D") < BOut or getField("收盤價","D") < BOut0 then { 啟動停利後最大獲利點 }
    begin
        SetPosition(0,market);
        Weekout = xf_GetDTValue("W",Date);
        end;
if position = 0 then BOut = 0;

print("Date=",Date,"部位",position,"收盤價",getField("收盤價","D")[1],"週開盤價",getField("開盤價", "W"),
      "現價",getField("收盤價","D"),"進場點",filledavgPrice,"初停點",BOut0,"移停點",BOut,
      "出場週數",weekout,"當前週數",xf_GetDTValue("W",Date),"可買進張數",shares_to_buy);

附加文件

虎科大許教授 發文於   2024/07/12

是否還有其他進場條件?你目前的進場條件只有空手、日收盤價大於週開盤價2%,且上次出場日期與目前日期不同週次。這些條件在5/18以前連續幾天漲停都符合,照理說,5/18前的那幾天漲停收盤,都應該符合進場條件。

榛果 發文於   2024/09/06

許教授你好~請問這個策略可以用在分K嗎? 

另是不是也能把這個策略寫成指標來看呢? 

虎科大許教授 發文於   2024/09/06

1.若要用在分K,把

if barfreq<>"D" then raiseRunTimeError("限用日頻率");

改成

if barfreq<>"Min" then raiseRunTimeError("限用分鐘頻率");

2.可以。

顯示更多回應 發表回覆
Close