作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
罗格里奥·尼古拉斯·门格尔
验证专家 在工程

Rogelio是一位多才多艺且积极进取的全栈工程师,拥有超过13年的多种语言工作经验, 框架, 和平台.

以前在

IBM
分享

编者注:本文由我们的编辑团队于2022年7月21日更新. 它已被修改,以包括最近的来源,并与我们目前的编辑标准保持一致.

你们可能知道, 外汇(forex或FX)市场用于货币对之间的交易. 但你可能没有意识到它是世界上流动性最强的市场. (是的,甚至 与加密货币相比在美国,外汇通常被认为更安全、更有利可图.)

几年前, 好奇心驱使, 我创建了一个模拟账户,并在网上(用假钱)进行模拟,从而迈出了进入外汇算法交易世界的第一步 Meta Trader 4 电子交易平台.

经过一周的“交易”,我的钱几乎翻了一番. 受我成功的算法交易的激励, 我进行了更深入的研究,最终注册了一些外汇论坛. 很快, 我花了几个小时阅读关于外汇算法交易系统(决定你应该买入还是卖出的规则集)的内容。, 自定义指标市场情绪等等.

我的第一个外汇自动交易客户

大约在这个时候, 巧合的是, 我听说有人想找一个软件开发人员来构建一个简单的, 自动外汇交易系统. 这是在我上大学的时候,当时我正在学习 并发编程 在Java中(线程、信号量等). 我以为这个外汇自动交易系统不会比我的系统复杂得多 高级数据科学 所以我打听了一下这份工作,然后就加入了.

客户想要算法交易软件 MQL4, 一种函数式编程语言,由Meta Trader 4平台用于执行与股票相关的操作.

MQL5 已被释放. 如你所料, 它解决了MQL4的一些问题,并提供了更多的内置功能, 这让生活更轻松.


交易平台的角色(Meta Trader 4), 在这种情况下)是提供与外汇经纪人的连接. 然后,经纪人提供一个实时市场信息的平台,并执行买入/卖出指令. 对于不熟悉外汇算法交易的读者, 以下是数据馈送提供的信息:

这张图展示了外汇算法交易中涉及的数据.

通过Meta Trader 4, 您可以使用内部函数访问所有这些数据, 可在不同时间范围内访问:M1(每分钟), M5(每五分钟一班), M15, M30, H1(每小时), H4, D1(每天), W1(每周), 及MN(每月).

当前价格的变动称为a 蜱虫. 点差是一种货币对买入价或卖出价的变化. 在市场活跃的时候,每秒钟可能有很多次波动. 在市场缓慢的时候,几分钟的时间可能会毫无征兆地过去. 嘀嗒是外汇市场机器人的心跳.

当您通过该平台下订单时, 你买入或卖出一定数量的某种货币. 你还可以设定止损和获利上限. 的 止损限额 在放弃交易之前,你能承受的最大点数(价格变动)是多少. 的 获利的限制 在兑现之前,你会累积多少点数.

如果你想了解更多关于交易的基础知识(e.g.(点,订单类型,点差,滑点,市场订单等), BabyPips 是一个很好的资源.


客户的算法交易规范很简单:一个基于两个指标的外汇机器人. 作为背景,指标如下 非常 在试图定义市场状态和做出交易决策时很有帮助, 因为它们是基于过去的数据.g.,价格最高,价值在最后 n 天). 许多是内置在Meta Trader 4中的. 然而,我的客户感兴趣的指标来自自定义外汇交易系统.

每当两个自定义指标相交时,客户都希望进行交易, 只有在一个特定的角度.

这个外汇交易软件的例子说明了我的客户的需求.

动手工作与外汇交易软件

在亲身体验之后,我了解到MQL4程序具有以下结构:

  • 预处理器指令
  • 外部参数
  • 全局变量
  • 初始化函数
  • Deinit函数
  • 启动功能
  • 自定义函数

start函数是每个MQL4程序的核心. 它在每次市场变动时执行(因此,这个函数每滴答执行一次)。. 无论给定的时间框架如何,情况都是如此. 例如, 你可以在H1(一小时)时间段内操作, 然而,start函数每小时将执行数千次.

为了解决这个问题,我强制函数每个周期单位执行一次:

    int start ()
    {if(currentTimeStamp == Time[0]) return (0);
       
       currentTimeStamp =时间[0];

   //  ...

接下来,我必须获得指示器的值:

    //加载自定义指示器
    extern string indName = "SonicR Solid Dragon-Trend (White)";
    双dragon_min;
    双dragon_max;
    双截龙;
    双趋势;
    int start ()
    {  
    /// ...
      //更新保存指示值的变量
      actInfoIndicadores ();

    // ...
    字符串actInfoIndicadores ()
    {  
        dragon_max= icustomm (NULL, 0, indName, 0, 1);
        dragon_min= icustomm (NULL, 0, indName, 1,1);
        dragon= iccustom (NULL, 0, indName, 4,1);
        trend= iccustom (NULL, 0, indName, 5, 1);
    }

现在,我们将编码决策逻辑,包括指标的交集和它们的角度:

    int start ()
    {
    // ...
       如果(票= = 0) 
       {  
             if (dragon_min > trend && (ordAbierta== "OP_SELL" || primeraOP == true) && anguloCorrecto("BUY") == true && DiffPrecioActual("BUY")== true) {
                primeraOP = false;
                abrirOrden(“OP_BUY”,假);
             }
             if (dragon_max < trend && (ordAbierta== "OP_BUY" || primeraOP == true) && anguloCorrecto("SELL") == true && DiffPrecioActual("SELL")== true) {
                primeraOP = false;
                abrirOrden(“OP_SELL”,假);
             }  
       }     
       其他的
       {       
           如果(OrderSelect(票,SELECT_BY_TICKET) = = true)
           {
               datetime中医= OrderCloseTime ();
               if (ctm>0) { 
                  票= 0;
                  返回(0);
               }
           }
           其他的
              Print("OrderSelect失败的错误码是",GetLastError());

           if (ordAbierta == "OP_BUY")  && dragon_min <= trend  ) cerrarOrden(false);
           if (ordAbierta == "OP_SELL") && dragon_max >= trend ) cerrarOrden(false);
       }
    }

最后,我们要发送订单:

    void abrirOrden(string tipoOrden, bool log)
    {  
       RefreshRates ();
       double volume = AccountBalance() * point; 
       double pip = point * pipAPer;   
       双票= 0;
       while( 蜱虫et <= 0)
       {if (tipoOrden == "OP_BUY") 蜱虫et=OrderSend(simbolo ., OP_BUY,  羊皮纸书卷, 问, 3, 0/*出价-(点* 100)*/, 问 +(点* 50), “Orden买” , 16384, 0, 绿色);
          if (tipoOrden == "OP_SELL") 蜱虫et=OrderSend(simbolo, OP_SELL, 羊皮纸书卷, 报价, 3, 0/*问 +(点* 100)*/, 出价-(点* 50), “Orden卖”, 16385, 0, 红色);
          if (蜱虫et<=0)               Print("Error abriendo orden de ", tipoOrden , " : ", ErrorDescription(GetLastError()); 
       } ordAbierta = tipoOrden;
       
       if (log==true) mostrarOrden();
    }

您可以在 GitHub.

外汇回溯测试算法交易

一旦我建立了我的算法交易系统, 我想知道它的行为是否恰当,它使用的外汇交易策略是否有效.

回溯测试是在过去的事件下测试特定系统(自动化或非自动化)的过程. 换句话说,您使用过去作为现在的代理来测试您的系统.

MT4提供了一个可接受的工具,用于回测外汇交易策略(现在), 有更专业的工具提供更强大的功能). 开始, you set up your time frames and run your program under a simulation; the tool will simulate each 蜱虫, 知道每个单位应该以一定的价格开盘, 以某一价格收盘, 达到特定的高潮和低谷.

在将该计划的行动与历史价格进行比较之后, 你会对它是否正确执行有一个很好的感觉.

我的客户选择的指标,连同决策逻辑,都是不赚钱的.

通过val, I had checked the FX robot’s return ratio for some random time intervals; I knew that my client wasn’t going to get rich with the trading strategy used—the chosen indicators, 以及决策逻辑, 没有盈利. 下面是在M15窗口上运行164个操作的结果:

这些是运行我开发的外汇交易软件程序的结果.

注意,余额(蓝线)在其起点以下结束.

警告:说一个系统“盈利”或“不盈利”并不总是准确的. 经常, 根据市场的“情绪”,系统在一段时间内(不)盈利,,它可以遵循许多图表模式:

我们的算法交易例子中的一些趋势.

参数优化及其谎言

虽然回溯测试让我对这个FX机器人的实用性有所警惕, 当我开始研究它的外部参数并注意到整体回报率的巨大差异时,我很感兴趣. 这被称为 参数优化.

我做了一些粗略的测试,试图推断外部参数对回报率的重要性,得出如下结论:

外汇算法的一个方面是回报率.

清理后,看起来是这样的:

算法交易回报率清理后可能是这样的.

你可能会像我一样认为,你应该使用参数A. 但这个决定并不像看起来那么简单. 具体来说,请注意 不可预知性 对于小的误差值,它的返回值变化很大. 换句话说, 参数A很可能高估了未来的结果,因为任何不确定性——任何变化——都会导致更差的性能.

但事实上,未来是不确定的! 所以参数A的返回值也是不确定的. 事实上,最好的选择是依靠不可预测性. 经常, 最大收益较低但可预测性较强(波动较小)的参数优于收益高但可预测性较差的参数.

你唯一能确定的是,你不知道市场的未来, 假设你根据过去的数据就知道市场将如何表现,这是错误的. 因此,您必须承认您的外汇预测存在这种不可预测性.

假设你根据过去的数据知道市场将如何表现是错误的.

This does not necessarily mean we should use parameter B because even the lower returns of parameter A perform better than the returns of parameter B; optimizing parameters can result in 测试s that overstate likely future results, 这种想法并不明显.

整体外汇算法交易考虑

从我第一次接触外汇算法交易开始, 我为客户建立了几个自动交易系统, 我可以告诉你,总有探索和进一步分析外汇的空间. 例如, 我最近建立了一个基于寻找所谓的“大鱼”运动的系统:在非常小的时间单位内产生巨大的点变化. 这是一个使我着迷的课题.

建立自己的外汇模拟系统是了解更多外汇市场交易的绝佳选择, 可能性是无限的. 例如, 你可以试着破译价格变化的概率分布,作为一个市场(例如欧元/美元)波动的函数。, 或者使用每个波动状态的分布建立蒙特卡罗模拟模型, 使用你喜欢的任何精确度. 我把这个留作练习 急切的 读者.

外汇市场有时会让人不知所措, 但我鼓励你探索自己的外汇算法交易策略.

进一步阅读建议

现在, 有大量的工具可供构建, 测试, 提高外汇交易系统的自动化程度; 交易Blox 进行检测, NinjaTrader 进行贸易;及 OCaml 对于编程,仅举几例.

我读了很多关于货币市场这个神秘世界的书. 这里有一些可供程序员和热心读者参考的资源:

了解基本知识

  • 什么是外汇交易?

    外汇交易是通过货币对进行买卖.g.美元兑美元. 欧元)在外汇市场上.

  • 外汇是如何赚钱的?

    外汇经纪人通过佣金和手续费赚钱. 外汇交易者的赚钱(或亏钱)取决于他们的时机:如果他们卖出的价格相对于买入时足够高, 他们可以盈利.

  • 什么是回测交易策略?

    回溯测试是使用过去的事件测试特定策略或系统的过程.

  • 什么是算法交易?

    算法交易是指机器人/程序使用一套规则来告诉它何时买入或卖出.

聘请Toptal这方面的专家.
现在雇佣
罗格里奥·尼古拉斯·门格尔

Jujuy、阿根廷

2013年5月6日成为会员

作者简介

Rogelio是一位多才多艺且积极进取的全栈工程师,拥有超过13年的多种语言工作经验, 框架, 和平台.

作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

以前在

IBM

世界级的文章,每周发一次.

输入您的电子邮件,即表示您同意我们的 隐私政策.

世界级的文章,每周发一次.

输入您的电子邮件,即表示您同意我们的 隐私政策.

Toptal开发者

加入总冠军® 社区.