Проблема со стохастиком - не поддается контролю(((

 
extern int K=8;
extern int D=5;
extern int slowing=3;
extern int Average_method=2;
extern int price_field=1;
extern int GoodDelta=1;
extern int Rperiod=26;
bool Cls_S=false, Cls_B=false;
bool Ans  =false;
bool Work=true;                    // Эксперт будет работать.
string Symb; 
extern double Lots       =0.1;     // Жестко заданное колич. лотов
extern double Prots      =0.07;    // Процент свободных средств
int
   Total,                           // Количество ордеров в окне 
   Tip,                          // Тип выбран. ордера (B=0,S=1)
   Ticket;                          // Номер ордера
   double
   Lot,                             // Колич. лотов в выбран.ордере
   Lts,                             // Колич. лотов в открыв.ордере
   Min_Lot,                         // Минимальное количество лотов
   Step,                            // Шаг изменения размера лота
   Free,                            // Текущие свободные средства
   One_Lot,                         // Стоимость одного лота
   Price;
int K_level=0;
int down=0;
int up=0;

void CloseDirect(int cntr, string comm)
  {
    double closeprice;
    if(OrderSelect(cntr,SELECT_BY_POS,MODE_TRADES))
      {
        RefreshRates();
        if (OrderType()==OP_BUY)
          closeprice=Bid;
        else  
          closeprice=Ask;          
        if (OrderClose(OrderTicket(),OrderLots(),closeprice,10,Green))
        {
          Print(comm, OrderTicket());
        }
        else
          {
            Print("ОШИБКА в CloseDirect():OrderClose() - ",GetLastError());
          }
      }
    else
      { 
        Print("ОШИБКА в CloseDirect():OrderSelect() - ",GetLastError());
      }  
  }

int init()
  {

   return(0);
  }

int deinit()
  {

   return(0);
  }

int start()
  {
    int ticket=0;
    double stoch_1m=iStochastic(NULL,0,K,D,slowing,Average_method,price_field,MODE_MAIN,1);
    double stoch_0m=iStochastic(NULL,0,K,D,slowing,Average_method,price_field,MODE_MAIN,0);
    double KLline=30;
    double KHline=70;
    double KSline=50;
    
    if (stoch_1m < KLline && stoch_0m >= KLline && MathAbs(NormalizeDouble(stoch_0m,Digits)-NormalizeDouble(KLline,Digits))<GoodDelta);
     {OP_BUY;
     }
     if (stoch_1m > KHline && stoch_0m <= KHline && MathAbs(NormalizeDouble(KHline,Digits)-NormalizeDouble(stoch_0m,Digits))<GoodDelta);
     {OP_SELL;
     }
     if (ticket>0&&stoch_0m==KSline&&stoch_1m<KSline)
    {Cls_B;
     }
     if (ticket>0&&stoch_0m==KSline&&stoch_1m>KSline)
    {Cls_S;
     }
    if(OrdersTotal()<1)
      {        
        if(OP_BUY)//сигнал на покупку
              {
                RefreshRates();
                ticket=OrderSend(Symbol(),OP_BUY,0.1,Ask,10,0,0,"buy_order1",1,0,Blue);
                        
              }
            if(OP_SELL)//сигнал на продажу
              {
                RefreshRates();
                ticket=OrderSend(Symbol(),OP_SELL,0.1,Bid,10,0,0,"sell_order1",1,0,Red);
                             }
          }
            
     if (OrdersTotal()>=1)
      { 
        if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES))
          {
            if(OrderType()==OP_BUY)
              {
                if(Cls_B=true)
                  while(OrdersTotal()>0)
                    {
                      CloseDirect(0,"Принудительное закрытие сделки при обратном движении рынка, ticket=");
                    }
              }
            if(OrderType()==OP_SELL)
              {
                if(Cls_S=true)
                  while(OrdersTotal()>0)
                    {
                      CloseDirect(0,"Принудительное закрытие сделки при обратном движении рынка, ticket=");
                    }
              }  
          }
        else
          {
            Print("ОШИБКА в Start()(блок закрытия при обратном движении) :OrderSelect() - ",GetLastError());
            return(-1);
          }  
      }
   
         
    return(0);
  }
Доброго времени суток! Вот собственно код, прошу помощи решить задачу: по идее, должен был входить (на этом этапе) при стохастике на уровне 30/70, выход - на уровне 50. Сейчас заходит и выходит сразу же, и так бесконечное число раз(((((
 
Evgen117:
Доброго времени суток! Вот собственно код, прошу помощи решить задачу: по идее, должен был входить (на этом этапе) при стохастике на уровне 30/70, выход - на уровне 50. Сейчас заходит и выходит сразу же, и так бесконечное число раз(((((

Какое тут должно быть действие ???

if (stoch_1m < KLline && stoch_0m >= KLline &&
    MathAbs(NormalizeDouble(stoch_0m,Digits)-NormalizeDouble(KLline,Digits))<GoodDelta);
     {OP_BUY; // Какое тут должно быть действие ???
     }

Если надо открыть позицию на покупку, используйте OrderSend().

 

Ошибок очень много. Если, например, Cls_B надо присвоить true, то надо писать Cls_B=true:

// не правильно
if (ticket>0 && stoch_0m==KSline && stoch_1m<KSline)
    {
     Cls_B;
    }

// правильно
if (ticket>0 && stoch_0m==KSline && stoch_1m<KSline)
    {
     Cls_B=true;
    }
else
    {
     Cls_B=false;
    }
 

И открывает только Sell.

Не надо использовать константы торговых операций в качестве флагов.

if(OP_SELL)//сигнал на продажу
Это условие всегда истинно...
 
Спасибо, переписал немного, теперь у него следующий вид:
extern int K=13;
extern int D=8;
extern int slowing=5;
extern int Average_method=2;
extern int price_field=1;
extern int GoodDelta=1;
extern int Rperiod=26;
bool OP_B=false, OP_S=false, Cls_S=false, Cls_B=false;
bool Ans  =false;
bool Work=true;                    // Эксперт будет работать.
string Symb; 
extern double Lots       =0.1;     // Жестко заданное колич. лотов
extern double Prots      =0.07;    // Процент свободных средств
int
   Total,                           // Количество ордеров в окне 
   Tip,                          // Тип выбран. ордера (B=0,S=1)
   Ticket;                          // Номер ордера
   double
   Lot,                             // Колич. лотов в выбран.ордере
   Lts,                             // Колич. лотов в открыв.ордере
   Min_Lot,                         // Минимальное количество лотов
   Step,                            // Шаг изменения размера лота
   Free,                            // Текущие свободные средства
   One_Lot,                         // Стоимость одного лота
   Price;
int K_level=0;
int down=0;
int up=0;

void CloseDirect(int cntr, string comm)
  {
    double closeprice;
    if(OrderSelect(cntr,SELECT_BY_POS,MODE_TRADES))
      {
        RefreshRates();
        if (OrderType()==OP_BUY)
          closeprice=Bid;
        else  
          closeprice=Ask;          
        if (OrderClose(OrderTicket(),OrderLots(),closeprice,10,Green))
        {
          Print(comm, OrderTicket());
        }
        else
          {
            Print("ОШИБКА в CloseDirect():OrderClose() - ",GetLastError());
          }
      }
    else
      { 
        Print("ОШИБКА в CloseDirect():OrderSelect() - ",GetLastError());
      }  
  }

int init()
  {

   return(0);
  }

int deinit()
  {

   return(0);
  }

int start()
  {
    int ticket=0;
    double stoch_1m=iStochastic(NULL,0,K,D,slowing,Average_method,price_field,MODE_MAIN,1);
    double stoch_0m=iStochastic(NULL,0,K,D,slowing,Average_method,price_field,MODE_MAIN,0);
    double KLline=30;
    double KHline=70;
    double KSline=50;
    
    if (stoch_1m < KLline && stoch_0m >= KLline && MathAbs(NormalizeDouble(stoch_0m,Digits)-NormalizeDouble(KLline,Digits))<GoodDelta);
     {OP_B=true;
     }
     if (stoch_1m > KHline && stoch_0m <= KHline && MathAbs(NormalizeDouble(KHline,Digits)-NormalizeDouble(stoch_0m,Digits))<GoodDelta);
     {OP_S=true;
     }
     if (ticket>0&&stoch_0m==KSline&&stoch_1m<KSline)
    {Cls_B=true;
     }
     if (ticket>0&&stoch_0m==KSline&&stoch_1m>KSline)
    {Cls_S=true;
     }
    if(OrdersTotal()<1)
      {        
        if(OP_B=true)//сигнал на покупку
              {
                RefreshRates();
                ticket=OrderSend(Symbol(),OP_BUY,0.1,Ask,10,0,0,"buy_order1",1,0,Blue);
                        
              }
            if(OP_S=true)//сигнал на продажу
              {
                RefreshRates();
                ticket=OrderSend(Symbol(),OP_SELL,0.1,Bid,10,0,0,"sell_order1",1,0,Red);
                             }
          }
            
     if (OrdersTotal()>=1)
      { 
        if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES))
          {
            if(OrderType()==OP_BUY)
              {
                if(Cls_B=true)
                  while(OrdersTotal()>0)
                    {
                      CloseDirect(0,"Принудительное закрытие сделки при обратном движении рынка, ticket=");
                    }
              }
            if(OrderType()==OP_SELL)
              {
                if(Cls_S=true)
                  while(OrdersTotal()>0)
                    {
                      CloseDirect(0,"Принудительное закрытие сделки при обратном движении рынка, ticket=");
                    }
              }  
          }
        else
          {
            Print("ОШИБКА в Start()(блок закрытия при обратном движении) :OrderSelect() - ",GetLastError());
            return(-1);
          }  
      }
   
         
    return(0);
  }
 но, если честно, не сильно изменилась картина((( - все равно "штампует" ордера друг за другом на одном и том же месте. Прошу гуру указать еще на ошибки, которые нужно поправить....
 
Evgen117:
Спасибо, переписал немного, теперь у него следующий вид: но, если честно, не сильно изменилась картина((( - все равно "штампует" ордера друг за другом на одном и том же месте. Прошу гуру указать еще на ошибки, которые нужно поправить....

Тут так много неправильных конструкций, что код надо полностью переписывать, чего естественно никто не собирается делать. Ниже общая схема конструкции как надо искать ордер:

if(OrdersTotal()>0)
  {
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()!=Symbol()) continue; // если не тот символ на котором работает советник, то переходим к другому ордеру
         // какие то действия
        }
     }
  }

Когда пишете код (или по крайней мере тут вставляете код) пользуйтесь Стилизатором, чтоб удобнее было читать код.

В случае с OrderSend(), посмотрите там в справке в примере как надо выставлять ордер.

 

Ну почему же, можно и по новому написать. Предлагаю начать с точек входа/ выхода:

 подскажите, пожалуйста, все ли верно? Может что-то добавить/убрать?

ПС, спс, стилизатором воспользовался... 

int start()
  {
   int ticket=0;
   double stoch_1m=iStochastic(NULL,0,K,D,slowing,Average_method,price_field,MODE_MAIN,1);
   double stoch_0m=iStochastic(NULL,0,K,D,slowing,Average_method,price_field,MODE_MAIN,0);
   double KLline=30;
   double KHline=70;
   double KSline=50;

   if(stoch_1m<KLline && stoch_0m>=KLline && MathAbs(NormalizeDouble(stoch_0m,Digits)-NormalizeDouble(KLline,Digits))<GoodDelta);
     {
      OP_B=true;
     }
   if(stoch_1m>KHline && stoch_0m<=KHline && MathAbs(NormalizeDouble(KHline,Digits)-NormalizeDouble(stoch_0m,Digits))<GoodDelta);
     {
      OP_S=true;
     }
   if(ticket>0 && stoch_0m==KSline && stoch_1m<KSline)
     {
      Cls_B=true;
     }
   if(ticket>0 && stoch_0m==KSline && stoch_1m>KSline)
     {
      Cls_S=true;
     }
 

Начните с того, что лучше учитесь сразу работать на обновлённом языке MQL4. Например, вместо int start() используйте void OnTick(). "Скелет" советника будет выглядеть примерно так:

//+------------------------------------------------------------------+
//|                                                      Example.mq4 |
//|                                                         Evgen117 |
//+------------------------------------------------------------------+
#property copyright "Evgen117"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+

Тут важное значение имеет строка #property strict, которая велит использовать новый компилятор.

 

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

//+------------------------------------------------------------------+
//|                                                      Example.mq4 |
//|                                                         Evgen117 |
//+------------------------------------------------------------------+
#property copyright "Evgen117"
#property strict
//--- Внешние параметры советника.
input ENUM_TIMEFRAMES St_time_frame  = PERIOD_CURRENT; // Time frame
input int             St_K           = 13;             // K period
input int             St_D           = 8;              // D period
input int             St_slowing     = 5;              // Slowing
input ENUM_MA_METHOD  St_aver_method = MODE_EMA;       // Average method
input ENUM_STO_PRICE  St_price       = STO_CLOSECLOSE; // Price field
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Проверка соединения клиентского терминала с сервером.
   if(!IsConnected())
     {
      Comment("Связь отсутствует!"); return;
     }
//--- Проверка состояния потока выполнения торговых операций.
   if(IsTradeContextBusy())
     {
      Comment("Торговый поток занят. Подождите.");
      Sleep(2*1000); return;
     }
//--- Ищем значения стохастиков
   double Stoch_1=iStochastic(_Symbol,St_time_frame,St_K,St_D,St_slowing,
                              St_aver_method,St_price,MODE_MAIN,1);
   double Stoch_0=iStochastic(_Symbol,St_time_frame,St_K,St_D,St_slowing,
                              St_aver_method,St_price,MODE_MAIN,0);
//--- В комментарии просто посмотрим значения стохастиков.
   Comment("Stoch_1 = ",DoubleToStr(Stoch_1,2),"\n",
           "Stoch_0 = ",DoubleToStr(Stoch_0,2));
  }
//+------------------------------------------------------------------+
 

Доброго времени суток! Огромное спасибо, код просмотрел, допинфу на этом сайте прочитал... вопросов ПОКА нет (будут в ходе написания). Вопрос по точкам входа/выхода остался, немного переписал и вот он выглядет так. Подскажите, пожалуйста, все ли норм, можно переходить к блоку "открытие ордеров"? 

ПС. Прошу прощения, что пишу блоками, но я так привык еще с универа... 

if(Stoch_1<KLline && Stoch_0>=KLline && MathAbs(NormalizeDouble(Stoch_0,Digits)-NormalizeDouble(KLline,Digits))<GoodDelta);
     {
      OP_B=true;
     }
   if(Stoch_1>KHline && Stoch_0<=KHline && MathAbs(NormalizeDouble(KHline,Digits)-NormalizeDouble(Stoch_0,Digits))<GoodDelta);
     {
      OP_S=true;
     }
   if(Stoch_0==KSline && Stoch_1<KSline)
     {
      Cls_B=true;
     }
   if(Stoch_0==KSline && Stoch_1>KSline)
     {
      Cls_S=true;
     }
 

Примерно так, но всё равно есть неточности:

//---------------------
if(Stoch_1<KLline && Stoch_0>=KLline && MathAbs(Stoch_0-KLline)<GoodDelta);
  {
   OP_B=true;
  }
else
  {
   OP_B=false;
  }
//---------------------
if(Stoch_1>KHline && Stoch_0<=KHline && MathAbs(KHline-Stoch_0)<GoodDelta);
  {
   OP_S=true;
  }
else
  {
   OP_S=false;
  }
//---------------------
if(Stoch_0==KSline && Stoch_1<KSline)
  {
   Cls_B=true;
  }
else
  {
   Cls_B=false;
  }
//---------------------
if(Stoch_0==KSline && Stoch_1>KSline)
  {
   Cls_S=true;
  }
else
  {
   Cls_S=false;
  }

Проблема с открытием множества позиций состоит в том, что при первом тике, когда срабатывает условие на покупку будет OP_B=true и на этом тике будет открыта позиция. НО на следующем тоже будет OP_B=true и снова будет открываться вторая позиция и т.д. Если надо чтоб была открыта только одна позиция, то надо проверять наличие уже существующей в списке ордеров и блокировать дальнейшее действие.

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