805% 回測背後:三 EMA 趨勢策略與 Monte Carlo 模擬驗證實戰

第 16 課・共 18 課

⚠️ 本站內容僅作教育用途,不構成投資建議。投資涉及風險,作出任何投資決定前請諮詢持牌專業人士。
目錄

回測做出 805% 回報的策略,究竟有多少是實力、多少是運氣?本課筆記整理自 Algo-trading with Saleh 的教學影片:講者 Saleh 把一套三條指數移動平均線 EMA 加 ADX 濾網的趨勢跟蹤策略交給 GPT 轉成 Python 代碼回測,標題的「805%」屬特定時段與倉位設定下的回測教學案例,並非實盤承諾。影片真正有價值的部分,是他用 Monte Carlo 模擬對回測結果做的兩重壓力測試——這套驗證思路,比策略本身更值得學。

學習重點

詳細筆記

進場邏輯:慢半拍的趨勢跟蹤

講者先在 TradingView 上交代規則。時間框架定為 4 小時,標的為 BTC-USDT。第一步用 ADX 確認市場處於趨勢狀態,門檻設為 43——只在 ADX 高於 43 時才允許開倉。第二步用三條 EMA 判斷方向:週期分別為 30、46、80,當 30 線在 46 線之上、46 線又在 80 線之上,且現價處於三線之上,視為上升趨勢,只做多;排列完全相反則只做空。

講者坦言這是「慢半拍」的設計,性質接近海龜交易策略:不追求在趨勢起點進場,因為波段交易只要捕捉到趨勢的中段已足夠。他在圖上示範,整段升勢中策略只觸發兩宗交易,頻率極低。

三條 EMA 排列與 ADX 門檻(截圖出自原片(Algo-trading with Saleh))

出場與倉位:ATR 止損加 5% 風險

出場用 平均真實波幅 ATR 設定:止損為入場價減 1.8 倍 ATR,止盈為入場價加 3.3 倍 ATR,做空則加減互換。這個不對稱設計是策略的靈魂——贏的時候贏 3.3 個 ATR,輸的時候只輸 1.8 個,即使勝率只有四至五成,期望值仍為正數,不需要經常看對市。

倉位方面,因為交易頻率低,講者把每宗交易的風險定為本金的 5%。他特別解釋:若入場價與止損價的距離小於 5%,要令實際風險達到本金 5% 便須動用槓桿。他認為槓桿不一定等同危險——在固定風險框架下有限度使用,只是補足注碼的工具,關鍵在於風險百分比不變,而非倉位名義價值的大小。

用 GPT 把規則轉成 Python

講者把上述規則寫成一段提示詞,交給他自建的雲端 GPT(自訂指令針對 Jesse 框架的算法交易,他選用最便宜的模型)生成策略代碼,再貼進 Jesse 儀表板,並建議用 VS Code 這類編輯器逐行閱讀。生成的代碼結構如下:先以屬性定義各指標,Jesse 框架內寫法相當簡潔。

@property
def ema30(self):
    return ta.ema(self.candles, 30)

def should_long(self) -> bool:
    return (self.ema30 > self.ema46 > self.ema80
            and self.price > self.ema30
            and self.adx > 43)

(以上代碼摘錄自原片教學)

進場方法內設定市價單、ATR 止損,並用 Jesse 內建的 risk_to_qty 工具函數,按可用保證金與 5% 風險反推注碼,連手續費率也傳入計算。

def go_long(self):
    entry = self.price
    stop = entry - 1.8 * self.atr
    qty = utils.risk_to_qty(
        self.available_margin, 5,
        entry, stop, fee_rate=self.fee_rate)
    self.buy = qty, entry

(以上代碼摘錄自原片教學)

持倉期間再提交止盈與止損單,做空邏輯完全鏡像。

def update_position(self):
    if self.is_long:
        sl = self.position.entry_price - 1.8 * self.atr
        tp = self.position.entry_price + 3.3 * self.atr
        self.stop_loss = self.position.qty, sl
        self.take_profit = self.position.qty, tp

(以上代碼摘錄自原片教學)

值得留意的是講者的覆核過程:模型自作主張加入了 update_position 提前平倉條件與 should_cancel_entry 撤單方法,兩者都不是他要求的功能,他逐一指出後刪除。他的取態是:代碼寫得醜但邏輯正確可以保留,邏輯多餘或出錯必須動手——LLM 生成的交易代碼不覆核就跑回測,是新手常犯錯誤。

回測結果:逐年拆開再合併

