外彙算法交易:工程師的實用故事
已發表: 2022-03-11您可能知道,外匯(Forex,或 FX)市場用於貨幣對之間的交易。 但您可能不知道它是世界上流動性最強的市場。
幾年前,在好奇心的驅使下,我通過創建一個模擬賬戶並在 Meta Trader 4 交易平台上進行模擬(使用假幣),邁出了進入外彙算法交易世界的第一步。
經過一周的“交易”,我的錢幾乎翻了一番。 在我自己成功的算法交易的推動下,我深入挖掘並最終註冊了一些外匯論壇。 很快,我就花了幾個小時閱讀算法交易系統(決定你應該買還是賣的規則集)、自定義指標、市場情緒等等。
我的第一個客戶
大約在這個時候,巧合的是,我聽說有人想找一個軟件開發人員來自動化一個簡單的交易系統。 這要追溯到我大學時代,當時我正在學習 Java 中的並發編程(線程、信號量和所有那些垃圾)。 我認為這個自動化系統不會比我的高級數據科學課程工作複雜多少,所以我詢問了這份工作並加入了。
客戶想要使用 MQL4 構建的算法交易軟件,MQL4 是 Meta Trader 4 平台用於執行股票相關操作的功能編程語言。
交易平台(在本例中為 Meta Trader 4)的作用是提供與外匯經紀商的連接。 然後經紀人提供一個平台,提供有關市場的實時信息並執行您的買/賣訂單。 對於不熟悉外匯交易的讀者,以下是數據饋送提供的信息:
通過 Meta Trader 4,您可以使用內部功能訪問所有這些數據,可在各種時間範圍內訪問:每分鐘 (M1)、每五分鐘 (M5)、M15、M30、每小時 (H1)、H4、D1、W1、MN .
當前價格的變動稱為跳動。 換句話說,報價變動是貨幣對買入價或賣出價的變化。 在活躍的市場中,每秒可能有許多滴答聲。 在緩慢的市場中,可能有幾分鐘沒有滴答聲。 滴答聲是貨幣市場機器人的心跳。
當您通過此類平台下訂單時,您買入或賣出一定數量的某種貨幣。 您還可以設置止損和止盈限制。 止損限制是您在放棄交易之前可以承受的最大損失點數(價格變化)。 止盈限額是您在兌現之前積累的對您有利的點數。
客戶的算法交易規範很簡單:他們想要一個基於兩個指標的外匯機器人。 作為背景,指標在嘗試定義市場狀態和做出交易決策時非常有用,因為它們基於過去的數據(例如,過去n天的最高價格值)。 Meta Trader 4 內置了許多指標。但是,我的客戶感興趣的指標來自自定義交易系統。
他們想在這些自定義指標中的兩個相交時進行交易,並且只能以某個角度進行交易。
動手
當我親身體驗時,我了解到 MQL4 程序具有以下結構:
- [預處理器指令]
- [外部參數]
- [全局變量]
- [初始化函數]
- [去初始化函數]
- [啟動功能]
- [自定義功能]
start 函數是每個 MQL4 程序的核心,因為它會在每次市場變動時執行(因此,該函數將在每個分時執行一次)。 無論您使用的時間範圍如何,情況都是如此。 例如,您可能在 H1(一小時)時間範圍內運行,但 start 函數將在每個時間範圍內執行數千次。
為了解決這個問題,我強制該函數在每個週期單位執行一次:
int start() { if(currentTimeStamp == Time[0]) return (0); currentTimeStamp = Time[0]; ...
獲取指標值:
// Loading the custom indicator extern string indName = "SonicR Solid Dragon-Trend (White)"; double dragon_min; double dragon_max; double dragon; double trend; int start() { … // Updating the variables that hold indicator values actInfoIndicadores(); …. string actInfoIndicadores() { dragon_max=iCustom(NULL, 0, indName, 0, 1); dragon_min=iCustom(NULL, 0, indName, 1, 1); dragon=iCustom(NULL, 0, indName, 4, 1); trend=iCustom(NULL, 0, indName, 5, 1); }
決策邏輯,包括指標及其角度的交集:
int start() { … if(ticket==0) { if (dragon_min > trend && (ordAbierta== "OP_SELL" || primeraOP == true) && anguloCorrecto("BUY") == true && DiffPrecioActual("BUY")== true ) { primeraOP = false; abrirOrden("OP_BUY", false); } if (dragon_max < trend && (ordAbierta== "OP_BUY" || primeraOP == true) && anguloCorrecto("SELL") == true && DiffPrecioActual("SELL")== true ) { primeraOP = false; abrirOrden("OP_SELL", false); } } else { if(OrderSelect(ticket,SELECT_BY_TICKET)==true) { datetime ctm=OrderCloseTime(); if (ctm>0) { ticket=0; return(0); } } else Print("OrderSelect failed error code is",GetLastError()); if (ordAbierta == "OP_BUY" && dragon_min <= trend ) cerrarOrden(false); else if (ordAbierta == "OP_SELL" && dragon_max >= trend ) cerrarOrden(false); } }
發送訂單:

void abrirOrden(string tipoOrden, bool log) { RefreshRates(); double volumen = AccountBalance() * point; double pip = point * pipAPer; double ticket = 0; while( ticket <= 0) { if (tipoOrden == "OP_BUY") ticket=OrderSend(simbolo, OP_BUY, volumen, Ask, 3, 0/*Bid - (point * 100)*/, Ask + (point * 50), "Orden Buy" , 16384, 0, Green); if (tipoOrden == "OP_SELL") ticket=OrderSend(simbolo, OP_SELL, volumen, Bid, 3, 0/*Ask + (point * 100)*/, Bid - (point * 50), "Orden Sell", 16385, 0, Red); if (ticket<=0) Print("Error abriendo orden de ", tipoOrden , " : ", ErrorDescription( GetLastError() ) ); } ordAbierta = tipoOrden; if (log==true) mostrarOrden(); }
如果您有興趣,可以在 GitHub 上找到完整的、可運行的代碼。
回測
一旦我建立了我的算法交易系統,我想知道:1)它的行為是否適當,以及 2)它使用的外匯交易策略是否有任何好處。
回測(有時寫為“回測”)是在過去的事件下測試特定(自動化或非自動化)系統的過程。 換句話說,您使用過去作為當前的代理來測試您的系統。
MT4 附帶了一個可接受的外匯交易策略回測工具(如今,有更專業的工具提供更強大的功能)。 首先,您設置您的時間框架並在模擬下運行您的程序; 該工具將模擬每個分時,知道每個單位應該以特定價格開盤,以特定價格收盤,並達到指定的高點和低點。
在將程序的操作與歷史價格進行比較後,您將對它是否正確執行有一個很好的了解。
通過回測,我檢查了 FX 機器人在一些隨機時間間隔內的回報率; 不用說,我知道我的客戶不會因此而致富——他選擇的指標以及決策邏輯都無法盈利。 作為示例,以下是在 M15 窗口上運行程序進行 164 次操作的結果:
請注意,我們的餘額(藍線)在其起點下方結束。
參數優化及其謊言
雖然回測讓我對這個 FX 機器人的實用性持謹慎態度,但當我開始嘗試它的外部參數並註意到整體回報率的巨大差異時,我很感興趣。 這種特殊的科學被稱為參數優化。
我做了一些粗略的測試來嘗試推斷外部參數對回報率的重要性,並想出了這樣的事情:
或者,清理:
您可能認為(和我一樣)您應該使用參數 A。但這個決定並不像看起來那麼簡單。 具體來說,請注意參數 A 的不可預測性:對於小的誤差值,它的返回值會發生巨大變化。 換句話說,參數 A 很可能會過度預測未來的結果,因為任何不確定性、任何變化都會導致性能下降。
但事實上,未來是不確定的! 所以參數A的返回也是不確定的。 事實上,最好的選擇是依靠不可預測性。 通常,與具有高回報但可預測性差的參數相比,具有較低最大回報但可預測性較高(波動較小)的參數將更可取。
你唯一可以確定的是你不知道市場的未來,並且認為你知道市場將如何根據過去的數據表現是錯誤的。 反過來,您必須在您的外匯預測中承認這種不可預測性。
這並不一定意味著我們應該使用參數 B,因為即使參數 A 的較低迴報也比參數 B 表現得更好; 這只是為了向您展示優化參數可能會導致測試誇大可能的未來結果,而這種想法並不明顯。
整體外彙算法交易注意事項
自從第一次算法外匯交易經驗以來,我已經為客戶建立了幾個自動交易系統,我可以告訴你,總有探索和進一步外匯分析的空間。 例如,我最近建立了一個基於尋找所謂“大魚”運動的系統; 也就是說,微小的時間單位內的巨大點差。 這是一個令我著迷的話題。
建立自己的外匯模擬系統是了解更多外匯市場交易的絕佳選擇,而且可能性無窮無盡。 例如,您可以嘗試將價格變化的概率分佈破譯為一個市場(例如歐元/美元)波動率的函數,並且可以使用每個波動率狀態的分佈來製作蒙特卡羅模擬模型,使用任何程度的你想要的準確性。 我將把這個作為練習留給熱心的讀者。
外匯世界有時會讓人不知所措,但我希望這篇文章能給您一些關於如何開始您自己的外匯交易策略的觀點。
延伸閱讀
如今,有大量工具可用於構建、測試和改進交易系統自動化:用於測試的 Trading Blox、用於交易的 NinjaTrader、用於編程的 OCaml 等等。
我廣泛閱讀了有關貨幣市場這個神秘世界的文章。 以下是我推薦給程序員和熱心讀者的一些文章:
- BabyPips:如果您不了解外匯交易,這是起點。
- 烏龜之路,作者:Curtis Faith:在我看來,這本是外匯聖經。 一旦您有一些交易經驗並了解一些外匯策略,請閱讀它。
- 交易專業人士的技術分析——當今動蕩的全球金融市場的策略和技術,Constance M. Brown
- 智能交易系統編程 – 在 MQL 中為 Meta Trader 4 創建自動交易系統,作者:Andrew R. Young
- 交易系統——一種系統開發和投資組合優化的新方法,作者 Urban Jeckle 和 Emilio Tomasini:非常技術性,非常專注於外匯測試。
- Rui Pedro Barbosa 和 Orlando Belo 的多代理貨幣交易系統的逐步實現:這個非常專業,描述瞭如何創建交易系統和測試平台。