最多進場2次,為何當沖獲利後,以下
第二次(再進場)回測總是沒執行到?
// B. 第二次(再進場)邏輯 (僅在狀態為 2:等待再進場 時觸發)
if StrategyState = 2 then begin
time_passed = TimeDiff(CurrentTime, LastProfitExitTime, "M") >= ReentryDelayMinutes;
price_pulled_back = Close <= LastProfitExitPrice * (1 - ReentryPullbackPercent/100);
if time_passed and price_pulled_back then begin
SetPosition(1, Market, label:="二次進場-獲利後回檔");
Alert("觸發二次進場條件,送出買單。");
end;
end;
// 腳本名稱:Two_Stage_Entry_Strategy_Final
// 說明:此版本採用「狀態機」邏輯,徹底解決再進場條件判斷錯誤的問題。
//----------------------------------------------------------------------
// 輸入參數區塊
//----------------------------------------------------------------------
Input:
// === 首次進場參數 ===
BollingerLength(10, "布林中軌天期"),
TowerLength(3, "寶塔線天期"),
// === 再次進場參數 ===
ProfitTargetForReentry(2.5, "觸發再進場的獲利率(%)"),
ReentryDelayMinutes(30, "再進場等待時間(分鐘)"),
ReentryPullbackPercent(2, "再進場價格回檔(%)"),
// === 風控出場參數 ===
StopLossPercent(30, "最終停損率(%)");
//----------------------------------------------------------------------
// 變數宣告區塊
//----------------------------------------------------------------------
Var:
// === 狀態變數 (使用IntrabarPersist確保當日K棒內資料能持續保存) ===
// StrategyState 策略狀態:0=待命中, 1=持倉中, 2=等待再進場, 3=當日已結束
IntrabarPersist StrategyState(0),
IntrabarPersist MyCostPrice(0),
IntrabarPersist LastProfitExitTime(0),
IntrabarPersist LastProfitExitPrice(0),
// === 指標與條件變數 ===
MiddleBand_D(0),
Condition_DailyRedK(False),
Condition_BollingerRedK(False),
Condition_PagodaRedK(False),
time_passed(False),
price_pulled_back(False);
//----------------------------------------------------------------------
// 每日初始化區塊:每天開盤時,重置所有狀態變數
//----------------------------------------------------------------------
if Date <> Date[1] then begin
StrategyState = 0; // 每日重置為「待命中」狀態
MyCostPrice = 0;
LastProfitExitTime = 0;
LastProfitExitPrice = 0;
end;
//----------------------------------------------------------------------
// 資料讀取與指標計算
//----------------------------------------------------------------------
SetBarBack(maxlist(BollingerLength, TowerLength), "D");
MiddleBand_D = Average(GetField("Close", "D"), BollingerLength);
Condition_DailyRedK = GetField("Close", "D") > GetField("Open", "D");
Condition_BollingerRedK = GetField("Close", "D") > MiddleBand_D;
Condition_PagodaRedK = GetField("Close", "D") > Highest(GetField("High", "D"), TowerLength)[1];
//----------------------------------------------------------------------
// 交易邏輯主體
//----------------------------------------------------------------------
// 1. 進場邏輯 (只在空手時判斷)
if Position = 0 then begin
// A. 首次進場邏輯 (僅在狀態為 0:待命中 時觸發)
if StrategyState = 0 and Condition_DailyRedK and Condition_BollingerRedK and Condition_PagodaRedK then begin
SetPosition(1, Market, label:="首次進場-三紅K條件");
Alert("觸發首次進場條件,送出買單。");
end;
// B. 第二次(再進場)邏輯 (僅在狀態為 2:等待再進場 時觸發)
if StrategyState = 2 then begin
time_passed = TimeDiff(CurrentTime, LastProfitExitTime, "M") >= ReentryDelayMinutes;
price_pulled_back = Close <= LastProfitExitPrice * (1 - ReentryPullbackPercent/100);
if time_passed and price_pulled_back then begin
SetPosition(1, Market, label:="二次進場-獲利後回檔");
Alert("觸發二次進場條件,送出買單。");
end;
end;
end;
// 2. 部位狀態更新 (根據成交回報更新策略狀態)
if Filled > Filled[1] then begin // 當買單成交時
MyCostPrice = FilledAvgPrice;
StrategyState = 1; // 無論是首次還是再次進場,成交後狀態都變為「持倉中」
end;
// 3. 出場邏輯 (只在持倉中,且狀態為 1 時判斷)
if Position > 0 and Filled > 0 and MyCostPrice > 0 and StrategyState = 1 then begin
// A. 獲利出場 (觸發二次進場的條件)
if Close >= MyCostPrice * (1 + ProfitTargetForReentry/100) then begin
Alert(Text("達成", NumToStr(ProfitTargetForReentry, 1), "%獲利目標,執行平倉。"));
LastProfitExitTime = CurrentTime; // 記錄出場時間與價格
LastProfitExitPrice = Close;
StrategyState = 2; // 將狀態切換為「等待再進場」
SetPosition(0, Market, label:="獲利平倉(觸發再進場)");
end
// B. 最終停損出場
else if Close <= MyCostPrice * (1 - StopLossPercent/100) then begin
Alert(Text("觸及", NumToStr(StopLossPercent, 1), "%最終停損,執行平倉。"));
StrategyState = 3; // 停損後,將狀態切換為「當日已結束」
SetPosition(0, Market, label:="最終停損");
end;
end;
9 評論