Изучаем язык программирования MQL4

Mezon

Новичок форума
Замечательно! Выигравший или проигравший (спор, пари?) будет обучать меня и мне подобных с 0 м уровнем знаний?
 

BorisSedov

Активный участник
Кстати. Я так и не увидел практического применения здоровенных простых чисел. Есть пример?
Простые числа являются ключом к разрешению многих математических проблем и появляются в разных областях математики и ее приложениях. Криптография, имитационное моделирование, тестирование материнских плат персональных компьютеров – вот современный перечень практического применения простых чисел. Поэтому простые числа интересуют не только математиков, но и некоторые коммерческие организации, а также военных (разведку и контрразведку), ввиду их особого применения в области защиты информации.
 

BorisSedov

Активный участник
Задача о простых числах без использования операций / и %.
C++:
#property strict
#property script_show_inputs

input ulong k = 2147483647;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
bool result;

result=fntest(k);

if(result) Print("Число k - простое");
else Print("Число k - составное");
}
//+------------------------------------------------------------------+

bool fntest(ulong num)
{
if(num<2 || !(num&1) || fm(num,3)) return(false);
if(num<4) return(true);

ulong i,n;

n=(ulong)MathSqrt(num);

for(i=5; i<=n; i+=6)
   {
   if(fm(num,i)) return(false);
   if(fm(num,i+2)) return(false);
   }

return(true);
}

bool fm(ulong num, ulong x)
{
ulong a;
int i;

while(num>=x)
   {
   a=x;
 
   while(a<1844674407370955162 && a*10<=num) a*=10;
 
   for(i=2; i<11; i++)
      {
      if(a*i>num || a*i<=a*(i-1))
         {
         a*=(i-1);
         break;
         }
      }
 
   num-=a;
   }

if(num==0) return(true);

return(false);
}
Без использования операций / и %, и в случае значения k близкого к 18446744073709551615, на решение уходит приблизительно 30 минут. В реализации с использованием операций %, подобная задача решается приблизительно за 15 секунд. Это актуально для чисел которые действительно являются простыми. В случае если число составное, то затрачивается значительно меньше времени на решение. При числах k близких к 2147483647, код работает очень быстро – приблизительно 0.007 секунды.

Такой тест простоты, в котором не используются операции %, реализован только в образовательных целях.
 

Ugar

Гуру форума
Простые числа являются ключом к разрешению многих математических проблем и появляются в разных областях математики и ее приложениях. Криптография, имитационное моделирование, тестирование материнских плат персональных компьютеров – вот современный перечень практического применения простых чисел. Поэтому простые числа интересуют не только математиков, но и некоторые коммерческие организации, а также военных (разведку и контрразведку), ввиду их особого применения в области защиты информации.
Для разработки печатных плат есть P-Cad и ему подобные системы, Если мне понадобится плата, я точно её не буду разрабатывать с помощью MQL. Простую я на миллиметровке нарисую, а чуть по сложнее с использованием софта. Кроме того, инженер пыхтящий над платой точно не задумывается о простых числах. Если они и используются то уже в самой системе проектирования. А и программисты, писавшие эту систему, может и думали он них, но точно писали её не на MQL. Та же бодяга с математиками и криптографами.
MQL придуман для трейдера, что бы он мог свою торговую систему запрограммировать. Если трейдер придумал торговую систему со сложными вычислениями, то в этих вычислениях о хорошо соображает. А значит знает как наиболее эффективно их решать. Его надо научить программировать, а не решать ненужные математические задачи. Если трейдер крутой математик и в своей торговой системе решает сложные уравнения, ему полезнее будет знать как подключить и использовать библиотеки от матлаба или подобной системы. Так как он их знает лучше.
Уверен что большинство трейдеров на этом форуме и не только, при разработке торговой системы, даже не интересуются простыми числами, тем более большими.
В общем понты все эти простые числа. Ближе к практике. Ну например приведите пример вычисления канала линейной регрессии. Больше будет пользы. Некоторые трейдеры любят этот инструмент. Хотя я таких встречал не много, да и сам не люблю перерисовываемые инструменты.
 
Последнее редактирование:

BorisSedov

Активный участник
Еще раз напоминаю всем, кто невнимательно отслеживает эту тему.
Задачи с простыми числами предназначались для опытных программистов, для профессионалов.
Для начинающих была задача рассматривающая применение операции % (остаток от деления), о простых числах в этой задаче речи не было.
На этом считаю дискуссию завершенной и рассуждения о бесполезности операции % в программировании считаю глупыми и не уместными в данной теме.
 
Последнее редактирование:

BorisSedov

Активный участник
Следующая задача.
Нужно написать советник, торгующий по сигналам двух стандартных технических индикаторов Moving Average. Один индикатор с более быстрым периодом усреднения чем второй. Ордер Бай открывается, когда быстрая MA пересекает медленную снизу вверх. Ордер Селл открывается, когда быстрая MA пересекает медленную сверху вниз. Открытие осуществлять по закрытию сигнальной свечи, то есть – свеча на которой было пересечение вверх/вниз должна быть закрыта, а вход на новой свече. Советник должен работать по инструменту своего графика, и открывать только один ордер. Закрытие происходит по стоп уровням СтопЛосс и ТейкПрофит. Переменные MagicNumber, СтопЛосс и ТейкПрофит, а также периоды MA – вывести во входные параметры советника.
Постарайтесь при реализации не использовать лишних операций (действий).
 

DomovenokBrest

♔♕♖♗♘♙
Следующая задача.
Нужно написать советник, торгующий по сигналам двух стандартных технических индикаторов Moving Average. Один индикатор с более быстрым периодом усреднения чем второй. Ордер Бай открывается, когда быстрая MA пересекает медленную снизу вверх. Ордер Селл открывается, когда быстрая MA пересекает медленную сверху вниз. Открытие осуществлять по закрытию сигнальной свечи, то есть – свеча на которой было пересечение вверх/вниз должна быть закрыта, а вход на новой свече. Советник должен работать по инструменту своего графика, и открывать только один ордер. Закрытие происходит по стоп уровням СтопЛосс и ТейкПрофит. Переменные MagicNumber, СтопЛосс и ТейкПрофит, а также периоды MA – вывести во входные параметры советника.
Постарайтесь при реализации не использовать лишних операций (действий).
Советник работает. Выдавал ошибку 131 при параметре лота 0,01. При написании советника пришлось смотреть и документацию и ковырять чужие кода. Пока, что бы писать программу чисто из головы речь не идет... :(
Проверьте пожалуйста.

C++:
#property strict

// Следующая задача.
// Нужно написать советник, торгующий по сигналам двух стандартных технических индикаторов Moving Average.
// Один индикатор с более быстрым периодом усреднения чем второй.
// Ордер Бай открывается, когда быстрая MA пересекает медленную снизу вверх.
// Ордер Селл открывается, когда быстрая MA пересекает медленную сверху вниз.
// Открытие осуществлять по закрытию сигнальной свечи, то есть – свеча на которой было пересечение вверх/вниз должна быть закрыта, а вход на новой свече.
// Советник должен работать по инструменту своего графика, и открывать только один ордер.
// Закрытие происходит по стоп уровням СтопЛосс и ТейкПрофит.
// Переменные MagicNumber, СтопЛосс и ТейкПрофит вывести во входные параметры советника.
// Постарайтесь при реализации не использовать лишних операций (действий).

//+------------------------------------------------------------------+
input int                FastMA        = 164;         // FastMAPeriod
input ENUM_MA_METHOD     FastMAMethod  = MODE_EMA;    // FastMAMethod
input ENUM_APPLIED_PRICE FastMAPrice   = PRICE_CLOSE; // FastMAPrice
input int                FastMAShift   = 0;           // FastMAShift

input int                SlowMA        = 384;         // SlowMAPeriod
input ENUM_MA_METHOD     SlowMAMethod  = MODE_EMA;    // SlowMAMethod
input ENUM_APPLIED_PRICE SlowMAPrice   = PRICE_CLOSE; // SlowMAPrice
input int                SlowMAShift   = 0;           // SlowMAShift

input double             Lots          = 0.1;         // Lots:
input double             TakeProfit    = 300;         // Take Profit:
input double             StopLoss      = 100;         // Stop Loss:
input int                Magic         = 12345;       // Magic Number:
input int                Slippage      = 3;           // Slippage:
//+------------------------------------------------------------------+
int    slipp, ticket;
double point;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//----Определение пяти значного брокера 
   point = _Point;
   if(_Digits == 3 || _Digits == 5)
      {
       point = 10.0 * Point;
       slipp = Slippage * 10;
       }
//---
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  int OrdersSum=0;
  int i=0;
  double MA1_0,MA2_0,MA1_1,MA2_1;
  int total;
  bool   resalt;
 
 
  MA1_0       = iMA ( NULL, 0, FastMA, FastMAShift, FastMAMethod,FastMAPrice, 0 ); // Получаем значение FastMA
  MA1_1       = iMA ( NULL, 0, FastMA, FastMAShift, FastMAMethod,FastMAPrice, 1 ); // Получаем значение FastMA
  MA2_0       = iMA ( NULL, 0, SlowMA, SlowMAShift, SlowMAMethod,SlowMAPrice, 0 ); // Получаем значение SlowMA
  MA2_1       = iMA ( NULL, 0, SlowMA, SlowMAShift, SlowMAMethod,SlowMAPrice, 1 ); // Получаем значение SlowMA
 
  total=OrdersTotal();
 
//---- buy
  if (total<1)
   {
   if(MA1_1<MA2_1 && MA1_0>MA2_0)
     {
      ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,slipp,Ask-StopLoss*Point,Ask+TakeProfit*Point,"",Magic,0,Blue);
        if(ticket>0)
              {
               if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
                  Print("Открыт ордер BUY : ",OrderOpenPrice());
              }
            else
              {
               Print("Ошибка открытия BUY ордера : ",GetLastError());
               return;
              }
     }

//---- sell   
   if(MA1_1>MA2_1 && MA1_0<MA2_0)
     {
      ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,slipp,Bid+StopLoss*Point,Bid-TakeProfit*Point,"",Magic,0,Red);
        if(ticket>0)
              {
               if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
                  Print("Открыт ордер SELL : ",OrderOpenPrice());
              }
            else
              {
               Print("Ошибка открытия SELL ордера : ",GetLastError());
               return;
              }
     }
   } 
//----
   for(i = OrdersTotal()-1; i >= 0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderMagicNumber()!=Magic || OrderSymbol()!=Symbol()) continue;
      //---- check order type
      if(OrderType()==OP_BUY)
        {
         if(Bid>=(OrderOpenPrice()+TakeProfit*Point)) // проверим не пора ли закрываться по профиту
          {
            resalt = OrderClose(OrderTicket(),OrderLots(),Bid,slipp,Blue); // закрываем длинную позицию по профиту
            break;
          }
         if(Bid<=(OrderOpenPrice()-StopLoss*Point))   // проверим не пора ли закрываться по ст.лоссу
          {
            resalt = OrderClose(OrderTicket(),OrderLots(),Bid,slipp,Red); // закрываем длинную позицию по стопу
            break;
          }
        }
      else
        {
         if(Ask<=(OrderOpenPrice()-TakeProfit*Point))
          {
            resalt = OrderClose(OrderTicket(),OrderLots(),Ask,slipp,Red);  // закрываем короткую позицию по профиту
            break;
          }
         if(Ask>=(OrderOpenPrice()+StopLoss*Point))
          {
            resalt = OrderClose(OrderTicket(),OrderLots(),Ask,slipp,Red);          // закрываем короткую позицию по стопу
            break;
          }
        }
       }
    
   return;

  }
 

Mezon

Новичок форума
Хоть я и не написал ни одного скрипта, индикатора, советника но здесь ошибка...

//----Определение пяти значного брокера point = _Point; if(_Digits == 3 || _Digits == 5) { point = 10.0 * Point; slipp = Slippage * 10; }
Думаю что нужно в строке: point = 10.0 * Point; добавить к Point нижнее подчеркивание _ или как?
 

DomovenokBrest

♔♕♖♗♘♙
Хоть я и не написал ни одного скрипта, индикатора, советника но здесь ошибка...


Думаю что нужно в строке: point = 10.0 * Point; добавить к Point нижнее подчеркивание _ или как?
Спасибо, должно быть так:

C++:
//----Определение пяти значного брокера
   point = _Point;
   if(_Digits == 3 || _Digits == 5)
      {
       point = 10.0 * point;
       slipp = Slippage * 10;
       }

просмотрел вчера. Поправил...

C++:
#property strict

// Следующая задача.
// Нужно написать советник, торгующий по сигналам двух стандартных технических индикаторов Moving Average.
// Один индикатор с более быстрым периодом усреднения чем второй.
// Ордер Бай открывается, когда быстрая MA пересекает медленную снизу вверх.
// Ордер Селл открывается, когда быстрая MA пересекает медленную сверху вниз.
// Открытие осуществлять по закрытию сигнальной свечи, то есть – свеча на которой было пересечение вверх/вниз должна быть закрыта, а вход на новой свече.
// Советник должен работать по инструменту своего графика, и открывать только один ордер.
// Закрытие происходит по стоп уровням СтопЛосс и ТейкПрофит.
// Переменные MagicNumber, СтопЛосс и ТейкПрофит вывести во входные параметры советника.
// Постарайтесь при реализации не использовать лишних операций (действий).

//+------------------------------------------------------------------+
input int                FastMA        = 164;         // FastMAPeriod
input ENUM_MA_METHOD     FastMAMethod  = MODE_EMA;    // FastMAMethod
input ENUM_APPLIED_PRICE FastMAPrice   = PRICE_CLOSE; // FastMAPrice
input int                FastMAShift   = 0;           // FastMAShift

input int                SlowMA        = 384;         // SlowMAPeriod
input ENUM_MA_METHOD     SlowMAMethod  = MODE_EMA;    // SlowMAMethod
input ENUM_APPLIED_PRICE SlowMAPrice   = PRICE_CLOSE; // SlowMAPrice
input int                SlowMAShift   = 0;           // SlowMAShift

input double             Lots          = 0.1;         // Lots:
input double             TakeProfit    = 30;         // Take Profit:
input double             StopLoss      = 10;         // Stop Loss:
input int                Magic         = 12345;       // Magic Number:
input int                Slippage      = 3;           // Slippage:
//+------------------------------------------------------------------+
int    slipp, ticket;
double point;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//----Определение пяти значного брокера
   point = _Point;
   if(_Digits == 3 || _Digits == 5)
      {
       point = 10.0 * point;
       slipp = Slippage * 10;
       }
