外汇算法交易:工程师的实用故事
已发表: 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 的多代理货币交易系统的逐步实现:这个非常专业,描述了如何创建交易系统和测试平台。