講者在 Jesse 回測頁面把 2021 年至 2025 年 9 月(影片拍攝時間)逐年分段運行,再開基準比較頁並排檢視。2021 年的結果:14 宗交易、回報 +78%、最大回撤僅 -3%、勝率 71%、平均盈虧比 1.44、平均持倉 265 小時、Sharpe ratio 接近 2、Calmar ratio 5.63。2022 年熊市仍有 +67%,之後各年繼續造好。他提醒平均持倉動輒逾百小時,短線操作者會很難受,這是策略的性情成本。

分段回測中部分年份跑輸「買入並持有」BTC 的基準,講者的解法是直接放大注碼:把 risk_to_qty 算出的數量乘以 1.5 或 2。他的理由是最大回撤低於自身風險承受度,有放大空間;但他同時警告,放大注碼等於放大風險,策略失效時虧損同步放大。乘大 1.5 倍後跑 2021 年初至 2025 年 9 月的整段回測:回報 +1,425%、最大回撤 -27.9%、勝率 54%、盈利因子 1.4、平均持倉 118 小時、Sharpe ratio 1.61,共 112 宗交易,已計手續費。標題的 805% 與這個 1,425% 屬不同注碼設定的產物,解讀時須分清。

整段回測績效:112 宗交易、+1,425%、最大回撤 -27.9%(截圖出自原片(Algo-trading with Saleh))

Monte Carlo 模擬:本課最有價值的部分

講者明言,展示這個策略的主因不是回測數字,而是它的 Monte Carlo 模擬結果。他用自己發布的腳本配合 Jesse 運行,設定 200 次模擬、12 個 CPU 核心並行,數分鐘完成。

為甚麼要做? 單一回測只是一條路徑:交易按歷史實際順序發生,回撤與 Sharpe ratio 都帶有「順序運氣」。若連贏變成連輸,權益曲線的形狀會完全不同。Monte Carlo 的精神是以大量隨機重組,把單一結果變成結果分佈,再問:這個分佈我接不接受?

做法一:交易順序洗牌。 取回測產生的同一批交易,隨機打亂先後次序,重新畫出權益曲線。由於交易本身不變,所有模擬的最終權益完全相同,改變的只有中途的最大回撤與 Sharpe ratio 等路徑指標。原回測最大回撤 20.29%,洗牌後中位數達 32.6%,最佳 5% 為 17%,最差 5% 高達 84.7%。講者的解讀:最差情境在任何策略的洗牌中都很極端,不必當真;重點是中位數 32.6% 已明顯差於原回測的 20%,這才是「正常運氣」下應預期的回撤。

交易順序洗牌結果:原回撤 20.29%,中位數 32.6%(截圖出自原片(Algo-trading with Saleh))

做法二:K 線路徑重組。 這一層更進取:不只洗牌交易,而是基於真實 K 線生成全新的模擬數據再重新回測。講者用的方法叫移動區塊拔靴法 Moving Block Bootstrap——把真實 K 線切成區塊再隨機重拼,保留局部波動結構之餘改變整體路徑,等於讓策略在大量「平行時空」的市況中接受壓力測試。他特意選 2022 至 2023 年做模擬期,因為該段同時包含一個熊市與一個牛市。實務細節:200 次模擬只有 138 次有效,部分模擬數據會產生不合理價格(例如負值)令回測報錯,講者表示屬正常,不需要全部模擬成功才有可讀的結果。

K 線重組模擬表:淨利中位數 93.4%、回撤中位數 -28.4%(截圖出自原片(Algo-trading with Saleh))

怎樣解讀? K 線重組的結果:原回測淨利 412.6%、最大回撤 -20.3%、Sharpe ratio 1.98;模擬中位數淨利 93.4%、回撤 -28.4%、Sharpe ratio 1.13;最差 5% 的 Sharpe ratio 為 0.04。講者的判讀框架有三條。第一,忘掉原始回測與最佳 5%,直接讀中位數:中位回撤 -28% 在他 -30% 的風險承受度之內,代表「即使沒有原回測那麼好運」仍可接受。第二,檢查原始回測是否落在最佳 5% 之內——若是,代表單一回測有極端好運之嫌;本例 Sharpe ratio 原值 1.98 略低於最佳 5% 的 2.01,未算離譜。第三,留意最差 5% 是否仍然為正:本例最差 5% 的 Sharpe ratio 為 0.04,雖接近零但未變負,他視之為策略長期運行大概率有利的佐證。他最後補上必要的一句:交易沒有必勝,模擬通過不代表保證賺錢,他只是喜歡看到的賠率。

補充:前向表現

講者透露此策略早於一年多前已在其頻道與網站發布(名為 TrendSwingTrader V2 的進階版本),因此 2024 年與 2025 年初至 9 月的結果,相當於策略發布後才產生的數據:兩段時期策略仍然獲利。這可視為一種現實世界的前向測試,雖非嚴謹的樣本外設計,但總比純粹事後回測多一分說服力。

🙏 覺得內容有用?本站所有內容免費提供,使用推薦碼開戶就是支持我們繼續營運的最大鼓勵:

ZA Bank 邀請碼 P20923 —— 你享 HKD 2,000 迎新獎賞,本站獲得營運支持。 立即開戶 → (聯盟連結|投資涉及風險,受條款及細則約束,此資料僅可於香港境內分發)

MT5 可行性速評

項目評估
邏輯可移植性完全可移植:EMA、ADX、ATR 均有 MQL5 內建指標函數,三線排列與門檻判斷只是簡單比較;ATR 倍數止損止盈與固定風險百分比注碼(按止損距離反推手數)亦是標準寫法,無任何框架依賴。
平台限制策略本身無障礙,但 MT5 無內建 Monte Carlo 工具:交易洗牌可自行讀取回測交易紀錄後在 EA 外處理,K 線路徑重組(Moving Block Bootstrap)則幾乎必須離線用 Python 完成,再將合成數據匯入自訂品種回測,工程量不小。
評級可直接移植——進出場與倉位邏輯全部有現成函數,半日內可完成 EA;唯本課核心價值(Monte Carlo 驗證)須在 MT5 以外進行,驗證流程要另建。
MQL5 寫法提示見下方示意。
// 示意:三 EMA 排列 + ADX 濾網 + ATR 出場(非完整 EA)
int hEma30 = iMA(_Symbol, PERIOD_H4, 30, 0, MODE_EMA, PRICE_CLOSE);
// EMA46、EMA80 同法;ADX 用 iADX、ATR 用 iATR 建 handle 後 CopyBuffer
bool uptrend = ema30[0] > ema46[0] && ema46[0] > ema80[0] && close > ema30[0];
double sl = entry - 1.8 * atr[0];          // 止盈用 entry + 3.3 * atr[0]
double lots = RiskToLots(0.05 * equity, entry, sl);  // 須自寫

注意:MT5 回測同樣會過度擬合,參數 43、30/46/80、1.8/3.3 在任何平台都一樣有被歷史數據「度身訂造」的風險。

欣利克的看法

名詞解釋

常見問題 FAQ

Monte Carlo 模擬結果漂亮,就代表策略將來一定賺錢嗎?

不代表。模擬重組的仍是同一段歷史數據,它能量度該段歷史中的運氣成分與路徑依賴,但無法預測市場結構轉變。講者本人也強調交易沒有保證,模擬中位數可接受只代表「賠率合理」,與「未來必賺」是兩回事;樣本外驗證與前向測試仍須另行補做。

交易順序洗牌後最終權益不變,做這個測試有甚麼意義?

意義在於回撤與風險指標。同批交易換個順序,最終賺的一樣多,但中途的最大回撤可以由 -20% 變成 -33% 甚至更深。若你的風險承受度或強制平倉線處於兩者之間,同一策略在「不好運的順序」下已足以令你出局。洗牌測試正是把這種順序運氣量化,讓你按中位數而非原回測來設定倉位與心理預期。

MT5 用家怎樣做 Monte Carlo 驗證?

MT5 沒有內建工具,常見做法是離線處理:先在策略測試器跑出回測,匯出交易紀錄後用 Python 或試算表做交易順序洗牌;至於 K 線路徑重組,可用 Python 的移動區塊拔靴法生成合成價格序列,再以 MT5 自訂品種功能匯入重新回測。流程比 Jesse 一條腳本繁瑣,但概念完全一樣。

勝率只有五成多的策略值得研究嗎?

值得,因為盈利取決於勝率與盈虧比的乘積,而非單看勝率。本策略贏時賺 3.3 倍 ATR、輸時蝕 1.8 倍 ATR,勝率即使低於五成,期望值仍可以是正數。反而要留意的是執行層面:平均持倉過百小時、交易稀疏,能否長期遵守規則不提早離場,才是這類策略真正的門檻。

原影片

本文整理自以下影片,版權屬原創作者所有,建議配合原片觀看:

來源:https://www.youtube.com/watch?v=_aGRboYs5xA

🏦 ZA Bank 開戶優惠

本站所有內容免費提供。多使用網站的推薦碼,就是對我們繼續製作優質內容的最大鼓勵和支持 🙏

去 ZA Bank 開戶,享價值 HKD 2,000 迎新獎賞,仲有機會享 USD 30 指定美股兌換券!

  • 💛 全線上開戶,無需前往分行
  • 💛 無最低存款要求,零賬戶管理費
  • 💛 24x7 銀行服務

專屬邀請碼:P20923

立即開戶 → (聯盟連結)