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

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

附上回測設定

附上程式碼
// 外部參數設定
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;


1 評論