print log 正確,但回測報告中交易分析的圖表卻對不上

  •   7 
  • 最後發表   BJT  12 小時前
BJT 發文於   2026/08/23

3532台勝科圖表顯示第一筆交易出場為20250331,但從Log來看應為20240611就有出廠;且從該次出場後,還有20250214的出場交易紀錄,所以回測報告的交易分析圖表上第一筆,完全錯誤。

3532出場點錯誤

1513中興電,交易分析圖表顯示第一筆出場為20241209,但是從 log 看,第一筆的出場應為 20240805,並非20241209。

1513

附上回測設定

附上程式碼

// 外部參數設定
input: N_Multiple(3.0, "預估量爆量倍數(N)");
input: M_StopPct(1.0, "隔日起停損百分比(M%)");
input: IsLiveMode(false, "實盤模式開關(回測設false / 實盤設true)");

// 一般變數宣告
variable: Avg5Vol(0);         // 近 5 日平均成交量
variable: YesterdayVol(0);    // 昨日總成交量
variable: EstVolume(0);       // 當日預估量
variable: FirstEntryPrice(0); // 首次進場價格 (基準價)
variable: FirstEntryDate(0);  // 首次進場日期
variable: IsInPosition(false);// 是否持股中標記
variable: RefPrice(0);        // 當日平盤參考價
variable: TodayOpen(0);       // 當日開盤價
variable: LastAddDate(0);     // 紀錄上次加碼日期 (確保當天擇一條件加碼一次)

// 使用 intrabarpersist 確保逐筆洗價時數值即時記憶不被回滾
variable: intrabarpersist HasEnteredToday(false); // 當日是否已執行過進場的強效記憶標記

// ----------------------------------------------------
// 1. 每日開盤第一根 K 線初始化參數
// ----------------------------------------------------
if Date <> Date[1] then begin
    Avg5Vol = Average(GetField("Volume", "D")[1], 5);
    YesterdayVol = GetField("Volume", "D")[1];
    RefPrice = GetField("參考價", "D");
    TodayOpen = OpenD(0);
    EstVolume = 0;              // 每日開盤重置預估量
    HasEnteredToday = false;    // 每日開盤重置「當日進場狀態」
end;

// ----------------------------------------------------
// 2. 預估量計算邏輯 (回測鎖定 09:30 累計量 / 實盤使用語法)
// ----------------------------------------------------
if IsLiveMode then begin
    EstVolume = GetField("估計量");
end else begin
    // 回測模式:鎖定在 09:30 那一刻的累計成交量 * 4.5
    if Time = 093000 then begin
        EstVolume = GetField("Volume", "D") * 4.5;
    end;
end;

// ----------------------------------------------------
// 3. 持股狀態下的出場
// ----------------------------------------------------
if IsInPosition then begin

    // ==================== 【出場邏輯:停損】 ====================

    // a) 買進當日低於平盤價或開盤價則停損
    if Date = FirstEntryDate then begin
        if Low < RefPrice or Low < TodayOpen then begin
            SetPosition(0, Label := "當日跌破平盤/開盤停損");
            IsInPosition = false;
            Print(Date, Time, "【出場-當日停損】原因: 盤中低點跌破平盤價或開盤價 | 低點:", Low, " 平盤:", RefPrice, " 開盤:", TodayOpen);
        end;
    end

    // b) 買進隔日起,低於第一次買進價的 M% 則停損出場
    else if Date > FirstEntryDate then begin

        if Low <= FirstEntryPrice * (1 - M_StopPct * 0.01) then begin
            SetPosition(0, Label := "隔日跌破M%停損");
            IsInPosition = false;
            Print(Date, Time, "【出場-隔日起停損】原因: 盤中低點跌破首次買進價 M% 停損位 | 低點:", Low, " 停損位:", FirstEntryPrice * (1 - M_StopPct * 0.01));
        end;
    end;

end;


// ----------------------------------------------------
// 4. 無持股狀態下的進場邏輯 (結合 HasEnteredToday 判斷)
// ----------------------------------------------------
if not IsInPosition and not HasEnteredToday then begin

    // 09:30 預估量 > 5日均量 * N 且 預估量 > 昨日量 且 目前價格 > 平盤價 且 目前價格 > 開盤價
    if Time = 093000 then begin

        if EstVolume > Avg5Vol * N_Multiple and EstVolume > YesterdayVol and Close > RefPrice and Close > TodayOpen then begin

            SetPosition(1, Label := "首次爆量進場");  // 買進 1 張並加註標籤
            IsInPosition = true;                  // 標記持股部位
            HasEnteredToday = true;               // 強效標記:當日已成功進場,避免洗價重複判定
            FirstEntryPrice = Close;              // 記錄第一次進場價格
            FirstEntryDate = Date;                // 記錄第一次進場日期
            LastAddDate = 0;                      // 重置加碼日期紀錄

            Print("==================================================");
            Print(Date, Time, "【進場-首次買進 1 張】原因: 09:30爆量且價格高於平盤價與開盤價");
            Print("記錄首次進場價 (FirstEntryPrice):", FirstEntryPrice);
            Print("09:30預估量:", EstVolume, " (5日均N倍門檻:", Avg5Vol * N_Multiple, ", 昨日量:", YesterdayVol, ")");
            Print("當前價:", Close, " > 平盤價:", RefPrice, " 且 > 當日開盤價:", TodayOpen);
            Print("==================================================");
        end;
    end;

end;

虎科大許教授 發文於   2026/08/23

我使用最新版本20.02測試,是正常的。你是否使用了較舊的版本?

 

發表回覆
Close