新人对MQL4和MQL5的任何问题,对算法和代码的帮助和讨论 - 页 1549

 
MakarFX:

当你知道该怎么做的时候,就好说话了......

帮助我提供如何 "尽可能多地获取有用信息 "的建议。

我已经说得很清楚了。那么对于你个人来说,让我来问问。

这里有两个函数,而且都是通过历史订单 进行的

//+------------------------------------------------------------------+
//|  Возвращает пункты убытка закрытых ордеров с начала цикла        |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|  Возвращает кол-во серии убыточных ордеров                       |
//+------------------------------------------------------------------+

同一订单上的两个周期。你不可能在一个周期内得到这些函数所返回的所有东西,对吗?

 

你好

我正试图在猫头鹰上添加一个交易逆转。我是按照说明中描述的那样做的:https://www.mql5.com/ru/forum/128200

我在编译时没有错误,但在测试器中翻转不工作。

日志给出了一个错误。

2021.07.29 20:06:34.316 2015.01.08 22:10:00 SMA with flip through code AUDUSD,M5: OrderSend error 130

2021.07.29 20:06:34.316 2015.01.08 22:05:45 SMA与反转通过AUDUSD,M5: OrderSend error 4107

2021.07.29 20:06:34.316 2015.01.08 22:05:45 SMA with flip via AUDUSD,M5: OrderSend功能的无效止损

你能告诉我这里的问题是什么吗?

我自己认为,在

int ReversOrderSend (string symbol,int cmd,double volume,double price,int slippage,double stoploss,double takeprofit,string comment,int magic=0, datetime expiration=0, color arrow_color=CLR_NONE)

与主代码没有关系。

我已经在不同的终端、4号和5号标志中试过了。

这里是整个代码。

//+-----------------------------------------------------------------------------------------------+
//|                                                                     Simple Moving Average.mq4 |
//|                                                                 Copyright 2016, Andrey Minaev |
//|                                                     https://www.mql5.com/ru/users/id.scorpion |
//+-----------------------------------------------------------------------------------------------+
#property copyright "Copyright 2016, Andrey Minaev"
#property link      "https://www.mql5.com/ru/users/id.scorpion"
#property version   "1.00"
#property strict

// Параметры советника
extern string sParametersEA = "";     // Параметры советника
extern double dLots         = 0.01;   // Количество лотов
extern int    iStopLoss     = 30;     // Уровень убытка (в пунктах)
extern int    iTakeProfit   = 30;     // Уровень прибыли (в пунктах)
extern int    iSlippage     = 3;      // Проскальзование (в пунктах)
extern int    iMagic        = 1;      // Индентификатор советника
extern double K_Martin     = 2.0;
extern int    OrdersClose  = 5;
extern int    DigitsLot    = 2;
extern int    ReversOrder  = 0;             // Переворот сделок 1-да; 0-нет;
// Параметры индикатора
extern string sParametersMA = "";     // Параметры индикатора
extern int    iPeriodMA     = 14;     // Период усреднения
// Глобальные переменные
double dMA;
//+-----------------------------------------------------------------------------------------------+
int OnInit()
  {
// Если брокер использует 3 или 5 знаков после запятой, то умножаем на 10
   if(Digits == 3 || Digits == 5)
     {
      iStopLoss   *= 10;
      iTakeProfit *= 10;
      iSlippage   *= 10;
     }

   return(INIT_SUCCEEDED);
  }
//+-----------------------------------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

  }
//+-----------------------------------------------------------------------------------------------+
void OnTick()
  {
// Получим значение индикатора
   dMA = iMA(Symbol(), 0, iPeriodMA, 0, MODE_SMA, PRICE_CLOSE, 0);

// Если нет открытых ордеров, то входим в условие
   if(bCheckOrders() == true)
     {
      // Если появился сигнал на покупку, то откроем ордер на покупку
      if(bSignalBuy() == true)
         vOrderOpenBuy();

      // Если появился сигнал на продажу, то откроем ордер на продажу
      if(bSignalSell() == true)
         vOrderOpenSell();
     }
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция проверки открытых оредров |
//+-----------------------------------------------------------------------------------------------+
bool bCheckOrders()
  {
// Переберем в цикле ордера, для проверки открытых ордеров данным советником
   for(int i = 0; i <= OrdersTotal(); i++)
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == iMagic)
            return(false);

   return(true);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на покупку |
//+-----------------------------------------------------------------------------------------------+
bool bSignalBuy()
  {
   if(dMA > Open[1] && dMA < Close[1])
      return(true);

   return(false);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на продажу |
//+-----------------------------------------------------------------------------------------------+
bool bSignalSell()
  {
   if(dMA < Open[1] && dMA > Close[1])
      return(true);

   return(false);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                            Функция открытия ордера на покупку |
//+-----------------------------------------------------------------------------------------------+
void vOrderOpenBuy()
  {
   int iOTi = 0;   // Тикет ордера

   iOTi = ReversOrderSend(Symbol(), OP_BUY, LOT(), Ask, iSlippage, 0, 0, "", iMagic, 0, clrNONE);

// Проверим открылся ли ордер
   if(iOTi > 0)
      // Есди да, то выставим уровни убытка и прибыли
      vOrderModify(iOTi);
   else
      // Если нет, то получим ошибку
      vError(GetLastError());
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                            Функция открытия ордера на продажу |
//+-----------------------------------------------------------------------------------------------+
void vOrderOpenSell()
  {
   int iOTi = 0;   // Тикет ордера

   iOTi = ReversOrderSend(Symbol(), OP_SELL, LOT(), Bid, iSlippage, 0, 0, "", iMagic, 0, clrNONE);

// Проверим открылся ли ордер
   if(iOTi > 0)
      // Есди да, то выставим уровни убытка и прибыли
      vOrderModify(iOTi);
   else
      // Если нет, то получим ошибку
      vError(GetLastError());
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                                    Функция модификации ордера |
//+-----------------------------------------------------------------------------------------------+
void vOrderModify(int iOTi)
  {
   int    iOTy = -1;   // Тип ордера
   double dOOP = 0;    // Цена открытия ордера
   double dOSL = 0;    // Стоп Лосс
   int    iMag = 0;    // Идентификатор советника

   double dSL = 0;     // Уровень убытка
   double dTP = 0;     // Уровень прибыли

// Выберем по тикету открытый ордер, получим некоторые значения
   if(OrderSelect(iOTi, SELECT_BY_TICKET, MODE_TRADES))
     {
      iOTy = OrderType();
      dOOP = OrderOpenPrice();
      dOSL = OrderStopLoss();
      iMag = OrderMagicNumber();
     }

// Если ордер открыл данный советник, то входим в условие
   if(OrderSymbol() == Symbol() && OrderMagicNumber() == iMag)
     {
      // Если Стоп Лосс текущего ордера равен нулю, то модифицируем ордер
      if(dOSL == 0)
        {
         if(iOTy == OP_BUY)
           {
            dSL = NormalizeDouble(dOOP - iStopLoss * Point, Digits);
            dTP = NormalizeDouble(dOOP + iTakeProfit * Point, Digits);

            bool bOM = OrderModify(iOTi, dOOP, dSL, dTP, 0, clrNONE);
           }

         if(iOTy == OP_SELL)
           {
            dSL = NormalizeDouble(dOOP + iStopLoss * Point, Digits);
            dTP = NormalizeDouble(dOOP - iTakeProfit * Point, Digits);

            bool bOM = OrderModify(iOTi, dOOP, dSL, dTP, 0, clrNONE);
           }
        }
     }
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                                      Функция обработки ошибок |
//+-----------------------------------------------------------------------------------------------+
void vError(int iErr)
  {
   switch(iErr)
     {
      case 129:   // Неправильная цена
      case 135:   // Цена изменилась
      case 136:   // Нет цен
      case 138:   // Новые цены
         Sleep(1000);
         RefreshRates();
         break;

      case 137:   // Брокер занят
      case 146:   // Подсистема торговли занята
         Sleep(3000);
         RefreshRates();
         break;
     }
  }
//+-----------------------------------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double LOT()
  {
   int n=0;
   double OL=dLots;
   for(int j = OrdersHistoryTotal()-1; j >= 0; j--)
     {
      if(OrderSelect(j, SELECT_BY_POS,MODE_HISTORY))
        {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == iMagic)
           {
            if(OrderProfit()<0)
              {
               if(n==0)
                  OL=NormalizeDouble(OrderLots()*K_Martin,DigitsLot);
               n++;
               if(n>=OrdersClose)
                 {
                  Comment("1");
                  return(dLots);
                 }
              }
            else
              {
               if(n==0)
                 {
                  Comment("2");
                  return(dLots);
                 }
               else
                 {
                  Comment("3");
                  return(OL);
                 }
              }
           }
        }
     }
   return(OL);
  }
//------------------------------------------------------------------
int ReversOrderSend (string symbol,int cmd,double volume,double price,int slippage,double stoploss,double takeprofit,string comment,int magic=0,datetime expiration=0,color arrow_color=CLR_NONE)
{
int Ret=0;
double sprd=MarketInfo(symbol,MODE_SPREAD)*Point;
//Print ("----------------------------",sprd);
if (ReversOrder==0) // Открываем ордера без разворота
{
Ret=OrderSend (symbol,cmd,volume,price,slippage,stoploss,takeprofit,comment,magic,expiration,arrow_color);
}
if (ReversOrder==1)
{
///////////////
if (cmd==OP_SELLSTOP) // Переворачиваем ордера OP_SELLSTOP
{
Ret=OrderSend (symbol,OP_BUYLIMIT,volume,price+sprd,slippage,takeprofit-sprd,stoploss-sprd,comment,magic,expiration,arrow_color);
}
if (cmd==OP_BUYSTOP) // Переворачиваем ордера OP_BUYSTOP
{
Ret=OrderSend (symbol,OP_SELLLIMIT,volume,price-sprd,slippage,takeprofit+sprd,stoploss+sprd,comment,magic,expiration,arrow_color);
}
///////////////
if (cmd==OP_SELL) // Переворачиваем ордера OP_SELL
{
Ret=OrderSend (symbol,OP_BUY,volume,price+sprd,slippage,takeprofit-sprd,stoploss-sprd,comment,magic,expiration,arrow_color);
}
if (cmd==OP_BUY) // Переворачиваем ордера OP_BUY
{
Ret=OrderSend (symbol,OP_SELL,volume,price-sprd,slippage,takeprofit+sprd,stoploss+sprd,comment,magic,expiration,arrow_color);
}
//////////////
if (cmd==OP_SELLLIMIT) // Переворачиваем ордера OP_SELLLIMIT
{
Ret=OrderSend (symbol,OP_BUYSTOP,volume,price+sprd,slippage,takeprofit-sprd,stoploss-sprd,comment,magic,expiration,arrow_color);
}
if (cmd==OP_BUYLIMIT) // Переворачиваем ордера OP_BUYLIMIT
{
Ret=OrderSend (symbol,OP_SELLSTOP,volume,price-sprd,slippage,takeprofit+sprd,stoploss+sprd,comment,magic,expiration,arrow_color);
}
}
return (Ret);
}
Предлагаю функцию реверса ордеров, для сливающих советников.
Предлагаю функцию реверса ордеров, для сливающих советников.
  • 2010.08.24
  • www.mql5.com
Помню, поначалу сталкивался с вопросом, как грамотно "перевернуть" ордера с покупки на продажу и наоборот...
 
Alexey Viktorov:

我已经说得够清楚了。我问你一个私人问题。

这里有两个函数,它们都是在历史订单 中进行循环。

同一订单上有两个循环。你不可能在一个周期内获得这些函数所返回的所有东西,对吗?

阿列克谢,我已经写过了,我知道你是一个好的程序员!你是一个好的程序员。

但我不是一个程序员,对你来说 "足够清楚 "的东西对我来说却不那么清楚......

至于两个循环,对我来说,"在一个循环中获得一切 " 是不可能的,因为它们返回的是不同类型的数据。

 
MakarFX:

阿列克谢,我已经写过了,我知道你是一个很好的程序员!"。

但我不是一个程序员,对你来说 "足够清楚 "的东西对我来说是黑暗的森林......。

至于两个循环,对我来说,"在一个循环中获得所有的东西 " 是不可能的,因为它们返回不同类型的数据。

返回的类型与此无关。如果在同一个数据上有2个循环,有不同的检查和过滤,你总是可以把所有的东西放在一个循环里,但代码读起来就不那么清楚了,但它应该工作得更快)在调试阶段,我不在一个循环里做所有的事情。在不同的中更容易发现错误。

 
MakarFX:

阿列克谢,我已经写过了,我知道你是一个很好的程序员!"。

但我不是一个程序员,对你来说 "足够清楚 "的东西对我来说是黑暗的森林......。

至于两个循环,对我来说,"在一个循环中获得所有东西 " 是不可能的,因为它们返回不同类型的数据。

我有两个变种。

  1. 在全局层面上制作变量。然后,他们将在所有的功能中都可以使用。
  2. 通过引用传递局部变量。那么如果你改变这个变量,本地变量也会被改变。
    /********************Script program start function*******************/
    void OnStart()
     {
      int a = 0;
      f_0(a);
      Print(a);
     }/******************************************************************/
    
    void f_0(int & b)
     {
      b = 100;
     }
    而且可能有多达64个这样的变量,上帝保佑我不要撒谎。如果我错了,有人可以纠正我。
  3. 更加认真地阅读文件。那里写得很详细。
 
MakarFX:

我在挂单之间有冲突。

第一个结果:货币对之间有冲突,EA在挂单 上有冲突。 例如,我对欧元兑美元下了一个挂单,EA遵循了算法(在1.18901买入,开仓,EA在1.18751设置止损,在1.19051获利,在1.18751卖出),一切按计划进行。

但现在是时候在GBPUSD开启交易了,那里的价格是不同的,EA做的一切都很好,除了设置一个挂单。在1.39393的卖出订单已经触发,EA试图打开它,在1.39633设置止损,并采取1.39153,但在1.39633的买入订单在欧元兑美元完全重复,在1.18751的卖出订单)

我刚刚发现了另一个问题:在欧元兑美元的开仓交易中,在1.18751处有一个止损,在1.18901处有一个卖出挂单,在1.18595处有一个拿货。专家顾问没有把触发的止损添加到历史上的取值中。

这些是问题所在。

 
законопослушный гражданин:

你好

我正试图将交易的 翻转拧到猫头鹰身上。

你是什么意思?你买入/卖出的某一价格范围?

 
SGarnov:

下午好。对EA的帮助。根据策略,如果止损被触发,那么EA应该通过ID将(点数)添加到历史上的下一个套利
,但由于某些原因,它没有这样做。

代码中的问题是什么?

if(isLimitOn && OrderSelect(OrderMagicNumber(), SELECT_BY_TICKET, MODE_HISTORY)){
            tpc += stop_loss;
            if(OrderSelect(lastMagic, SELECT_BY_TICKET)){
               if(OrderType() == OP_BUY) {
                  double tp_price = NormalizeDouble((OrderOpenPrice() + Point() * (tp + tpc)), Digits);
                  if(!OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp_price, OrderExpiration()))
                     Print("Ошибка модификации ордера:", GetLastError());
               }else if(OrderType() == OP_SELL){
                  double tp_price = NormalizeDouble((OrderOpenPrice() - Point() * (tp + tpc)), Digits);
                  if(!OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp_price, OrderExpiration()))
                     Print("Ошибка модификации ордера:", GetLastError());
               }
            }
               
            isLimitOn = false;
         }

Makar正确地指出了OrderMagicNumber(),但却误解了这个错误。请阅读该函数的语法文件......它应该是订单列表中的索引或某一订单的票据,但不是一个魔术。而OrderTicket()在这里没有帮助。不要试图把它放在那里。

 
SGarnov:

你是什么意思?你买入/卖出的某一价格范围?

根据我的理解,代码的作者建议如下。

如果猫头鹰开了一个带止损的买入交易,那么他的这段代码在同一时间在同一地点 开了一个带止损的卖出交易(考虑到价差),而不是买入交易

因此,寻找EA进入点的逻辑并没有改变,只是考虑到点差的方向改变。

这正是我所需要的

 
MakarFX:

简要地描述一下你想从这个EA中得到什么(操作逻辑)。

我认为你的代码中有很多不必要的东西,或者我不明白什么。

猫头鹰应该根据他们自己的算法来开立交易

如果止损,下一笔交易用马丁,以此类推,直到我指定的乘法次数(函数-OrdersClose = .....;)

此外,如果猫头鹰与终端一起被禁用,只需按下"自动交易 "按钮 和另一个猫头鹰,那么下一次交易将从起始手数开始,而不是从上一次被马丁格尔增加的手数。

如果能给它附上一个时间表,那就更好了,但这个想法我也是刚刚才想到。

例如:周一10:00启动,开始抽签,然后在白天取得一些成果后关闭,周二早上10:00再次启动,再次开始抽签。

一切都是。

原因: