+321 123 4567
info@test.com
My Account
Forex Lab
  • Главная
  • Софт
  • Стратегии
  • Брокер
  • Блог
  • Item A
    • Sub item A1
    • Sub item A2
  • Item B
    • Sub item B1
    • Sub item B2
  • Item C
    • Sub item C1
    • Sub item C2

Глобальные переменные и «светофор» приправленные Мартингейлом

Мы уже использовали в предыдущих уроках глобальные переменные, видимые в любом месте программы. Есть еще один вид глобальных переменных (GlobalVariables).  Это переменная клиентского терминала, ее значения доступны всем программам клиентского терминала (скрипт, индикатор, советник). С ее помощью, например можно организовать связь между двумя советниками или между советником и индикатором. GV-переменная записывается на жесткий диск, так что в ней сохраняются данные, даже если компьютер выключен. Если к GV-переменной не обращались в течении 30 дней она автоматически удаляется с жесткого диска.

С GV-переменной одновременно может работать только одна программа. Если к  GV-переменной одновременно обратятся несколько советников, данные скорей всего будут испорчены.

Несколько функций для работы с GV-переменными.

GlobalVariableCheck(string имя_GV-переменной) – Проверяет существует ли данная переменная. Если да возвращает true иначе false.

GlobalVariableGet(string имя_GV-переменной) – Возвращает значение существующей глобальной переменной (тип double), или 0 в случае ошибки.

GlobalVariableSet(string имя_GV-переменной,double числовое_значение) – Если переменой нет, создает. Если есть, присваивает ей новое значение.

GlobalVariableSetOnCondition(stringимя_GV-переменной,double новое_числовое_значение,double проверочное_числовое_значение) – Устанавливает новое значение существующей глобальной переменной и вернет true, если переменная существует и текущее значение равно проверочному значению. В других случаях вернет false.

В этом уроке рассмотрим пример применения GV-переменной. Создадим GV-переменную «Semafor», она будет иметь значение -1 или 1, «зеленый» и «красный свет» соответственно.

Задача организовать «светофор», что бы при работе нескольких экспертов они не мешали один одному и торговали по очереди. Для этого напишем две функции Lock() и UnLock(),Lock() будет вызываться перед OrderSend а UnLock() после.

// проверяем, есть ли от других экспертов нам "зеленый свет" для торговли... если есть пытаемся заблокировать торговлю для других
if(Lock() == -1) return(0); // если не удалось заблокировать... выходим
// заблокировали... теперь можно выставить ордер
OrderSend(Symbol(),cmd,lot,price,3,stoploss,takeprofit,NULL,Magic№,0,Green);
UnLock(); // разблокируем... разрешаем торговлю для других

Перед торговой операцией советник проверяет, есть ли «зеленый свет» (не торгует ли другой советник в данный момент). Вызываем функции Lock() она проверяет, есть ли «зеленый» для торговли, если да устанавливает «красный» для других советников (блокирует их). Выполняет все необходимые торговые операции и вызывает функцию UnLock() которая переключает «светофор» на «зеленый», разрешает другим экспертам совершать торговые операции.

Функции Lock() и UnLock() почти идентичны, в UnLock() GlobalVariableSetOnCondition помещена в бесконечный цикл.

while(!IsStopped()) // если эксперт остановлен - выходим из цикла
 {                  // бесконечный цикл
  if(GlobalVariableSetOnCondition("Semafor", -1.0, 1.0)) return(-1);// зажгли "зеленый". разблокировали всех
  Sleep(100);       // если не удалось разблокировать. ждем 0.1 сек. и пробуем снова
 }

Если не удалось зажечь «зеленый» сразу, то в бесконечном цикле будем пробовать снова и снова, пока не зажжется «зеленый» или будет нажата кнопка остановки «эксперта» (IsStopped).

IsStopped() – Возвращается TRUE, если программа (эксперт или скрипт) получила команду на завершение своей работы, иначе возвращает FALSE.

Теперь о самом «эксперте». Все это сделаем для примера в «советнике» торгующем по системе Мартингейла.

Алгоритм «советника»:
Если нет открытых ордеров «эксперт» смотрит историю закрытых ордеров. И остатний из них закрылся с профитом значит, предыдущий цикл завершился успешно, начинаем новый открываем buy ордер с выставленными стоплосом и тейкпрофитом. Если же предыдущий ордер  закрылся по стоплосу значит, цикл не закончился «советник» открывает ордер в противоположную сторону с удвоенным лотом. Если цена пошла в нужную сторону и ордер закрылся по тейкпрофиту, цикл завершен и сразу открывается новый buy ордер (начало нового цикла).

При переключении в настройках «советника» Trade в FALSE и если есть открытый ордер, «эксперт» не перестанет выставлять ордера, пока один из них не закроется с прибылью (завершится цикл). И новый цикл не начнется.

Функция HistoryOrders() в отличии от Orders() из предыдущих уроков ведет среди закрытых ордеров, благодаря идентификатору MODE_HISTORY в функции OrderSelect.

OrdersHistoryTotal() – Возвращает количество закрытых и удаленных ордеров в истории текущего счета, загруженной в клиентском терминале. Размер списка истории зависит от текущих настроек вкладки «История счета» терминала.

Полный код программы:

//+------------------------------------------------------------------+
//|                                                       Martin.mq4 |
//|                      Copyright © 2011, MetaQuotes Software Corp. |
//|                                         |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

//--- input parameters
extern int  Magic№     = 777;
extern bool Trade      = false; //запрещаем/разрешаем торговлю
extern int  TakeProfit = 50;
extern int  StopLoss   = 50;

int LastOrder; // позиция в массиве останего из закрытых ордеров

double HMas_Ord_New[1000][7]; // массив закрытых ордеров
double HMas_Ord_Old[1000][7];

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
 {
  double Lot, LastLot, profit;
  if(OrdersTotal() == 0)         // если нет открытых ордеров.. будем открывать
   {
    HistoryOrders();                                     // заполняем масив закрытых ордеров
    profit = HMas_Ord_New[LastOrder][6];                 // получаем профит останего ордера
    if(Trade == true && ((profit > 0) || (profit == 0))) // если прошлый ордер закрылся с прибылью...
     {                                                   // начинаем новый цикл
      Send(OP_BUY,0.01,Ask,Ask - StopLoss*Point);        // открываем бай
      return(0);
     }
    if((profit > 0) || (profit == 0)) return(0);
 // если дошли сюда значит прошлый ордер закрылся с убытком
    LastLot = HMas_Ord_New[LastOrder][4]; // получаем размер лота останего из закрытых ордеров
// определяем какое это колено Мартина :)
    if(LastLot == 0.01) Lot = 0.02; // если лот убыточного ордера был 0.01.. лот нового будет 0.02
    if(LastLot == 0.02) Lot = 0.04; // если лот убыточного ордера был 0.02.. лот нового будет 0.04
    if(LastLot == 0.04) Lot = 0.08;
    if(LastLot == 0.08) Lot = 0.16;
    if(LastLot == 0.16) Lot = 0.32;
    if(LastLot == 0.32) Lot = 0.64;
    if(LastLot == 0.64) Lot = 1.28;
    if(LastLot == 1.28) Lot = 2.56;
    if(LastLot == 2.56) Lot = 5.12;
    if(HMas_Ord_New[LastOrder][3] == 0) Send(OP_SELL,Lot,Bid,HMas_Ord_New[LastOrder][5]); // если прошлый ордер был бай.. открываем селл
    if(HMas_Ord_New[LastOrder][3] == 1) Send(OP_BUY,Lot,Ask,HMas_Ord_New[LastOrder][5]); // если прошлый ордер был селл.. открываем бай
   }
  return(0);
 }
//-------------------------------------------------------------------+
// Функция открытия ордеров                                          |
//-------------------------------------------------------------------+
int Send(int cmd, double lot, double price, double stoploss)
 {
  double takeprofit;
  if(cmd == OP_BUY) takeprofit = price + TakeProfit*Point;
  if(cmd == OP_SELL) takeprofit = price - TakeProfit*Point;
// проверяем, есть ли от других экспертов нам "зеленый свет" для торговли... если есть пытаемся заблокировать торговлю для других
  if(Lock() == -1) return(0);          // если не удалось заблокировать... выходим
// заблокировали... теперь можно выставить ордер
  OrderSend(Symbol(),cmd,lot,price,3,stoploss,takeprofit,NULL,Magic№,0,Green);
  UnLock();                           // разблокируем... разрешаем торговлю для других
 }
//-------------------------------------------------------------------+
//учет закрытых ордеров... сколько, каких, цена открытия и тд.       |
//-------------------------------------------------------------------+
int HistoryOrders()
 {
  int ticket;
  int Qnt = 0;                 // Счётчик количества ордеров // Обнуление счётчика ордеров
  LastOrder = 0;
  ArrayCopy(HMas_Ord_Old, HMas_Ord_New);  // Сохраняем предыдущую историю
  ArrayInitialize(HMas_Ord_New,0);        // Обнуление массива
  for(int i = 0; i < OrdersHistoryTotal(); i++)    {     Qnt++;     if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) == false) continue;//Если есть следующ.     if(Magic№ != OrderMagicNumber()) continue;     if(Symbol() != OrderSymbol()) continue;            //.. и наша вал.пара     HMas_Ord_New[Qnt][1] = OrderMagicNumber();         // Магическое число     HMas_Ord_New[Qnt][2] = OrderTicket();              // Номер ордера     HMas_Ord_New[Qnt][3] = OrderType();                // Тип ордера     HMas_Ord_New[Qnt][4] = OrderLots();                // Количество лотов     HMas_Ord_New[Qnt][5] = OrderOpenPrice();           // Курс открытия орд     HMas_Ord_New[Qnt][6] = OrderProfit();     if(OrderTicket() > ticket)
     {                 // ищем останий между закрытыми
      ticket = OrderTicket();
      LastOrder = Qnt; // запоминаем позицию в масиве останего ордера
     }
   }
  HMas_Ord_New[0][0] = Qnt;                         // Колич. ордеров
  return(0);
 }
//+------------------------------------------------------------------+
//| Функция блокировки торговли для других экспертов                 |
//+------------------------------------------------------------------+
int Lock()
 {
  bool CheckGV = false;
  CheckGV = GlobalVariableCheck("Semafor");// контроль переменной перед использованием
  if(CheckGV == false) // проверим, существует ли переменная Semafor
   {                                    // переменная не существует,
    if(GetLastError() != 0) return(-1);
// ошибки нет
    if(GlobalVariableSet("Semafor", -1.0) == 0) return(-1);// создадим переменную
// переменная создана
   }
  if(GlobalVariableGet("Semafor") == -1.0)
   {                                                        // "зеленый свет" загорелся, зажигаем "красный свет"
    if(GlobalVariableSetOnCondition("Semafor", 1.0, -1.0)) return(1);// зажгли "красный". других заблокировали
                                                            // нас опередили, поэтому ждем "зеленого света"
    Sleep(100);
   }
  return(-1);
 }
//+------------------------------------------------------------------+
//| Функция разблокировки торговли для других экспертов              |
//+------------------------------------------------------------------+
int UnLock()
 {
  bool CheckGV = false;
  CheckGV = GlobalVariableCheck("Semafor");  // контроль переменной перед использованием
  if(CheckGV == false)                       // проверим, существует ли переменная Semafor
   {                                         // переменная не существует
    if(GetLastError() != 0) return(-1);
    if(GlobalVariableSet("Semafor", -1.0) == 0) return(-1); // создадим переменную
                          // переменная создана, поэтому выходим return(-1);
   }
  while(!IsStopped())     // если эксперт остановлен - выходим из цикла
   { // бесконечный цикл
    if(GlobalVariableSetOnCondition("Semafor", -1.0, 1.0)) return(-1); // зажгли "зеленый". разблокировали всех
    Sleep(100);                                 // если неудалось разблокировать. ждем 0.1 сек. и пробуем снова
   }
 }

Внимание. Этот «эксперт» в отличие от тех, что мы изучали ранее, полуфабрикат его можно использовать только в тестере. Все что мы учили в прошлых уроках о «правильной» торговле (обработка ошибок и тд.) здесь отсутствуют. Довести его до ума это Ваше домашнее задание.

Исходник: Martin

Трейлинг — https://forexlab.ru/mql-trailing/

Предыдущая запись
Трейлинг
Следующая запись
Защита советника

Свежие записи

  • Как работают биржи: классификация, виды, особенности
  • Moving Average: описание, настройка, стратегии
  • Что такое Non farm payrolls
  • HQBroker: мошенники или честный брокер
  • Торговля на бирже для начинающих: полный гайд

Рубрики

  • CFD (2)
  • FOREX (14)
  • Meta Trader 5 (6)
  • MetaTrader 4 (13)
  • Price Action (9)
  • QUIK (2)
  • Акции (9)
  • Бинарные опционы (11)
  • Биржи (1)
  • Брокеры (5)
  • Волновой анализ (7)
  • Графический анализ (28)
  • Индикаторный анализ (36)
  • Криптовалюты (2)
  • Методы управления капиталом (11)
  • Новости проекта Forex Lab (2)
  • Объемы (10)
  • Основы торговли (7)
  • Подкаст (7)
  • Полезное (3)
  • Программирование (20)
  • Психология трейдинга (25)
  • Свечной анализ (2)
  • Скальпинг (1)
  • Технический анализ (19)
  • Торговые платформы (26)
  • Торговые стратегии и системы (73)
  • Фибо (11)
  • Фондовый рынок (27)
  • Фракталы (4)
  • Фундаментальный анализ (19)
  • Фьючерсы (20)

Представленная информация не является индивидуальной инвестиционной рекомендацией, ни при каких условиях, в том числе при внешнем совпадении ее содержания с требованиями нормативно-правовых актов, предъявляемых к индивидуальной инвестиционной рекомендации. Любое сходство представленной информации с индивидуальной инвестиционной рекомендацией является случайным.
Какие либо из указанных финансовых инструментов или операций могут не соответствовать Вашему инвестиционному профилю.
Упомянутые в представленном сообщении операции и (или) финансовые инструменты ни при каких обстоятельствах не гарантируют доход, на который Вы возможно рассчитываете при условии использования предоставленной информации для принятия инвестиционных решений.
Информационный портал ForexLab не несет ответственности за возможные убытки инвестора в случае совершения операций, либо инвестирования в финансовые инструменты, упомянутые в представленной информации.
Во всех случаях определение соответствия финансового инструмента либо операции инвестиционным целям, инвестиционному горизонту и толерантности к риску является задачей инвестора.
Не является образовательной деятельностью. Не сопровождается выдачей документов об образовании и (или) квалификации. При полном или частичном использовании материалов сайта ссылка на https://forexlab.ru/ обязательна.

© 2008-2020 Forex Lab

  • Главная
  • Политика
  • Авторские права
  • Согласие
  • Риски
  • Оферта