核心策略概述 (商品 NAS100)
這是一個日內型態與背離交易策略。策略透過價格型態識別(多單)與CCI背離確認(空單)來捕捉交易機會,搭配嚴格的風險管理與時段控制,專注於單次高勝率進場。
基礎概念
動態手數計算(基於風險百分比、帳戶餘額與SL),手數限制在0.01~0.3
資金風控門檻: 低於門檻時停止交易
商品平均點差限制: 進場前檢查點差 < 商品平均點差 * Point()
交易限制:
每日限制1次進場(EntriesToday < 1)
出場後須間隔1根K棒以上(BarSinceExit > 1)
交易時段: 僅允許 00:00~16:00 交易
進出場策略
多單進場條件
LE_Cond = (High3Bar_LClose() == false && Low[1] < Low[2])
條件分析:
非高點破頂急跌: High3Bar_LClose() == false —— 排除特定高點型態後的急跌走勢
低點下破: Low[1] < Low[2] —— 前一根K棒低點低於前兩根K棒,確認價格下探進場方式:市價單買入
僅在無部位、點差小於限制、今日未進場、BarSinceExit > 1 時執行
額外條件: 最近6筆內有空單平倉(最近幾筆內有空單平倉() == true)
空單進場條件
SE_Cond = (CCI_LDiv_02() && BigMin3L < a_BigAvg13[1])
條件分析:
CCI低檔背離02: CCI_LDiv_02() —— CCI指標出現低檔背離型態(價格創新低但CCI未創新低)
三線最低值低於13線: BigMin3L < a_BigAvg13[1] —— 大週期三線指標的最低值低於13期均線,確認弱勢環境
進場方式:市價單賣出
僅在無部位、點差小於限制、今日未進場、BarSinceExit > 1 時執行
出場機制
多單出場
LX_Cond = ((LX_MinPF && RSI高檔鈍化()) || (Close[1] >= 多單停損價格 && Bid < 多單停損價格))
出場條件:
最小獲利+RSI鈍化: 獲利達 SP*3 且RSI出現高檔鈍化
停損觸發: 前一根收盤價突破停損價,但當前Bid價回落至停損價下方
停損停利設定:
停利價: 進場價 + TP * Point()
停損價: 進場價 - SL * Point()
移動停損 (若 移動停損利 == true):
追蹤多單最高價(進場後所有K棒的最高點)
當獲利達TP的30%以上時,停損調整為: 多單最高價 - SL * Point()
保本出場 (若 保藍設定 == true):
當獲利達TP的50%時啟動保本機制
保本價: 進場價 + TP * 0.168
若前一根收盤價高於保本價,但當前Bid低於保本價,則平倉
空單出場
SX_Cond = ((Close[1] >= 空單停利價格 && Ask < 空單停利價格) || (Close[1] <= 空單停損價格 && Ask > 空單停損價格))
出場條件:
停利觸發: 前一根收盤價突破停利價,但當前Ask回落至停利價上方
停損觸發: 前一根收盤價跌破停損價,但當前Ask回升至停損價下方
停損停利設定:
動態停利價: 進場價 - (TP + Day5Range) * Point() —— 結合近5日平均日內波動範圍
停損價: 進場價 + SL * Point()
移動停損 (若 移動停損利 == true):
追蹤空單最低價(進場後所有K棒的最低點)
當獲利達TP的30%以上時,停損調整為: 空單最低價 + SL * Point()
保本出場 (若 保藍設定 == true):
當獲利達TP的50%時啟動保本機制
保本價: 進場價 - TP * 0.168
若前一根收盤價低於保本價,但當前Ask高於保本價,則平倉
基礎概念
動態手數計算(基於風險百分比、帳戶餘額與SL),手數限制在0.01~0.3
資金風控門檻: 低於門檻時停止交易
商品平均點差限制: 進場前檢查點差 < 商品平均點差 * Point()
交易限制:
每日限制1次進場(EntriesToday < 1)
出場後須間隔1根K棒以上(BarSinceExit > 1)
交易時段: 僅允許 00:00~16:00 交易
進出場策略
多單進場條件
LE_Cond = (High3Bar_LClose() == false && Low[1] < Low[2])
條件分析:
非高點破頂急跌: High3Bar_LClose() == false —— 排除特定高點型態後的急跌走勢
低點下破: Low[1] < Low[2] —— 前一根K棒低點低於前兩根K棒,確認價格下探進場方式:市價單買入
僅在無部位、點差小於限制、今日未進場、BarSinceExit > 1 時執行
額外條件: 最近6筆內有空單平倉(最近幾筆內有空單平倉() == true)
空單進場條件
SE_Cond = (CCI_LDiv_02() && BigMin3L < a_BigAvg13[1])
條件分析:
CCI低檔背離02: CCI_LDiv_02() —— CCI指標出現低檔背離型態(價格創新低但CCI未創新低)
三線最低值低於13線: BigMin3L < a_BigAvg13[1] —— 大週期三線指標的最低值低於13期均線,確認弱勢環境
進場方式:市價單賣出
僅在無部位、點差小於限制、今日未進場、BarSinceExit > 1 時執行
出場機制
多單出場
LX_Cond = ((LX_MinPF && RSI高檔鈍化()) || (Close[1] >= 多單停損價格 && Bid < 多單停損價格))
出場條件:
最小獲利+RSI鈍化: 獲利達 SP*3 且RSI出現高檔鈍化
停損觸發: 前一根收盤價突破停損價,但當前Bid價回落至停損價下方
停損停利設定:
停利價: 進場價 + TP * Point()
停損價: 進場價 - SL * Point()
移動停損 (若 移動停損利 == true):
追蹤多單最高價(進場後所有K棒的最高點)
當獲利達TP的30%以上時,停損調整為: 多單最高價 - SL * Point()
保本出場 (若 保藍設定 == true):
當獲利達TP的50%時啟動保本機制
保本價: 進場價 + TP * 0.168
若前一根收盤價高於保本價,但當前Bid低於保本價,則平倉
空單出場
SX_Cond = ((Close[1] >= 空單停利價格 && Ask < 空單停利價格) || (Close[1] <= 空單停損價格 && Ask > 空單停損價格))
出場條件:
停利觸發: 前一根收盤價突破停利價,但當前Ask回落至停利價上方
停損觸發: 前一根收盤價跌破停損價,但當前Ask回升至停損價下方
停損停利設定:
動態停利價: 進場價 - (TP + Day5Range) * Point() —— 結合近5日平均日內波動範圍
停損價: 進場價 + SL * Point()
移動停損 (若 移動停損利 == true):
追蹤空單最低價(進場後所有K棒的最低點)
當獲利達TP的30%以上時,停損調整為: 空單最低價 + SL * Point()
保本出場 (若 保藍設定 == true):
當獲利達TP的50%時啟動保本機制
保本價: 進場價 - TP * 0.168
若前一根收盤價低於保本價,但當前Ask高於保本價,則平倉
//+------------------------------------------------------------------+
//| MT5 自動交易程式 (Expert Advisor)
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh> // 引入 MT5 交易函數庫
#include <MagicMT5_函數庫V2.mqh> // 引入自定義函數庫
ENUM_TIMEFRAMES 時間週期 = PERIOD_M6; // EA 主要運行的時間週期。
ENUM_TIMEFRAMES 時間框架 = PERIOD_H1; // 相對大週期,可能用於趨勢判斷或過濾
//+------------------------------------------------------------------+
//| 初始化函式 (EA 載入時執行一次)
//+------------------------------------------------------------------+
int OnInit()
{
LoadEA = TimeCurrent(); // 記錄 EA 載入的當前時間。
return(INIT_SUCCEEDED); // 初始化成功。
}
//+------------------------------------------------------------------+
//| OnTick 函式 (每次報價變動時執行)
//+------------------------------------------------------------------+
int OnInit()
{
// 記錄 EA 加載時的當前時間,用於後續計算 K 棒偏移量
LoadEA = TimeCurrent();
return(INIT_SUCCEEDED); // 返回初始化成功
}
//+------------------------------------------------------------------+
//| 報價驅動函數:每當價格跳動(Tick)時即執行一次 |
//+------------------------------------------------------------------+
void OnTick()
{
// 資金風控檢查:若帳戶餘額低於設定的「資金風控」值,則停止執行並報警
if(AccountInfoDouble(ACCOUNT_BALANCE) < 資金風控)
{
Alert("********** 資金不足 *************");
return;
}
// 計算當前 K 棒相對於 EA 啟動時間 (LoadEA) 的位置編號
BarNumber = iBarShift(Symbol(),時間週期,LoadEA);
// 計算自上次平倉後經過了多少根 K 棒
BarSinceExit = BarNumber-CloseOrderNo ;
// 特殊邏輯:當處於啟動後的第一根 K 棒且尚未標記過 JudgeNo 時執行
if((BarNumber == 1 && BarNumber != JudgeNo))
{
// 進行首根 K 棒的測試性進出場(市價買入後立即平倉,通常用於測試連結或初始化參數)
多單進場單號 = 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) ;
// 紀錄平倉時的 K 棒編號
CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA);
// 初始化快慢均線參數,確保 LenA1 為較小值,LenB1 為較大值
FastSma = MathMin(LenA1, LenB1);
SlowSma = MathMax(LenA1, LenB1);
}
// 換 K 棒偵測:當 K 棒編號改變時,執行定時更新函數
if(BarNumber != JudgeNo)
{
換K棒(); // 執行自訂的換 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()) ; // 計算當前點差(Ask-Bid 的絕對值)
//+------------------------------------------------------------------+
//| 計算交易手數:根據風險比例或固定手數進行動態調整 |
//+------------------------------------------------------------------+
if(動態計算手數 == true)
{
// 呼叫外部函數計算手數,通常基於止損距離(SL)與風險百分比
Lots = get_dynamic_lot_size(是否偶數單,Symbol(),風險百分比,AccountBalance,SL) ;
// 限制手數區間,最小 0.01 手,最高不超過 0.3 手,防止超量交易
Lots = MathMin(0.3,MathMax(0.01,Lots)) ;
}
// 交易時段判斷
if(允許交易時段 == true)
{
//+------------------------------------------------------------------+
//| 多單進場邏輯區塊 |
//+------------------------------------------------------------------+
set_BuyCondition(); // 載入多單過濾條件
// 判斷條件:符合進場信號、點差小於平均值、且最近 6 筆成交內有空單平倉紀錄(特定的策略慣性)
if(LE_Cond == true && SP < NormalizeDouble(商品平均點差*Point(),Digits()) && 最近幾筆內有空單平倉(Symbol(),6) == true)
{
// 確保當前無多空部位,且同一根 K 棒內不重複下單
if(多單部位() == 0 && 空單部位() == 0 && BarNumber != OrderBarNo)
{
// 進場冷卻限制:距離上次平倉需超過 1 根 K 棒,且今日下單次數小於 1(每日限一單)
if(BarSinceExit > 1 && EntriesToday(MagicNumber,Symbol()) < 1)
{
多單進場單號 = Buy_at_MARKET(Symbol(),Lots,TP,SL,"BUY MARKET",MagicNumber) ;
OrderBarNo = iBarShift(Symbol(),時間週期,LoadEA); // 紀錄下單時的 K 棒
} // end of BarSinceExit > 1
} // end of 空手檢查
} // end of LE_Cond
//+------------------------------------------------------------------+
//| 空單進場邏輯區塊 |
//+------------------------------------------------------------------+
set_ShortCondition() ; // 載入空單過濾條件
// 判斷條件:符合進場信號、點差在合理範圍內
if(SE_Cond == true && SP < NormalizeDouble(商品平均點差*Point(),Digits()))
{
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);
} //end of BarSinceExit > 1
} // end of 空手檢查
} // end of SE_Cond
} //end of 允許交易時段 == true
// 無論是否在交易時段內,皆持續監控部位的停損與停利(保護部位)
交易時段外也可停損停利();
// 更新判斷編號,用於判斷下次 Tick 是否為新 K 棒
JudgeNo = iBarShift(Symbol(),時間週期,LoadEA);
} //end of OnTick
//+------------------------------------------------------------------+
//| 自訂函數:計算當前持有的多單部位數量 |
//+------------------------------------------------------------------+
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棒()
{
// 每逢新 K 棒,清除該 MagicNumber 下的所有未成交掛單
if(total_pending_order_count(Symbol(), MagicNumber,-1) != 0)
{
delete_pending_orders_all(Symbol(), MagicNumber, -1, 0x0000ff);
}
// 更新 K 線數據數組(Open, High, Low, Close)
Set_OHLC_Bar_Series();
Set_OHLC_Day_Series();
Get_OHLC_Bar(30) ; // 獲取最近 30 根 K 棒數據
Get_OHLC_BigBar(15) ; // 獲取較大時區的數據
Get_OHLC_Day(15) ; // 獲取最近 15 天數據
// 重新計算技術指標
set_RSI(); // RSI 指標
set_BigThreeLine(); // 三線指標
FixBarHL(); // 修正 K 棒高低點數據
// 計算最近 5 天的平均波動範圍 (Daily Range)
Day5Range = ((HighD[1] - LowD[1])+(HighD[2] - LowD[2])+(HighD[3] - LowD[3])+(HighD[4] - LowD[4])+(HighD[5] - LowD[5]))/5;
}
//+------------------------------------------------------------------+
//| 自訂函數:設定允許交易的時段 |
//+------------------------------------------------------------------+
void 交易時段賦值()
{
// 僅允許在 00:00 到 16:00 之間進場
允許交易時段 = (getTM_hour(TimeCurrent()) >= 0 && getTM_hour(TimeCurrent()) < 16);
}
//+------------------------------------------------------------------+
//| 自訂函數:核心監控 - 處理停損、停利、移動止損與保本 |
//+------------------------------------------------------------------+
void 交易時段外也可停損停利()
{
// --- 多單監控區 ---
if(多單部位() > 0)
{
double 多單最小停利 = 0.0, 多單保本價格 = 0.0 ;
bool LX_MinPF = false, LongPull = false ;
// 取得進場價格並計算各項價格線
多單進場價格 = LE_EntryPrice(MagicNumber,多單進場單號);
多單最小停利 = NormalizeDouble(多單進場價格 + SP*3,Digits()) ; // 至少需覆蓋 3 倍點差才算最小利潤
LX_MinPF = Bid > 多單最小停利 ; // 判斷是否已達最小利潤
多單停利價格 = NormalizeDouble(多單進場價格 + TP * Point(),Digits()) ;
多單停損價格 = NormalizeDouble(多單進場價格 - SL * Point(),Digits()) ;
// 移動停損 (Trailing Stop) 邏輯
if(移動停損利 == true)
{
// 找出進場後出現的最高價
多單最高價 = iHigh(Symbol(),時間週期, iHighest(Symbol(),時間週期,MODE_HIGH,LE_BarsSinceEntry(MagicNumber,多單進場單號,時間週期),1));
多單最高價 = NormalizeDouble(多單最高價,Digits()) ;
// 若目前獲利已超過 TP 的 30%,則將停損線向上拉升 (跟隨最高價回撤 SL 點位)
if(多單最高價 > (多單進場價格+TP * Point()*0.3))
多單停損價格 = NormalizeDouble(多單最高價 - SL * Point(),Digits()) ;
}
// 保本機制 (保藍設定:確保獲利後不再虧損)
if(保藍設定 == true)
{
// 若獲利超過 TP 的 50%,啟動保本
if(多單最高價 > 多單進場價格+TP * Point()*0.5)
{
LongPull = true ;
// 將保護價格設在獲利 16.8% 的位置 (確保利潤鎖定)
多單保本價格 = NormalizeDouble(多單進場價格+TP * Point()*0.168,Digits()) ;
// 若價格跌破保本價格,觸發平倉信號
LX_Cond = (LongPull == true && Close[1] >= 多單保本價格 && Bid < 多單保本價格);
}
else
LX_Cond = false ;
// 執行保本平倉
if(LX_Cond == true && BarNumber != CloseOrderNo && LE_BarsSinceEntry(MagicNumber,多單進場單號,時間週期) > 0)
{
LX_CloseByTicket(多單進場單號,Lots) ;
if(多單部位() == 0) CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA) ;
}
}
// 特殊多單出場模式 (RSI 鈍化出場)
LX_Cond = ((LX_MinPF == true && (RSI高檔鈍化() == true)) || (Close[1] >= 多單停損價格 && Bid < 多單停損價格)) ;
// 執行最終多單出場判斷
if(LX_Cond == true && BarNumber != CloseOrderNo && LE_BarsSinceEntry(MagicNumber,多單進場單號,時間週期) > 0)
{
LX_CloseByTicket(多單進場單號,Lots) ;
if(多單部位() == 0) CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA) ;
}
} // end of 多單監控
// --- 空單監控區 ---
if(空單部位() > 0)
{
double 空單最小停利 = 0.0, 空單保本價格 = 0.0 ;
bool SX_MinPF = false, ShortPull = false ;
空單進場價格 = SE_EntryPrice(MagicNumber,空單進場單號);
空單最小停利 = NormalizeDouble(空單進場價格 - SP*3,Digits()) ;
SX_MinPF = Ask < 空單最小停利 ;
空單停利價格 = NormalizeDouble(空單進場價格 - TP * Point(),Digits()) ;
空單停損價格 = NormalizeDouble(空單進場價格 + SL * Point(),Digits()) ;
// 空單移動停損
if(移動停損利 == true)
{
// 找出進場後出現的最低價
空單最低價 = iLow(Symbol(),時間週期, iLowest(Symbol(),時間週期,MODE_LOW,SE_BarsSinceEntry(MagicNumber,空單進場單號,時間週期),1));
空單最低價 = NormalizeDouble(空單最低價,Digits()) ;
// 若獲利超過 30%,停損線下移
if(空單最低價 < (空單進場價格-TP * Point()*0.3))
空單停損價格 = NormalizeDouble(空單最低價 + SL * Point(),Digits()) ;
}
// 空單保本出場
if(保藍設定 == true)
{
if(空單最低價 < 空單進場價格-TP * Point()*0.5)
{
ShortPull = true ;
空單保本價格 = NormalizeDouble(空單進場價格-TP * Point()*0.168,Digits()) ;
SX_Cond = (ShortPull == true && Close[1] <= 空單保本價格 && Ask > 空單保本價格);
}
else
SX_Cond = false ;
if(SX_Cond == true && BarNumber != CloseOrderNo && SE_BarsSinceEntry(MagicNumber,空單進場單號,時間週期) > 0)
{
SX_CloseByTicket(空單進場單號,Lots) ;
if(空單部位() == 0) CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA) ;
}
}
// 特殊空單出場模式 (結合 5 日平均波幅 TP)
空單停利價格 = NormalizeDouble(空單進場價格 - (TP+Day5Range) * Point(),Digits()) ;
SX_Cond = ((Close[1] >= 空單停利價格 && Ask < 空單停利價格) || (Close[1] <= 空單停損價格 && Ask > 空單停損價格)) ;
// 執行最終空單出場判斷
if(SX_Cond == true && BarNumber != CloseOrderNo && SE_BarsSinceEntry(MagicNumber,空單進場單號,時間週期) > 0)
{
SX_CloseByTicket(空單進場單號,Lots) ;
if(空單部位() == 0) CloseOrderNo = iBarShift(Symbol(),時間週期,LoadEA) ;
}
} // end of 空單監控
} // end of 停損停利監控函數
//+------------------------------------------------------------------+
//| 多單策略模組:定義買入信號 |
//+------------------------------------------------------------------+
void set_BuyCondition()
{
// 檢查非特定急跌型態,且前一根 K 棒低點低於再前一根(找尋反轉或突破)
LE_Cond = (High3Bar_LClose() == false && Low[1] < Low[2]) ;
}
//+------------------------------------------------------------------+
//| 空單策略模組:定義賣出信號 |
//+------------------------------------------------------------------+
void set_ShortCondition()
{
// CCI 指標低檔背離且價格三線最小值低於 13 週期均線
SE_Cond = (CCI_LDiv_02() && BigMin3L < a_BigAvg13[1]) ;
}
回測結果
測試參數交易商品:NAS100(那斯達克指數)樣本內區間:2019/1/1 ~ 2023/10/30
交易手數:固定 1 手
時間框架: M6 圖表
交易模式:波段交易

沒有留言:
張貼留言