Группа "Стол заказов MQL"

Рейтинг 2114



РЕКОМЕНДУЮ



Прошу реализовать советник "Импульс"

Добрый день! Нужна помощь в реализации автоматического торгового алгоритма. Суть простая, вход в предполагаемый импульс, отработка, выход. Хотелось бы посмотреть, какой процент прибыльных сделок будет давать индикатор Trend direction and force — JMA smoothed на дистанции.
Пример настроек:
— Торговое время(ч), начало торговли советником и конец торговли советником
— Настройки индикатора
— Объем в первой сделке
— Режим мартингейл после убыточной сделки, через коэффициент. Если устанавливается «1» то активный,
если устанавливается «0» то не активный
— Стоп лосс
— Тейк профит
— Б/У, при достижении указанного значения(плюс тик в сторону профита), стоп переводится в безубыток учитывая спред
— Спред
— Проскальзывание

Индикатор: Trend direction and force — JMA smoothed.mq5 (0 Kb)

  • +1
  • Просмотров: 1849
  • 27 мая 2024, 14:01
  • ZERNO
Понравилcя материал? Не забудьте поставить плюс и поделиться в социальной сети!

Вступите в группу "Стол заказов MQL", чтобы следить за обновлениями
ПРИСОЕДИНИТЬСЯ К ГРУППЕ
присоединиться
  Предыдущая запись в группе
почему меня игнорят?
25 мая 2024
27 мая 2024

Комментарии (22)

+
0


Инд. не загружен...!
avatar

  18  Marik007 Сообщений: 409 - Forexman

  • 27 мая 2024, 19:28
+
0
Оставляю ссылку на индикатор:

www.mql5.com/ru/code/21871


Редактирован: 27 мая 2024, 20:22
avatar

  4  ZERNO Автор Сообщений: 45 - ZERNO

  • 27 мая 2024, 20:20
+
+1
посмотрю завтра
avatar

  34  AM2 Сообщений: 15964 - Андрей

  • 27 мая 2024, 21:08
+
0
Я бы добавил:
Красная линия — сел до серой.
Перелом красной вверх — бай до перелома линии вниз.
Перелом зеленой вниз — сел до перелома вверх.

Перелом — это не обязательно рост вверх, а на следующей свече падение вниз.
Можно использовать замедление роста-падения с заданным процентом замедления.
Редактирован: 27 мая 2024, 21:25
avatar

  7  kvashnin007 Сообщений: 598 - Андрей

  • 27 мая 2024, 21:24
+
0
Это все потом можно сделать, уже данные идеи рассматривалась по плану. Сейчас нужно для начала реализовать прототип, для понимания какой будет винрейт на базовом функционале. А там уже можно допиливать различные варианты открытия, сопровождения, закрытия сделок. Так же не хочется грузить большим объемом работы программиста, и так очередь не малая в столе заказов.
Редактирован: 28 мая 2024, 09:59
avatar

  4  ZERNO Автор Сообщений: 45 - ZERNO

  • 27 мая 2024, 22:12
+
0
По вопросу добавок.

Здесь сЦуть в чем?

Кэшируем основную сделку. Т.е. не зарабатываем, но и не теряем. Спред и комиссию при TF М15 и выше можем считать досадным недоразумением. Индикатор (цена) вновь развернулся в направление основной сделки. фиксируем профит от доп. сделки, а основная как-бы продолжает движение вниз, только с более лучшей цены. Мы ничего не теряем. Даже, если доп. профит будет минусовой, он компенсируется профитом основной сделки.

Кроме того, таким же образом можно поступать в «серой зоне».
При переходе индикатора в серую зону, просто кэшируем основную сделку.
А при выходе из этой зоны, просто закрываем противоположную. Она то даст прибыль. В противном случае просто съест накопленную прибыль. Т.е. убыток.

Можно побаловать с периодами. Интересные варианты получаются. Например TrendPeriod=2.
Можно взять тот же индюк, но Forse.
Два индюка на разных TF.

Понимаю. Все это потом. Просто мысли сейчас. И их надо записать.
Склероз, понимаешь ли.
avatar

  7  kvashnin007 Сообщений: 598 - Андрей

  • 28 мая 2024, 10:18
+
+1
Интересно.
avatar

  17  Boris54 Сообщений: 787 - ПенSионер

  • 28 мая 2024, 02:17
+
0
Два облегченных TrendDirection. А как интересно.



Сами индюки по ссылке: www.opentraders.ru/downloads/3848/
avatar

  7  kvashnin007 Сообщений: 598 - Андрей

  • 28 мая 2024, 10:44
+
0
*za* 
avatar

  17  Boris54 Сообщений: 787 - ПенSионер

  • 28 мая 2024, 11:13
+
0
Два облегченных TrendDirection. А как интересно.



www.opentraders.ru/downloads/3848/
Редактирован: 28 мая 2024, 10:47
avatar

  7  kvashnin007 Сообщений: 598 - Андрей

  • 28 мая 2024, 10:47
+
+1
На МТ4 не интересуют в данном случае индюки, считаю приоритетом МТ5 для алготрейдинга. Если конкретно такой вариант индикатора как я вначале скинул есть на МТ5, то делитесь, буду благодарен. Лучше в личку скидывайте, обязательно гляну.
А так если кому интересно то на 4ку этого типа индюков море, читайте, выбирайте, облегчайте, крутите, применяйте на свое усмотрение. Ссылка: forex-station.com/trend-direction-force-index-indicators-mt4-t8438707.html
Ребята, в целом спасибо за участие, но дайте получить для начала базовый вариант советника. Ситуация похожа на деление шкуры неубитого медведя. Плюс я как автор идеи начинаю уходить в сторону от своей концепции, сторонние советы порою бывают лишними. Я без негатива, просто если кому то не в терпеж и имеются свои дополнения, делайте новый пост на данную тему и творите на свой вкус советник. Всё что выше предложено в добавку к посту, имеет естественно место быть, но это уже и так в моих планах прокручивалось. Потом всё прикинем, не суетитесь раньше времени.
Всем добра!
avatar

  4  ZERNO Автор Сообщений: 45 - ZERNO

  • 28 мая 2024, 11:49
+
+1
avatar

  34  AM2 Сообщений: 15964 - Андрей

  • 28 мая 2024, 17:11
+
0
Приветствую! При много благодарен сходу за работу! Пару вопросов есть по настройкам параметров. То что сразу усреднение добавлено это хорошо, но параметр не понятен, на скрине отметил. Далее еще три параметра не могу понять для чего, что делают или фильтруют, в ТЗ не прописывал про это, то же скрин прилагаю.





avatar

  4  ZERNO Автор Сообщений: 45 - ZERNO

  • 28 мая 2024, 17:36
+
0
Андрей еще принципиальный момент, я в ТЗ спред и проскальзывание отмечал, в текущей версии советника их не видно. Я понимаю что на МТ5 спред типа автоматом берется, но я для надежности хотел бы его чуток добавлять еще от себя. Проскальзывание то же считаю должно быть по идее, рынок в тесторе послушным и правильным может быть а на реале чудить будет. Стараюсь сразу все погрешности сводить к нулю.
Редактирован: 28 мая 2024, 18:12
avatar

  4  ZERNO Автор Сообщений: 45 - ZERNO

  • 28 мая 2024, 17:49
+
+1
поправил добавил: www.opentraders.ru/downloads/3849/


input double Lots     = 0.1; // торговый объем
input double MaxLot   = 5;   // максимальный торговый объем
input double KLot     = 1.5; // увеличение лота

input int StopLoss   = 5555; // стоп
input int TakeProfit = 111;  // тейк
input int Count      = 20;   // число поз
input int Step       = 333;  // шаг

input int StartHour  = 0;    // час начала торговли
input int StartMin   = 30;   // минута начала торговли
input int EndHour    = 23;   // час окончания торговли
input int EndMin     = 30;   // минута окончания торговли

input ulong Magic    = 123;  // магик
input int Spread     = 33;   // спред
input int Slip       = 22;   // проскальзывание

input bool Buy       = 1;    // покупки
input bool Sell      = 1;    // продажи

input string Comm    = "Scalp";

input string IndName = "Trend direction and force - JMA smoothed";

input int       trendPeriod  = 20;      // Trend period
input int       smoothPeriod = 3;       // Smoothing period
input double    TriggerUp    =  0.1;    // Trigger up level
input double    TriggerDown  = -0.1;    // Trigger down level


avatar

  34  AM2 Сообщений: 15964 - Андрей

  • 29 мая 2024, 09:40
+
0
Добрый день! Отлично, большое спасибо! Теперь можно тестировать прототип более детально. Далее будет видно что допилить или убрать в логике работы алгоритма. Скорее всего это будет сопровождение и закрытие сделок. Так же интересен вариант с тралом, т.к. стратегия все таки изначально заточена под импульс/краткосрочный тренд. В принципе сейчас советник на базе одного индикатора, но скорее всего будет интересен для добавки индикатор волатильности, при ее низких значения советник отдыхает.
Ладно ребята, всем успехов!

Редактирован: 29 мая 2024, 11:49
avatar

  4  ZERNO Автор Сообщений: 45 - ZERNO

  • 29 мая 2024, 10:36
+
+1
Расчет общего безубытка в функции All () в корне не верен.
Он истинен только для ордеров одного направления. Если советник просто перевёртыш, функция будет работать корректно. Опять же, безубыток будет равен цене открытия ордера и расчет не нужен. Правда, без учета поборов брокера.
Предлагаю универсальную функцию на все случаи жизни. Еще не известно куда нас приведут наши доработки.
Кроме того, такой вариант практически на 100% (косвенно) учитывает поборы брокера, если есть разнонаправленные ордера.
Сюда же можно добавить расчет БУ отдельно для ордеров Buy, отдельно для Sell.
Легко. Добавив две переменные.


