核心策略概述
多單:
雙K突破布林上軌(High[1]>BBUP[1] && High[2]>BBUP[2] && Close[1]>Close[2] && FastSma[1]>SlowSma[1]),以 Buy_at_MARKET 市價買入
空單:
空單:
黑三兵低收 + ADX轉強 + 量能放大(Black3Bar_LClose() && ADX[1]>ADX[2] && Volume[1]>Volume[2]),以 Short_at_STOP 掛單突破賣出(非市價單)
交易限制
時段控制:交易時段編號==12 時,允許時段為 16:00~次日08:00(其餘時段僅出場、不進場)
換倉避讓:若非當沖模式(!當沖),呼叫 CheckAndCloseForSwap(23,30) 在 23:30 前執行避讓出場
每日限 2 次進場:EntriesToday(MagicNumber,Symbol()) < 2
同根K棒不重複下單:BarNumber != OrderBarNo && BarNumber != CloseOrderNo
點差過濾:SP < 商品平均點差 * Point()
資金風控:帳戶餘額 < 資金風控 門檻時,刪除所有掛單、多空部位全平倉、ExpertRemove() 強制退出
進場條件
多單模組
前兩根K棒最高價皆突破布林上軌(High[1]>BBUP[1], High[2]>BBUP[2])
收盤價遞增(Close[1]>Close[2])
快線在慢線之上(FastSma[1]>SlowSma[1],多頭排列)
空單模組
黑三兵低收型態(Black3Bar_LClose())
ADX 走強(a_ADX[1] > a_ADX[2])
成交量放大(Volume[1] > Volume[2])
進場方式
多單下單方式 :空手狀態下直接市價買入(Buy_at_MARKET)
空單下單方式 :非市價單,而是計算「賣出價格」(Get_ShortPrice(),
近期低點 − ATR×1.382)後掛突破停損賣單(Short_at_STOP),並有以下距離過濾:
賣出價需低於 Bid 且超過最小止損距離的2倍
賣出價距市價不超過收盤價的「突破距離百分比」上限
前一根收盤價須高於賣出價
且不可在商品收盤時間下單
賣出價需低於 Bid 且超過最小止損距離的2倍
賣出價距市價不超過收盤價的「突破距離百分比」上限
前一根收盤價須高於賣出價
且不可在商品收盤時間下單
出場條件
多單出場方式 (固定停損停利,只往有利方向調整):
新停利 = 進場價 + (SL×3) × Point()
新停損 = 進場價 − SL × Point()
若新值優於現有值才更新(只上移不下移)
出場條件:Bid <= 停損價 或 Bid >= 停利價
空單出場方式 (近3日低點動態調整停利):
若「近3日最低價」低於「最小停利目標(進場價−TP×0.4)」且優於現有停利價,則將停利價更新為近3日低點
出場條件:(Ask < 空單最小停利 && BB_W底形態()) 或 Ask >= 停損價 或 Ask <= 停利價
空單最小停利 = 進場價 − SP×3(以進場後的價差作最小獲利門檻)
停損停利設計
進場首根K棒(BarsSinceEntry==0)立即呼叫 TPSLchange() 將初始停損停利推送至券商端
每個Tick透過 PositionGetDouble(POSITION_TP/SL) 讀取當前實際停損停利(反映追蹤調整後狀態)
多單:初始停利 = 進場價 + TP×Point();初始停損 = 進場價 − SL×Point()
空單:初始停利 = 進場價 − TP×Point();初始停損 = 進場價 + SL×Point()
進場首根K棒(BarsSinceEntry==0)立即呼叫 TPSLchange() 將初始停損停利推送至券商端
每個Tick透過 PositionGetDouble(POSITION_TP/SL) 讀取當前實際停損停利(反映追蹤調整後狀態)
多單:初始停利 = 進場價 + TP×Point();初始停損 = 進場價 − SL×Point()
空單:初始停利 = 進場價 − TP×Point();初始停損 = 進場價 + SL×Point()
換K棒更新項目(換K棒())
商品收盤整點前自動刪除所有掛單
更新:K棒/日線 OHLC 序列、ATR、波動率(Volatility)、布林通道(BBAND)、雙均線(FloatTwoLine)、ADX
計算 Day5Range(近5日振幅平均)
樣本內區間:2019/10/1 ~ 2025/06/30
交易手數:固定 1 手
時間框架: H1圖表
交易模式:波段交易
商品收盤整點前自動刪除所有掛單
更新:K棒/日線 OHLC 序列、ATR、波動率(Volatility)、布林通道(BBAND)、雙均線(FloatTwoLine)、ADX
計算 Day5Range(近5日振幅平均)
//+------------------------------------------------------------------+
//| OnTick
//+------------------------------------------------------------------+
void OnTick()
{
if(!IsMarketOpen(10))
return;
if(AccountInfoDouble(ACCOUNT_BALANCE) < 資金風控)
{
Alert("********** 資金不足 *************");
// 刪除所有掛單 && 持倉部位平倉 && 退出EA
if(total_pending_order_count(Symbol(), MagicNumber,-1) != 0)
{
delete_pending_orders_all(Symbol(), MagicNumber, -1, 0x0000ff);
}
if(多單部位() > 0 && BarNumber != CloseOrderNo)
LX_CloseByTicket(多單進場單號,Lots) ;
if(空單部位() > 0 && BarNumber != CloseOrderNo)
SX_CloseByTicket(空單進場單號,Lots) ;
ExpertRemove();
return;
}
if(!當沖)
CheckAndCloseForSwap(23, 30);
BarNumber = iBarShift(Symbol(),時間週期,LoadEA);
BarSinceExit = BarNumber - CloseOrderNo;
if((BarNumber == 1 && BarNumber != JudgeNo))
{
CloseOrderNo = -1;
}
if(BarNumber != JudgeNo)
{
換K棒();
交易時段賦值();
}
Ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
Bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
AccountBalance=AccountInfoDouble(ACCOUNT_BALANCE);
Tickvalue=SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE);
SP = NormalizeDouble(MathAbs(Ask-Bid),Digits()) ;
if(動態計算手數 == true)
{
Lots = get_dynamic_lot_size(是否偶數單,Symbol(),風險百分比,AccountBalance,SL) ;
Lots = MathMin(0.3,MathMax(0.01,Lots)) ;
}
交易時段外也可停損停利();
if(允許交易時段 == true)
{
int TempTP = (int)(Close[1]*0.005/Point()) ;
int TempSL = (int)(Close[1]*0.005/Point()) ;
double 價格遠距上限 = Close[1] * 突破距離百分比; // 距市價不超過0.004%
double 價格遠距下限 = Close[1] * 限價距離百分比; // 距市價不超過0.002%
// SL = MathMax(SL,最小止損*2) ;
//+------------------------------------------------------------------+
//|多單進場
//+------------------------------------------------------------------+
set_BuyCondition();
if(LE_Cond == true && SP < NormalizeDouble(商品平均點差*Point(),Digits()))
{
if(多單部位() == 0 && 空單部位() == 0 && BarNumber != OrderBarNo && BarNumber != CloseOrderNo) // OnTradeTransaction 設定
{
if(EntriesToday(MagicNumber,Symbol()) < 2)
{
if(多單下單方式 == 1) // 空手+市價單買入
{
// 空手+市價單買入
Print("✅✅✅ 準備開市價多單 | K棒:", BarNumber," 舊單號",OrderBarNo, " 上次平倉單號",CloseOrderNo);
多單進場單號 = Buy_at_MARKET(Symbol(),Lots,TempTP,TempSL,"BUY MARKET",MagicNumber) ;
if(多單進場單號 > 0)
{
上次進場K棒 = BarNumber;
Print("✅ 多單開倉成功 | Ticket:", 多單進場單號, " |新單號 OrderBarNo:", OrderBarNo);
}
}
} // end of EntriesToday
} // end of 空手且不同根K棒() == true
} // end of LE_Cond == true
//+------------------------------------------------------------------+
//|空單進場
//+------------------------------------------------------------------+
set_ShortCondition() ;
if(SE_Cond == true && SP < NormalizeDouble(商品平均點差*Point(),Digits()))
{
if(多單部位() == 0 && 空單部位() == 0 && BarNumber != OrderBarNo && BarNumber != CloseOrderNo) // OnTradeTransaction 設定
{
賣出價格 = Get_ShortPrice();
if(EntriesToday(MagicNumber,Symbol()) < 2)
{
if(空單下單方式 == 2) // 空手+掛單突破賣出
{
if(賣出價格 < Bid - (最小止損*Point()) * 2 // 低於市價且超過最小止損距離*2
&& 賣出價格 > Bid - 價格遠距上限 // 距離不超過收盤價0.4%
&& Close[1] > 賣出價格 && getTM_hour(TimeCurrent()) != 商品收盤時間)
{
// 空手+掛單突破賣出
if(total_pending_order_count(Symbol(), MagicNumber,-1) == 0)
{
Print("✅✅✅ 準備開突破空單 | K棒:", BarNumber,
" | 掛單價:", 賣出價格,
" | 距市價%:", DoubleToString((Bid - 賣出價格) / Close[1] * 100, 3));
空單進場單號 = Short_at_STOP(Symbol(),MagicNumber,賣出價格,Lots,TempTP,TempSL,"Short STOP",3600) ;
}
}
}
} //end of EntriesToday
} // end of 空手且不同根K棒() == true
} // end of SE_Cond == true
} //end of 允許交易時段 == true
JudgeNo = iBarShift(Symbol(),時間週期,LoadEA);
}
//+------------------------------------------------------------------+
//| 自訂函數庫
//+------------------------------------------------------------------+
int 多單部位()
{
return get_TradeCounts(Symbol(), MagicNumber, POSITION_TYPE_BUY);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int 空單部位()
{
return get_TradeCounts(Symbol(), MagicNumber, POSITION_TYPE_SELL);
}
void 換K棒()
{
// 商品收盤時間前刪除所有掛單
if((getTM_hour(TimeCurrent()) == CloseHour) && (total_pending_order_count(Symbol(), MagicNumber,-1) != 0))
{
delete_pending_orders_all(Symbol(), MagicNumber, -1, 0x0000ff);
}
Set_OHLC_Bar_Series(); //保留
Set_OHLC_Day_Series(); //保留
Get_OHLC_Bar(30) ; //保留
Get_OHLC_Day(15) ; //保留
set_BarInfo(); //保留
set_ATR(); //保留
Get_Volatility() ; //保留
set_BBAND();
FloatTwoLine();
set_ADX();
Day5Range = ((HighD[1]-LowD[1])+(HighD[2]-LowD[2])+(HighD[3]-LowD[3])+(HighD[4]-LowD[4])+(HighD[5]-LowD[5]))/5;
}
//+------------------------------------------------------------------+
//| 交易時段賦值(保持原版不變)
//+------------------------------------------------------------------+
void 交易時段賦值()
{
允許交易時段 = (getTM_hour(TimeCurrent()) >= 16 || getTM_hour(TimeCurrent()) < 8);
}
//+------------------------------------------------------------------+
//|
//+------------------------------------------------------------------+
void 交易時段外也可停損停利()
{
// 交易時段外也可停損停利
if(多單部位() > 0)
{
//+------------------------------------------------------------------+
//| 多單出場邏輯
//+------------------------------------------------------------------+
double 多單最小停利 = 0.0, 多單保本價格 = 0.0 ;
bool LX_MinPF = false, LongPull = false;
多單進場價格 = LE_EntryPrice(MagicNumber, 多單進場單號);
多單最小停利 = NormalizeDouble(多單進場價格 + SP * 3, Digits());
LX_MinPF = Bid > 多單最小停利;
// 計算進場後的最高價
多單最高價 = iHigh(Symbol(), 時間週期, iHighest(Symbol(), 時間週期, MODE_HIGH, LE_BarsSinceEntry(MagicNumber, 多單進場單號, 時間週期), 1));
多單最高價 = NormalizeDouble(多單最高價, Digits());
//--- 進場時設定初始停損停利
if(LE_BarsSinceEntry(MagicNumber, 多單進場單號, 時間週期) == 0)
{
double 初始停利 = NormalizeDouble(多單進場價格 + TP * Point(), Digits());
double 初始停損 = NormalizeDouble(多單進場價格 - SL * Point(), Digits());
TPSLchange(Symbol(), 多單進場單號, 初始停利, 初始停損, 時間週期);
}
// 獲取當前實際的 TP/SL (供 LX_Cond 判斷用)
if(PositionSelectByTicket(多單進場單號))
{
多單停利價格 = PositionGetDouble(POSITION_TP);
多單停損價格 = PositionGetDouble(POSITION_SL);
}
//+------------------------------------------------------------------+
//| 出場方式計算
//+------------------------------------------------------------------+
//--- 固定停損停利
double 新停利 = NormalizeDouble(多單進場價格 + (SL * 3) * Point(), Digits());
double 新停損 = NormalizeDouble(多單進場價格 - SL * Point(), Digits());
if(新停利 > 多單停利價格)
多單停利價格 = 新停利 ;
if(新停損 > 多單停損價格)
多單停損價格 = 新停損 ;
TPSLchange(Symbol(), 多單進場單號, 多單停利價格, 多單停損價格, 時間週期);
LX_Cond = (Bid <= 多單停損價格) || (Bid >= 多單停利價格);
//+------------------------------------------------------------------+
//| 多單出場執行
//+------------------------------------------------------------------+
if(LX_Cond == true && BarNumber != OrderBarNo && BarNumber != CloseOrderNo &&
LE_BarsSinceEntry(MagicNumber, 多單進場單號, 時間週期) > 0)
{
LX_CloseByTicket(多單進場單號, Lots);
}
} // end of 多單部位() > 0
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
if(空單部位() > 0)
{
//+------------------------------------------------------------------+
//| 空單出場邏輯
//+------------------------------------------------------------------+
double 空單最小停利 = 0.0, 空單保本價格 = 0.0;
bool SX_MinPF = false, ShortPull = false;
空單進場價格 = SE_EntryPrice(MagicNumber, 空單進場單號);
空單最小停利 = NormalizeDouble(空單進場價格 - SP * 3, Digits());
SX_MinPF = Ask < 空單最小停利;
// 計算進場後的最低價
空單最低價 = iLow(Symbol(), 時間週期, iLowest(Symbol(), 時間週期, MODE_LOW, SE_BarsSinceEntry(MagicNumber, 空單進場單號, 時間週期), 1));
空單最低價 = NormalizeDouble(空單最低價, Digits());
//--- 進場時設定初始停損停利
if(SE_BarsSinceEntry(MagicNumber, 空單進場單號, 時間週期) == 0)
{
double 初始停利 = NormalizeDouble(空單進場價格 - TP * Point(), Digits());
double 初始停損 = NormalizeDouble(空單進場價格 + SL * Point(), Digits());
TPSLchange(Symbol(), 空單進場單號, 初始停利, 初始停損, 時間週期);
}
// 獲取當前實際的 TP/SL (供 SX_Cond 判斷用)
if(PositionSelectByTicket(空單進場單號))
{
空單停利價格 = PositionGetDouble(POSITION_TP);
空單停損價格 = PositionGetDouble(POSITION_SL);
}
//+------------------------------------------------------------------+
//| 出場方式計算
//+------------------------------------------------------------------+
double 近3日低 = NormalizeDouble(
MathMin(LowD[1], MathMin(LowD[2], LowD[3])),
Digits());
double 最小停利 = NormalizeDouble(空單進場價格 - TP * 0.4 * Point(), Digits());
if(近3日低 < 最小停利 && 近3日低 < 空單停利價格)
{
空單停利價格 = 近3日低;
TPSLchange(Symbol(), 空單進場單號, 空單停利價格, 0, 時間週期);
}
SX_Cond = (Ask < 空單最小停利 && BB_W底形態())
|| (Ask >= 空單停損價格) || (Ask <= 空單停利價格);
//+------------------------------------------------------------------+
//| 空單出場執行
//+------------------------------------------------------------------+
if(SX_Cond == true && BarNumber != OrderBarNo && BarNumber != CloseOrderNo &&
SE_BarsSinceEntry(MagicNumber, 空單進場單號, 時間週期) > 0)
{
SX_CloseByTicket(空單進場單號, Lots);
}
} // end of 空單部位() > 0
} // end of 交易時段外也可停損停利()
//+------------------------------------------------------------------+
//| 依編號Get_ShortPrice
//+------------------------------------------------------------------+
double Get_ShortPrice()
{
double ShortPrice = 0.0;
ShortPrice = get_LRangeOHLC(Symbol(),時間週期,MODE_LOW,LBar,2) - a_ATR[2]*1.382;
return NormalizeDouble(ShortPrice,Digits()) ;
} // end of get ShortPrice
//+------------------------------------------------------------------+
//|多單模組編號
//+------------------------------------------------------------------+
void set_BuyCondition()
{
// 雙K突破布林上軌
if(多單模組編號 == 9)
LE_Cond = High[1] > a_BBUP[1] && High[2] > a_BBUP[2] && Close[1] > Close[2] && a_FastSma[1] > a_SlowSma[1];
}
//+------------------------------------------------------------------+
//| 空單模組編號
//+------------------------------------------------------------------+
void set_ShortCondition()
{
// 黑三兵低收 + ADX + 量能
if(空單模組編號 == 210)
SE_Cond = Black3Bar_LClose() && a_ADX[1] > a_ADX[2] && Volume[1] > Volume[2] ;
}
回測結果
測試參數交易商品:NAS100(那指)樣本內區間:2019/10/1 ~ 2025/06/30
交易手數:固定 1 手
時間框架: H1圖表
交易模式:波段交易

沒有留言:
張貼留言