个性化阅读
专注于IT技术分析

外汇交易算法:工程师的实用故事

本文概述

如你所知, 外汇(Forex, 或FX)市场用于货币对之间的交易。但是你可能不知道这是世界上流动性最高的市场。

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

外汇封面图

经过一周的”交易”, 我的钱几乎翻了一番。在我自己成功的算法交易的刺激下, 我更深入地挖掘并最终注册了许多外汇论坛。很快, 我花了几个小时阅读有关算法交易系统(确定是否应该买卖的规则集), 自定义指标, 市场情绪等信息。

我的第一个客户

巧合的是, 大约在这个时候, 我听说有人试图找到一个软件开发人员来自动化一个简单的交易系统。那是我上大学时学习Java并发编程(线程, 信号量和所有垃圾)的时候。我以为这个自动化系统不会比我的高级数据科学课程工作复杂得多, 所以我询问了这项工作并加入了。

客户需要使用MQL4构建的算法交易软件, MQL4是Meta Trader 4平台用于执行与股票相关的操作的功能编程语言。

此后已发布MQL5。如你所料, 它解决了MQL4的一些问题, 并带有更多内置函数, 使工作变得更轻松。

交易平台(在本例中为Meta Trader 4)的作用是提供与外汇经纪商的联系。然后, 经纪人为平台提供有关市场的实时信息, 并执行你的买卖订单。对于不熟悉外汇交易的读者, 以下是数据Feed提供的信息:

此图演示了外汇算法交易中涉及的数据。

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

当前价格的变动称为刻度。换句话说, 报价是一种货币对的买价或卖价的变化。在活跃的市场中, 每秒可能有许多滴答声。在低迷的市场中, 可能会有几分钟没有滴答声。滴答是货币市场机器人的心跳。

通过这样的平台下订单时, 你买卖一定数量的某种货币。你还可以设置止损和止盈限制。止损限制是你放弃交易之前可以承受的最大点数(价格波动)。获利限制是你兑现前积累的对你有利的点数。

如果你想了解有关交易基础的更多信息(例如, 点数, 订单类型, 点差, 滑点, 市场订单等), 请参见此处。

客户的算法交易规范很简单:他们想要一个基于两个指标的外汇机器人。对于背景而言, 指标在尝试定义市场状态并做出交易决策时非常有帮助, 因为它们基于过去的数据(例如, 最近n天的最高价格)。许多内置在Meta Trader 4中。但是, 我的客户感兴趣的指标来自自定义交易系统。

他们希望每次这些自定义指标中的两个相交时都以某个角度进行交易。

这个交易算法示例演示了我客户的要求。

动手

当我弄脏手时, 我了解到MQL4程序具有以下结构:

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

启动函数是每个MQL4程序的核心, 因为它在每次市场变动时都会执行(因此, 此函数每执行一个报价就会执行一次)。无论你使用的是什么时间期限, 情况都是如此。例如, 你可能在H1(一小时)时间范围内进行操作, 但是启动功能将在每个时间范围内执行数千次。

要解决此问题, 我强制该函数每个周期单位执行一次:

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)
  • EA交易程序设计–在MQL中为Meta Trader 4创建自动交易系统, 作者Andrew R. Young
  • 交易系统-系统开发和投资组合优化的新方法, 作者:Urban Jeckle和Emilio Tomasini:技术性强, 非常专注于外汇测试。
  • Rui Pedro Barbosa和Orlando Belo的多代理货币交易系统的分步实施:这是非常专业的文章, 描述了如何创建交易系统和测试平台。
赞(1)
未经允许不得转载:srcmini » 外汇交易算法:工程师的实用故事

评论 抢沙发

评论前必须登录!