//+------------------------------------------------------------------+      // Это мой первый код на mql5.
//|     Общий Безубыток должен выглядеть так                         |      //  Требует проверки !!!!!!!!!
//+------------------------------------------------------------------+      // Надеюсь получилось. 
double All()
{
      double AllBU=0;
      double BuyLotsSum=0,SelLotsSum=0;
      double WeighBuy=0,WeighSel=0;
   
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(PositionSelectByTicket(PositionGetTicket(i)))
            if(PositionGetString(POSITION_SYMBOL)==_Symbol)
               if(PositionGetInteger(POSITION_MAGIC)==Magic)               
                  {
                  if(PositionGetInteger(POSITION_TYPE)==0)
                     {
                     WeighBuy   += PositionGetDouble(POSITION_PRICE_OPEN)*PositionGetDouble(POSITION_VOLUME);
                     BuyLotsSum += PositionGetDouble(POSITION_VOLUME);
                     }
                  if(PositionGetInteger(POSITION_TYPE)==1)
                     {
                     WeighSel   += PositionGetDouble(POSITION_PRICE_OPEN)*PositionGetDouble(POSITION_VOLUME);
                     SelLotsSum += PositionGetDouble(POSITION_VOLUME);
                     }
                  }
      if(BuyLotsSum-SelLotsSum!=0)
         AllBU=(WeighBuy-WeighSel)/(BuyLotsSum-SelLotsSum);
   return(NormalizeDouble(AllBU,_Digits));
}
//+------------------------------------------------------------------+


Просто поменяйте функции и будет вам счастье. Надеюсь.

Всем удачи.
avatar

  7  kvashnin007 Сообщений: 598 - Андрей

  • 30 мая 2024, 20:53
+
0
Стряпал когда-то индюка для ловли импульса. Правда на МТ4. Посмотри. Может подойдет. На текущей свече может путать в показаниях (впрочем как и любой индюк). Но не перерисовывает закрытые свечи. А путание в показаниях идет (шло) на пользу. Стратегия была рассчитана на откат цены. Т.е. на истории не все Arrows остались. На текущей свече появился сигнал, открыли сделку, цена откатила — сигнал исчез. Работать по закрытым свечам не интересно.

<code>
//+------------------------------------------------------------------+
//|                                                   KAE Impuls.mq4 |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""

#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 clrCoral
#property indicator_color2 clrCornflowerBlue
#property indicator_color3 Red
#property indicator_color4 Blue

extern int                Per_ATR  = 3;
extern int                Per_MA   = 3;
extern ENUM_MA_METHOD     Ma_Type  = MODE_SMMA;
extern ENUM_APPLIED_PRICE PRICE    = PRICE_CLOSE;
extern double             Level_Up = 16.7;
extern double             Level_Dn = 16.7;
//---
extern bool   alertsOn        = false;
extern bool   alertsOnCurrent = true;
extern bool   alertsMessage   = true;
extern bool   alertsSound     = false;
extern bool   alertsEmail     = false;
//---
double AboveBuff[];
double ShortBuff[];
double LongBuffe[];
double BelowBuff[];

// ---
int init() {
   SetIndexBuffer(0, AboveBuff); SetIndexStyle(0, DRAW_HISTOGRAM, EMPTY, 3);                          
   SetIndexBuffer(1, BelowBuff); SetIndexStyle(1, DRAW_HISTOGRAM, EMPTY, 3);                          
   SetIndexBuffer(2, ShortBuff); SetIndexStyle(2, DRAW_ARROW, EMPTY, 1);       SetIndexArrow(2, 108);
   SetIndexBuffer(3, LongBuffe); SetIndexStyle(3, DRAW_ARROW, EMPTY, 1);       SetIndexArrow(3, 108); 
   
   SetIndexLabel(0, "Вверх");
   SetIndexLabel(1, "Вниз");   
   SetIndexLabel(2, NULL);  
   SetIndexLabel(3, NULL);  
   
   SetLevelStyle(STYLE_DOT, 0, SteelBlue);

   IndicatorShortName(" KAE Impuls ");
   return (0);
}
// ---
void deinit() {
   Comment("");
}
// ---
void start()
{
   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return;
      if(counted_bars>0) counted_bars--;
           int limit=MathMin(Bars-counted_bars,Bars-1);
      
      for (int i = limit; i >=0; i--) 
        {
        double Main =iMA(NULL,0,Per_MA,0,Ma_Type,PRICE,i);//  !!! +1
        double Minr = 0.2 * iATR(NULL,PERIOD_CURRENT,Per_ATR,i);
         
        if (Minr!=0)
          {
          AboveBuff[i] = 3.0 * (High[i]  - Main) / Minr;
          BelowBuff[i] = 3.0 * (Low[i]   - Main) / Minr;
          }
        
        if(AboveBuff[i] + BelowBuff[i]>=0)
          {
          AboveBuff[i] = AboveBuff[i] + BelowBuff[i];
          BelowBuff[i] = 0;
          }
        if(AboveBuff[i] + BelowBuff[i]<0)
          {
          BelowBuff[i] = AboveBuff[i] + BelowBuff[i];
          AboveBuff[i] = 0;
          }
                       
        ShortBuff[i] = EMPTY_VALUE;
        LongBuffe[i] = EMPTY_VALUE;
        
        if (AboveBuff[i] >  Level_Up && Close[i] > Open[i]) 
          ShortBuff[i] =  Level_Up;
          
        if (BelowBuff[i] < -Level_Dn && Close[i] < Open[i]) 
          LongBuffe[i] = -(Level_Dn);
        }
   manageAlerts();
   return;
}
//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------
void manageAlerts()
{
    if (alertsOn)
      {
      if (alertsOnCurrent)
           int whichBar = 0;
      else     whichBar = 1;
      
      if (ShortBuff[whichBar] != EMPTY_VALUE || LongBuffe[whichBar] != EMPTY_VALUE)
        {
        if (ShortBuff[whichBar] !=  EMPTY_VALUE) doAlert(whichBar,"down");
        if (LongBuffe[whichBar] !=  EMPTY_VALUE) doAlert(whichBar,"up");
        }
      }
}
// ---
void doAlert(int forBar, string doWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;
   
   if (previousAlert != doWhat || previousTime != Time[forBar]) 
     {
     previousAlert  = doWhat;
     previousTime   = Time[forBar];

     message =  StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," SimilarFxMNT signal ",doWhat);
       if (alertsMessage) 
         Alert(message);
       if (alertsEmail)   
         SendMail
           (StringConcatenate(Symbol()," SimilarFxMNT "),message);
       if (alertsSound)   
         PlaySound("alert2.wav");
     }
}
// ------------------------------------------------------------------------------------------------------------------

</code>




Если проявится интерес, можно будет просить Андрея перевести на mql5.
Редактирован: 30 мая 2024, 21:16
avatar

  7  kvashnin007 Сообщений: 598 - Андрей

  • 30 мая 2024, 21:10
+
0
Погонял в тестере.

Кажется, не тот вариант дал. Давно это было.

Попробуй этот:

<code>
//+------------------------------------------------------------------+
//|                                               KAE Impuls v.2.mq4 |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""

#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 clrCoral
#property indicator_color2 clrCornflowerBlue
#property indicator_color3 Red
#property indicator_color4 Blue

extern int                Per_ATR  = 9;
extern int                Per_MA   = 5;
extern ENUM_MA_METHOD     Ma_Type  = MODE_SMMA;
extern ENUM_APPLIED_PRICE PRICE    = PRICE_CLOSE;
extern double             Level_Up = 16.7;
extern double             Level_Dn = 16.7;
//---
extern bool   alertsOn        = false;
extern bool   alertsOnCurrent = true;
extern bool   alertsMessage   = true;
extern bool   alertsSound     = false;
extern bool   alertsEmail     = false;
//---
double AboveBuff[];
double ShortBuff[];
double LongBuffe[];
double BelowBuff[];

// ---
int init() {
   SetIndexBuffer(0, AboveBuff); SetIndexStyle(0, DRAW_HISTOGRAM, EMPTY, 3);                          
   SetIndexBuffer(1, BelowBuff); SetIndexStyle(1, DRAW_HISTOGRAM, EMPTY, 3);                          
   SetIndexBuffer(2, ShortBuff); SetIndexStyle(2, DRAW_ARROW, EMPTY, 1);       SetIndexArrow(2, 108);
   SetIndexBuffer(3, LongBuffe); SetIndexStyle(3, DRAW_ARROW, EMPTY, 1);       SetIndexArrow(3, 108); 
   
   SetIndexLabel(0, "Вверх");
   SetIndexLabel(1, "Вниз");   
   SetIndexLabel(2, NULL);  
   SetIndexLabel(3, NULL);  
   
   SetLevelStyle(STYLE_DOT, 0, SteelBlue);

   IndicatorShortName(" KAE Impuls v.2 ");
   return (0);
}
// ---
void deinit() {
   Comment("");
}
// ---
void start()
{
   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return;
      if(counted_bars>0) counted_bars--;
           int limit=MathMin(Bars-counted_bars,Bars-1);
      
      for (int i = limit; i >=0; i--) 
        {
        double Main =iMA(NULL,0,Per_MA,0,Ma_Type,PRICE,i);//  !!! +1
        double Minr = 0.2 * iATR(NULL,PERIOD_CURRENT,Per_ATR,i);
         
        if (Minr!=0)
          {
          AboveBuff[i] = 3.0 * (High[i]  - Main) / Minr;
          BelowBuff[i] = 3.0 * (Low[i]   - Main) / Minr;
          }
        
        if(AboveBuff[i] + BelowBuff[i]>=0)
          {
          AboveBuff[i] = AboveBuff[i] - BelowBuff[i];
          BelowBuff[i] = 0;
          }
        if(AboveBuff[i] + BelowBuff[i]<0)
          {
          BelowBuff[i] = -AboveBuff[i] + BelowBuff[i];
          AboveBuff[i] = 0;
          }
                       
        ShortBuff[i] = EMPTY_VALUE;
        LongBuffe[i] = EMPTY_VALUE;
        
        if (AboveBuff[i] >  Level_Up && Close[i] > Open[i]) 
          ShortBuff[i] =  Level_Up;
          
        if (BelowBuff[i] < -Level_Dn && Close[i] < Open[i]) 
          LongBuffe[i] = -(Level_Dn);
        }
   manageAlerts();
   return;
}
//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------
void manageAlerts()
{
    if (alertsOn)
      {
      if (alertsOnCurrent)
           int whichBar = 0;
      else     whichBar = 1;
      
      if (ShortBuff[whichBar] != EMPTY_VALUE || LongBuffe[whichBar] != EMPTY_VALUE)
        {
        if (ShortBuff[whichBar] !=  EMPTY_VALUE) doAlert(whichBar,"down");
        if (LongBuffe[whichBar] !=  EMPTY_VALUE) doAlert(whichBar,"up");
        }
      }
}
// ---
void doAlert(int forBar, string doWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;
   
   if (previousAlert != doWhat || previousTime != Time[forBar]) 
     {
     previousAlert  = doWhat;
     previousTime   = Time[forBar];

     message =  StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," IMPULS signal ",doWhat);
       if (alertsMessage) 
         Alert(message);
       if (alertsEmail)   
         SendMail
           (StringConcatenate(Symbol()," IMPULS "),message);
       if (alertsSound)   
         PlaySound("alert2.wav");
     }
}
// ------------------------------------------------------------------------------------------------------------------

</code>



Редактирован: 30 мая 2024, 21:35
avatar

  7  kvashnin007 Сообщений: 598 - Андрей

  • 30 мая 2024, 21:33
+
0
Пересмотрел код советника. Есть куча замечаний. Возможно не правильных.
Замечания сделал в виде комментариев в коде. Так удобнее править-отвечать.
Сигнальный блок надо сильно дорабатывать.
С наскока не вышло. Сказывается незнание mql5.

Посмотрите, кто попродвинутее. Или к Андрею может пробиться.

Даю код с замечаниями. В один файл не поместился. Два склеить, думаю, проблем не составит.


//+------------------------------------------------------------------+
//|                                               TrendDirection.mq5 |
//|                                             Copyright 2024, AM2. |
//|                                      http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, AM2."
#property link      "http://www.forexsystems.biz"
#property version   "1.00"

#include <Trade\Trade.mqh>
CTrade trade;

input double    Lots        = 0.1;      // торговый объем
input double    MaxLot      = 5;        // максимальный торговый объем
input double    KLot        = 1.5;      // увеличение лота
input int       StopLoss    = 5555;     // стоп
input int       TakeProfit  = 111;      // тейк
input int       Count       = 20;       // число поз
input int       Step        = 333;      // шаг
input int       StartHour   = 0;        // час начала торговли
input int       StartMin    = 30;       // минута начала торговли
input int       EndHour     = 23;       // час окончания торговли
input int       EndMin      = 30;       // минута окончания торговли
input ulong     Magic        = 1961;    // магик
input int       Spread       = 33;      // спред
input int       Slip         = 22;      // проскальзывание
input bool      Buy          = 1;       // покупки
input bool      Sell         = 1;       // продажи
input string    Comm         = "Scalp";
input string    IndName      = "Trend direction and force - JMA smoothed";
input int       trendPeriod  = 20;      // Trend period
input int       smoothPeriod = 3;       // Smoothing period
input double    TriggerUp    =  0.1;    // Trigger up level
input double    TriggerDown  = -0.1;    // Trigger down level
//---
datetime t=0;
int td=0, Spr;
double    Ask, Bid;
double tr[2];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
      td = iCustom(NULL,0,IndName,trendPeriod,smoothPeriod,TriggerUp,TriggerDown);        // А какой массив из четырех ???????????????????
      trade.SetExpertMagicNumber(Magic);
      trade.SetDeviationInPoints(Slip);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   double sl=0,tp=0;
   
   Spr = (int)SymbolInfoInteger(NULL,SYMBOL_SPREAD);
   Ask = SymbolInfoDouble(NULL,SYMBOL_ASK);
   Bid = SymbolInfoDouble(NULL,SYMBOL_BID);

   CopyBuffer(td,2,1,2,tr);                            // А чему равен tr? Не вижу нигде наполнения массива. ????????????????????????????????

   bool buy = tr[1]>TriggerUp && tr[0]<TriggerUp;      // !!!!!!!!!!!!!!!!!!!!    // Сигналы требуют коррекции
   bool sell = tr[1]<TriggerDown && tr[0]>TriggerDown; // !!!!!!!!!!!!!!!!!!!!    // Другой раз !!!

   if(Spr<=Spread)
      {
      if(CountTrades()<1 && TimeSession(StartHour,StartMin,EndHour,EndMin,TimeCurrent()))
         {
         if(buy && Buy)
            {
            PutOrder(0);
            ModifyOrders();
            }
         if(sell && Sell)
            {
            PutOrder(1);
            ModifyOrders();
            }
         }
      //---
      if(CountTrades()>0 && CountTrades()<Count)
         {
         if(PositionType()==0 && FindLastBuyPrice()-Ask>Step*_Point)
            {
            PutOrder(0);
            ModifyOrders();
            }

         if(PositionType()==1 && Bid-FindLastSellPrice()>Step*_Point)
            {
            PutOrder(1);
            ModifyOrders();
            }
         }
      }
   Comment("\n tr1: ",tr[0],
           "\n tr2: ",tr[1]);
}//+------------------------------------------------------------------+
//|   Расчет лота                                                    |   // Получение лота. Лот каждой позиции *KLot. Зачем????????????????
//+------------------------------------------------------------------+   // Против направления - согласен. По ходу - ?!
double Lot(int type)
{
      double lot=Lots;
   
      if(CountTrades(type)>0)
         lot=NormalizeDouble(Lots*MathPow(KLot,CountTrades(type)),2);
      if(lot>MaxLot)
         lot=Lots;
   return(lot);
}
//+------------------------------------------------------------------+
//|     Подсчет открытых позиций по типу                             |
//+------------------------------------------------------------------+
int CountTrades(int type=-1)
{
      int count=0;
   
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(PositionSelectByTicket(PositionGetTicket(i)))
            if(PositionGetString(POSITION_SYMBOL)==_Symbol)
               if(PositionGetInteger(POSITION_MAGIC)==Magic)
                  if(PositionGetInteger(POSITION_TYPE)==type || type==-1)  // ... || type==-1 - нет необходимости. Даже вредно для здоровья. 
                     count++;                                              // если предполагается ручное вмешательство,
   return(count);                                                          // то надо создавать кнопки на открытиЯ, но уже с Magic !!!!!!!!! 
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseAll(int type=-1)
{
   for(int i=PositionsTotal()-1; i>=0; i--)
      if(PositionSelectByTicket(PositionGetTicket(i)))
         if(PositionGetString(POSITION_SYMBOL)==_Symbol)
            if(PositionGetInteger(POSITION_MAGIC)==Magic)
               if(PositionGetInteger(POSITION_TYPE)==type || type==-1)     // ... || type==-1 - нет необходимости. Даже вредно для здоровья. 
                  trade.PositionClose(PositionGetTicket(i));               // если предполагается ручное вмешательство,
}                                                                          // то надо создавать кнопки на открытиЯ, но уже с Magic !!!!!!!!!
avatar

  7  kvashnin007 Сообщений: 598 - Андрей

  • 31 мая 2024, 13:13
+
+1
Вторая часть склейки:


//+------------------------------------------------------------------+
//|   Получение цены открытия последнего ордера на покупку           |
//+------------------------------------------------------------------+
double FindLastBuyPrice()
{
      double pr=0;
   
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(PositionSelectByTicket(PositionGetTicket(i)) && PositionGetInteger(POSITION_TYPE)==0)
            if(PositionGetString(POSITION_SYMBOL)==_Symbol)
               if(PositionGetInteger(POSITION_MAGIC)==Magic)
                  {
                  pr=PositionGetDouble(POSITION_PRICE_OPEN);
                  break;                                       // Где гантия, что PositionSelectByTicket() даст последний OP_BUY  ?????????????
                  }                                            // Хотя, почему-то, работает !!!
   return(pr);
}
//+------------------------------------------------------------------+
//|   Получение цены открытия последнего ордера на продажу           |
//+------------------------------------------------------------------+
double FindLastSellPrice()
{
      double pr=0;
   
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(PositionSelectByTicket(PositionGetTicket(i)) && PositionGetInteger(POSITION_TYPE)==1)
            if(PositionGetString(POSITION_SYMBOL)==_Symbol)
               if(PositionGetInteger(POSITION_MAGIC)==Magic)
                  {
                  pr=PositionGetDouble(POSITION_PRICE_OPEN);
                  break;                                       // Где гантия, что PositionSelectByTicket() даст последний OP_SELL  ?????????????
                  }                                            // Хотя, почему-то, работает !!!
   return(pr);
}
//+------------------------------------------------------------------+
//|  Position Profit    ??? Type ???                                 |     // Это что?  Тип последнего открытого ордера. А почему Profit ?
//+------------------------------------------------------------------+
int PositionType()
{
      int type=8;
   
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(PositionSelectByTicket(PositionGetTicket(i)))
            if(PositionGetString(POSITION_SYMBOL)==_Symbol)
               if(PositionGetInteger(POSITION_MAGIC)==Magic)
                  {
                  type=(int)PositionGetInteger(POSITION_TYPE);   
                  break;
                  }
   return(type);
}
//+------------------------------------------------------------------+
//|  Соответствие времени заданному отрезку                          |
//+------------------------------------------------------------------+
bool TimeSession(int aStartHour,int aStartMinute,int aStopHour,int aStopMinute,datetime aTimeCur)
{
      //--- время начала сессии
      int StartTime=3600*aStartHour+60*aStartMinute;
      //--- время окончания сессии
      int StopTime=3600*aStopHour+60*aStopMinute;
      //--- текущее время в секундах от начала дня
      aTimeCur=aTimeCur%86400;
      if(StopTime<StartTime)
         //--- переход через полночь
         if(aTimeCur>=StartTime || aTimeCur<StopTime)
            return(true);
      else
         //--- внутри одного дня
         if(aTimeCur>=StartTime && aTimeCur<StopTime)
            return(true);
   return(false);
}
//+------------------------------------------------------------------+
//|      Открытие ордеров по типу                                    |   // А если ECN - SL и ТР надо открывать после открытия ордера !!!!
//+------------------------------------------------------------------+
void PutOrder(int type)
{
   int r=0;
   color clr=Green;                                                      // Не используется !!!!!!!!
   double sl=0,tp=0;
   double price;

   if(type==0) //OP_BUY
      {
      clr=Blue;                                                          // Не используется !!!!!!!!
      price=Ask;

      if(StopLoss>0)
         sl=NormalizeDouble(price-StopLoss*_Point,_Digits);
      if(TakeProfit>0)
         tp=NormalizeDouble(price+TakeProfit*_Point,_Digits);

      trade.Buy(Lot(type),_Symbol,price,sl,tp,Comm);                     // Правильно: trade.Buy(Lot(type),_Symbol,price,0,0,Comm)
      }                                                                  // Тем более, что по коду все правильно: Открыли - модифицировали.
   //---
   if(type==1) //OP_SELL                                                 // Аналогично
      {
      clr=Red;                                               
      price=Bid;

      if(StopLoss>0)
         sl=NormalizeDouble(price+StopLoss*_Point,_Digits);
      if(TakeProfit>0)
         tp=NormalizeDouble(price-TakeProfit*_Point,_Digits);

      trade.Sell(Lot(type),_Symbol,price,sl,tp,Comm);
      }
}
//+------------------------------------------------------------------+
//|     Общий Безубыток                                              |      // Расчет в корне не верен.!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//+------------------------------------------------------------------+      // Эта ункция истинна для ордеров одного направления. Выбери какого ?????
double All()
{
      double all=0, num=0;
   
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(PositionSelectByTicket(PositionGetTicket(i)))
            if(PositionGetString(POSITION_SYMBOL)==_Symbol)
               if(PositionGetInteger(POSITION_MAGIC)==Magic)
                  {
                  all+=PositionGetDouble(POSITION_PRICE_OPEN)*PositionGetDouble(POSITION_VOLUME);
                  num+=PositionGetDouble(POSITION_VOLUME);
                  }
      if(num>0)
         all=NormalizeDouble(all/num,_Digits);
   return(all);
}
//+------------------------------------------------------------------+      // Это мой первый код на mql5.
//|     Общий Безубыток должен выглядеть так                         |      //  Требует проверки !!!!!!!!!
//+------------------------------------------------------------------+      // Надеюсь получилось. 
double AllBE()
{
      double AllBU=0;
      double BuyLotsSum=0,SelLotsSum=0;
      double WeighBuy=0,WeighSel=0;
   
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(PositionSelectByTicket(PositionGetTicket(i)))
            if(PositionGetString(POSITION_SYMBOL)==_Symbol)
               if(PositionGetInteger(POSITION_MAGIC)==Magic)               
                  {
                  if(PositionGetInteger(POSITION_TYPE)==0)
                     {
                     WeighBuy   += PositionGetDouble(POSITION_PRICE_OPEN)*PositionGetDouble(POSITION_VOLUME);
                     BuyLotsSum += PositionGetDouble(POSITION_VOLUME);
                     }
                  if(PositionGetInteger(POSITION_TYPE)==1)
                     {
                     WeighSel   += PositionGetDouble(POSITION_PRICE_OPEN)*PositionGetDouble(POSITION_VOLUME);
                     SelLotsSum += PositionGetDouble(POSITION_VOLUME);
                     }
                  }
      if(BuyLotsSum-SelLotsSum!=0)
         AllBU=(WeighBuy-WeighSel)/(BuyLotsSum-SelLotsSum);
   return(NormalizeDouble(AllBU,_Digits));
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ModifyOrders()
{
   double sl=0, tp=0;

   for(int i=PositionsTotal()-1; i>=0; i--)
      if(PositionSelectByTicket(PositionGetTicket(i)))
         if(PositionGetString(POSITION_SYMBOL)==_Symbol)
            if(PositionGetInteger(POSITION_MAGIC)==Magic)
               {
               if(PositionGetInteger(POSITION_TYPE)==0)
                  {
                  tp=NormalizeDouble(All()+TakeProfit*_Point,_Digits);
                  sl=NormalizeDouble(All()-StopLoss*_Point,_Digits);

                  if(PositionGetDouble(POSITION_TP)!=tp && PositionGetDouble(POSITION_SL)!=sl)  // А если ...==tp, а !=sl, то что??????????????????????
                     trade.PositionModify(PositionGetTicket(i),sl,tp);                          // Возможно необходимо && заменить на ||  !!!!!!!!!!!!!
                  }

               if(PositionGetInteger(POSITION_TYPE)==1)
                  {
                  tp=NormalizeDouble(All()-TakeProfit*_Point,_Digits);
                  sl=NormalizeDouble(All()+StopLoss*_Point,_Digits);

                  if(PositionGetDouble(POSITION_TP)!=tp && PositionGetDouble(POSITION_SL)!=sl)  // Аналогично.
                     trade.PositionModify(PositionGetTicket(i),sl,tp);
                  }
               }
}
//+------------------------------------------------------------------+


Смотрите, комментируйте, исправляйте.
avatar

  7  kvashnin007 Сообщений: 598 - Андрей

  • 31 мая 2024, 13:15
+
+1
Хотя так и не понял как берутся показания индикатора, чисто по аналогии создал еще три варианта открытия ордеров.
Ввел внешнюю переменную VariantOpen.
Если VariantOpen=1, то это вариант АМ2. Если 2-4, то это мои извращения. Хотя это не последнее слово. Только надо разобраться с показаниями индикатора. Массив tr это что такое? Какому массиву он соответствует в индикаторе?
double val[],valc[],levup[],levdn[];

В mql4 просто указываешь номер массива, с которого снимаешь пальчики, а здесь как?
Ладно буду изучать матчасть.

К нашему баранчику. Как всегда даю две части для склейки. Сохраните как версию 2. Погоняйте. Должно быть получше, чем на скрине: zakaz.opentraders.ru/uploads/images/2/9/e/4/638/big/2b963a13c1.png.

Удачи.

Часть1.


//+------------------------------------------------------------------+
//|                                               TrendDirection.mq5 |
//|                                             Copyright 2024, AM2. |
//|                                      http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, AM2."
#property link      "http://www.forexsystems.biz"
#property version   "1.02"

#include <Trade\Trade.mqh>
CTrade trade;

input double    Lots         = 0.1;      // торговый объем
input double    MaxLot       = 5;        // максимальный торговый объем
input double    KLot         = 1.5;      // увеличение лота
input int       StopLoss     = 5555;     // стоп
input int       TakeProfit   = 111;      // тейк
input int       Count        = 20;       // число поз
input int       Step         = 333;      // шаг
input int       StartHour    = 0;        // час начала торговли
input int       StartMin     = 30;       // минута начала торговли
input int       EndHour      = 23;       // час окончания торговли
input int       EndMin       = 30;       // минута окончания торговли
input ulong     Magic        = 1961;     // магик
input int       Spread       = 33;       // спред
input int       Slip         = 22;       // проскальзывание
input bool      Buy          = 1;        // покупки
input bool      Sell         = 1;        // продажи
input string    Comm         = "Scalp";
input string    IndName      = "Trend direction and force - JMA smoothed";
input int       trendPeriod  = 20;       // Trend period
input int       smoothPeriod = 3;        // Smoothing period
input double    TriggerUp    = 0.1;      // Trigger up level
input double    TriggerDn    =-0.1;      // Trigger down level
input int       VariantOpen  = 3;        // Вариант отработки открытия ордеров (1-3)
//---
datetime t=0;
int td=0, Spr;
double    Ask, Bid;
double tr[2];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
      td = iCustom(NULL,0,IndName,trendPeriod,smoothPeriod,TriggerUp,TriggerDn);        // А какой массив из четырех ???????????????????
      trade.SetExpertMagicNumber(Magic);
      trade.SetDeviationInPoints(Slip);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   double sl=0,tp=0;
   bool buy=false, sell=false;
   
   Spr = (int)SymbolInfoInteger(NULL,SYMBOL_SPREAD);
   Ask = SymbolInfoDouble(NULL,SYMBOL_ASK);
   Bid = SymbolInfoDouble(NULL,SYMBOL_BID);

   CopyBuffer(td,2,1,2,tr);                            // А чему равен tr? Не вижу нигде наполнения массива. ????????????????????????????????

   if(VariantOpen==1)
      {
      buy  = tr[1]>TriggerUp && tr[0]<TriggerUp;      
      sell = tr[1]<TriggerDn && tr[0]>TriggerDn;
      }      

   if(VariantOpen==2)
      {
      if(tr[1]<TriggerDn && tr[0]<tr[1])
         buy=true;      
      if(tr[1]>TriggerUp && tr[0]>tr[1])
         sell=true; 
      }
           
   if(VariantOpen==3)
      {
      if(tr[1]<TriggerDn && tr[0]<tr[1] && tr[2]<tr[1])
         buy=true;      
      if(tr[1]>TriggerUp && tr[0]>tr[1] && tr[2]<tr[1])
         sell=true; 
      }     
   
   if(VariantOpen==4)
      {
      if(tr[0]<tr[1] && tr[2]<tr[1])
         buy=true;      
      if(tr[0]>tr[1] && tr[2]<tr[1])
         sell=true; 
      }     
   
   if(Spr<=Spread)
      {
      if(CountTrades()<1 && TimeSession(StartHour,StartMin,EndHour,EndMin,TimeCurrent()))
         {
         if(buy && Buy)
            {
            PutOrder(0);
            ModifyOrders();
            }
         if(sell && Sell)
            {
            PutOrder(1);
            ModifyOrders();
            }
         }
      //---
      if(CountTrades()>0 && CountTrades()<Count)
         {
         if(PositionType()==0 && FindLastBuyPrice()-Ask>Step*_Point)
            {
            PutOrder(0);
            ModifyOrders();
            }

         if(PositionType()==1 && Bid-FindLastSellPrice()>Step*_Point)
            {
            PutOrder(1);
            ModifyOrders();
            }
         }
      }
   Comment("\n tr1: ",tr[0],
           "\n tr2: ",tr[1]);

avatar

  7  kvashnin007 Сообщений: 598 - Андрей

  • 1 июня 2024, 22:31

Зарегистрируйтесь или авторизуйтесь, чтобы оставить комментарий
Начать торговлю с Альпари