//---
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
 
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  int OrdersSum=0;
  int i=0;
  double MA1_0,MA2_0,MA1_1,MA2_1;
  int total;
  bool   resalt;


  MA1_0       = iMA ( NULL, 0, FastMA, FastMAShift, FastMAMethod,FastMAPrice, 0 ); // Получаем значение FastMA
  MA1_1       = iMA ( NULL, 0, FastMA, FastMAShift, FastMAMethod,FastMAPrice, 1 ); // Получаем значение FastMA
  MA2_0       = iMA ( NULL, 0, SlowMA, SlowMAShift, SlowMAMethod,SlowMAPrice, 0 ); // Получаем значение SlowMA
  MA2_1       = iMA ( NULL, 0, SlowMA, SlowMAShift, SlowMAMethod,SlowMAPrice, 1 ); // Получаем значение SlowMA

  total=OrdersTotal();

//---- buy
  if (total<1)
   {
   if(MA1_1<MA2_1 && MA1_0>MA2_0)
     {
      ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,slipp,Ask-StopLoss*point,Ask+TakeProfit*point,"",Magic,0,Blue);
        if(ticket>0)
              {
               if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
                  Print("Открыт ордер BUY : ",OrderOpenPrice());
              }
            else
              {
               Print("Ошибка открытия BUY ордера : ",GetLastError());
               return;
              }
     }

//---- sell  
   if(MA1_1>MA2_1 && MA1_0<MA2_0)
     {
      ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,slipp,Bid+StopLoss*point,Bid-TakeProfit*point,"",Magic,0,Red);
        if(ticket>0)
              {
               if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
                  Print("Открыт ордер SELL : ",OrderOpenPrice());
              }
            else
              {
               Print("Ошибка открытия SELL ордера : ",GetLastError());
               return;
              }
     }
   }
//----
   for(i = OrdersTotal()-1; i >= 0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderMagicNumber()!=Magic || OrderSymbol()!=Symbol()) continue;
      //---- check order type
      if(OrderType()==OP_BUY)
        {
         if(Bid>=(OrderOpenPrice()+TakeProfit*point)) // проверим не пора ли закрываться по профиту
          {
            resalt = OrderClose(OrderTicket(),OrderLots(),Bid,slipp,Blue); // закрываем длинную позицию по профиту
            break;
          }
         if(Bid<=(OrderOpenPrice()-StopLoss*point))   // проверим не пора ли закрываться по ст.лоссу
          {
            resalt = OrderClose(OrderTicket(),OrderLots(),Bid,slipp,Blue); // закрываем длинную позицию по стопу
            break;
          }
        }
      else
        {
         if(Ask<=(OrderOpenPrice()-TakeProfit*point))
          {
            resalt = OrderClose(OrderTicket(),OrderLots(),Ask,slipp,Red);  // закрываем короткую позицию по профиту
            break;
          }
         if(Ask>=(OrderOpenPrice()+StopLoss*point))
          {
            resalt = OrderClose(OrderTicket(),OrderLots(),Ask,slipp,Red);          // закрываем короткую позицию по стопу
            break;
          }
        }
       }
   
   return;

  }
 
Последнее редактирование:

Mezon

Новичок форума
Борис, ни чего личного... я прочитал несколько раз "учебник" Ковалева и даже имел "удовольствие" переписываться с автором. А так же просмотрел все! видео из приведенной вами серии и все остальные что есть в интернете... результат 0. Ну не совсем 0, я могу тупо скопировать и "написать" все о чем говорят в видео, но мне это не нужно! Мне нужно научиться разбираться в коде, то есть понимать о чем речь, зачем и почему, для чего я должен писать то то а не это... Мне ни чего не понятно, тем более что вы пытаетесь объяснить (ни чего учебного и познавательного кроме ни кому не нужных задач)... Главное я не могу понять зачем??? И как это поможет мне( и подобных мне с 0м уровнем знаний ни когда не изучающих ни одни язык программирования) начать понимать что написано в "учебнике" и документации, справке по MQL4...
 

Mezon

Новичок форума
C++:
//----Определение пяти значного брокера
point = _Point;
if(_Digits == 3 || _Digits == 5)
{
point = 10.0 * point;
slipp = Slippage * 10;
}
просмотрел вчера. Поправил...

По моему так тоже работать не будет. Вверху _Point с большой буквы, внизу с маленькой, думаю что должны быть одинаковые?
 

DomovenokBrest

♔♕♖♗♘♙
По моему так тоже работать не будет. Вверху _Point с большой буквы, внизу с маленькой, думаю что должны быть одинаковые?
Код определяе 4x значный или 5и значный брокер

