2025年9月26日 星期五

MT5 EA交易策略開發教學[16]

核心策略概述 (交易商品 NAS100 ) - 這是一個基於多重技術指標的當沖交易系統 - 主要使用Force Index、RVI、一目均衡表等指標 - 採用2小時時間框架進行分析,當日強制平倉 多單策略 進場條件: 1. FORCE_MultiConfirm() >= 2 (Force Index多重確認≥2個看漲信號) 2. WeekHPB >= 3 (兩週高點出現3日前以上) 3. High[1] > Highest_OHLC(5期) (創5日新高) 出場條件: 1. 達到最小獲利(點差*3)後,高點跌破一目均衡表轉換線 2. 或觸及停損點(-19600點) 3. 當沖時間(23:00或01:00)強制平倉
空單策略 進場條件: 1. RVI_死叉() (RVI主線下穿信號線) 2. RVI_HDiv_01() (RVI出現高點背離) 出場條件: 1. 達到最小獲利後,低點突破一目均衡表轉換線 2. 或觸及停損點(+19600點) 3. 當沖時間強制平倉 風控機制 1. 資金門檻:帳戶餘額< 5000時停止交易 2. 點差控制:進場前檢查點差< 商品平均點差(130點) 3. 頻率限制:每日最多1次進場,上次平倉後需間隔>1根K線 4. 手數管理:可選動態計算(基於風險百分比)或固定手數 5. 時間限制:當沖模式下18:00-01:00禁止進場 技術指標應用 1. Force Index:三組不同週期EMA/SMA,用於趨勢確認與背離檢測 2. RVI:用於空單策略的死叉與背離信號 3. 一目均衡表:主要用於出場信號的轉換線突破 4. 兩週高低點:用於多單策略的時間過濾條件

//+------------------------------------------------------------------+
//| MT5 自動交易程式 (Expert Advisor)                                                 
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>                                             // 引入 MT5 交易函數庫
#include <MagicMT5_函數庫V2.mqh>                            // 引入自定義函數庫

ENUM_TIMEFRAMES 時間週期 = PERIOD_H2; // 主要分析時間框架(2小時) ENUM_TIMEFRAMES 時間框架 = PERIOD_D1; // 相對大週期(日線)

