EMA 三線排列波段交易策略:Python 回測實戰
第 2 課・共 18 課
目錄
本課由 Algo-trading with Saleh 示範一個以三條 指數移動平均線 EMA 為核心的波段交易策略:先以均線排列確認趨勢方向,再用 ATR 設定止損與分批止盈,最後以追蹤止損盡量「坐完」整段趨勢,全部在 Python 回測框架 Jesse 上實作。
學習重點
- 三線排列定義趨勢:EMA21 高於 EMA50、兩者同時高於 EMA100,且價格站在最上方,才算上升趨勢;反向排列則為下跌趨勢,其餘狀態視為橫行
- 出場分兩層:2 倍 ATR 止損、3 倍 ATR 先走一半倉位,另一半改掛保本止損再逐根 K 線追蹤
- 倉位由「每筆風險 3%」反推,取代全倉重押,同一套進出場規則下回測績效即時改善
- 加入 ADX > 25 過濾器剔除橫行市,講者回測中利潤與最大回撤同時顯著改善
- 回測結果高度依賴參數與回測期選擇,績效數字必須連同時間脈絡一併解讀
詳細筆記
策略構想:跟住趨勢坐到尾
講者開宗明義說,這是一個趨勢跟隨型的波段策略:目標是盡量持倉跟隨趨勢,只在認為趨勢完結時才離場。他也預告這個策略會成為下一條片的基礎——之後再用遺傳演算法(genetic algorithm)優化參數。
入場條件:三條 EMA 的排列
策略只用三條 EMA,週期分別為 21、50、100(圖上以紫、黃、藍三色顯示)。在 TradingView 上,直接修改指標的 length 參數即可設定。

截圖出自原片(Algo-trading with Saleh):BTC-USDT 4 小時圖上疊加 EMA 21(紫)、50(黃)、100(藍),均線排列一目瞭然。
好倉(long)條件:EMA21 在 EMA50 之上,兩者又同時在 EMA100 之上,而且現價站在 EMA21 之上——均線由短到長整齊排列,價格在最頂,才是乾淨的升勢。淡倉(short)條件完全相反:EMA21 低於 EMA50、兩者低於 EMA100,且現價在 EMA21 之下。講者特別補充最後一個條件的原因:均線剛形成空頭排列時,價格往往仍在 EMA21 附近徘徊,他要求價格明確跌穿最短那條線才進場,避免在排列初成、方向未確認時倉卒開倉。
其餘所有狀態——均線互相纏繞、排列不齊——一律視為橫行市,不交易。
在 Jesse 框架上實作
講者在 Jesse 回測框架建立新策略,命名為 Trend swing Trader。第一步是定義一個 trend 屬性,計算三條 EMA 後回傳三態:1 代表升勢、-1 代表跌勢、0 代表橫行:
# 摘錄自原片教學(Jesse 框架)
e1 = ta.ema(self.candles, 21)
e2 = ta.ema(self.candles, 50)
e3 = ta.ema(self.candles, 100)
if e3 < e2 < e1 < self.price:
return 1
elif e3 > e2 > e1 > self.price:
return -1
else:
return 0
should_long 只需檢查 self.trend == 1,should_short 則檢查 self.trend == -1,邏輯非常乾淨。由於進場用市價單,should_cancel_entry(掛單未成交時是否取消的鉤子)回傳甚麼都無所謂,講者直接略過。
第一版的倉位計算很粗糙:用 size_to_qty 把全部可用保證金換成倉位數量,以市價單進場。講者當時已說明這只是「先把策略跑起來」的權宜之計,稍後會改。
出場設計:ATR 止損+分批止盈+追蹤止損
出場是這課的重頭戲,分三層處理:
第一層:初始止損與首個止盈。 講者用他最愛的 ATR 指標量度每根 K 線的平均波動幅度。止損設在入場價外 2 倍 ATR——他示範時單倍 ATR 約 886 美元,嫌太近,所以用兩倍。止盈設在 3 倍 ATR,但只平掉一半倉位。為何不全走?因為這是波段策略,講者想保留一半倉位繼續跟隨趨勢。
# 摘錄自原片教學:on_open_position(好倉版本)
atr = ta.atr(self.candles, 14)
qty = self.position.qty
self.stop_loss = qty, self.price - atr * 2
self.take_profit = qty / 2, self.price + atr * 3
第二層:止盈觸發後保本。 講者定義 on_reduced_position 事件方法——這是 Jesse 在倉位被「減少但未平完」時觸發的鉤子(hook),正好對應止盈走了一半的時刻。此時把餘下倉位的止損直接移到入場價(self.position.entry_price):前半已鎖定利潤,後半最壞情況只是保本離場,整筆交易立於不敗。Jesse 會自動取消舊止損單、掛上新單,無需手動處理。
第三層:逐 K 線追蹤。 保本只是起點,講者要的是追蹤止損。他在 update_position 方法中,每根新 K 線都把止損更新為「現價減 2 倍 ATR」(淡倉則為現價加 2 倍 ATR)。但有一個陷阱:若直接更新,價格回調時止損反而會被拉遠、放大虧損。所以好倉要用 max 比較新止損價與現有止損價,只准收緊、不准放寬;淡倉則用 min。
另一個細節:update_position 每根 K 線都會執行,包括止盈未觸發之前。講者加了一個條件——只有當 reduced_count == 1(即已經走過一半倉位)才啟動追蹤,避免順序錯亂。