C++:
   point = _Point; // Назначаем переменную point равную переменной _Point,  в которой
                   // хранится размер пункта текущего инструмента в валюте котировки
   if(_Digits == 3 || _Digits == 5) // здесь читаем так: если в цене текущего графика
                   // количество пунктов = 3 или = 5, то
      {
       point = 10.0 * point; // размер пункта умножаем на 10
       slipp = Slippage * 10;
       }

Теперь попробую объяснить, для чего это нужно. Если я ошибусь, более опытные коллеги поправят.
Мы задаем внешние переменные в окнах свойств программы. Но мы не знаем, на терминале какого брокера эта программа будет работать - 4ч значного или 5и значного. Так вот, дабы в ручную не изменять задаваемые параметры мы и используем данный кусочек кода.
т.е. к примеру, если в переменной тэйк профит задан параметр 30
C++:
input double             TakeProfit    = 30;         // Take Profit:
то в 4x значном брокере программа будет рассчитывать тэйк = 30 пунктам, а в 5ти значном = 300 пунктов.
 
Последнее редактирование:

Ugar

Гуру форума
_Point, Point, _Digits, Digits,
Это предопределённые переменные. То есть они уже встроены в язык и что то уже означают. Соответственно, пользователи не могут создавать свои переменные с точно таким же именем. По этому пользователь может создать переменные для своих нужд point, digits. заглавную букву заменили и это уже другая переменная.
 

gravity

Местный знаток
Следующая задача.
Напишите скрипт, который находит все выбранные в обзоре рынка инструменты, и выводит имена этих инструментов в журнал. Вывод построчный при помощи функции Print.
Читал справочник, хотел сам сделать. Но удалось лишь найти и выписать нужные функции из справочника и ступор:D. В итоге ,разбирал предложенные коды.
C++:
int total=SymbolsTotal(true);
Print("Символов ",total);
for(int i=0; i<total; i++)Print(i," ",SymbolName(i,true));
C++:
#property strict

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
int n=0;

for(int i=SymbolsTotal(true)-1; i>=0; i--)
   {
   n++;
   Print("Symbol = ",SymbolName(i,true)," - ",n);
   }
}
//+------------------------------------------------------------------+
В варианте Бориса, я так понял, n нужен для того, чтобы сделать привычную нумерацию с 1, а не с 0.
C++:
int total=SymbolsTotal(true);
Print("Символов ",total);
string Symbols[];
ArrayResize(Symbols,total);
for(int i=0; i<total; i++)Symbols[i]=SymbolName(i,true);
for(int i=0; i<total; i++)Print(i," ",Symbols[i]);
Тут, вроде, второй for можно опустить и поместить Print {в тело цикла} первого for.
 
Последнее редактирование:

Thebuzzard

Интересующийся
Здраствуйте Лорды.
Могу ли я увидеть как выглядит функция для советника
которая закроет все ордера в безубыток ,при условии что присутствуют открытые ордера обеих направлений(buy and sell)?
Спасибо.
 

gravity

Местный знаток
Следующая задача.
Нужно написать советник, торгующий по сигналам двух стандартных технических индикаторов Moving Average.
Постарайтесь при реализации не использовать лишних операций (действий).
Тут я тоже конечно же смотрел готовые коды Домовенка и предыдущего советника.
Вход я сделал не на основании состояния машек на 0 и 1 барах. А на состоянии машек на 1 баре и положения цены относительно машки. Кажется большого отличия быть не должно, а код чуть меньше стал.
C++:
#property strict

// Следующая задача.
// Нужно написать советник, торгующий по сигналам двух стандартных технических индикаторов Moving Average.
// Один индикатор с более быстрым периодом усреднения чем второй.
// Ордер Бай открывается, когда быстрая MA пересекает медленную снизу вверх.
// Ордер Селл открывается, когда быстрая MA пересекает медленную сверху вниз.
// Открытие осуществлять по закрытию сигнальной свечи, то есть – свеча на которой было пересечение вверх/вниз должна быть закрыта, а вход на новой свече.
// Советник должен работать по инструменту своего графика, и открывать только один ордер.
// Закрытие происходит по стоп уровням СтопЛосс и ТейкПрофит.
// Переменные MagicNumber, СтопЛосс и ТейкПрофит вывести во входные параметры советника.
// Постарайтесь при реализации не использовать лишних операций (действий).

//+------------------------------------------------------------------+
input int                FastMA        = 55;          // МА1
input ENUM_MA_METHOD     FastMAMethod  = MODE_EMA;    // Метод1
input ENUM_APPLIED_PRICE FastMAPrice   = PRICE_CLOSE; // Цена1
input int                FastMAShift   = 0;           // Сдвиг1

input int                SlowMA        = 233;         // МА2
input ENUM_MA_METHOD     SlowMAMethod  = MODE_EMA;    // Метод2
input ENUM_APPLIED_PRICE SlowMAPrice   = PRICE_CLOSE; // Цена2
input int                SlowMAShift   = 0;           // Сдвиг2

input double             Lots          = 0.1;         // Лот
input int                TakeProfit    = 30;          // TP
input int                StopLoss      = 10;          // SL
input int                Magic         = 12345;       // Летающий слоник
input int                Slippage      = 3;           // Проскальзывание
//+------------------------------------------------------------------+
int    slipp, ticket;
double point, ima1, ima2, SL, TP;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
     point = Point;
     slipp = Slippage;

//----Определение пяти значного брокера
    if(Digits == 3 || Digits == 5)
    {
      point *= 10;
      slipp *= 10;
    }
    
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{

   ima1 = iMA ( Symbol(), 0, FastMA, FastMAShift, FastMAMethod, FastMAPrice,1 );  // 55
   ima2 = iMA ( Symbol(), 0, SlowMA, SlowMAShift, SlowMAMethod, SlowMAPrice,1 );  // 233

   if (CountTrades() == 0)                                                        // если нет открытых ордеров, то...
   {
      if (ima1 > ima2 && Bid  > ima1)                                             // 55 > 233, И цена на покупку выше Ма55, то...
      {
         SL     = NormalizeDouble(Ask - StopLoss*point,Digits);                   // считаем стоп стоп-лосс(BUY)
         TP     = NormalizeDouble(Ask + TakeProfit*point,Digits);                 // считаем тейк профит(BUY)
         ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, slipp, 0, 0, "Покупка", Magic, 0, Blue);//открываем BAY
         if (ticket < 1)                                                          // если ордер не открылся, то возвращает (-1) и...
         {
            Print("Ошибка открытия ордера BUY: ",GetLastError());                 //пишем в журнал об ошибке
         }
         else if (OrderSelect(ticket,SELECT_BY_TICKET))                           // если ордер есть(ticket>1), то...
              {
                  if (OrderModify(ticket,OrderOpenPrice(),SL,TP,0,clrRed))        // модифицируем ордер с выставлением SL и TP
                    Print ("Ордер BUY успешно модифицирован");                    // пишем об успешной модификации
               }
               else                                                               // если OrderModify вернул false, то...
                   Print ("Ошибка модификации ордера BUY");                       // пишем об ошибке модификации
      }
      else if (ima1 < ima2 && Ask < ima1)   // если нет открытых ордеров (строка 76) и если...
                                         // 55 < 233, И цена на продажу ниже Ма 55, то...
        {
            TP     = NormalizeDouble(Bid - TakeProfit*point, Digits);             // считаем стоп стоп-лосс(SELL)
            SL     = NormalizeDouble(Bid + StopLoss*point,Digits);                // считаем тейк профит(SELL)
            ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, slipp, 0, 0, "Продажа", Magic, 0, Red);//открываем SELL
            if (ticket < 1)                                                       // если ордер не открылся, то возвращает (-1) и...
            {
               Print("Ошибка открытия ордера SELL: ",GetLastError());             //пишем в журнал об ошибке
            }
            else if (OrderSelect(ticket,SELECT_BY_TICKET))                        // если ордер есть(ticket>1), то...
                 {
                     if (OrderModify(ticket,OrderOpenPrice(),SL,TP,0,clrRed))     // модифицируем ордер с выставлением SL и TP
                        Print ("Ордер SELL успешно модифицирован");               // пишем об успешной модификации
                 }
                 else                                                             // если OrderModify вернул false, то...
                     Print ("Ошибка модификации ордера SELL");                    // пишем об ошибке модификации 
        }                                         
      
   }
                
}

//+------------------------------------------------------------------+
//| Ф. считаем количество ордеров                                    |
//+------------------------------------------------------------------+

int CountTrades()                                                   
{
   int count = 0;                                                     // задаем счетчик равным 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); // возвращаем функции CountTrades() количество ордеров(cont)

}
//+------------------------------------------------------------------+
Нашел косяк и в предыдущем советнике, где блок перевода на 5знак.
Было 336416 Стало336417

Ошибка была в том:
1) я забыл умножить на 10 проскальзывание при переводе на 5-знак.
2) размер пункта для 4х-знака у меня не был бы задан, т.к. дальше в формуле я использую point. А при 4х-знаке, нигде не написано, чему будет равнятся это значение.
SL = NormalizeDouble(Ask - StopLoss*point,Digits);
 

Ugar

Гуру форума
Читал справочник, хотел сам сделать. Но удалось лишь найти и выписать нужные функции из справочника и ступор:D. В итоге ,разбирал предложенные коды.
C++:
int total=SymbolsTotal(true);
Print("Символов ",total);
for(int i=0; i<total; i++)Print(i," ",SymbolName(i,true));

