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

 
MakarFX:
你有一个支持手动下单的EA吗?
是的,我手动下挂单或直接开仓交易,然后专家顾问就会工作。
 
SGarnov:
试着插入它,它没有被编译。整个代码,如果有必要,我会放一张编译的屏幕截图。我想可能还有一个问题,我的TP是通过系数(外部变量)来设置与STOP的关系的,也许可以改成手动设置,这样EA会更容易添加?

职能

  double GetPointLastLoss(){
            datetime t=0;
            double result=0,p=0,tp=0;
            int i=OrdersHistoryTotal(),magic=0;
         for(int pos=0; pos<i; pos++)
         {
          if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
         {
          if((OrderSymbol()==_Symbol) && (OrderMagicNumber()==magic))
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(t<OrderCloseTime())
                 {t=OrderCloseTime(); p=OrderProfit(); tp=OrderType();
                  if(tp==OP_BUY&&p<0)
                    {
                     result=OrderOpenPrice()-OrderClosePrice();
                    } else {result=0;}
                  if(tp==OP_SELL&&p<0)
                    {
                     result=OrderClosePrice()-OrderOpenPrice();
                    } else {result=0;}
                 }
              }
           }
        }
     }
   return(result);
  }

从全局范围看,magic=0,用于编译。

magic=0

	          
 
Galim_V:

职能

从全局范围移除。magic=0,用于编译。

删除了,没有编译错误,只有在第三列函数行tp=0中弹出1个警告,对外部变量int tp=0进行了听证。我不太明白程序员不喜欢什么。所有的代码附在后面,如果你不难纠正,真相就在附近。

input int takeProfitC = 2;// Коэффициент Take Profit
input int stop_loss = 100;//Уровень Stop Loss
input int stop_count = 2;//Количество Stop Loss
input double lots = 0.01;//Лоты
input int slippage = 30;//Проскальзывание
input int datePeriod = 48;// Время удержания при SL


int tp = 0;
int tpc = 0;
double tp_price_old = 777;
int stopLossCount = 0;
datetime startOrder = 0;
int pending_ticket = 0;
int lastMagic = 0;
bool isLimitOn = false;
bool isStart = True;
datetime startTime = 0;
bool isFinal = false;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
//
   //OrderSend(Symbol(), OP_SELL, 0.01, 0.76228, 300, 0, 0);
   //OrderSend(Symbol(), OP_SELLSTOP, 0.01, 0.77057, 300, 0, 0);
   //OrderSend(Symbol(), OP_BUYSTOP, 0.01, 0.76928, 300, 0, 0);
   tp = stop_loss * takeProfitC;
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
//--

}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {
//---
//Comment("StopCount: " + stopLossCount + "\n" + "CurrentStopC: " + stop_count);
   for(int i = OrdersTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if(OrderSymbol() == Symbol()) {
         int magic = OrderMagicNumber();
            if((OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderOpenTime()) {
               int ticket = OrderTicket();
               if(!findPending(ticket)) {
                  if(OrderSelect(ticket, SELECT_BY_TICKET) && (((TimeCurrent() <= (startTime + datePeriod * 3600))) || isStart)) {
                     if(OrderType() == OP_BUY) {
                        double sl_price = NormalizeDouble(OrderOpenPrice() - Point() * MathMax(stop_loss, MarketInfo(Symbol(), MODE_STOPLEVEL)), Digits);
                        double tp_price = NormalizeDouble((OrderOpenPrice() + Point() * (tp)), Digits);
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), sl_price, tp_price, OrderExpiration())) {
                           Print("Ошибка модификации ордера:", GetLastError());
                        } else {
                           if(stopLossCount < stop_count && tp_price != tp_price_old){
                              pending_ticket = OrderSend(Symbol(), OP_SELLSTOP, lots, sl_price, slippage, 0, 0, NULL, OrderTicket());
                              lastMagic = ticket;
                              isLimitOn = true;
                              if(isStart){
                                 startTime = TimeCurrent();
                                 isStart = false;
                              }
                              tp_price_old = tp_price;
                              stopLossCount++;                         
                           }
                        }
                     } else if(OrderType() == OP_SELL) {
                        double sl_price = NormalizeDouble(OrderOpenPrice() + Point() * MathMax(stop_loss, MarketInfo(Symbol(), MODE_STOPLEVEL)), Digits);
                        double tp_price = NormalizeDouble((OrderOpenPrice() - Point() * (tp)), Digits);
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), sl_price, tp_price, OrderExpiration())) {
                           Print("Ошибка модификации ордера:", GetLastError());
                        } else {
                          if(stopLossCount < stop_count && tp_price != tp_price_old){
                              pending_ticket = OrderSend(Symbol(), OP_BUYSTOP, lots, sl_price, slippage, 0, 0, NULL, OrderTicket());
                              lastMagic = ticket;
                              isLimitOn = true;
                              if(isStart){
                                 startTime = TimeCurrent();
                                 isStart = false;
                              }
                              stopLossCount++;
                              tp_price_old = tp_price;  
                          }
                        }
                     }
                  }
               }
         }
         if(startTime > 0 && (TimeCurrent() >= (startTime + datePeriod * 3600))){
            deletePending(lastMagic);
            isFinal = true;
         }
            
         if(lastMagic != 0 && !IsSell() && !IsBuy() && magic == lastMagic) {
            tpc = 0;
            startTime = 0;
            stopLossCount = 0;
            deletePending(lastMagic);
            isStart = true;
            }
         }
     }
   }
   if((startTime > 0 || isFinal) && !IsSell() && !IsBuy()){
            tpc = 0;
            startTime = 0;
            stopLossCount = 0;
            isStart = true;
            isFinal = false;
   }
}
//+----------------------------------------------------------------------------+
//|  Возвращает пункты убытка последнего закрытого ордера в пунктах            |
//+----------------------------------------------------------------------------+
double GetPointLastLoss(){
            datetime t=0;
            double result=0,p=0,tp=0;
            int i=OrdersHistoryTotal(),magic=0;
         for(int pos=0; pos<i; pos++)
         {
          if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
         {
          if((OrderSymbol()==_Symbol) && (OrderMagicNumber()==magic))
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(t<OrderCloseTime())
                 {t=OrderCloseTime(); p=OrderProfit(); tp=OrderType();
                  if(tp==OP_BUY&&p<0)
                    {
                     result=OrderOpenPrice()-OrderClosePrice();
                    } else {result=0;}
                  if(tp==OP_SELL&&p<0)
                    {
                     result=OrderClosePrice()-OrderOpenPrice();
                    } else {result=0;}
                 }
              }
           }
        }
     }
   return(result);
  }                                                                
//+------------------------------------------------------------------+
bool findPending(int ticket) {
   for(int i = OrdersTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if(OrderMagicNumber() == ticket) {
            return true;
         }
      }
   }

   for(int i = OrdersHistoryTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
         if(OrderMagicNumber() == ticket) {
            return true;
         }
      }
   }
   return false;
}
//+------------------------------------------------------------------+
void deletePending(int magic) {
   for(int i = OrdersTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if(OrderMagicNumber() == magic) {
            if(OrderType() != OP_BUY && OrderType() != OP_SELL) {
               if(!OrderDelete(OrderTicket())) {
                  Print("Ошибка удаления отложеного одера: ", GetLastError());
               }
            }
            break;
         }
      }
   }
}
//+------------------------------------------------------------------+
bool IsSell()
{
   int count = 0;
   for (int trade = OrdersTotal () -1; trade >= 0; trade--)
   {
      if (OrderSelect (trade, SELECT_BY_POS, MODE_TRADES) 
          && OrderSymbol() == Symbol()
          && OrderType() == OP_SELL)
      {
         count++;
      }
      
   }
   if (count == 0)
      return false;
   else
      return true;
}
//+------------------------------------------------------------------+
bool IsBuy()
{
   int count = 0;
   for (int trade = OrdersTotal () -1; trade >= 0; trade--)
   {
      if (OrderSelect (trade, SELECT_BY_POS, MODE_TRADES) 
          && OrderSymbol() == Symbol()
          && OrderType() == OP_BUY)
      {
         count++;
      }
      
   }
   if (count == 0)
      return false;
   else
      return true;
}
 
SGarnov:

删除了,没有编译错误,只有在列tp=0的函数第三行弹出了1个警告,对外部变量int tp=0的听证。我不太明白程序员不喜欢什么。所有的代码都附上了,如果你不难纠正,真相就在附近。

它看起来像这样

//+------------------------------------------------------------------+
//|                                                   SGarnov.v2.mq4 |
//|                                           Copyright 2020, DrMak. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, DrMak."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//--- input parameters
input int      T_Profit = 2;     // Коэффициент Take Profit
input int      S_Loss   = 100;   // Уровень Stop Loss
input double   O_Lots   = 0.01;  //Лоты
input int      Input4;
input int      Input5;
input int      Input6;

double sl_price,tp_price,t_profit,s_loss;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- 
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   t_profit = S_Loss*T_Profit;
   s_loss   = MathMax(S_Loss, MarketInfo(Symbol(), MODE_STOPLEVEL));
   // Проверяем наличие ордеров BUY
   if(CountOrders(_Symbol, 0)>0)
     {
      // Проверяем последний закрытый ордер SELL на наличие убытка в пунктах
      if(GetPointLastLoss(1)>0)
        {
         // Если убыток есть, то добавляем пункты убытка
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(GetPointLastLoss(1)+Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
      else
        {
         // Если убытка нет
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
     }
   // Проверяем наличие ордеров SELL
   if(CountOrders(_Symbol, 1)>0)
     {
      // Проверяем последний закрытый ордер BUY на наличие убытка в пунктах
      if(GetPointLastLoss(0)>0)
        {
         // Если убыток есть, то добавляем пункты убытка
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(GetPointLastLoss(0)+Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
      else
        {
         // Если убытка нет
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
     }
  }
//+--------------------------------------------------------------------------------------------------------------------+
//| Подсчет ордеров по типу                                                                                            |
//+--------------------------------------------------------------------------------------------------------------------+
//|  0 - ордера типа BUY          1 - ордера типа SELL                                                                 |
//|  2 - ордера типа BUYLIMIT     3 - ордера типа SELLLIMIT                                                            |
//|  4 - ордера типа BUYSTOP      5 - ордера типа SELLSTOP                                                             |
//|  6 - ордера типа Balance     -1 - Все типы ордеров                                                                 |
//+--------------------------------------------------------------------------------------------------------------------+
int CountOrders(string symb="", int or_ty=-1) 
  {
   int cnt=0;
   if(symb=="0") symb=_Symbol;
   for(int pos=OrdersTotal()-1;pos>=0;pos--)
     {
      if(OrderSelect(pos,SELECT_BY_POS)==true)
        {
         if(OrderSymbol()==symb || symb=="")
           {
            if(or_ty<0 || or_ty==OrderType()) cnt++;
           }
        }
     }
   return(cnt);
  }
//+----------------------------------------------------------------------------+
//| Модификация ордера                                                         |
//+----------------------------------------------------------------------------+
//|    sl - ценовой уровень стопа                                              |
//|    tp - ценовой уровень тейка                                              |
//+----------------------------------------------------------------------------+
void ModifyOrder(string symb="", double sl=0, double tp=0)
  {
   if(symb=="0") symb=_Symbol;
   for(int pos=OrdersTotal()-1;pos>=0;pos--)
     {
      if(OrderSelect(pos,SELECT_BY_POS)==true)
        {
         if(OrderSymbol()==symb || symb=="")
           {
            if(OrderStopLoss()==0)
              {
               if(OrderType()==OP_BUY)
                 {
                  if(OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()-sl_price, OrderOpenPrice()+tp_price, OrderExpiration()))
                    {Print("Ордер модифицирован");}
                  else
                    {Print("Ошибка модификации ордера:", GetLastError());}
                 }
               if(OrderType()==OP_SELL)
                 {
                  if(OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()+sl_price, OrderOpenPrice()-tp_price, OrderExpiration()))
                    {Print("Ордер модифицирован");}
                  else
                    {Print("Ошибка модификации ордера:", GetLastError());}
                 }
              }
           }
        }
     }
  }
//+----------------------------------------------------------------------------+
//|  Возвращает пункты убытка последнего закрытого ордера в пунктах            |
//|  0 - последний ордер BUY                                                   |
//|  1 - последний ордер SELL                                                  |
//+----------------------------------------------------------------------------+
double GetPointLastLoss( int or_ty=-1)
  {
   datetime t=0;
   double result=0,p=0;
   int i=OrdersHistoryTotal();
   for(int pos=0; pos<i; pos++)
     {
      if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
        {
         if((OrderSymbol()==_Symbol))
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(t<OrderCloseTime())
                 {t=OrderCloseTime(); p=OrderProfit(); or_ty=OrderType();
                  if(or_ty==OP_BUY&&p<0)
                    {
                     result=OrderOpenPrice()-OrderClosePrice();
                    } else {result=0;}
                  if(or_ty==OP_SELL&&p<0)
                    {
                     result=OrderClosePrice()-OrderOpenPrice();
                    } else {result=0;}
                 }
              }
           }
        }
     }
   return(result);
  }
//+------------------------------------------------------------------+

在你的情况下,你根本不需要魔法

 
MakarFX:

这就对了。

在你的情况下,根本不需要魔法。

谢谢,将进行测试,并向您报告。我希望它的工作原理和我的一样,但在新的拍摄中增加一个停顿(如果它被触发)。

外部参数Input4; 5; 6需要做什么?

 
SGarnov:
谢谢你,我将测试并报告。我希望它的工作原理和我的一样,但在新的拍摄中增加一个停顿(如果它触发了)。

这里只有修改。不存在删除或撤销订单的情况。

如果你描述一下EA应该做什么,我将尝试提供帮助。

 
SGarnov:

外部参数Input4; 5; 6需要做什么?

我忘了删除
 
MakarFX:

如果你描述一下EA应该做什么,我将尝试提供帮助。

我下了一个买入挂单--EA正在工作--挂单触发--EA "看到 "这一点,并在这个未平仓订单上设置了止损。

止损(外部参数在设置中设定)。

获利(外部参数在设置中使用例如1到2的比例来设置)

在止损水平上的挂单卖出

可能出现的情况。

变体1。

A) 如果价格达到Takei - 专家顾问删除了止损和一个挂起的卖出订单。

变体2。

B) 如果止损被触发,EA "进入历史",那么。

一个卖出订单被打开,专家顾问重新定位这个订单。

止损(外部参数在设置中设定)

获利+从历史上触发的止损。

在止损价位上的 买入挂单。

价格达到拿下的时候--专家顾问会取消止损和买入挂单。

反之亦然,如果工作开始时有一个卖出挂单。

所以顾问工作直到它用外部参数止损号码停止工作(在我的例子中它是2,这意味着变量2将重复3次,顾问将在未来停止工作并将删除所有挂单,第一个止损不被考虑)。

如果takei没有达到,并且重复变体2,那么takei将增加2个止损,以此类推,这取决于设置的外部参数"止损计数"


我提出的代码,除了我所描述的问题(在历史上没有看到1站或2站,这应该是增加了的),它的工作原理是一样的。

像这样。

 
SGarnov:

我下了一个待定的买入订单--EA正在工作--待定订单被触发--EA "看到 "了这一点,并在这个未结订单上设置了止损。

止损(外部参数在设置中设定)。

获利(外部参数在设置中使用例如1到2的比例来设置)

在止损水平上的挂单卖出

可能出现的情况。

变体1。

A) 如果价格达到Takei - 专家顾问删除了止损和一个挂起的卖出订单。

变体2。

B) 如果止损被触发,EA "进入历史",那么。

一个卖出订单被打开,专家顾问重新定位这个订单。

止损(外部参数在设置中设置)

获利+从历史上触发的止损。

在止损价位上的 买入挂单。

价格达到拿下的时候--专家顾问会取消止损和买入挂单。

反之亦然,如果工作开始时有一个卖出挂单。

所以顾问工作直到它用外部参数止损号码停止工作(在我的例子中它是2,这意味着变量2将重复3次,顾问将在未来停止工作并将删除所有挂单,第一个止损不被考虑)。

如果takei没有达到,并且重复变体2,那么takei将增加2个止损,以此类推,这取决于设置的外部参数"止损计数"


我提出的代码,除了我所描述的问题(在历史上没有看到1站或2站,这应该是增加了的),它的工作原理是一样的。

它是这样的。

"止损次数"--是连续的还是当天的?

 
MakarFX:

"止损次数"--是连续的还是当天的?

在一个货币对上连续停顿的数量。

为了分析历史,专家顾问最初用他们的ID标记订单,但没有在历史中找到他们,我以为OrderMagikNumber()会搜索到他们。也许是因为在不同货币对的历史停止中,EA停止 "看到 "它们?

再把消息来源放上来?他需要做的是纠正 "从历史中搜索止损交易,并使其加入到新投放的交易中"。