文章 "跨平台的EA交易: 信号" - 页 2

 

谢谢你,恩里科、

我想知道是否可以将一个信号作为另一个信号的附加过滤器...

例如,我有一个主信号,它给出多头入场信号。然后检查 第二个信号。如果它也给出了多头信号,那么总信号就是多头信号。但如果第二个信号给出多头,而第一个信号是中性的,那么总信号也必须是中性的,因为第二个信号只是第一个信号的附加过滤器,它本身并不是进入信号。

另外,有没有办法根据特定信号控制资金管理。例如,该信号的手数为 1,另一个信号的手数为 2,以此类推。就我的第一个问题而言,默认手数是第一个信号的手数,但如果第二个信号得到确认,手数就会翻倍。

谢谢。

 
mbjen:

我想了解是否可以使用一个信号作为另一个信号的附加过滤器...

例如,我有一个主信号,它给出多头入场信号。然后检查第二个信号。如果它也给出了多头信号,那么总信号就是多头信号。但如果第二个信号给出多头,而第一个信号是中性的,那么总信号也一定是中性的,因为第二个信号只是第一个信号的附加过滤器,它本身并不是进入信号。

这是可能的。最直接的方法是将两个信号合并到 CSignal 子类的一个实例中。您也可以在 CSignal 后代中创建 CSignals 实例,并让子过滤器相应地修改父信号。

mbjen

还有,有没有办法根据特定信号控制资金管理。例如,该信号的手数是 1,另一个信号的手数是 2,以此类推。关于我的第一个问题,默认手数是第一个信号的手数,但如果第二个信号得到确认,手数就会翻倍。

是的,这是可能的。CSignals 实例的容器是CExpertAdvisor 的实例,而每个 CSignal 实例的父实例都是相同的 CSignals 实例。您只需不断获取父/容器,直到找到 CExpertAdvisor 实例,获取其资金管理器指针,然后通过索引或名称分配所需的资金管理方法。

 
Enrico Lambino:

这是可能的。最直接的方法是将两个信号合并到 CSignal 后代的一个实例中。您也可以在 CSignal 后代中创建 CSignals 实例,并让子过滤器相应地修改父信号。

是的,这是可行的。CSignals 实例的容器是 CExpertAdvisor 实例,而每个 CSignal 实例的父级都是相同的 CSignals 实例。您只需不断获取父/容器,直到找到 CExpertAdvisor 实例,获取其资金管理器的指针,然后通过索引或名称分配所需的资金管理方法。


谢谢你,恩里科,我会试试的。

 

我刚刚开始使用跨平台 EA 框架。

我将 TEMA 和 MA 指标合并为 SignalTEMA_MA。计算以及 LongCondition 和 ShortCondition 如下。我还附上了 EA 代码。


bool SignalTEMA_MA::Calculate(void)
{
   int   tema_ma_state_current=0;
   bool  ret;
   
   if(m_ma.Main(m_signal_bar) >= m_tema.Main(m_signal_bar))
      tema_ma_state_current = 1;
   else
      tema_ma_state_current = -1;

   if (m_tema_ma_state != tema_ma_state_current) {
      ret = m_tema_ma_state == 0 ? false : true;
      m_tema_ma_state = tema_ma_state_current;
   }
   else {
      ret = false;
   }
   return ret;      
}

