同一根K棒(1min)進出問題?

  •   9 
  • 最後發表   小傑  6 小時前
小傑 發文於   2026/02/07

交易的前輩們你們好~
XQ可以做到同一根K棒(1min) 進場與停損嗎?
目前的問題是, 不確定以下的程式碼是否存在邏輯bug 或是 程式bug?

 

var: intrabarpersist trigger_buy(false);

var: intrabarpersist trigger_count(0);

var: trigger_time(0);

 

trigger_buy=h[0]>h[1];

 

if trigger_buy=true and trigger_count=0 and Position=0 then begin

    // 進場

    SetPosition(1, h[1]+1);

    // 紀錄交易次數

    trigger_count=trigger_count+1;

    trigger_time=time;

end 

else if trigger_buy=false and c[0]<l[1] then begin

    // 若沒有成交: 試著刪除委託

    CancelAllOrders();

    // 若已經成交: 進行停損

    SetPosition(0);

end

else if timediff(time,trigger_time,"M")>=5 and trigger_time>0 then begin

    // 交易超過5min, 且還沒有被停損, 停利出場

    SetPosition(0);

    // 變數初始化

    trigger_count=0;

    trigger_time=0;

end;

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

(1)你用IF巢狀處理進場、刪單及出場,除了邏輯容易讓人搞混,也容易造成邏輯錯誤。

(2)建議這三個部份個別處理。例如:

If Position=0 then

   begin

      //處理進場

   end;

If Position>0 then

   begin

      //用條件判斷處理刪單

      //用條件判斷處理出場

   end;

(3)若要判斷是否成交,除了Position之外,你還需要把Filled加進來判斷。

(4)只要你沒用Time控制進場及出場,就可在同一根K棒進場並出場。

 

  • 按讚來自於
  • jaylooloomi
小傑 發文於   2026/02/07

Hi 教授您好, 依照您的建議, 改成以下的方式, 是否更清楚明瞭?
不確定還有沒有什麼可能的Bug, 您能夠一眼看出? 方便指教

// 變數宣告區

var: intrabarpersist trigger_count(0);

var: intrabarpersist trigger_time(0);

var: entry_price(0);

 

// =================================================================================================

// 1. 進場邏輯處理 (Entry Logic)

// =================================================================================================

if Position = 0 and Filled = 0 and trigger_count = 0 then begin

    

    // 條件:當前K棒最高價 > 前一根K棒最高價

    if h[0] > h[1] then begin

        entry_price = h[1] + 1; // 設定進場價

        SetPosition(1, entry_price);

        

        // 紀錄進場觸發時間

        trigger_time = Time;

    end;

end;

 

// =================================================================================================

// 2. 持倉/掛單狀態處理 (Position Management)

// =================================================================================================

if Position > 0 then begin

 

    // ---------------------------------------------------------

    // A. 尚未成交 (Pending Order Management)

    // ---------------------------------------------------------

    if Filled = 0 then begin

        // 刪單條件:沒有持續創新高,且價格跌破前低

        if h[0] <= h[1] and c[0] < l[1] then begin

            CancelAllOrders(); // 取消掛單

            // 注意:這裡不設 SetPosition(0),因為還沒成交,不需要平倉指令

        end;

    end

    

    // ---------------------------------------------------------

    // B. 已經成交 (Open Position Management)

    // ---------------------------------------------------------

    else if Filled > 0 then begin

        

        // 標記已成交狀態 (防止重複進場,直到重置)

        if trigger_count = 0 then trigger_count = 1;

 

        // 條件1:停損出場 (Stop Loss)

        // 邏輯:價格跌破前一根K棒低點

        if c[0] < l[1] then begin

            SetPosition(0); // 市價平倉

            

            // 重置狀態,準備下一次交易

            trigger_count = 0;

            trigger_time = 0;

        end

        

        // 條件2:時間出場 (Time Exit)

        // 邏輯:持倉超過 5 分鐘

        else if TimeDiff(Time, trigger_time, "M") >= 5 and trigger_time > 0 then begin

            SetPosition(0); // 市價平倉

            

            // 重置狀態

            trigger_count = 0;

            trigger_time = 0;

        end;

    end;

 

end;

 

虎科大許教授 發文於   2026/02/07

 

程式看起來應該OK,但幾個地方要修改:

(1)進場價格為前一期高點加1,若你的本意是前期高點價格加上1檔,用addSpread函數處理比較好。

(2)進場時間不要用Time,若你是5分鐘頻率,則這5分鐘裡面的時間都是相同的Time,建議改用Tick成交價。

(3)h[0]、c[0]改成h、c比較好,不要沒事額外叫程式去判斷0,那樣是沒有效率的做法。

(4)你進場的條件之一是trigger_count要等於0,部位成交之後讓它變成1,但出場時又讓它歸零,似乎用來控制不要重複進場,而不是控制進場次數。其實Position就有控制避免重複進場的功能,不需要額外用其他變數控制。若trigger_count只是用來控制不要重複進場,則可省略這個變數。

//var: intrabarpersist trigger_count(0);
var: intrabarpersist trigger_time(0);
var: entry_price(0);
// =================================================================================================
// 1. 進場邏輯處理 (Entry Logic)
// =================================================================================================
if Position = 0 and Filled = 0 {and trigger_count = 0} then 
    begin
        // 條件:當前K棒最高價 > 前一根K棒最高價
        if h > h[1] then 
            begin
                entry_price = addSpread(h[1], 1); // 設定進場價
                SetPosition(1, entry_price);
                // 紀錄進場觸發時間
                trigger_time = GetField("Time", "Tick");
            end;
    end;
// =================================================================================================
// 2. 持倉/掛單狀態處理 (Position Management)
// =================================================================================================
if Position > 0 then 
    begin
        // ---------------------------------------------------------
        // A. 尚未成交 (Pending Order Management)
        // ---------------------------------------------------------
        if Filled = 0 then 
            begin
                // 刪單條件:沒有持續創新高,且價格跌破前低
                if h <= h[1] and c < l[1] then 
                    begin
                        CancelAllOrders(); // 取消掛單
                        // 注意:這裡不設 SetPosition(0),因為還沒成交,不需要平倉指令
                    end;
            end
            // ---------------------------------------------------------
            // B. 已經成交 (Open Position Management)
            // ---------------------------------------------------------
        else 
            if Filled > 0 then 
                begin
                    // 標記已成交狀態 (防止重複進場,直到重置)
                    //if trigger_count = 0 then trigger_count = 1;
                    // 條件1:停損出場 (Stop Loss)
                    // 邏輯:價格跌破前一根K棒低點
                    if c < l[1] then 
                        begin
                            SetPosition(0, market); // 市價平倉
                            // 重置狀態,準備下一次交易
                            //trigger_count = 0;
                            trigger_time = 0;
                        end
                        // 條件2:時間出場 (Time Exit)
                        // 邏輯:持倉超過 5 分鐘
                    else 
                        if TimeDiff(Time, trigger_time, "M") >= 5 and trigger_time > 0 then 
                            begin
                                SetPosition(0); // 市價平倉
                                // 重置狀態
                                //trigger_count = 0;
                                trigger_time = 0;
                            end;
                end;
    end;

 

  • 按讚來自於
  • jaylooloomi
小傑 發文於   2026/02/07

感謝教授的回覆,

您的經驗, 讓我這段小型的進出場邏輯, 更加的完善!

發表回覆
Close