截圖出自原片(Algo-trading with Saleh):Jesse 策略原始碼,可見 go_long 內先算 ATR 止損價,再決定倉位數量。
第一次回測與倉位管理的威力
講者以 BTC-USDT 永續合約、4 小時圖,由 2022 年初回測至 2024 年中(講者製作影片時),並開啟 fast mode 與 benchmark 選項,讓淨值曲線可以直接與買入持有的 BTC 走勢對照。選 4 小時圖是波段策略的典型選擇:K 線夠密,能在趨勢中段給出進出場訊號;又不像 5 分鐘、15 分鐘圖般充斥雜訊與交易成本。第一版(全倉進出)的結果:利潤 77%,最大回撤 -23%,勝率 47%,平均盈虧比 1.4,跑贏同期買入持有的基準。
然後他做了一件「教學上最有價值」的事:進出場規則一個字不改,只把倉位計算由全倉改為 risk_to_qty——先算止損價(入場價減 2 倍 ATR),再以「每筆交易風險本金 3%」反推倉位大小。重跑後利潤微升至 79%,最大回撤收窄至 -18% 左右。講者強調:指標、入場、出場完全一樣,單單改變倉位管理,績效已經不同——這正是 position sizing 的威力。
用 ADX 過濾橫行市
講者接著指出淨值曲線的弱點:橫行市期間曲線持續下滑。這是趨勢跟隨策略的典型毛病——橫行市中均線反覆交叉、訊號不斷失效。他的解法是加入 平均趨向指數 ADX 作過濾器:ADX 數值介乎 0 至 100,只量度趨勢強度、不分方向;數值低於閾值(他用 25)代表無趨勢、不交易,高於閾值才允許進場。
實作上只需新增一個 adx 屬性回傳布林值,再在 should_long 與 should_short 各加一個 and self.adx 條件。重跑回測後(同樣為講者影片中的數據):利潤大幅上升、最大回撤顯著收窄至約 -13%,勝率 52%,平均盈虧比 1.57;橫行市期間淨值曲線不再明顯下沉。

截圖出自原片(Algo-trading with Saleh):最終版回測結果,回測期 912 日(2022-01-01 至 2024-07-01)、80 宗已平倉交易,Total Net Profit 125.05%,Max Drawdown -13.35%。
跑贏大市的爭論與槓桿取態
講者再示範一個有意思的情境:若只由 2024 年初開始回測,策略帳面不及買入持有,但最大回撤只有約 -10%,遠低於同期市場本身的跌幅。他的論點是:策略的價值在於回撤控制,若投資者的波動容忍度較高(他自稱可接受到 -30%),可以把每筆風險由 3% 加至 5%,甚至動用槓桿(他示範時交易所槓桿設為 2 倍)放大倉位去追平或超越大市的回報,而回撤仍低於市場。但他同時表明個人立場:不會為追回報而開 5 倍、10 倍槓桿,因為控制波動、晚上睡得著對他更重要——「你按自己的容忍度決定,我也按我的做」。

截圖出自原片(Algo-trading with Saleh):2024 年 1 月至 7 月的回測,17 宗交易、利潤 27.59%,最大回撤僅 -10.67%,用作說明回撤控制與「跑贏大市」之間的取捨。
值得留意的是講者對「甚麼叫做好策略」的定義:不是帳面利潤最高,而是在自己睡得著的波動範圍內取得合理回報。回撤、勝率、盈虧比三個數字要一齊看,單獨追求任何一個都會誤導。
片尾講者提到,他為此策略做了一個 premium 版本上載到其平台的策略索引頁(屬其產品推廣,此處不轉載細節),並預告下條片會用 Jesse 的遺傳演算法優化模式調參——下一課再跟進。
🙏 覺得內容有用?本站所有內容免費提供,使用推薦碼開戶就是支持我們繼續營運的最大鼓勵:
ZA Bank 邀請碼 P20923
—— 你享 HKD 2,000 迎新獎賞,本站獲得營運支持。
立即開戶 →
(聯盟連結|投資涉及風險,受條款及細則約束,此資料僅可於香港境內分發)
MT5 可行性速評
| 項目 | 評估 |
|---|---|
| 邏輯可移植性 | 高。三條 EMA 用 iMA(MODE_EMA)開三個句柄即可,ATR(iATR)、ADX(iADX)全屬內建指標;均線排列比較、ATR 止損、「風險 3% 反推倉位」、分批平倉與追蹤止損都是標準 EA 寫法。 |
| 平台限制 | Jesse 的 on_reduced_position 事件在 MQL5 沒有直接對應,須在 OnTradeTransaction 偵測部分平倉後手動改掛保本止損;追蹤邏輯則放 OnTick 並記錄「只收緊」的上次止損價。另外原片標的為 BTC 永續合約,一般 MT5 券商未必提供,移植後參數須重新驗證。 |
| 評級 | ✅ 全部指標皆為內建基本款,入場條件是單純的數值比較,出場雖有三層(初始止損/保本/追蹤)但狀態簡單,是本系列中移植難度最低的一類策略。 |
| MQL5 寫法提示 | 見下 |
int e21 = iMA(_Symbol, PERIOD_CURRENT, 21, 0, MODE_EMA, PRICE_CLOSE);
int e50 = iMA(_Symbol, PERIOD_CURRENT, 50, 0, MODE_EMA, PRICE_CLOSE);
int e100 = iMA(_Symbol, PERIOD_CURRENT, 100, 0, MODE_EMA, PRICE_CLOSE);
int atr_h = iATR(_Symbol, PERIOD_CURRENT, 14);
int adx_h = iADX(_Symbol, PERIOD_CURRENT, 14);
// 好倉:e21 > e50 > e100 && Close < ... 實際為 Close > e21 && ADX > 25
// 止損 = entry - 2*ATR;3*ATR 平一半;其後止損只准上移(好倉取 max)
注意:即使成功移植,MT5 策略測試器跑出的回測同樣會過度擬合——21/50/100、2 倍與 3 倍 ATR、ADX 25、風險 3% 全是對著歷史數據選出來的參數,換平台並不能解決方法論問題。
欣利克的看法
- 績效的構成要拆開看。 講者最終版回測利潤 125%,但這個數字由幾層改動疊加:先是倉位管理由全倉改為風險 3%,再來是 ADX 過濾。每一層都是看過前一版結果後才加上的改動,屬於典型的「邊看結果邊調策略」,最終數字含有相當的樣本內優化成分,不能直接當作未來期望回報。
- 均線滯後是結構性的,橫行市連敗無可避免。 三線排列要等趨勢走了一段才確認,進場必然遲、出場也必然遲;利潤來自少數大波段,代價是橫行市中反覆小虧。ADX 過濾是正統解法,但 ADX 同樣滯後,趨勢尾段數值仍可偏高,只能減少假訊號、不能消滅。
- 參數擬合的警號:21/50/100 沒有「為甚麼」。 影片未有解釋選這三個週期的原因,2 倍與 3 倍 ATR、ADX 閾值 25、風險 3% 同樣是經驗值。下一條片講者還會用遺傳演算法進一步「優化」參數——優化越多、回測越亮麗,策略對歷史的依賴也越深。健康做法是留一段沒碰過的樣本外數據做最終驗證,而非把全部歷史都用來調參。
- 槓桿放大的是整條淨值曲線,不只是利潤。 講者示範把風險加至 5%、配合 2 倍槓桿追大盤回報,帳面回撤「仍低於市場」,但那是以 2024 年上半年順風期計算;同一設定放到 2022 年深度回撤段,結果會完全不同。截至講者 2024 年中發片時的數據,只反映那兩年半的市況。
- 保本止損不是免費午餐。 「先走一半、餘下保本」聽起來穩賺不蝕,但不少本可發展成大贏家的倉位會被提前掃走,期望值結構因此改變——勝率上升、平均盈利下降。這是取捨而非純粹優化,評估時應與不分批的版本並列比較,而非只看「不會虧」的心理舒適度。
名詞解釋
- 指數移動平均線 EMA:對近期價格加權較高的移動平均線,反應比 SMA 快,常用週期組合如 21/50/100 判斷趨勢排列
- 波段交易 Swing Trading:持倉數日至數週、捕捉趨勢中段行情的交易風格
- 趨勢跟隨 Trend Following:順著已確認的趨勢交易、不預測轉勢,靠少數大贏交易覆蓋多數小虧
- 平均真實波幅 ATR:量度每根 K 線平均波動範圍的指標,常用於設定止損距離與反推倉位
- 平均趨向指數 ADX:量度趨勢強度而不分方向的指標,常用作過濾橫行市假訊號
- 追蹤止損 Trailing Stop:隨價格順向移動而收緊的止損單,只收緊不放寬,用來鎖定浮盈
- 最大回撤 Drawdown:淨值由高點回落的最大幅度,衡量策略最壞時期的資金縮水程度
- 過度擬合 Overfitting:策略參數過度貼合歷史數據,回測亮麗但樣本外表現失靈的現象
常見問題 FAQ
為甚麼用 EMA 而不用 SMA?
EMA 對近期價格加權較高,對趨勢轉變的反應比 SMA 快。在波段策略中,進出場時機差幾根 K 線已可影響整筆交易的盈虧,所以講者及多數趨勢策略都傾向用 EMA。不過兩者本質都是滯後指標,選哪一種對策略成敗的影響,遠小於倉位管理與出場設計。
ADX 閾值一定要用 25 嗎?
不一定。25 是講者採用的經驗值,常見參考範圍是 20 至 30:閾值越低,過濾越少、交易次數越多;閾值越高,訊號越精但會錯過趨勢初段。閾值本身也是可被過度擬合的參數,應用樣本外數據驗證,而不是在回測中試到最亮麗為止。
分批止盈加保本止損,豈不是穩賺?
不是。保本止損只保證該筆交易「最壞情況」不虧,但代價是許多本可繼續發展的倉位被提前掃走,拉低整體平均盈利。而且保本止損未觸發前,倉位仍承受 2 倍 ATR 的初始風險,連續幾宗止損出場一樣會造成可觀回撤。
這個策略可以直接用在股票或外匯上嗎?
邏輯上可以——均線排列、ATR 止損、ADX 過濾都是跨市場通用的概念。但原片的所有參數(21/50/100、2 倍與 3 倍 ATR、4 小時圖)都是對著 BTC 永續合約的波動特性調出來的,換標的、換時間框架後必須重新回測驗證,並留意股票有隔晚跳空、外匯有點差與隔夜利息等影片未有處理的成本。
原影片
本文整理自以下影片,版權屬原創作者所有,建議配合原片觀看: