關於停損停利設定

  •   1.7K 
  • 最後發表   lee vick  2023 八月 30
lee vick 發文於   2023/07/25

請問為什麼我這樣設定停損了,程式到了2%沒有幫我自動停損,而且漲超過6%的股票我應該也也設置不交易了呀,停損在自動交易那邊也是設定市價了,可是還是被鎖漲停,另外我設定只有9:30以前交易,可是在回測的時候常常會超過9.30還在交易,13:00也未必照著我的設定平倉

--------------------------------------------------------------------------

input: profit_percent(2.5, "停利(%)");
input: loss_percent(2, "停損(%)");
input: open_percent(2, "開盤漲幅(%)");
input: before_920_percent(5, "9:20之前漲幅(%)");

settotalbar(1); // 只考慮當日的開盤價
value3 = GetField("漲停價", "D") * 0.96;
var: entry_condition(false); // 進場條件


// 判斷開盤價漲幅是否小於2%
entry_condition = Open < Open[1] * (1 + 0.01 * open_percent);

if entry_condition then begin
    // 只考慮9:20之前的價格資訊
    settotalbar(20); // 15分鐘內的資訊

    // 判斷9:20之前股價是否漲幅大於5%且價格在48元以下
    entry_condition = XXOO(某條件) and
                     Time < 093000 ;
    
    if entry_condition then begin
        // 在這裡處理符合進場條件時的交易指令
        // 例如 SetPosition(-1) 表示進行空頭交易
        SetPosition(-6, AddSpread(Close, 4));
    end;
   

end;   


if Position = -6 and Filled = -6 then begin

    
    if profit_percent > 0 and Close <= FilledAvgPrice*(1-0.01*profit_percent) then begin
     
        SetPosition(0);
    end else if loss_percent > 0 and Close >= FilledAvgPrice*(1+0.01*loss_percent) then begin   
 
        SetPosition(0);
    end else if CurrentTime >130000 then begin SetPosition(0);
       
    end;
    
end;
if Position = -5 and Filled = -5 then begin
    
    
    if profit_percent > 0 and Close <= FilledAvgPrice*(1-0.01*profit_percent) then begin
      
        SetPosition(0);
    end else if loss_percent > 0 and Close >= FilledAvgPrice*(1+0.01*loss_percent) then begin   
      
        SetPosition(0);
    end else if time >130000 then begin SetPosition(0);
       
    end;
    
end;

if Position = -4 and Filled = -4 then begin
   
    
    if profit_percent > 0 and Close <= FilledAvgPrice*(1-0.01*profit_percent) then begin
      
        SetPosition(0);
    end else if loss_percent > 0 and Close >= FilledAvgPrice*(1+0.01*loss_percent) then begin   
       
        SetPosition(0);
    end else if time >130000 then begin SetPosition(0);
       
    end;
    
end;

if Position = -3 and Filled = -3 then begin
 
    
    if profit_percent > 0 and Close <= FilledAvgPrice*(1-0.01*profit_percent) then begin
     
        SetPosition(0);
    end else if loss_percent > 0 and Close >= FilledAvgPrice*(1+0.01*loss_percent) then begin   

        SetPosition(0);
    end else if time >130000 then begin SetPosition(0);
       
    end;
    
end;


if Position = -2 and Filled = -2 then begin
    
    
    if profit_percent > 0 and Close <= FilledAvgPrice*(1-0.01*profit_percent) then begin
 
        SetPosition(0);
    end else if loss_percent > 0 and Close >= FilledAvgPrice*(1+0.01*loss_percent) then begin   
 
        SetPosition(0);
    end else if time >130000 then begin SetPosition(0);
       
    end;
    
end;

