Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 1324

 
Alexey Viktorov:

Вчера скачал это чудо для посмотреть… И вдруг лишили меня тырнета. После грозы технические работы до конца дня. Вот и решил я от безделья переписать это чудо на MQL5, опубликован тут.

Получается нет худа без добра………

я тут в Ваш эксперт добавил Индикатор - думаю Вы будете не против!? вроде получилось как хотел  Sprut 185 

(жёлтым что добавил в существующий эксперт  тут. ) 

//+------------------------------------------------------------------+
//|                                                 2 DVA_Martin.mq5 |
//|                                          © 2021, Alexey Viktorov |
//|                     https://www.mql5.com/ru/users/alexeyvik/news |
//+------------------------------------------------------------------+
#property copyright "© 2021, Alexey Viktorov"
#property link      "https://www.mql5.com/ru/users/alexeyvik/news"
#property version   "2.00"
//---
#include <Trade\Trade.mqh>
CTrade trade;
//---
input int     TakeProfit1         = 300;  // профит первой позиции
input int     TakeProfit2         = 250;  // профит второй позиции
input int     TakeProfit3         = 200;  // профит третьей позиции
input int     TakeProfit4         = 100;  // профит четвертой и следующих позиций
input int     Step                = 200;  // шаг первой позиции
input int     Delta               = 100;  // добавка к шагу
// со второй позиции увеличивает расстояние последующих позиций на величину "дельта" от предыдущего
input double  Lot                 = 0.03; // первый лот открытия
input double  MaximalLot          = 0.5;  // максимальный лот, который мы разрешаем
input int     MaxTrades           = 9;    // максимальное количество позиций одного направления
input double  MultiplicatorLot    = 1.6;  // умножаем последующие позиции
input int     Magic               = 123;  // идентификатор советника
//--- Пременные для хранения собранной информации
double MaxLot  = 0;
double LotBuy  = 0;
double LotSell = 0;
//---
int m_bar_current=0;
int StepMA_NRTR_Handle;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   trade.SetExpertMagicNumber(Magic);
   MaxLot = contractSize(MaximalLot);
//--- create StepMA_NRTR indicator
   StepMA_NRTR_Handle=iCustom(NULL,0,"StepMA_NRTR");
   if(StepMA_NRTR_Handle==INVALID_HANDLE)
     {
      printf("Error creating StepMA_NRTR indicator");
      return(false);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   Comment("");
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double StepMA_NRTR[],StepMA_NRTRS[];
   ArraySetAsSeries(StepMA_NRTR,true);
   ArraySetAsSeries(StepMA_NRTRS,true);
   int start_pos=1,count=3;
   if(!iGetArray(StepMA_NRTR_Handle,0,start_pos,count,StepMA_NRTR)||
      !iGetArray(StepMA_NRTR_Handle,1,start_pos,count,StepMA_NRTRS))
     {
      return;
     }
//---
   int posTotal = PositionsTotal();
   double BuyMinPrice = DBL_MAX, //  Минимальная цена Buy позиции
          SelMaxPrice = DBL_MIN, //  Максимальная цена Sell позиции
          BuyMinLot = 0,         //  Лот самой нижней Buy позиции
          SelMaxLot = 0,         //  Лое самой верхней Sell позиции
          posPrice = 0.0,
          posLot = 0.0,
          BuyAwerage = 0,
          SelAwerage = 0,
          BuyPrice = 0,
          SelPrice = 0,
          BuyLot = 0,
          SelLot = 0;
   MqlTick tick;
   if(!SymbolInfoTick(_Symbol, tick))
      return;
   int b = 0,
       s = 0;
   for(int i = 0; i < posTotal; i++)
     {
      ulong posTicket = PositionGetTicket(i);
      if(PositionGetString(POSITION_SYMBOL) == _Symbol && PositionGetInteger(POSITION_MAGIC) == Magic)
        {
         posPrice = PositionGetDouble(POSITION_PRICE_OPEN);
         posLot = PositionGetDouble(POSITION_VOLUME);
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
           {
            b++; // Считаем открытые позиции на покупку
            if(posPrice < BuyMinPrice)
              {
               BuyMinPrice = posPrice;
               BuyMinLot = posLot;
               BuyPrice += posPrice*posLot;  // добавить к переменной BuyPrice Цена оредра 1 * лот ордера 1
               BuyLot += posLot;             // суммируем лоты
              }
           }
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
           {
            s++; // Считаем открытые позиции на продажу
            if(posPrice > SelMaxPrice)
              {
               SelMaxPrice = posPrice;
               SelMaxLot = posLot;
               SelPrice += posPrice*posLot;  // добавить к переменной BuyPrice Цена оредра 1 * лот ордера 1
               SelLot += posLot;             // суммируем лоты
              }
           }
        }
     }
   LotBuy = b == 0 ? contractSize(Lot) : fmin(MaxLot, contractSize(BuyMinLot*MultiplicatorLot));
   LotSell = s == 0 ? contractSize(Lot) : fmin(MaxLot, contractSize(SelMaxLot*MultiplicatorLot));
//---
//--- BUY Signal
   if(StepMA_NRTR[m_bar_current]<StepMA_NRTRS[m_bar_current])
     {
      if(b == 0 || (b < MaxTrades && BuyMinPrice-tick.ask >= (Step+Delta*b)*_Point))
         openPos(ORDER_TYPE_BUY, LotBuy, tick.ask);
     }
//--- SELL Signal
   if(StepMA_NRTR[m_bar_current]>StepMA_NRTRS[m_bar_current])
     {
      if(s == 0 || (s < MaxTrades && tick.bid-SelMaxPrice >= (Step+Delta*s)*_Point))
         openPos(ORDER_TYPE_SELL, LotSell, tick.bid);
     }
//--- посчитаем математические формулы средних цен
   switch(b)
     {
      case 0 :
         return;
      case 1 :
         BuyAwerage = BuyPrice/BuyLot+TakeProfit1*_Point;
         break;
      case 2 :
         BuyAwerage = BuyPrice/BuyLot+TakeProfit1*_Point;
         break;
      case 3 :
         BuyAwerage = BuyPrice/BuyLot+TakeProfit3*_Point;
         break;
      default:
         BuyAwerage = BuyPrice/BuyLot+TakeProfit4*_Point;
         break;
     }
   switch(s)
     {
      case 0 :
         return;
      case 1 :
         SelAwerage = SelPrice/SelLot-TakeProfit1*_Point;
         break;
      case 2 :
         SelAwerage = SelPrice/SelLot-TakeProfit2*_Point;
         break;
      case 3 :
         SelAwerage = SelPrice/SelLot-TakeProfit3*_Point;
         break;
      default:
         SelAwerage = SelPrice/SelLot-TakeProfit4*_Point;
         break;
     }
   normalizePrice(BuyAwerage); // Произведем расчет цены TP Buy
   normalizePrice(SelAwerage); // Произведем расчет цены TP Sell
//---
   for(int i = 0; i < posTotal; i++)
     {
      ulong posTicket = PositionGetTicket(i);
      if(PositionGetString(POSITION_SYMBOL) == _Symbol && PositionGetInteger(POSITION_MAGIC) == Magic)
        {
         double posTP = PositionGetDouble(POSITION_TP);
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
           {
            if(fabs(posTP-BuyAwerage) > _Point && tick.ask < BuyAwerage) // Если тейк не равен требуемой цене
               if(!trade.PositionModify(posTicket, 0.0, BuyAwerage))
                  Print("Ошибка ", __LINE__);
           }
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
           {
            if(fabs(posTP-SelAwerage) > _Point && tick.bid > SelAwerage) // Если тейк не равен требуемой цене
               if(!trade.PositionModify(posTicket, 0.0, SelAwerage))
                  Print("Ошибка ", __LINE__);
           }
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void openPos(ENUM_ORDER_TYPE type, double lot, double price)
  {
   trade.CheckVolume(_Symbol, lot, price, type);
   if(trade.CheckResultMarginFree() <= 0.0)
     {
      Print("Not enough money for ", EnumToString(type), " ", lot, " ", _Symbol, " Error code=", trade.CheckResultRetcode());
      return;
     }
   if(!trade.PositionOpen(_Symbol, type, LotBuy, price, 0.0, 0.0))
      Print(trade.ResultRetcode());
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double contractSize(double volume, string symbol = NULL)
  {
   symbol = symbol == NULL ? _Symbol : symbol;
   double v = volume;
   double volumeStep = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   v = round(volume/volumeStep)*volumeStep;
   double minLot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
   return((v < minLot ? minLot : v));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double normalizePrice(double &price, string symbol = NULL)
  {
   symbol = symbol == NULL ? _Symbol : symbol;
   double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
   price = round(price/tickSize)*tickSize;
   return(tickSize);
  }
//+------------------------------------------------------------------+
//| Filling the indicator buffers from the indicator                 |
//+------------------------------------------------------------------+
bool iGetArray(const int handle,const int buffer,const int start_pos,
               const int count,double &arr_buffer[])
  {
   bool result=true;
   if(!ArrayIsDynamic(arr_buffer))
     {
      return(false);
     }
   ArrayFree(arr_buffer);
//--- reset error code
   ResetLastError();
//--- fill a part of the iBands array with values from the indicator buffer
   int copied=CopyBuffer(handle,buffer,start_pos,count,arr_buffer);
   if(copied!=count)
     {
      return(false);
     }
   return(result);
  }
//+------------------------------------------------------------------+

Советники: DVA_Martin
Советники: DVA_Martin
  • 2021.06.30
  • www.mql5.com
Статьи и техническая библиотека по автоматическому трейдингу: Советники: DVA_Martin
 
SanAlex:

я тут в Ваш эксперт добавил Индикатор - думаю Вы будете не против!? вроде получилось как хотел  Sprut 185 

(жёлтым что добавил в существующий эксперт  тут. ) 

А зачем значения индикаторов с трёх баров? И зачем переворачивать массив в таймсерию?

А вообще, получилось, как мне кажется, не то… Никакой мартин работать не будет.

 
Alexey Viktorov:

А зачем значения индикаторов с трёх баров? И зачем переворачивать массив в таймсерию?

А вообще, получилось, как мне кажется, не то… Никакой мартин работать не будет.

Индикатор здесь просто как фильтр направления - а всю задачу выполняет Ваш эксперт 

\\\\\\\\\\\\\

сам индикатор не открывает позиции.

 
SanAlex:

Индикатор здесь просто как фильтр направления - а всю задачу выполняет Ваш эксперт 

Задачу должен выполнять написанный код. Но вы поставили такое условие, что мартин никогда не включится. Мне так кажется, но проверять у меня нет ни желания, ни времени.

 
Alexey Viktorov:

Задачу должен выполнять написанный код. Но вы поставили такое условие, что мартин никогда не включится. Мне так кажется, но проверять у меня нет ни желания, ни времени.

вот я проверяю его работу - всё работает по задумке.

2 DVA_Martin

 
Alexey Viktorov:

Мартин должен включаться только при противоположном сигнале индикатора или не зависимо от этого?

Пример: Открыта позиция Buy в соответствии с индикатором. Цена опустилась на заданное расстояние, и индикатор уже показывает Sell. Позиции Buy должны открываться?

Как и обещал - что то на фотошопил.

1

Если и так не будет понятно, то только при личном общении смогу разъяснить смысл моей задумки

 
SanAlex:

что то я тут намудрил - что сам не пойму со 100000 руб. до двух миллионов настрогало 

поменял Индикатор и на 5мин. евро\бакс за 15 дней до миллиона.

LeMan_BrainTrend1Sig 2

LeMan_BrainTrend1Sig

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

в эксперт добавил - по общей прибыли (со всех пар) закрывать прибыль и удалить эксперта

input group  "---- : Parameters:  ----"
input int    TargetProfit     = 1000000; // : Balance + Profit(add to balance)
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(void)
  {
//---
   if(AccountInfoDouble(ACCOUNT_EQUITY)>=TargetProfit)
     {
      AllClose();
      ExpertRemove();
     }
//---

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

нужно что бы эти 2 индикатора присутствовали ( имена индикаторов что бы не менялись) 

 
SanAlex:

поменял Индикатор и на 5мин. евро\бакс за 15 дней до миллиона.

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

в эксперт добавил - по общей прибыли (со всех пар) закрывать прибыль и удалить эксперта

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

нужно что бы эти 2 индикатора присутствовали ( имена индикаторов что бы не менялись) 

Не хватает стоплосса в настройке

 

Есть способы разбития строки на строки методом типа \n".

а есть способы уже разбитую по строкам строковую переменную, склеить/преобразовать в одну строку?

То есть чтобы все тексты значения параметры и т.п. имеющееся в этой строкой(string) переменной записались в одну строку.

Проблема возникла при записи в csv(значения строковой переменной записывается в кучу строк).

 
Vitaly Muzichenko:

Не хватает стоплосса в настройке

c Stop Loss уже нет той прибыли 

Stop Loss

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

думаю просто нужно чаще перезапускать эксперта - например взяла прибыль общую(со всех пар) за неделю и удалился эксперт со всех пар.

и по новой запускаем эксперта, до новой общей прибыли со всех пар. 

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

появилась ещё мысль по стопу - стоп не закрывать позиции а открыть противоположную позицию с лотом противоположных(убыточных) открытых позиции 

вот тут есть счёт открытых позиции в лотах 

   int total=PositionsTotal();
   for(int i=total-1; i>=0; i--) // returns the number of open positions
     {
      string   position_GetSymbol=PositionGetSymbol(i); // GetSymbol позиции
      if(position_GetSymbol==m_symbol.Name())
        {
         if(m_position.PositionType()==POSITION_TYPE_BUY)
           {
            PROFIT_BUY=PROFIT_BUY+PositionGetDouble(POSITION_PROFIT);
            PROFIT_BUY_Lot=PROFIT_BUY_Lot+PositionGetDouble(POSITION_VOLUME);
           }
         else
           {
            PROFIT_SELL=PROFIT_SELL+PositionGetDouble(POSITION_PROFIT);
            PROFIT_SELL_Lot=PROFIT_SELL_Lot+PositionGetDouble(POSITION_VOLUME);
           }
           {
            PROFIT_CLOSE=AccountInfoDouble(ACCOUNT_PROFIT);
           }
        }
     }
//---

Stop Loss 777

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

получается полная ерунда . короче руками нужно открывать а всё остальное должно помогать ручной торговле.

Причина обращения: