文章 "开发多币种 EA 交易(第 2 部分):过渡到交易策略的虚拟仓位"

 

新文章 开发多币种 EA 交易(第 2 部分):过渡到交易策略的虚拟仓位已发布:

让我们继续开发多币种 EA,让多个策略并行工作。让我们尝试将与市场开仓相关的所有工作从策略级转移到管理策略的 EA 级。这些策略本身只进行虚拟交易,并不建立市场仓位。

在上一篇文章中,我们开始开发一种可同时使用多种交易策略的多币种 EA。在第一阶段,只有两种不同的策略。它们代表了相同交易理念的实现,在相同的交易工具(交易品种)和图表时段(时间框架)上运行。它们之间的区别仅在于参数的数值不同。

我们还根据所需的最大回撤水平(存款的 10%)确定了未平仓仓位的最佳大小。我们对每种策略都分别进行了这样的设置。当我们将这两种策略结合在一起时,我们不得不减少开仓头寸的大小,以维持给定的回撤水平。对于两个策略,减少的幅度还算小。但是,如果我们想将数十或数百个策略实例组合在一起呢?对于某些策略,我们很可能不得不将仓位减小到经纪商允许的最小敞口仓位大小以下。在这种情况下,这些策略根本无法参与交易。如何让它们发挥作用?

为此,我们将剥夺策略独立开仓和设置挂单的权利。策略只需进行虚拟交易,即记住在什么水平应该开立一定大小的头寸,并根据要求报告现在应该开立的交易量。只有在对所有策略进行调查并计算出所需的总交易量后,我们才会开立真实的市场头寸,同时考虑到要保持一定的回撤比例。

我们现在只想测试这种方法的适用性,而不是其实施效率。因此,在本文的框架内,我们将尝试至少开发出这种方法的一些可行实现方案,这将有助于我们日后从架构的角度构建出更美观的方案,因为我们已经掌握了如何避免错误的知识。

作者:Yuriy Bykov

 

我还没有读完。投入就是一个很好的例子。

1.

input string      symbol_              = "EURGBP";    // 交易工具(符号)
input ENUM_TIMEFRAMES  timeframe_       = PERIOD_H1;   // 计划期间

input group "===开启信号的参数"
input int         signalPeriod_        = 13;    // 平均交易量的蜡烛数量
input double      signalDeviation_     = 0.3;   // 开第一单时与平均值的相对偏差
input double      signaAddlDeviation_  = 1.0;   // 开仓第二单和后续单时与平均值的相对偏差

input group "===待处理订单参数"。
input int         openDistance_        = 0;     // 从价格到挂单的距离
input double      stopLevel_           = 10500; // 止损点(单位:点)
input double      takeLevel_           = 465;   // 止盈(点数)
input int         ordersExpiration_    = 1000;  // 挂单到期时间(分钟)

input group "===资本管理选项"
input int         maxCountOfOrders_    = 3;     // 同时打开的最大订单数
2.
int OnInit() {
   expert = new CAdvisor(new CVolumeReceiver(magic_));
   expert.Add(new CSimpleVolumesStrategy(
                         symbol_, timeframe_,
                         fixedLot_,
                         signalPeriod_, signalDeviation_, signaAddlDeviation_,
                         openDistance_, stopLevel_, takeLevel_, ordersExpiration_,
                         maxCountOfOrders_)
                     );       // 添加一个策略实例

   return(INIT_SUCCEEDED);
}
3.
class CSimpleVolumesStrategy : public CStrategy {
private:
   //--- 打开信号的参数
   int               m_signalPeriod;       // 平均交易量的蜡烛数量
   double            m_signalDeviation;    // 开第一单时与平均值的相对偏差
   double            m_signaAddlDeviation; // 开仓第二单和后续单时与平均值的相对偏差

   //--- 挂单参数
   int               m_openDistance;       // 从价格到挂单的距离
   double            m_stopLevel;          // 止损点(单位:点)
   double            m_takeLevel;          // 止盈(点数)
   int               m_ordersExpiration;   // 挂单到期时间(分钟)

   //--- 基本建设管理参数
   int               m_maxCountOfOrders;   // 同时打开的最大订单数

4.

public:
   //--- 公共方法
   CSimpleVolumesStrategy(
      string           p_symbol,
      ENUM_TIMEFRAMES  p_timeframe,
      double           p_fixedLot,
      int              p_signalPeriod,
      double           p_signalDeviation,
      double           p_signaAddlDeviation,
      int              p_openDistance,
      double           p_stopLevel,
      double           p_takeLevel,
      int              p_ordersExpiration,
      int              p_maxCountOfOrders
   ); 

5-6.

//+------------------------------------------------------------------+
//| 构造函数|
//+------------------------------------------------------------------+
CSimpleVolumesStrategy::CSimpleVolumesStrategy(
   string           p_symbol,
   ENUM_TIMEFRAMES  p_timeframe,
   double           p_fixedLot,
   int              p_signalPeriod,
   double           p_signalDeviation,
   double           p_signaAddlDeviation,
   int              p_openDistance,
   double           p_stopLevel,
   double           p_takeLevel,
   int              p_ordersExpiration,
   int              p_maxCountOfOrders) :
   // 初始化列表
   CStrategy(p_symbol, p_timeframe, p_fixedLot), // 调用基类构造函数
   m_signalPeriod(p_signalPeriod),
   m_signalDeviation(p_signalDeviation),
   m_signaAddlDeviation(p_signaAddlDeviation),
   m_openDistance(p_openDistance),
   m_stopLevel(p_stopLevel),
   m_takeLevel(p_takeLevel),
   m_ordersExpiration(p_ordersExpiration),
   m_maxCountOfOrders(p_maxCountOfOrders) {
   ArrayResize(m_orders, m_maxCountOfOrders);

   // 加载指标以获取刻度线量
   iVolumesHandle = iVolumes(m_symbol, m_timeframe, VOLUME_TICK);

// 设置刻度卷数组接收器的大小和所需的寻址方式
   ArrayResize(volumes, m_signalPeriod);
   ArraySetAsSeries(volumes, true);
}

每个输入参数必须规定五到六次。

 
Сравнивая эти результаты с результатами аналогичного советника, но не использующего виртуальные позиции, можно отметить улучшение некоторых показателей: немного увеличилась прибыль и уменьшилась просадка, подрос коэффициент Шарпа и профит-фактор.
粗略地说,从对冲转为净额结算,得到了相应的统计数字。"改进"。例如,减少掉期交易的交易量。
 

阅读文章。感谢作者,探究得很好,我们可以朝哪个方向前进。


Нас сейчас будет интересовать только проверка пригодности такого подхода, а не эффективность его реализации. Поэтому в рамках этой статьи мы постараемся написать хотя бы какую-то рабочую реализацию этого подхода, которая в дальнейшем поможет нам построить более красивую с архитектурной точки зрения. Поможет не в том смысле, что мы будем улучшать уже имеющуюся, а в том, что мы сможем понять, что вот так делать не надо, а можно сделать по-другому, и это будет лучше.

这是一个有力的观察,之后就没有批评的必要了,而应该直接进入建设性的部分--提出建议。


文章讨论了虚拟交易的概念,以及虚拟交易与真实交易的单向同步。作为测试者的一个例子,它是可行的。但这只是一个例子。

在实践中,这样的 TS 投资组合是通过 EX5(免费提供给测试者)建立的--运行,获取单次运行的 tst 文件,用其中的任何 MM 规则建立联合单次运行。


对于 Tester 来说,您需要速度。试着估算有虚拟化和没有虚拟化的变量的优化速度变化有多大。


这个概念本身对实际交易很有帮助。但对于同步器,您必须保留虚拟交易的历史记录。这里面有很多问题。轻描淡写地说,这是一种严肃的方式。


从架构上讲,虚拟化将脱离 TS。我目前只有 350 Kb 的虚拟化源。它还会增长。


请谨慎选择虚拟交易的交易 API。从可用的 API 中进行选择。优先选择 API 是合乎逻辑的,因为在该 API 上可以尽可能方便地对 TS 进行编程。我不太理解所有交易平台发明自己的自行车--交易 API 的普遍做法。让它 "开箱即用 "OOP实体,等等。从这个意义上说,MQ 走了一条好路--所有的 API 都没有 OOP。

 

在阅读此类文章之前,我总会先看看测试结果。至少在测试仪上是这样。当我看到 5 年 19% 的利润时,我感到轻松愉快!这可比写了 75 篇神经网络文章的作者强多了!))

但现在我明白了如何在外汇交易中保证赚钱。我曾经以为只能教那些笨蛋学习艾略特波,但事实证明还是有好办法的))。

 
fxsaber #:

阅读文章。感谢作者,让我们了解了该朝哪个方向发展。

非常感谢你的关注和建设性意见。我会尽量考虑和利用这些意见。我稍后再详细回复,现在没时间。

 
Alexey Volchanskiy 测试结果。至少在测试仪上是这样。当我看到 5 年 19% 的利润时,我感到轻松愉快!这可比写了 75 篇神经网络文章的作者强多了!))

但现在我明白了如何在外汇交易中保证赚钱。我曾经以为只有艾略特波才能教那些笨蛋,但事实证明还是有好办法的))。

我忍不住要在此指出,在缩水小于 1000 美元的条件下,五年测试中 19% 的利润是由恒定手数赚取的,即 1%。如果我们把注意力集中在甚至 10%的最大缩水率上,并使用可变手数,结果会更加有趣。

 
//+------------------------------------------------------------------+
//|SimpleVolumesExpertSingle.mq5
//|Copyright 2024, Yuriy Bykov | |
//|https://www.mql5.com/zh/users/antekov|
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Yuriy Bykov"
#property link      "https://www.mql5.com/zh/articles/14107"
#property description "当蜡烛的成交量超过平均成交量时的 Expert Advisor 挂单"。
#property description "沿着当前蜡烛的方向"
#property description "如果订单尚未转为头寸,则会在到期时删除"。
#property description "未平仓头寸只能在 SL 或 TP 时平仓"。

#include "Advisor.mqh"
#include "SimpleVolumesStartegy.mqh"

打错了。

 
fxsaber #:

打错了。

是的,我在好几个地方都改正了,但还是在某个地方出现了。

 
fxsaber #:

在实践中,这种 TS 组合是通过 EX5 建立的(测试者市场提供免费服务)--运行,获取单次通过的 tst 文件,并根据这些文件与任何 MM 规则进行联合单次运行。

我还没有考虑过这个方案,但我会记住它也是可行的。但是,如果我设法从市场上找到一套现成的智能交易系统,我如何将它们结合起来使用呢?我是否只需使用选定的 MM 参数运行整套程序?

 
fxsaber #:

对于测试人员来说,您需要的是速度。试着估算带虚拟化和不带虚拟化的变体的优化速度变化有多大。

我会试一试,但当同时运行的策略数量达到几十或几百个实例时,似乎会有明显的增益。

我一直想更详细地介绍如何使用你的虚拟 库来加快测试速度,但还没来得及。主要原因是我已经习惯了 MT5 的交易功能,尽管当我不得不将我的智能交易系统从 MT4 重新设计为 MT5 时,与之相关的不便之处很多,而且我后来才了解到虚拟库。

现在我正在考虑从 CReceiver 中创建一个子类,使用虚拟环境。