if Position = -1 and Filled = -1 then begin
    // 依照成本價格設定停損/停利: 請注意當作空時, 判斷是否獲利的方向要改變
    
    if profit_percent > 0 and Close <= FilledAvgPrice*(1-0.01*profit_percent) then begin
       
        SetPosition(0);
    end else if loss_percent > 0 and Close >= FilledAvgPrice*(1+0.01*loss_percent) then begin   
        
        SetPosition(0);
    end else if time >130000 then begin SetPosition(0);
       
    end;
    
end;

排序方式: 標準 | 最新
lee vick 發文於   2023/07/25
lee vick 發文於   2023/07/25
lee vick 發文於   2023/07/25

現在發現我的value3好像寫錯了,要改成value3 = GetField("漲停價", "D")/1.1*1.06;            才能達到抓個股6%
可是其他如9:30以後還是會下單和停損停利依然都不是照著2%設定去執行

XQ小幫手 發文於   2023/07/27

Hello lee vick,

 

網站上有教學區,裡面有XS語法的基礎和應用可以閱覽。

建議您在遇到問題時可以使用 print 函數將數值印出確認 (ex. value3的數值)。

且小幫手不知道您使用的頻率,open[1] 和 close[19] 看起來像是想用在不同頻率上,但這種寫法都會是腳本目前執行的頻率。

舉例來說,Open < Open[1] * (1 + 0.01 * open_percent) 會是比較當根K棒開盤價與上根K棒開盤價。

另外 SetTotalBar 的說明可參考 資料讀取範圍與腳本執行的關係。

其是限定在執行範圍之前要額外運算多少筆,當有複數個SetTotalBar時只會執行最後一個。

和只考慮當日的開盤價或只考慮9:20之前的價格資訊沒有關係。

 

SetPosition(-6, AddSpread(Close, 4));

這會在符合條件時下出6筆空單,就算條件接下來不符合了,除非有取消不然委託就會持續掛在那邊直到成交。

所以是會發生在 9:30 以後成交的狀況。

 

小幫手不理解您為什麼停利停損的指令要從 position =-6 開始一直寫到 position = 1。

您的 position 只會是 0 或 -6 ,不會有其他的狀況,故除了 if Position = -6 and Filled = -6 then begin 以外其他的停利停損腳本都不會執行。

且這停損停利也不一定會是2%,因為這是進場價格向上向下2%,而交易時還會有手續費及滑價,不太可能剛好成交在2%上。

實際上價格可能根本不會落在2%上。

lee vick 發文於   2023/07/27

謝謝小幫手的回答,

1.position =-6 開始一直寫到 position = -1,是我假設若掛單6筆空單,卻只有部分成交的情況,所以我把每個可能成交的部分都寫進去

2.我是用一分K來執行,關於停損停利不會剛好2%的回應,我知道要計算入手續費及滑價,但是我拿合機7/25號我被鎖漲停來舉例好了

   9:04.08  用28.4價位掛單,你說有可能是之後才成交,9:05最高價有到28.45(所以我肯定有成交了),這時我的停損2%應該在28.95,9:15股票飆到29.1,我是設定用市價去出的,不可能沒出掉!!而且我的掛單紀錄9:15左右程式根本沒有幫我送出任何停損單!!9:16~9:20也一堆成交單根本也還沒鎖漲停板,但是程式單這樣搞得害我被鎖漲停

  還請小幫手幫我解釋一下

 

lee vick 發文於   2023/07/27

我再隨便附上回測上的數據,走勢如此平穩根本不可能停損滑價到這麼多

 

XQ小幫手 發文於   2023/07/31

Hello lee vick,

 

1.如同小幫手所說,就上面的腳本來看,您的 position 只會是 -6 或 0,不會有中間 -5 ~ -1 的狀況。

因此像是 Position = -5 and Filled = -5 的條件式不會符合的。

而且就算部分成交的話,尚未成交的委託單也會維持,故不需要另外做處理。

除非您是要針對未成交委託單進行調整,但這樣的話 position 的部分也應該為 0 或 -6。

 

2.建議您在腳本中加上 print 將相關數值印出,這樣會比較容易找出原因。