//+------------------------------------------------------------------+ //| EA初始化函數 //+------------------------------------------------------------------+ int OnInit() { LoadEA = TimeCurrent(); // 記錄EA載入時間 return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 主要執行函數(每個Tick執行) //+------------------------------------------------------------------+ void OnTick() { // 資金風控檢查 if(AccountInfoDouble(ACCOUNT_BALANCE) < 資金風控) { Alert("********** 資金不足 *************"); return; } // 計算當前K線編號與上次出場後的K線數 BarNumber = iBarShift(Symbol(),時間週期,LoadEA); BarSinceExit = BarNumber-CloseOrderNo; // 第一根K線時的測試交易(立即開倉後平倉) if((BarNumber == 1 && BarNumber != JudgeNo)) { 多單進場單號 = Buy_at_MARKET(Symbol(),Lots,0,0,"1st_K",MagicNumber); LX_CloseByTicket(多單進場單號,Lots); 空單進場單號 = Short_at_MARKET(Symbol(),Lots,0,0,"1st_K",MagicNumber); SX_CloseByTicket(空單進場單號,Lots); CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA); FastSma = MathMin(LenA1, LenB1); SlowSma = MathMax(LenA1, LenB1); } // 新K線處理 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)); // 限制手數範圍 0.01-0.3 } // 當沖模式的時間檢查 if(當沖 == true) { 接近收盤 = (getTM_hour(TimeCurrent()) >= 18 || getTM_hour(TimeCurrent()) <= 1); 允許交易時段 = (允許交易時段 && !接近收盤); } // 進場邏輯處理 if(允許交易時段 == true) { //+------------------------------------------------------------------+ //| 多單進場邏輯 //+------------------------------------------------------------------+ set_BuyCondition(); // 設定多單進場條件 // 多單進場條件檢查 if(LE_Cond == true && SP < NormalizeDouble(商品平均點差*Point(),Digits()) && // 點差檢查 最近幾筆內有空單平倉(Symbol(),6) == true) // 最近有空單平倉 { // 確保空手且不是同根K線 if(多單部位() == 0 && 空單部位() == 0 && BarNumber != OrderBarNo) { // 上次出場後間隔檢查與每日進場限制 if(BarSinceExit > 1 && EntriesToday(MagicNumber,Symbol()) < 1) { 多單進場單號 = Buy_at_MARKET(Symbol(),Lots,TP,SL,"BUY MARKET",MagicNumber); OrderBarNo = iBarShift(Symbol(),時間週期,LoadEA); } } } //+------------------------------------------------------------------+ //| 空單進場邏輯 //+------------------------------------------------------------------+ set_ShortCondition(); // 設定空單進場條件 // 空單進場條件檢查 if(SE_Cond == true && SP < NormalizeDouble(商品平均點差*Point(),Digits())) // 點差檢查 { // 確保空手且不是同根K線 if(多單部位() == 0 && 空單部位() == 0 && BarNumber != OrderBarNo) { // 上次出場後間隔檢查與每日進場限制 if(BarSinceExit > 1 && EntriesToday(MagicNumber,Symbol()) < 1) { 空單進場單號 = Short_at_MARKET(Symbol(),Lots,TP,SL,"Short Market",MagicNumber); OrderBarNo = iBarShift(Symbol(),時間週期,LoadEA); } } } } //+------------------------------------------------------------------+ //| 當沖強制平倉 //+------------------------------------------------------------------+ if(當沖 == true && (getTM_hour(TimeCurrent()) == 當沖出場時間 || getTM_hour(TimeCurrent()) == 1)) { if(多單部位() > 0 || 空單部位() > 0) { 當沖平倉(); } } 交易時段外也可停損停利(); // 執行停損停利檢查 JudgeNo = iBarShift(Symbol(),時間週期,LoadEA); // 更新判斷K線編號 } //+------------------------------------------------------------------+ //| 自訂函數區域 //+------------------------------------------------------------------+ // 多單部位計算 int 多單部位() { int count; count = get_TradeCounts(Symbol(), MagicNumber, POSITION_TYPE_BUY); return count; } // 空單部位計算 int 空單部位() { int count; count = get_TradeCounts(Symbol(), MagicNumber, POSITION_TYPE_SELL); return count; } // 換K線時的處理 void 換K棒() { // 刪除所有未成交的掛單 if(total_pending_order_count(Symbol(), MagicNumber,-1) != 0) { delete_pending_orders_all(Symbol(), MagicNumber, -1, 0x0000ff); } // 更新各時間框架的OHLC數據 Set_OHLC_Bar_Series(); // 設定K線數據序列 Set_OHLC_Day_Series(); // 設定日線數據序列 Get_OHLC_Bar(30); // 獲取30根K線數據 Get_OHLC_Day(15); // 獲取15個交易日數據 Set_OHLC_Week_Series(); // 設定週線數據序列 Get_OHLC_Week(5); // 獲取5週數據 // 計算技術指標 TwoWeekHL(); // 計算兩週高低點 set_RVI(); // 設定RVI指標 set_ICHIMOKU(); // 設定一目均衡表指標 set_FORCE_INDEX(); // 設定Force Index指標 // 計算五日平均振幅 Day5Range = ((HighD[1] - LowD[1])+(HighD[2] - LowD[2])+(HighD[3] - LowD[3]) +(HighD[4] - LowD[4])+(HighD[5] - LowD[5]))/5; } // 交易時段設定 void 交易時段賦值() { if(交易時段編號 == 45) 允許交易時段 = true; // 45代表全時段交易 } // 當沖平倉處理 void 當沖平倉() { if((getTM_hour(TimeCurrent()) == 當沖出場時間 || getTM_hour(TimeCurrent()) == 1)) { if(多單部位() > 0 && BarNumber != CloseOrderNo) LX_CloseByTicket(多單進場單號,Lots); if(空單部位() > 0 && BarNumber != CloseOrderNo) SX_CloseByTicket(空單進場單號,Lots); CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA); } } // 停損停利處理 void 交易時段外也可停損停利() { // 多單停損停利處理 if(多單部位() > 0) { double 多單最小停利 = 0.0; bool LX_MinPF = false; 多單進場價格 = LE_EntryPrice(MagicNumber,多單進場單號); 多單最小停利 = NormalizeDouble(多單進場價格 + SP*3,Digits()); LX_MinPF = Bid > 多單最小停利; // 最小獲利檢查 多單停利價格 = NormalizeDouble(多單進場價格 + TP * Point(),Digits()); 多單停損價格 = NormalizeDouble(多單進場價格 - SL * Point(),Digits()); // 出場條件:達最小獲利且跌破一目均衡表,或觸及停損 LX_Cond = ((LX_MinPF == true && CrossUnder(High[2],a_ICHI_C[2],High[1],a_ICHI_C[1])) || (Close[1] >= 多單停損價格 && Bid < 多單停損價格)); // 執行多單出場 if(LX_Cond == true && BarNumber != CloseOrderNo && LE_BarsSinceEntry(MagicNumber,多單進場單號,時間週期) > 0) { LX_CloseByTicket(多單進場單號,Lots); if(多單部位() == 0) { CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA); } } } // 空單停損停利處理 if(空單部位() > 0) { double 空單最小停利 = 0.0; bool SX_MinPF = false; 空單進場價格 = SE_EntryPrice(MagicNumber,空單進場單號); 空單最小停利 = NormalizeDouble(空單進場價格 - SP*3,Digits()); SX_MinPF = Ask < 空單最小停利; // 最小獲利檢查 空單停利價格 = NormalizeDouble(空單進場價格 - TP * Point(),Digits()); 空單停損價格 = NormalizeDouble(空單進場價格 + SL * Point(),Digits()); // 出場條件:達最小獲利且突破一目均衡表,或觸及停損 SX_Cond = ((SX_MinPF == true && CrossOver(Low[2],a_ICHI_C[2],Low[1],a_ICHI_C[1])) || (Close[1] <= 空單停損價格 && Ask > 空單停損價格)); // 執行空單出場 if(SX_Cond == true && BarNumber != CloseOrderNo && SE_BarsSinceEntry(MagicNumber,空單進場單號,時間週期) > 0) { SX_CloseByTicket(空單進場單號,Lots); if(空單部位() == 0) { CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA); } } } } //+------------------------------------------------------------------+ //| 多單進場條件設定 //+------------------------------------------------------------------+ void set_BuyCondition() { // 多單條件:Force Index多重確認≥2 且 兩週高點3日前 且 創5日新高 LE_Cond = (FORCE_MultiConfirm() >= 2 && WeekHPB >= 3 && High[1] > Highest_OHLC(Symbol(),時間週期,MODE_HIGH,5,1)); } //+------------------------------------------------------------------+ //| 空單進場條件設定 //+------------------------------------------------------------------+ void set_ShortCondition() { // 空單條件:RVI死叉 且 RVI高點背離 SE_Cond = (RVI_死叉() && RVI_HDiv_01()); } //+------------------------------------------------------------------+ //| RVI指標相關函數 //+------------------------------------------------------------------+ // RVI死叉檢測 bool RVI_死叉() { // RVI主線下穿信號線 if(a_RVI_1[2] >= a_RVI_2[2] && a_RVI_1[1] < a_RVI_2[1]) { return true; // 死叉確認 } return false; } // RVI高點背離檢測 bool RVI_HDiv_01() { // 價格高點在最近2根K線,RVI高點在更早期間,且RVI當前值較低 if((ArrayMaximum(High) !=0 && ArrayMaximum(High) <= 2) && (ArrayMaximum(a_RVI_1) > 2) && a_RVI_1[1] < 0.5) { return true; // 高點背離確認 } return false; }

回測結果
測試參數交易商品:NAS100(那斯達克指數)
樣本內區間:2019/1/1 ~ 2023/8/31
交易手數:固定 1 手
時間框架:H2 小時圖表
交易模式:當沖交易

現在就加入《外匯實戰 MT5 EA基礎班》,用量化思維,開啟你的交易新紀元!


★ ~~~ 早鳥優惠 ( 2025/11/13 前報名) ~~~ ★ 
🎁限量加碼 贈送 實戰EA *2
(XAUUSD *1 + NAS100 * 1)
可攜伴2位參加文創手作聖誕樹 DIY才藝班




沒有留言:

張貼留言