bool SignalTEMA_MA::LongCondition(void)
  {
   return m_tema.Main(m_signal_bar) > m_ma.Main(m_signal_bar);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
bool SignalTEMA_MA::ShortCondition(void)
  {
   return m_tema.Main(m_signal_bar) < m_ma.Main(m_signal_bar);
  }


该 EA 似乎可以工作,但在 TEMA/MA 指标交叉和订单之间出现了不必要的延迟,如下所示。
此示例使用 MT5 欧元兑美元 15 分钟周期(2017 年 12 月 4 日至 6 日)完成。

我的问题是,如何让订单在尽可能接近交叉点时输入?

一旦我解决了这个问题,我将继续实施 EA 策略,希望通过额外的进入/退出条件和过滤器以及资金管理来实现盈利。

/卡尔


附加的文件:
 

卡尔,你好、

您可以在交易条件中使用 >= 和 <=,而不是 < 和 >:

bool SignalTEMA_MA::LongCondition(void)
  {
   return m_tema.Main(m_signal_bar) >= m_ma.Main(m_signal_bar);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
bool SignalTEMA_MA::ShortCondition(void)
  {
   return m_tema.Main(m_signal_bar) <= m_ma.Main(m_signal_bar);

在您屏幕截图上第三个突出显示的圆圈中,EA 做空交易的时间太晚了。上面的代码会让卖出交易提前进入一个交易栏。

如果您想让它在十字星本身(后退 2 个条形图,即突出显示的圆圈所在的蜡烛图)上进行交易,那么您可以使用相同的设置,但 m_signal_bar = 0(当前条形图)。这将确保在尽可能接近交叉时进入交易,但这一栏的数据通常会重新绘制。在柱状图形成时,指标可能已经交叉,它可能会一直保持到该柱状图收盘,也可能不会。

 
Enrico Lambino:

嗨,卡尔、

您可以在交易条件中使用 >= 和 <=,而不是 < 和 >:

在您屏幕截图上第三个突出显示的圆圈中,EA 做空交易的时间太晚了。上面的代码会让卖出交易提前进入一个交易栏。

如果您想让它在十字星本身(后退 2 个条形图,即突出显示的圆圈所在的蜡烛图)上进行交易,那么您可以使用相同的设置,但 m_signal_bar = 0(当前条形图)。这将确保在尽可能接近交叉时进入交易,但这一栏的数据通常会重新绘制。在柱状图形成时,指标可能已经交叉,它可能会一直保持到该柱状图收盘,也可能不会。


你好,恩里科、

非常感谢你的快速回复,我会尝试你的建议。

/卡尔

 
Karl Klang:


你好,恩里科、

非常感谢你的快速回复,我会尝试你的建议。

/卡尔

你好,恩里科、

这个周末我做了一些测试。我按照你说的,将交易条件改为 >= 和 <=,但不幸的是,交易并没有提前一格(见下文剪辑)。


我还尝试设置 signal_bar=0。现在它可以在交叉盘本身进行交易,但尽管在 expert.Init 调用中 one_trade_per_candle=true 和 position_reverse=true,我还是得到了很多不需要的交易(见下面的剪辑)。

当前的专家源文件附后。

附加的文件:
 

也许 CExpertAdvisorBase::OnTick(void) 中的以下条件是错误的?

   if((checkopenlong || checkopenshort)
      && (m_every_tick || IsNewBar(m_symbol_name,m_period))
      && (!CheckPointer(m_times) || m_times.Evaluate()) 
      && (!m_one_trade_per_candle || m_last_trade_time<Time(0))
   )

应该是这样吗?

   if((checkopenlong || checkopenshort)
      && (m_every_tick || m_last_trade_time<Time(0))
      && (!CheckPointer(m_times) || m_times.Evaluate()) 
      && (!m_one_trade_per_candle || IsNewBar(m_symbol_name,m_period))
   )


然后我得到以下结果



 
Karl Klang:

也许 CExpertAdvisorBase::OnTick(void) 中的以下条件是错误的?

应该是这样吗?


然后我得到以下结果



卡尔,你好、

这通常是 TEMA 等指标的问题。这类指标给出的数值非常平缓,有时很难确认是否存在交叉。例如,在您的第一个屏幕截图(白色背景)中,第一笔和第二笔交易,如果您仔细观察,在这两笔交易之前的两个条形图中,信号仍然是反方向的。这就使得 1 根蜡烛前的那一格成为第一根发出反转信号的蜡烛(这导致了之后一格的交易)。至于第三笔交易,除非我们有打印在日志上的指标值,否则无法确认。从视觉上看,指标似乎是连续的,但实际上,数据是离散的。

关于CExpertAdvisorBase::OnTick(void),请确保如果设置信号栏 = 0,专家顾问的 m_every_tick = true。检查新蜡烛与维持每根蜡烛的单笔交易是不同的。

 

你好,恩里科、

我找到了一种处理计算功能的方法,其中包括滞后功能,当 MA 和 TEMA 指标交叉时,滞后功能似乎可以起作用。

但是,我在订单管理器中遇到了一个问题。在优化过程中,当我运行策略测试器进行一些循环时,就会出现这个问题。最初的循环运行正常,但循环几次后,每根蜡烛线都会下单。

这里运行正常:


但在这里,订单管理器开始下多个订单:


当我调试 COrderManager 的以下代码部分时,语句 orders_total = OrdersTotal(); 在工作时变成 1,但在失败时变成 0,这导致 if 条件 m_max_order>orders_total 总是评估为 true。

bool COrderManager::TradeOpen(const string symbol,ENUM_ORDER_TYPE type,double price,bool in_points=true)
  {
   bool ret=false;
   double lotsize=0.0;
   int trades_total =TradesTotal();
   int orders_total = OrdersTotal();
   m_symbol=m_symbol_man.Get(symbol);
   if(!IsPositionAllowed(type))
      return true;
   if(m_max_orders>orders_total && (m_max_trades>trades_total || m_max_trades<=0))

希望您能帮助解决这个问题。

最诚挚的问候/
卡尔