至於回測的部分,若將相關數值print出來還是沒辦法找出原因的話,麻煩您提供 交易腳本匯出檔、回測設定 (截圖或回測報告皆可) 以及 XQ Log 來檢驗。

Log資料夾(預設路徑:C:\SysJust\XQLite\LOG)直接壓縮後提供即可。

您可以直接將檔案上傳,如果檔案過大的話也可以保存到雲端後將連結Mail至客服信箱 XQservice@XQ.com.tw 且務必附上 討論文章連結網址(小幫手才能盡早處理)。

感謝。

lee vick 發文於   2023/07/31

已經用信件寄出相關文件,另外我想加入若10根K棒沒成交,則取消剩下的委託單

我查之前別人的帖子是這樣寫:

if trueall(position <> filled, 10) then setposition(filled);

不過我要如何加入我的程式碼,才不會破壞我現在的出場邏輯和出錯

 

XQ小幫手 發文於   2023/08/02

Hello lee vick,

 

針對您郵件裡面的問題,當腳本中同一次運算中 setposition 被執行多次時,只會執行第一個運作的 setposition。

詳情可參考setposition裡的說明。

https://xshelp.xq.com.tw/XSHelp/?HelpName=SetPosition&group=TRANSACTIONFUNC

郵件中附上的問題,腳本在 093000 以前 entry_condition 都會是 True,所以 093000 以前就算停利停損的條件符合,該setposition也不會被執行。

如果您在腳本中友加上print印出相關資訊的話就比較容易看出問題原因。

而上面的平緩走勢沒出場應該是相同原因。

 

建議您可以在進場條件內加上 position = 0 and filled = 0 的條件,避免進場的setposition阻礙到出場條件。

並在回測時都用市價單進出場,這樣會比較容易確認問題原因。

 

至於10根Bar未成交的部分,如果您希望最優先執行的話,可以將其放到腳本最上方,這樣就會最優先執行。

lee vick 發文於   2023/08/03

請問為何我平倉的寫法不同的話,竟然會影響到回測後的總交易次數(相同的時間距),正常不應該吧?也請小幫手順便幫我看看還有哪邊怪怪的,我這邊用position=filled是怕中間有取消單子,所以乾脆這樣寫

寫法一(總交易次數1156):

input: loss_percent(1.5, "停損(%)");          

input: profit_percent(1.7, "停利(%)");   

if xxoo and position = 0 and filled = 0  then setposition(-3);

 if trueall(position <> filled, 5) then setposition(filled)  ;  //5根K內沒成交就取消

 if position=filled and  profit_percent > 0 and close <= FilledAvgPrice*(1-0.01*profit_percent) then            

{ 停利 }               

SetPosition(0,market);             

 if position=filled and loss_percent > 0 and high >= FilledAvgPrice*(1+0.01*loss_percent) then             

{ 停損 }             

SetPosition(0,market);             

if position=filled and CurrentTime >130000 then SetPosition(0,market);             //13:00後自動回補

if position=filled and high>=addSpread(upLimit(closeD(0)),-6) then SetPosition(0,market);   //到達漲停前6檔就平倉

 

寫法二(交易次數只有2):

input: loss_percent(1.5, "停損(%)");          

input: profit_percent(1.7, "停利(%)");   

if xxoo and position = 0 and filled = 0  then setposition(-3);

 if trueall(position <> filled, 5) then setposition(filled)  ;  //5根K內沒成交就取消             

if  profit_percent > 0 and close <= FilledAvgPrice*(1-0.01*profit_percent) then            

{ 停利 }               

SetPosition(0,market);             

 if loss_percent > 0 and high >= FilledAvgPrice*(1+0.01*loss_percent) then             

{ 停損 }             

SetPosition(0,market);             

if   CurrentTime >130000 then SetPosition(0,market);             

if high>=addSpread(upLimit(closeD(0)),-6) then SetPosition(0,market);  :

 

顯示更多回應 發表回覆
Close