Группа "Напишу исправлю советник индикатор MQL4"

Рейтинг 27



просьба проверить советник и поправить если есть ошибки.

всем кто помогает участникам форума громадное спасибо особенно тем еще и объясняет как правильно софт должен работать.

и так к делу. собрал советник и даже вроде без ошибок.
тех. задание
1. вход в рынок в ручную в любую сторону (сам советник не входит в рынок ) 1 ордер
2.когда мы вручную входим то советник выставляет отложенник на определенном расстоянии и ставит тейк на нем. 2 ордер
3. когда срабатывает 2 ордер выставляет опять отложенный ордер с тейком (и так пока депозита хватит )
4.если мы закрываем все ордера которые в рынке то отложенник удаляется (может быть один или более открытых сделок)

это основная работа робота.

теперь просьба проверить чтобы советник соблюдал условия:
1. я сделал условия чтобы при минимальном + все ордера закрывались — но не работает

2.ограничение по количеству ордеров в рынке и после определенного количества не выставлял отложеники — не рабботает

3.ограничение по количеству объёма в открытых ордерах — не работает

4. не видит разницу в ордерах и не удаляет лишний отложенный ордер ( допустим что зашел несколько раз в рынок на каждый вход есть отложенный ордер при закрытии части ордеров отложеники остаются пока не закроешь все одера)

probuem ogranichit kolichestvo orderov v zamke.mq4 (23 Kb)

//+------------------------------------------------------------------+
//|                пробуем ограничить количество ордеров в замке.mq4 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict


//--- Inputs
extern double    Lots           = 2 ;          // противоположный ордер в обьеме (если 2 то это 2 лота постоянно)
extern double    MaxLot         = 5;           // максимальный торговый объем
extern double    KLot           = 2;           // увеличение лота

extern double    Profit         = 15;          // общии профит для закрытия всех открытых ордеров

extern int       TakeProfit    = 300;          // тейк на противоположном ордере
extern int       Delta         = 100;          // расстояние в пунктах на которое выстовляется отложенный ордер
extern int       BuySell       = 0;            // 1-buy 2-sell 0-off
extern int       Slip          = 30;           // реквот
extern int       Magic         = 0;            // магик
extern int       Count         = 3;            // число ордеров
extern int       Magik_Buy     = 1122;
extern int       Magik_Sell    = 2211;

int trades=0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
  
  
//+------------------------------------------------------------------+
//| Установка ордера                                                 |
//+------------------------------------------------------------------+
void PutOrder(int type,double price)
  {
   int r=0;
   color clr=Green;
   double sl=0,tp=0;

   if(type==1 || type==3 || type==5)
     {
      clr=Red;
      
      if(TakeProfit>0) tp=NormalizeDouble(price-TakeProfit*Point,Digits);
     }

   if(type==0 || type==2 || type==4)
     {
      clr=Blue;
      
      if(TakeProfit>0) tp=NormalizeDouble(price+TakeProfit*Point,Digits);
     }

   r=OrderSend(NULL,type,Lots,NormalizeDouble(price,Digits),Slip,sl,tp,"",Magic,0,clr);
   return;
  }
  
 //+---------------------------------------------------------------------------------+
//| получаем инормацию о счете и торговых условиях ДЦ                                 |
//+----------------------------------------------------------------------------------+
    
    //  if(OrdersTotal() == 0)
//  OrderSend(Symbol(),OP_BUY,0.1,Ask,3,0,0,"Primer",0,0,clrNONE);
  
  
    
    
 double min_lot = MarketInfo(Symbol(), MODE_MINLOT);                    //размер минимального лота
 double max_lot = MarketInfo(Symbol(), MODE_MAXLOT);                    //размер максимального лота
 double lot_cena = MarketInfo(Symbol(), MODE_MARGINREQUIRED);           //цена 1.0 лота
 double lot_zalog = MarketInfo(Symbol(), MODE_MARGININIT);              //залог за 1.0 лот
 double tickvalue = MarketInfo(Symbol(), MODE_TICKVALUE);               //цена одного пункта
 double swap_buy = MarketInfo(Symbol(), MODE_SWAPLONG);                 //своп для BUY в пунктах
 double swap_sell = MarketInfo(Symbol(), MODE_SWAPSHORT);               //своп для SELL в пунктах
 double spread = MarketInfo(Symbol(), MODE_SPREAD);                     //размер спрэда
 double freeze = MarketInfo(Symbol(), MODE_STOPLEVEL);                  //минимально допустимый уровень стоп-лосса/тейк-профита в пунктах
 double balance = AccountBalance();                                     //значение баланса активного счета 
 double equity = AccountEquity();                                       //имеющиеся на счету средства
 double margin = AccountMargin();                                       //сумма залоговых средств
 double freemargin = AccountFreeMargin();                               //имеющиеся на счету свободных средств
 double stop_out = AccountStopoutLevel();                               //Stop Out (принудительное закрытие позиций)
 double znakov = MathPow (10, MarketInfo(Symbol(), MODE_DIGITS));       //кооэф.умножения для знаков валютной пары
 double mindigits = NormalizeDouble(-MathLog(min_lot)/MathLog(10), 0);  //количество знаков в минимальном объеме лота
 double min_balans = lot_cena * min_lot;                                //расчет стоимости минимального лота
 double lots_take = freemargin / lot_cena;                              //количество лотов которое можно купить
 double OP_BuyStop,BuyLots,OP_BuyLimit,OP_SellLimit,SellLots,OP_SellStop,
  BuyProfit,BuySwapPlus,BuyProfitPlus,BuyLotsPlus,BuySwapMinus,BuyProfitMinus,
  BuyLotsMinus,SellProfit,SellSwapPlus,SellProfitPlus,SellLotsPlus,
  SellSwapMinus,SellProfitMinus,SellLotsMinus;
 int All_Order_Buy_Plus,All_Order_Buy_Minus,All_Order_Sell_Plus,
  All_Order_Sell_Minus,All_OP_BuyStop,All_Order_Buy,All_OP_BuyLimit,
  All_OP_SellLimit,All_Order_Sell,All_OP_SellStop; 
//---------------------------------------------------------------------------------------------//


  
  //+----------------------------------------------------------------+
//| Подсчет ордеров по типу                                          |
//+------------------------------------------------------------------+
int CountOrders(int type)
  {
   int count=0;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==type)
               count++;
           }
        }
     }
   return(count);
  }
  
  
  //+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseAll(int ot=-1)
  {
   bool cl;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==0 && (ot==0 || ot==-1))
              {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,_Digits),Slip,White);
              }
            if(OrderType()==1 && (ot==1 || ot==-1))
              {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,_Digits),Slip,White);
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Профит всех ордеров по типу ордера                               |
//+------------------------------------------------------------------+
double AllProfit(int ot=-1)
  {
   double pr=0;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==0 && (ot==0 || ot==-1))
              {
               pr+=OrderProfit()+OrderCommission()+OrderSwap();
              }

            if(OrderType()==1 && (ot==1 || ot==-1))
              {
               pr+=OrderProfit()+OrderCommission()+OrderSwap();
              }
           }
        }
     }
   return(pr);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CountTrades()
  {
   int count=0;
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL) count++;
           }
        }
     }
   return(count);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Lot()
  {
   double lot=0;
   if(CountTrades()>0) lot=NormalizeDouble(Lots*MathPow(KLot,CountTrades()),2);
   if(lot>MaxLot)lot=Lots;
   return(lot);
  }
 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double MarketOOP()
  {
   double oop=0;

   if(OrderSelect(OrdersTotal()-1,SELECT_BY_POS,MODE_TRADES))
     {
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
        {
         if(OrderType()<2) oop=OrderOpenPrice();
        }
     }

   return(oop);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int LastType()
  {
   int type=8;

   if(OrderSelect(OrdersTotal()-1,SELECT_BY_POS,MODE_TRADES))
     {
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
        {
         if(OrderType()<2) type=OrderType();
        }
     }

   return(type);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double StopOOP()
  {
   double oop=0;

   if(OrderSelect(OrdersTotal()-1,SELECT_BY_POS,MODE_TRADES))
     {
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
        {
         if(OrderType()>1) oop=OrderOpenPrice();
        }
     }

   return(oop);
  }
//+------------------------------------------------------------------+
//| Удаление отложенных ордеров                                      |
//+------------------------------------------------------------------+
void DelOrder()
  {
   bool del;
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()>1) del=OrderDelete(OrderTicket());
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(CountTrades()<1)
     {
      DelOrder();
      if(BuySell==1) PutOrder(0,Ask);
      if(BuySell==2) PutOrder(1,Bid);
     }

   if(MarketOOP()>0 && StopOOP()!=NormalizeDouble(MarketOOP()-Delta*Point,Digits) && LastType()==0) PutOrder(5,MarketOOP()-Delta*Point);
   if(MarketOOP()>0 && StopOOP()!=NormalizeDouble(MarketOOP()+Delta*Point,Digits) && LastType()==1) PutOrder(4,MarketOOP()+Delta*Point);
  }



 
 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

 


я думаю что перемудрил и вставил функции больше чем нужно но проблема я в программировании практически ноль. *help* 
  • +4
  • Просмотров: 3605
  • 3 декабря 2021, 18:40
  • eduard9898
Понравилcя материал? Не забудьте поставить плюс и поделиться в социальной сети!

Вступите в группу "Напишу исправлю советник индикатор MQL4", чтобы следить за обновлениями
ПРИСОЕДИНИТЬСЯ К ГРУППЕ
присоединиться
  Предыдущая запись в группе
Вопрос
19 июля 2021
29 декабря 2021

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

+
0
Сделал всё по тех.заданию
//+------------------------------------------------------------------+
//|                           Copyright © 2021, forex-time@mail.ru   |
//+------------------------------------------------------------------+
#property copyright   "Copyright © 2021, forex-time@mail.ru"
#property strict 
//+------------------------------------------------------------------+
extern double Lots       = 0.1;   //Фиксированный лот
extern double MaxLot     = 5.0;   //MAX лот
extern double KLot       = 2.0;   //Увеличение лота

extern double Profit     = 15.0;  //Закрыть общий профит $

extern int    TakeProfit = 0;     //Тейк профит (=0 откл)
extern int    DistNewOrd = 300;   //Дистанция новый ордер
extern int    MaxOrd     = 10;    //MAX ордеров
extern int    Magic      = 0;     //Магик ордеров
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   //Убрать сетку при тесте
   if(IsTesting()) ChartSetInteger(0,CHART_SHOW_GRID,false);
return(INIT_SUCCEEDED);}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment("");}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   //Если есть ордера и общий профит больше значения, то закрыть всё и отложенные удалить
   if(OP(-1)>0 && PrfOP(-1)>Profit) DeleteAll();
    
   //Если есть рыночные ордера то ставить отложенные
   if((OP(0)>0||OP(1)>0) && OP(-1)<MaxOrd)
     {
      //Рассчитать тейк профит для отложенных
      double TPb=0.0,TPs=0.0;
      if(TakeProfit>0){
         TPs=ND(LastPrcOP(0)-(DistNewOrd+TakeProfit)*Point,Digits);
         TPb=ND(LastPrcOP(1)+(DistNewOrd+TakeProfit)*Point,Digits);
         }
      //Поставить отложенный противоположный последнему рыночному 
      int Spread=int(((Ask-Bid)/Point)*2); //Дистанция нового ордера должна быть больше спреда *2
      if(DistNewOrd>0 && DistNewOrd>=Spread){
      if(LastTypeOP()==0 && OP(5)==0) Send(OP_SELLSTOP,Lot(),ND(LastPrcOP(0)-DistNewOrd*Point,Digits),0,TPs,Red);
      if(LastTypeOP()==1 && OP(4)==0) Send(OP_BUYSTOP,Lot(),ND(LastPrcOP(1)+DistNewOrd*Point,Digits),0,TPb,Blue);
      }
    }
  }   
//+------------------------------------------------------------------+
//| Подсчет открытых ордеров по типу                                 |
//+------------------------------------------------------------------+
int OP(int type=-1){
   int op=0;
   for(int i=OrdersTotal()-1;i>=0;i--) 
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol()){
   if(OrderType()==type||type<0) op++;}
return(op);}
//+------------------------------------------------------------------+
//| Профит всех ордеров по типу                                      |
//+------------------------------------------------------------------+
double PrfOP(int type=-1){
   double pf=0.0;
   for(int i=OrdersTotal()-1;i>=0;i--) 
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderType()<2 && OrderSymbol()==Symbol()){
   if(OrderType()==type||type<0) pf+=OrderProfit()+OrderCommission()+OrderSwap();}
return(pf);}
//+------------------------------------------------------------------+
//| Цена последнего ордера по типу                                   |
//+------------------------------------------------------------------+
double LastPrcOP(int type=-1){
   double prc=0.0;
   datetime t=0;
   for(int i=OrdersTotal()-1;i>=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol()){
   if((OrderType()==type||type<0) && t<OrderOpenTime()) {t=OrderOpenTime(); prc=OrderOpenPrice();}}
return(prc);}
//+------------------------------------------------------------------+
//| Тип последнего ордера                                            |
//+------------------------------------------------------------------+
int LastTypeOP(){
   int type=-1;
   datetime t=0;
   for(int i=OrdersTotal()-1;i>=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol()){
   if(t<OrderOpenTime()) {t=OrderOpenTime(); type=OrderType();}}
return(type);}
//+------------------------------------------------------------------+
//| Расчёт лота                                                      |
//+------------------------------------------------------------------+
double Lot(){
   double lot=0;
   if(OP(-1)>0) lot=ND(Lots*MathPow(KLot,OP(-1)),2);
   if(lot>MaxLot) lot=Lots;
return(lot);}
//+------------------------------------------------------------------+
//| ND - нормализация числа                                          |
//-------------------------------------------------------------------+
double ND(double value, int digits) {  
      return(NormalizeDouble(value, digits));}
//+------------------------------------------------------------------+
//| Открытие, закрытие ордеров                                       | 
//+------------------------------------------------------------------+
void Send(int type, double lt, double price, double sl, double tp, color clr){
   int send=0;
       send=OrderSend(Symbol(),type,lt,price,30,sl,tp,"",Magic,0,clr);
   if (send>0)
       Print("Успешно открыт ордер "+TypeToStr(type),", Lot: "+(string)lt,", Ticket: "+(string)send,", Magic: "+(string)Magic);
       else 
       Print("Невозможно открыть ордер "+TypeToStr(type),". Ошибка: "+string(GetLastError()));}
//+------------------------------------------------------------------+ 
void DeleteAll(){
   color cls=Gray;
   for(int i=OrdersTotal()-1; i>=0; i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol()){
   if(OrderType()==OP_BUY)  cls=DeepSkyBlue;
   if(OrderType()==OP_SELL) cls=Magenta;
   if(!OrderSelect(OrderTicket(),SELECT_BY_TICKET)||OrderCloseTime()>0) return;
   if(OrderType()<2 && !OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),30,cls)) Print("Невозможно закрыть ордер "+TypeToStr(OrderType()),". Ошибка: "+string(GetLastError()));
   if(OrderType()>1 && !OrderDelete(OrderTicket())) Print("Невозможно удалить ордер "+TypeToStr(OrderType()),". Ошибка: "+string(GetLastError()));}} 
//+------------------------------------------------------------------+ 
string TypeToStr(int type) {
   switch(type) {
      case 0: return("Buy");
      case 1: return("Sell");
      case 2: return("BuyLimit");
      case 3: return("SellLimit");
      case 4: return("BuyStop");
      case 5: return("SellStop");}
return("NONE");}
//-------------------------------------------------------------------+
avatar

  15  forextime Сообщений: 141 - ExpertFX

  • 6 декабря 2021, 19:16
+
0
1)Что бы протестировать, хорошо бы добавить, что бы первую позицию открывал по МА. Выше МА Бай, ниже Сел

2)Для ручной торговли добавить две кнопки на график: БАЙ, СЕЛ

3)В настройки добавить переключатель торговли: РУЧНАЯ/АВТО(по МА)
avatar

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

  • 7 декабря 2021, 12:24
+
0
Добавил пункт 1 и 3
avatar

  15  forextime Сообщений: 141 - ExpertFX

  • 7 декабря 2021, 13:34
+
0
спасибо буду экспериментировать *hi* 
avatar

  5  eduard9898 Автор Сообщений: 77

  • 7 декабря 2021, 12:57
+
0
спасибо буду экспериментировать *hi* 

и сразу вопрос если первый ордер закрываю в ручную то отложенный должен быть удалён?
и если можно добавить общий стоп лосс.
Редактирован: 7 декабря 2021, 13:44
avatar

  5  eduard9898 Автор Сообщений: 77

  • 7 декабря 2021, 13:24
+
0
Добавил условие
Если нет рыночных ордеров, то удалить отложенные ордера
avatar

  15  forextime Сообщений: 141 - ExpertFX

  • 7 декабря 2021, 13:34
+
0
//+------------------------------------------------------------------+
//|                           Copyright © 2021, forex-time@mail.ru   |
//+------------------------------------------------------------------+
#property copyright   "Copyright © 2021, forex-time@mail.ru"
#property strict 
//+------------------------------------------------------------------+
enum trade
  {
   Auto,  //Авто
   Fixed  //Ручная
  };
//+----------------+
extern trade  MethodTrade = Auto;  //Торговля МЕНЮ ==>>

extern double Lots        = 0.1;   //Фиксированный лот
extern double MaxLot      = 5.0;   //MAX лот
extern double KLot        = 2.0;   //Увеличение лота

extern double Profit      = 15.0;  //Закрыть общий профит $

extern int    TakeProfit  = 0;     //Тейк профит (=0 откл)
extern int    DistNewOrd  = 300;   //Дистанция новый ордер
extern int    MaxOrd      = 10;    //MAX ордеров
extern int    Magic       = 0;     //Магик ордеров

extern string IndMA       = "=== Moving Average ==="; //Индикатор ===>>
extern int    PeriodMA    = 20;            //Период
extern int    ShiftMA     = 3;             //Сдвиг линии
extern ENUM_MA_METHOD MethodMA = MODE_SMA; //Метод
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   //Убрать сетку при тесте
   if(IsTesting()) ChartSetInteger(0,CHART_SHOW_GRID,false);
return(INIT_SUCCEEDED);}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment("");}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(OP(-1)>0 && //Если есть ордера
     (PrfOP(-1)>Profit|| //Общий профит больше значения
     (OP(0)==0 && OP(1)==0))) //Нет открытых рыночных ордеров
      DeleteAll(); //Закрыть и удалить все ордера

   //Если выбран метод торговли АВТО
   if(MethodTrade==Auto){
     //Сигналы индикатора МА
     int SignalMA=-1;
     //Цена открытия текущей свечи выше МА и цена открытия предыдущей свечи ниже МА
     if(Open[0]>MA(0) && Open[1]<=MA(1)) SignalMA=0;
     //Цена открытия текущей свечи ниже МА и цена открытия предыдущей свечи выше МА
     if(Open[0]<MA(0) && Open[1]>=MA(1)) SignalMA=1;
     //Если нет ордеров, то открыть первый по сигналу МА
     if(OP(-1)==0){
        double TPb=0.0,TPs=0.0;
        if(TakeProfit>0){
           TPs=ND(Bid-TakeProfit*Point,Digits);
           TPb=ND(Ask+TakeProfit*Point,Digits);
           }
        //Сигнал МА, открыть ордер в направлении
        if(SignalMA==0) Send(OP_BUY,Lots,Ask,0,TPb,Blue);
        if(SignalMA==1) Send(OP_SELL,Lots,Bid,0,TPs,Red);
        }
      }
   //Если есть рыночные ордера то ставить отложенные
   if((OP(0)>0||OP(1)>0) && OP(-1)<MaxOrd)
     {
      //Рассчитать тейк профит для отложенных
      double TPb=0.0,TPs=0.0;
      if(TakeProfit>0){
         TPs=ND(LastPrcOP(0)-(DistNewOrd+TakeProfit)*Point,Digits);
         TPb=ND(LastPrcOP(1)+(DistNewOrd+TakeProfit)*Point,Digits);
         }
      //Поставить отложенный противоположный последнему рыночному 
      int Spread=int(((Ask-Bid)/Point)*2); //Дистанция нового ордера должна быть больше спреда *2
      if(DistNewOrd>0 && DistNewOrd>=Spread){
      if(LastTypeOP()==0 && OP(5)==0) Send(OP_SELLSTOP,Lot(),ND(LastPrcOP(0)-DistNewOrd*Point,Digits),0,TPs,Red);
      if(LastTypeOP()==1 && OP(4)==0) Send(OP_BUYSTOP,Lot(),ND(LastPrcOP(1)+DistNewOrd*Point,Digits),0,TPb,Blue);
      }
    }
  }   
//+------------------------------------------------------------------+
//| Индикатор Moving Average                                         |
//+------------------------------------------------------------------+
double MA(int bar){ 
   double ma=iMA(Symbol(),0, PeriodMA,ShiftMA,MethodMA,PRICE_CLOSE, bar);
return(ma);}
//+------------------------------------------------------------------+
//| Подсчет открытых ордеров по типу                                 |
//+------------------------------------------------------------------+
int OP(int type=-1){
   int op=0;
   for(int i=OrdersTotal()-1;i>=0;i--) 
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol()){
   if(OrderType()==type||type<0) op++;}
return(op);}
//+------------------------------------------------------------------+
//| Профит всех ордеров по типу                                      |
//+------------------------------------------------------------------+
double PrfOP(int type=-1){
   double pf=0.0;
   for(int i=OrdersTotal()-1;i>=0;i--) 
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderType()<2 && OrderSymbol()==Symbol()){
   if(OrderType()==type||type<0) pf+=OrderProfit()+OrderCommission()+OrderSwap();}
return(pf);}
//+------------------------------------------------------------------+
//| Цена последнего ордера по типу                                   |
//+------------------------------------------------------------------+
double LastPrcOP(int type=-1){
   double prc=0.0;
   datetime t=0;
   for(int i=OrdersTotal()-1;i>=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol()){
   if((OrderType()==type||type<0) && t<OrderOpenTime()) {t=OrderOpenTime(); prc=OrderOpenPrice();}}
return(prc);}
//+------------------------------------------------------------------+
//| Тип последнего ордера                                            |
//+------------------------------------------------------------------+
int LastTypeOP(){
   int type=-1;
   datetime t=0;
   for(int i=OrdersTotal()-1;i>=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol()){
   if(t<OrderOpenTime()) {t=OrderOpenTime(); type=OrderType();}}
return(type);}
//+------------------------------------------------------------------+
//| Расчёт лота                                                      |
//+------------------------------------------------------------------+
double Lot(){
   double lot=0;
   if(OP(-1)>0) lot=ND(Lots*MathPow(KLot,OP(-1)),2);
   if(lot>MaxLot) lot=Lots;
return(lot);}
//+------------------------------------------------------------------+
//| ND - нормализация числа                                          |
//-------------------------------------------------------------------+
double ND(double value, int digits) {  
      return(NormalizeDouble(value, digits));}
//+------------------------------------------------------------------+
//| Открытие, закрытие ордеров                                       | 
//+------------------------------------------------------------------+
void Send(int type, double lt, double price, double sl, double tp, color clr){
   int send=0;
       send=OrderSend(Symbol(),type,lt,price,30,sl,tp,"",Magic,0,clr);
   if (send>0)
       Print("Успешно открыт ордер "+TypeToStr(type),", Lot: "+(string)lt,", Ticket: "+(string)send,", Magic: "+(string)Magic);
       else 
       Print("Невозможно открыть ордер "+TypeToStr(type),". Ошибка: "+string(GetLastError()));}
//+------------------------------------------------------------------+ 
void DeleteAll(){
   color cls=Gray;
   for(int i=OrdersTotal()-1; i>=0; i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol()){
   if(OrderType()==OP_BUY)  cls=DeepSkyBlue;
   if(OrderType()==OP_SELL) cls=Magenta;
   if(!OrderSelect(OrderTicket(),SELECT_BY_TICKET)||OrderCloseTime()>0) return;
   if(OrderType()<2 && !OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),30,cls)) Print("Невозможно закрыть ордер "+TypeToStr(OrderType()),". Ошибка: "+string(GetLastError()));
   if(OrderType()>1 && !OrderDelete(OrderTicket())) Print("Невозможно удалить ордер "+TypeToStr(OrderType()),". Ошибка: "+string(GetLastError()));}} 
//+------------------------------------------------------------------+ 
string TypeToStr(int type) {
   switch(type) {
      case 0: return("Buy");
      case 1: return("Sell");
      case 2: return("BuyLimit");
      case 3: return("SellLimit");
      case 4: return("BuyStop");
      case 5: return("SellStop");}
return("NONE");}
//-------------------------------------------------------------------+

Редактирован: 7 декабря 2021, 13:35
avatar

  15  forextime Сообщений: 141 - ExpertFX

  • 7 декабря 2021, 13:35
+
0
Без тейк профита лучше торгует
avatar

  15  forextime Сообщений: 141 - ExpertFX

  • 7 декабря 2021, 13:37
+
0
«Вишенкой на торт» будет:

1)«Мягкий мартин» -прибавление начального лота, при увеличении лотности. Это уменьшит нагрузку на депо во флете! В настройки добавить:LotPlus= true/false

2)Размер начального ЛОТа как процент от средств. Risk= 0/1...10 // 0- false
Редактирован: 7 декабря 2021, 15:32
avatar

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

  • 7 декабря 2021, 15:25
+
0
извеняюсь вчера просто не понял о чем речь (впрочем как и сегодня )
если можно поподробнее.
в данный момент работает советник с такими параметрами



т.е захожу лотом (если в + то на 50$ закрыл если в минус то через 10 пунктов срабатывает отложенный на 2 лота вышли в + 50 $ вышли из сделки и т.д

где еще что можно проконтролировать?
Редактирован: 8 декабря 2021, 09:05
avatar

  5  eduard9898 Автор Сообщений: 77

  • 8 декабря 2021, 09:00
+
0
вау как все быстро (не ожидал)

думаю что все таки еще стопы нужны.т.е общие стопы чтобы не сидеть в замках и потом в просадке лучше чтобы закрывались в минус
Редактирован: 7 декабря 2021, 14:13
avatar

  5  eduard9898 Автор Сообщений: 77

  • 7 декабря 2021, 13:46
+
+1
Добавил параметр Общий убыток
//+------------------------------------------------------------------+
//|                           Copyright © 2021, forex-time@mail.ru   |
//+------------------------------------------------------------------+
#property copyright   "Copyright © 2021, forex-time@mail.ru"
#property strict 
//+------------------------------------------------------------------+
enum trade
  {
   Auto,  //Авто
   Fixed  //Ручная
  };
//+----------------+
extern trade  MethodTrade = Auto;  //Торговля МЕНЮ ==>>

extern double Lots        = 0.1;   //Фиксированный лот
extern double MaxLot      = 5.0;   //MAX лот
extern double KLot        = 2.0;   //Увеличение лота

extern double Profit      = 15.0;  //Закрыть общий профит $
extern double Loss        = 0.0;   //Общий убыток $ (=0 откл)

extern int    TakeProfit  = 0;     //Тейк профит (=0 откл)
extern int    DistNewOrd  = 300;   //Дистанция новый ордер
extern int    MaxOrd      = 10;    //MAX ордеров
extern int    Magic       = 0;     //Магик ордеров

extern string IndMA       = "=== Moving Average ==="; //Индикатор ===>>
extern int    PeriodMA    = 20;            //Период
extern int    ShiftMA     = 3;             //Сдвиг линии
extern ENUM_MA_METHOD MethodMA = MODE_SMA; //Метод
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   //Убрать сетку при тесте
   if(IsTesting()) ChartSetInteger(0,CHART_SHOW_GRID,false);
return(INIT_SUCCEEDED);}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment("");}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   //Закрытие ордеров
   if(OP(-1)>0 && //Если есть ордера
     (PrfOP(-1)>=Profit|| //Общий профит больше значения
     (PrfOP(-1)<0 && Loss!=0.0 && MathAbs(PrfOP(-1))>=MathAbs(Loss))|| //Общий убыток больше значения
     (OP(0)==0 && OP(1)==0))) //Нет открытых рыночных ордеров
      DeleteAll(); //Закрыть и удалить все ордера

   //Если выбран метод торговли АВТО
   if(MethodTrade==Auto){
     //Сигналы индикатора МА
     int SignalMA=-1;
     //Цена открытия текущей свечи выше МА и цена открытия предыдущей свечи ниже МА
     if(Open[0]>MA(0) && Open[1]<=MA(1)) SignalMA=0;
     //Цена открытия текущей свечи ниже МА и цена открытия предыдущей свечи выше МА
     if(Open[0]<MA(0) && Open[1]>=MA(1)) SignalMA=1;
     //Если нет ордеров, то открыть первый по сигналу МА
     if(OP(-1)==0){
        double TPb=0.0,TPs=0.0;
        if(TakeProfit>0){
           TPs=ND(Bid-TakeProfit*Point,Digits);
           TPb=ND(Ask+TakeProfit*Point,Digits);
           }
        //Сигнал МА, открыть ордер в направлении
        if(SignalMA==0) Send(OP_BUY,Lots,Ask,0,TPb,Blue);
        if(SignalMA==1) Send(OP_SELL,Lots,Bid,0,TPs,Red);
        }
      }
   //Если есть рыночные ордера то ставить отложенные
   if((OP(0)>0||OP(1)>0) && OP(-1)<MaxOrd)
     {
      //Рассчитать тейк профит для отложенных
      double TPb=0.0,TPs=0.0;
      if(TakeProfit>0){
         TPs=ND(LastPrcOP(0)-(DistNewOrd+TakeProfit)*Point,Digits);
         TPb=ND(LastPrcOP(1)+(DistNewOrd+TakeProfit)*Point,Digits);
         }
      //Поставить отложенный противоположный последнему рыночному 
      int Spread=int(((Ask-Bid)/Point)*2); //Дистанция нового ордера должна быть больше спреда *2
      if(DistNewOrd>0 && DistNewOrd>=Spread){
      if(LastTypeOP()==0 && OP(5)==0) Send(OP_SELLSTOP,Lot(),ND(LastPrcOP(0)-DistNewOrd*Point,Digits),0,TPs,Red);
      if(LastTypeOP()==1 && OP(4)==0) Send(OP_BUYSTOP,Lot(),ND(LastPrcOP(1)+DistNewOrd*Point,Digits),0,TPb,Blue);
      }
    }
  }   
//+------------------------------------------------------------------+
//| Индикатор Moving Average                                         |
//+------------------------------------------------------------------+
double MA(int bar){ 
   double ma=iMA(Symbol(),0, PeriodMA,ShiftMA,MethodMA,PRICE_CLOSE, bar);
return(ma);}
//+------------------------------------------------------------------+
//| Подсчет открытых ордеров по типу                                 |
//+------------------------------------------------------------------+
int OP(int type=-1){
   int op=0;
   for(int i=OrdersTotal()-1;i>=0;i--) 
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol()){
   if(OrderType()==type||type<0) op++;}
return(op);}
//+------------------------------------------------------------------+
//| Профит всех ордеров по типу                                      |
//+------------------------------------------------------------------+
double PrfOP(int type=-1){
   double pf=0.0;
   for(int i=OrdersTotal()-1;i>=0;i--) 
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderType()<2 && OrderSymbol()==Symbol()){
   if(OrderType()==type||type<0) pf+=OrderProfit()+OrderCommission()+OrderSwap();}
return(pf);}
//+------------------------------------------------------------------+
//| Цена последнего ордера по типу                                   |
//+------------------------------------------------------------------+
double LastPrcOP(int type=-1){
   double prc=0.0;
   datetime t=0;
   for(int i=OrdersTotal()-1;i>=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol()){
   if((OrderType()==type||type<0) && t<OrderOpenTime()) {t=OrderOpenTime(); prc=OrderOpenPrice();}}
return(prc);}
//+------------------------------------------------------------------+
//| Тип последнего ордера                                            |
//+------------------------------------------------------------------+
int LastTypeOP(){
   int type=-1;
   datetime t=0;
   for(int i=OrdersTotal()-1;i>=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol()){
   if(t<OrderOpenTime()) {t=OrderOpenTime(); type=OrderType();}}
return(type);}
//+------------------------------------------------------------------+
//| Расчёт лота                                                      |
//+------------------------------------------------------------------+
double Lot(){
   double lot=0;
   if(OP(-1)>0) lot=ND(Lots*MathPow(KLot,OP(-1)),2);
   if(lot>MaxLot) lot=Lots;
return(lot);}
//+------------------------------------------------------------------+
//| ND - нормализация числа                                          |
//-------------------------------------------------------------------+
double ND(double value, int digits) {  
      return(NormalizeDouble(value, digits));}
//+------------------------------------------------------------------+
//| Открытие, закрытие ордеров                                       | 
//+------------------------------------------------------------------+
void Send(int type, double lt, double price, double sl, double tp, color clr){
   int send=0;
       send=OrderSend(Symbol(),type,lt,price,30,sl,tp,"",Magic,0,clr);
   if (send>0)
       Print("Успешно открыт ордер "+TypeToStr(type),", Lot: "+(string)lt,", Ticket: "+(string)send,", Magic: "+(string)Magic);
       else 
       Print("Невозможно открыть ордер "+TypeToStr(type),". Ошибка: "+string(GetLastError()));}
//+------------------------------------------------------------------+ 
void DeleteAll(){
   color cls=Gray;
   for(int i=OrdersTotal()-1; i>=0; i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol()){
   if(OrderType()==OP_BUY)  cls=DeepSkyBlue;
   if(OrderType()==OP_SELL) cls=Magenta;
   if(!OrderSelect(OrderTicket(),SELECT_BY_TICKET)||OrderCloseTime()>0) return;
   if(OrderType()<2 && !OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),30,cls)) Print("Невозможно закрыть ордер "+TypeToStr(OrderType()),". Ошибка: "+string(GetLastError()));
   if(OrderType()>1 && !OrderDelete(OrderTicket())) Print("Невозможно удалить ордер "+TypeToStr(OrderType()),". Ошибка: "+string(GetLastError()));}} 
//+------------------------------------------------------------------+ 
string TypeToStr(int type) {
   switch(type) {
      case 0: return("Buy");
      case 1: return("Sell");
      case 2: return("BuyLimit");
      case 3: return("SellLimit");
      case 4: return("BuyStop");
      case 5: return("SellStop");}
return("NONE");}
//-------------------------------------------------------------------+
avatar

  15  forextime Сообщений: 141 - ExpertFX

  • 7 декабря 2021, 14:27
+
0
спасибо сейчас есть чем заняться буду проверять и оптимизировать
avatar

  5  eduard9898 Автор Сообщений: 77

  • 7 декабря 2021, 14:32
+
+1
Магик не учитывается в расчётах, т.к. может быть ордер первый ручной
Все расчёты только по валютной паре
Таким образом в процессе реальной торговли можно докидывать ручные отложенные ордера
avatar

  15  forextime Сообщений: 141 - ExpertFX

  • 7 декабря 2021, 14:40
+
0


думаю если еще добавляется то удвоениями можно слить депозит.

кроме того зачем в принципе советник для скальпинга. но если уменьшить вход и увиличить расстояние то можно и на среднюю дистанция пойти.

если интересно то работаю с несколькими индикаторами могу скинуть но они в ex4


Редактирован: 7 декабря 2021, 22:56
avatar

  5  eduard9898 Автор Сообщений: 77

  • 7 декабря 2021, 22:24
+
0
если не сильно напрягаю — можно добавить пересечение 2 машек для открытия ордера при условии что советник сам торгует. вместо выше или ниже средней.

//------- мувинги для работы ----------------------------------------+
extern string name_MA1 = "________ Быстрый MA_1 ________"; // Индикатор ==>>
extern int ma1_period = 13; // Период
extern int ma1_shift = 0; // Сдвиг
extern ENUM_MA_METHOD ma1_method = MODE_EMA; // Метод MA
extern ENUM_APPLIED_PRICE ma1_applied_price = PRICE_CLOSE; // Применить к
input string name_MA2 = "________ Средний MA_2 ________"; // Индикатор ==>>
extern int ma2_period = 26; // Период
extern int ma2_shift = 0; // Сдвиг
extern ENUM_MA_METHOD ma2_method = MODE_EMA; // Метод MA
Редактирован: 1 февраля 2022, 10:29
avatar

  5  eduard9898 Автор Сообщений: 77

  • 1 февраля 2022, 10:28

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