В варианте Бориса, я так понял, n нужен для того, чтобы сделать привычную нумерацию с 1, а не с 0.
Тогда достаточно при печати добавить 1 к i. Совсем не обязательно для этого заводить лишнюю переменную n.
Код:
int total=SymbolsTotal(true);
Print("Символов ",total);
for(int i=0; i<total; i++)Print(i+1," ",SymbolName(i,true));
 

gravity

Местный знаток
Тогда достаточно при печати добавить 1 к i. Совсем не обязательно для этого заводить лишнюю переменную n.
Код:
int total=SymbolsTotal(true);
Print("Символов ",total);
for(int i=0; i<total; i++)Print(i+1," ",SymbolName(i,true));

Я тоже хотел так попробовать) но я еще и тут SymbolName(i+1,true) прибавил, в итоге у меня не отображалось 2 валюты). А оказывается там не надо.
 

gravity

Местный знаток
Спасибо, должно быть так:

C++:
//----Определение пяти значного брокера
   point = _Point;
   if(_Digits == 3 || _Digits == 5)
      {
       point = 10.0 * point;
       slipp = Slippage * 10;
       }

просмотрел вчера. Поправил...

C++:
#property strict

// Следующая задача.
// Нужно написать советник, торгующий по сигналам двух стандартных технических индикаторов Moving Average.
// Один индикатор с более быстрым периодом усреднения чем второй.
// Ордер Бай открывается, когда быстрая MA пересекает медленную снизу вверх.
// Ордер Селл открывается, когда быстрая MA пересекает медленную сверху вниз.
// Открытие осуществлять по закрытию сигнальной свечи, то есть – свеча на которой было пересечение вверх/вниз должна быть закрыта, а вход на новой свече.
// Советник должен работать по инструменту своего графика, и открывать только один ордер.
// Закрытие происходит по стоп уровням СтопЛосс и ТейкПрофит.
// Переменные MagicNumber, СтопЛосс и ТейкПрофит вывести во входные параметры советника.
// Постарайтесь при реализации не использовать лишних операций (действий).

//+------------------------------------------------------------------+
input int                FastMA        = 164;         // FastMAPeriod
input ENUM_MA_METHOD     FastMAMethod  = MODE_EMA;    // FastMAMethod
input ENUM_APPLIED_PRICE FastMAPrice   = PRICE_CLOSE; // FastMAPrice
input int                FastMAShift   = 0;           // FastMAShift

input int                SlowMA        = 384;         // SlowMAPeriod
input ENUM_MA_METHOD     SlowMAMethod  = MODE_EMA;    // SlowMAMethod
input ENUM_APPLIED_PRICE SlowMAPrice   = PRICE_CLOSE; // SlowMAPrice
input int                SlowMAShift   = 0;           // SlowMAShift

input double             Lots          = 0.1;         // Lots:
input double             TakeProfit    = 30;         // Take Profit:
input double             StopLoss      = 10;         // Stop Loss:
input int                Magic         = 12345;       // Magic Number:
input int                Slippage      = 3;           // Slippage:
//+------------------------------------------------------------------+
int    slipp, ticket;
double point;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//----Определение пяти значного брокера
   point = _Point;
   if(_Digits == 3 || _Digits == 5)
      {
       point = 10.0 * point;
       slipp = Slippage * 10;
       }
//---
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  int OrdersSum=0;
  int i=0;
  double MA1_0,MA2_0,MA1_1,MA2_1;
  int total;
  bool   resalt;


  MA1_0       = iMA ( NULL, 0, FastMA, FastMAShift, FastMAMethod,FastMAPrice, 0 ); // Получаем значение FastMA
  MA1_1       = iMA ( NULL, 0, FastMA, FastMAShift, FastMAMethod,FastMAPrice, 1 ); // Получаем значение FastMA
  MA2_0       = iMA ( NULL, 0, SlowMA, SlowMAShift, SlowMAMethod,SlowMAPrice, 0 ); // Получаем значение SlowMA
  MA2_1       = iMA ( NULL, 0, SlowMA, SlowMAShift, SlowMAMethod,SlowMAPrice, 1 ); // Получаем значение SlowMA

  total=OrdersTotal();

//---- buy
  if (total<1)
   {
   if(MA1_1<MA2_1 && MA1_0>MA2_0)
     {
      ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,slipp,Ask-StopLoss*point,Ask+TakeProfit*point,"",Magic,0,Blue);
        if(ticket>0)
              {
               if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
                  Print("Открыт ордер BUY : ",OrderOpenPrice());
              }
            else
              {
               Print("Ошибка открытия BUY ордера : ",GetLastError());
               return;
              }
     }

//---- sell
   if(MA1_1>MA2_1 && MA1_0<MA2_0)
     {
      ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,slipp,Bid+StopLoss*point,Bid-TakeProfit*point,"",Magic,0,Red);
        if(ticket>0)
              {
               if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
                  Print("Открыт ордер SELL : ",OrderOpenPrice());
              }
            else
              {
               Print("Ошибка открытия SELL ордера : ",GetLastError());
               return;
              }
     }
   }
