EA: Diff_TF_MA_EA - 页 2

 
fxsaber:

实际上,代码中还有更多错误。例如,事实表明,仅仅为了 SB 风格而使用 CSymbolInfo 是邪恶的。

通过先前收集的票据列表平仓是邪恶的。这是一个非常常见的错误。

我认为这说明了很多问题:

值得理解的是,此 EA 是用于培训目的。

关于处理服务器返回代码。就我个人而言,我总是会处理它们。但在这里--在测试器中(我希望你明白,培训 EA 是为测试器和进一步改进自己而设计的)--处理所有必要的返回代码可能并不值得。此外,拥有自己的交易环境对实际交易来说是非常合理的,对测试者来说更是如此。

您可以看看都有什么:

首先,填写现有仓位的数据:

//--- 填写项目票清单
   int positions_total=PositionsTotal();
   if(prev_total!=positions_total)
     {
      FillingListTickets();
      prev_total=positions_total;
     }
   int num_b=NumberBuy();
   int num_s=NumberSell();

然后,检查信号,开仓(这里是买入仓位):

      if(open_long)
        {
         if(num_s>0) CloseSell();
         if(num_b==0)
           {
            double sl=(InpStopLoss==0   ? 0 : CorrectStopLoss(ORDER_TYPE_BUY,InpStopLoss));
            double tp=(InpTakeProfit==0 ? 0 : CorrectTakeProfit(ORDER_TYPE_BUY,InpTakeProfit));
            double ll=trade.CheckVolume(symb,lot,symbol_info.Ask(),ORDER_TYPE_BUY);
            if(ll>0 && CheckLotForLimitAccount(POSITION_TYPE_BUY,ll))
              {
               if(trade.Buy(ll,symb,0,sl,tp))
                  FillingListTickets();
              }
           }
        }

如果卖出数量大于零,则平仓。Expert Advisor 是摆动的 - 始终只有一个仓位。
然后检查买入 头寸的数量。只有在开仓后,它们的数量才可能大于零。但在卖出平仓后,买入头寸的数量必然等于零 - 这是一个摆动 EA。因此没有必要运行一个循环来寻找已经知道的东西。

接下来是最小正确性检查和买入头寸的开仓。返回 true 后,EA 交易环境的内部数组会立即更新。

一切都很简洁,没有多余的东西。如果有什么不明白的地方,请指正。

 
fxsaber:

错误在于枚举输入和调用,而不是最小距离。但计算结果也是错误的,因为


我没看到。给我看看 - 这很有趣。

 
Artyom Trishkin:

我认为这一条就足以说明问题:

值得注意的是,这个 EA 是用于培训的。

关于处理服务器返回代码。就我个人而言,我总是会处理它们。但在这里--在测试器中(我希望您明白,训练用智能交易系统是为测试器和独立的进一步修改而制作的)--可能没有必要处理所有必要的返回代码。此外,拥有自己的交易环境对于实际交易来说是非常合理的,对于测试器来说更是如此。

你没看清楚。我不想要任何退货代码。在票据上关闭卖出本身就是邪恶的。代码至少应该在演示版上正常运行,而不是有明显的潜在错误,测试人员与它有什么关系?

CloseSell 之后应该有 RefreshRates。但它不存在,因此即使在测试器中启用延迟模式也会出现故障。为了 SB 风格而使用标准圣经是邪恶的。代码很好地说明了这一点。


我只对SymbolInfo.mqh 做了几处修改,就成功编译并在 MT4 中使用。但是,在用 MQL4 编写代码时,有谁能想到这一点呢?为什么很多人在用 MQL5 编写代码时会想到这一点呢?这不仅会导致很多潜在错误,需要时间学习,而且看起来很笨拙。

 
fxsaber:

你没看清楚我不想要退票代码。票据上的 CloseSell 本身就是邪恶的。代码至少应该在演示版上正常运行,而且没有明显的潜在错误,测试人员该怎么办?

在 CloseSell 之后应该有 RefreshRates。但现在没有,因此即使在测试器中启用延迟模式也会出现故障。为了 SB 风格而使用标准圣经是邪恶的。代码很好地说明了这一点。

CloseSell()之后是一个价格为零的买入开仓:

      if(open_long)
        {
         if(num_s>0) CloseSell();
         if(num_b==0)
           {
            double sl=(InpStopLoss==0   ? 0 : CorrectStopLoss(ORDER_TYPE_BUY,InpStopLoss));
            double tp=(InpTakeProfit==0 ? 0 : CorrectTakeProfit(ORDER_TYPE_BUY,InpTakeProfit));
            double ll=trade.CheckVolume(symb,lot,symbol_info.Ask(),ORDER_TYPE_BUY);
            if(ll>0 && CheckLotForLimitAccount(POSITION_TYPE_BUY,ll))
              {
               if(trade.Buy(ll,symb,0,sl,tp))
                  FillingListTickets();
              }
           }
        }

为什么要执行两次 RefreshRates()?您看过CTrade 中的 SB 开仓代码吗?我看了:

//+------------------------------------------------------------------+
//| 购买操作|
//+------------------------------------------------------------------+
bool CTrade::Buy(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment="")
  {
   CSymbolInfo sym;
//--- 检查音量
   if(volume<=0.0)
     {
      m_result.retcode=TRADE_RETCODE_INVALID_VOLUME;
      return(false);
     }
//--- 检查符号
   sym.Name((symbol==NULL)?Symbol():symbol);
//--- 查看价格
   if(price==0.0)        
     {                   
      sym.RefreshRates();
      price=sym.Ask();   
     }                   
//---
   return(PositionOpen(sym.Name(),ORDER_TYPE_BUY,volume,price,sl,tp,comment));
  }
//+------------------------------------------------------------------+
 
Artyom Trishkin:

在 CloseSell() 之后,买入以零价格打开:

为什么要刷新两次 RefreshRates()?

因为调用了正确的函数。

您看过 CTrade 中的开仓代码吗?

Include\Trade\*.mqh I always watch/vigil, because you should know the enemy by sight.

 
fxsaber:

然后调用 Correct 函数。

Include\Trade\*.mqh I always watch/vigil, because you should know the enemy by sight.

敌人 :))))

是的,现在我看到了--正确的函数从 SB 的 m_tick 变量中读取价格,这些变量在更新过程中被填入,而不是直接通过SymbolInfoDouble()--这样就不可能有你所说的埋伏。此外,在正确函数之前没有太多代码,价格是在 tick 到达后立即更新的 - 在 OnTick() 的最开始:

//--- 检查零价格
   if(!RefreshRates()) return;
 
Artyom Trishkin:

敌人 :)))))

是的,现在我看到了--正确的函数是从 SB 的 m_tick 变量中读取价格的,更新时会填入这些变量,而不是直接通过 SymbolInfoDouble() --这不可能是你所说的问题。此外,在正确的函数之前并没有太多代码,价格是在 tick 到达后立即更新的 - 在 OnTick() 的最开始:

交易、自动交易系统和交易策略测试论坛。

智能交易系统:Diff_TF_MA_EA

fxsaber, 2018.02.01 22:10

在对SymbolInfo.mqh 做了很少的修改后,结果就可以编译并在 MT4 中使用它。但是,在 MQL4 中编写东西时,有谁能想到这一点!为什么很多人在 MQL5 中编码时会想到这一点呢?这不仅会导致很多潜在错误,花费时间学习,而且看起来很笨拙。

我将向 MQL4 花园投掷一块石头。强制刷新率的 Bid/Ask 是邪恶的。但有一个很棒的宏结构,可以提供无差错且简洁的结果。
 
fxsaber:
我要在 MQL4 花园里扔一块石头。强制刷新率的 Bid/Ask 是邪恶的。但是,有一种奇妙的宏结构可以提供明确而简洁的结果。

我一直在等你骑上你的驼背马 :))))。

在这些正确的函数中使用 SymbolInfoDouble() 即可获得必要的价格。不过,我在我的类似函数中也是这么做的。在这里,程序员对从符号对象接收到的数据的依赖是徒劳的--这些数据是旧的--只有在更新时才写入 m_tick。

 
Artyom Trishkin:

我一直在等你骑上你的驼背马 :))))))

在这些函数中使用 SymbolInfoDouble() 即可获得必要的价格。不过,我在我的类似函数中也是这么做的。在这里,程序员对从符号对象接收到的数据的依赖是徒劳 的--这些数据 是旧的--只有在更新时才写入 m_tick。

这里就出现了一个逻辑问题,是谁让他在 OOP 中获取最简单的数据?在 MQL4 中,他总是能顺利接收到这些数据,但他的想法发生了什么变化?

驼背马

关于交易、自动交易系统和测试交易策略的论坛。

MT4 测试仪 VS MT5 测试仪

fxsaber, 2017.05.08 10:04 AM

感谢subj找到了罪魁祸首,有机会比较的时候总是这样。

显示错误的智能交易系统

// MQL4&5 代码

#property strict

#ifdef __MQL5__
  #define Bid (SymbolInfoDouble(_Symbol, SYMBOL_BID))
  #define Ask (SymbolInfoDouble(_Symbol, SYMBOL_ASK))
#endif // __MQL5__

#define  PRINT(A) Print(#A + " = " + (string)(A));

void OnTick()
{
  static bool FirstRun = true;
  
  static const double PrevBid = Bid;
  static const double PrevAsk = Ask;
  
  if (FirstRun)
  {
    PRINT((PrevBid != Bid) || (PrevAsk != Ask))
    
    FirstRun = false;
  }
}


MT4

2017.05.08 10:57:33.056 2017.04.10 00:00:08  TDS_Test EURUSD,M1: (PrevBid!=Bid)||(PrevAsk!=Ask) = false


MT5

2017.05.08 11:01:31.266 2017.04.10 00:00:08   (PrevBid!=Bid)||(PrevAsk!=Ask) = true
 
代码已更新。我们来看看标准程序库