//----
   for(i = OrdersTotal()-1; i >= 0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderMagicNumber()!=Magic || OrderSymbol()!=Symbol()) continue;
      //---- check order type
      if(OrderType()==OP_BUY)
        {
         if(Bid>=(OrderOpenPrice()+TakeProfit*point)) // проверим не пора ли закрываться по профиту
          {
            resalt = OrderClose(OrderTicket(),OrderLots(),Bid,slipp,Blue); // закрываем длинную позицию по профиту
            break;
          }
         if(Bid<=(OrderOpenPrice()-StopLoss*point))   // проверим не пора ли закрываться по ст.лоссу
          {
            resalt = OrderClose(OrderTicket(),OrderLots(),Bid,slipp,Blue); // закрываем длинную позицию по стопу
            break;
          }
        }
      else
        {
         if(Ask<=(OrderOpenPrice()-TakeProfit*point))
          {
            resalt = OrderClose(OrderTicket(),OrderLots(),Ask,slipp,Red);  // закрываем короткую позицию по профиту
            break;
          }
         if(Ask>=(OrderOpenPrice()+StopLoss*point))
          {
            resalt = OrderClose(OrderTicket(),OrderLots(),Ask,slipp,Red);          // закрываем короткую позицию по стопу
            break;
          }
        }
       }

   return;

  }
Разбирал и твой код. Нашлись такие косяки. Кстати, благодаря им я и нашел ошибку, которую описал выше.
1) slipp для 4х-знака забыл задать.
2) Не ошибка, но лучше наверно привыкнуть изначально писать выражение
point = 10.0 * point;
как point *= 10;
Потому что это одно и то же, а путаницы, как мне кажется, меньше. Надо только запомнить.
3)
total=OrdersTotal();
if (total<1)
Здесь у тебя проверяет общее количество отложенных и рыночных ордеров на счете.
Нет проверки на магик и символ. Поэтому, если будет хоть какой-то ордер, на любом символе и с любым магиком, то уже этот советник не откроет ордер. Если я не ошибаюсь.

Закрытие по стопу и тейку, у тебя получается виртуальное.

А у меня была ошибка, что в один момент начинает выставлятся куча ордеров на селл. Оказалось я else if на открытие по второму условию задал за пределами тела оператора
if (CountTrades() == 0) .

Да и еще одно примечание, так скажем, там где комментарии для входных параметров, можно писать другие названия. Они и будут видны в окне настроек.
 
Последнее редактирование:

gravity

Местный знаток
Практическое применение многомерных массивов.
Например можно в двухмерный массив Price[][4] загнать цены бара High, Low, Open, Close. В 0 измерении будут бары, а в 1 измерении 4 цены.
Код:
double Price[10][4];
for(int i=0; i<10; i++)
{
Price[i][0]=iHigh(NULL,PERIOD_M1,i);
Price[i][1]=iLow(NULL,PERIOD_M1,i);
Price[i][2]=iOpen(NULL,PERIOD_M1,i);
Price[i][3]=iClose(NULL,PERIOD_M1,i);
}
Этот цикл заполнит ценами последних 10 баров М1 таймфрейма.

Напишите скрипт, который запишет в двухмерный массив цены открытия, цены закрытия, лоты, прибыль в валюте депозита с учётом свопов и комиссий, всех исторических ордеров счёта.
После этого, напечатает в лог всё что в массиве. Построчно. Каждый ордер в отдельной строке.
В конце напечатает среднюю прибыль в валюте депозита по всем ордерам.

Сложновато. Пытался.
Вот обрывки мыслей. Как все это правильно сложить, не знаю.
Может попроще задачу, ну или как эта решается?
Код:
#property strict

//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
// Напишите скрипт, который запишет в двухмерный массив цены открытия, цены закрытия, лоты,
// прибыль в валюте депозита с учётом свопов и комиссий, всех исторических ордеров счёта.
// После этого, напечатает в лог всё что в массиве. Построчно. Каждый ордер в отдельной строке.
// В конце напечатает среднюю прибыль в валюте депозита по всем ордерам.
{
double info[][4];

   for(int i=0;i<OrdersHistoryTotal();i++)         // считаем все исторические ордера на счете
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) // если ордер не выбран, то...
            {
               Print("Ошибка при доступе к исторической базе (",GetLastError(),")"); // выводим сообщение об ошибке и...
               break;                                                                // прерываем подсчет ордеров                                                         
            } 
         else
                  {
                     info[i][0]=OrderLots();
                     info[i][1]=AccountProfit() + OrderSwap() + OrderCommission();
                     info[i][2]=OrderClosePrice();
                     info[i][3]=OrderOpenPrice();
                  }
      }

Print("Лот = " info[i][0] ,"Профит = " info[i][1], "Цена закрытия = " info[i][2], "Цена открытия = " info[i][3])
 
Последнее редактирование:
Верх