Понедельник, 2025-07-07, 3:31 AM
Главная Регистрация RSS
Приветствую Вас, Гость

Меню сайта
Форма входа
Категории раздела
Поиск

  • БУДДАРА

  • «ПРИБЫЛЬНЫЕ ФОРЕКС СОВЕТНИКИ ИНДИКАТОРЫ И ТОРГОВЫЕ СИСТЕМЫ БЕСПЛАТНО»
    Ваш e-mail: *
    Ваше имя: *
    Подписчиков:




    Друзья сайта


  • БУДДАРА

  • «ПРИБЫЛЬНЫЕ ФОРЕКС СОВЕТНИКИ ИНДИКАТОРЫ И ТОРГОВЫЕ СИСТЕМЫ БЕСПЛАТНО»
    Ваш e-mail: *
    Ваше имя: *
    Подписчиков:







    Статистика

    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0
    Главная » Статьи » Форекс Советники

    Рождение форекс эксперта. Стохастическая Система ч1

    Рождение форекс эксперта. Стохастическая Система

    В данной статье я покажу, шаг за шагом, как был написан эксперт для Стохастической системы.

    Напомню правила торговли по этой системе:

    Общие правила:
    1. Торговые сигналы рассматриваются с 7.00 до 15.00 EST. (с 13.00 по 21.00 CET (используется в MetaTrader4))
    2. Безусловный выход из позиции в 16.00 EST (22.00 CET) (позиция не переносится на следующий день).
    3. Закрытие первой части позиции производится с целью по прибыли в 10 пунктов.
    Правила для длинной позиции:
    1. Покупаем, когда линия %К, находившаяся ниже уровня 30, пересекает уровень 50.
    2. Закрываем позицию на 2-ом снижении линии %К. Местоположение снижения не имеет значения.
    3. Закрываем позицию, если линия %К пересекает уровень 40 (защита от движения в противоположную сторону).
    Правила для короткой позиции:
    1. Продаем, когда линия %К, находившаяся выше уровня 70, пересекает уровень 50.
    2. Закрываем позицию на 2-ом повышении линии %К. Местоположение снижения не имеет значения.
    3. Закрываем позицию, если линия %К пересекает уровень 60 (защита от движения в противоположную сторону).

    Замечание: в эксперте, который мы будем писать, одновременно будут открываться два одинаковых ордера BUY или SELL. Это сделано для того, чтобы упростить алгоритм работы эксперта. Все дело в том, что при достижении профита в 10 пунктов предполагается, по правилам системы, закрыть часть позиции, а это проще сделать, если у нас открыто 2 одинаковых ордера. В этом случае достаточно закрыть один из ордеров, хотя, даже и этого нам не нужно делать, т.к. он закроется автоматически при достижении профита в 10 пунктов, потому что при открытии этого ордера мы выставим значение TakeProfit равным 10 пунктов. Итак, приступаем к написанию эксперта на MQL4 для MetaTrader4. Я предполагаю, что Вы имеете начальные представления об MQL4. Если нет, то прочитайте справку по MQL4. И вообще, в любом случае начинать изучать язык лучше с прочтения справки по данному языку. Это же касается и языка программирования MQL4. Открываем MetaEditor и создаем нового эксперта. Для этого идем в меню "Файл" -> "Создать…"-> выбираем "Советник". Далее вводим необходимую информацию, при этом поле "параметры" оставляем пустым. Параметры мы добавим по ходу написания эксперта. Жмем кнопку "Готово", и вот, что мы в итоге получим:

    1. //+-----------------------------------------------------------+ 
    2. //|                                      stochastic_system.mq4| 
    3. //|                                             Павел Смирнов | 
    4. //|                                          www.autoforex.ru | 
    5. //+-----------------------------------------------------------+ 
    6. #property copyright "Павел Смирнов" 
    7. #property link      "www.autoforex.ru" 
    8.  
    9. int init() 
    10.   { 
    11.    return(0); 
    12.   } 
    13.  
    14. int deinit() 
    15.   { 
    16.    return(0); 
    17.   } 
    18.  
    19. int start() 
    20.   { 
    21.    return(0); 
    22.   }  

    Я убрал некоторые закомментированные строки, которые автоматически вставляются редактором, исключительно для экономии места. Система построена на основе Стохастика, поэтому нам потребуется получать значения этого индикатора с помощью встроенной функции iStochastic(). Добавляем три строчки, в которых происходят расчеты значений индикатора:

    1. int start() 
    2.  { 
    3.    double stoch_1=iStochastic(NULL,0,K,D,slowing,Average_method,price_field,MODE_MAIN,1); 
    4.    double stoch_2=iStochastic(NULL,0,K,D,slowing,Average_method,price_field,MODE_MAIN,2); 
    5.    double stoch_3=iStochastic(NULL,0,K,D,slowing,Average_method,price_field,MODE_MAIN,3); 
    6.  
    7.    return(0); 
    8.  }   

    Так же объявляем внешние переменные, которые задают параметры Стохастика. Это позволит нам менять их во время тестирования:

    1. extern int K=9; 
    2. extern int D=3; 
    3. extern int slowing=5; 
    4. extern int Average_method=2; 
    5. extern int price_field=0;    

    Для вычислений нам потребуется именно три значения Стохастика т.к. нам нужно будет определять изменение направления в его движении. Причем заметьте, что мы вычисляем значения Стохастика только на 3-х уже сформировавшихся свечах предшествующих текущему, нулевому бару. Это важно, так как текущий бар при реальной торговле будет постоянно меняться, пока не примет окончательную форму с приходом нового бара. Текущее значение Стохастика, которое соответствует текущему, или нулевому бару, постоянно меняется с приходом новых тиков, т.к. сам нулевой бар изменяется. Все остальные свечи уже сформированы, и их можно использовать для расчетов, или же при принятии решений.

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

    1. int Hour_curr=TimeHour(TimeCurrent()); 

    Все приготовления сделаны, и наш эксперт принимает вид:

    1. //+------------------------------------------------------------------+ 
    2. //|                                             stochastic_system.mq4| 
    3. //|                                                    Павел Смирнов | 
    4. //|                                                 www.autoforex.ru | 
    5. //+------------------------------------------------------------------+ 
    6. #property copyright "Павел Смирнов" 
    7. #property link      "www.autoforex.ru" 
    8.  
    9. extern int K=9; 
    10. extern int D=3; 
    11. extern int slowing=5; 
    12. extern int Average_method=2; 
    13. extern int price_field=0; 
    14.  
    15. int init() 
    16.   { 
    17.    return(0); 
    18.   } 
    19.  
    20. int deinit() 
    21.   { 
    22.    return(0); 
    23.   } 
    24.  
    25. int start() 
    26.   { 
    27.     double stoch_1=iStochastic(NULL,0,K,D,slowing,Average_method,price_field,MODE_MAIN,1); 
    28.     double stoch_2=iStochastic(NULL,0,K,D,slowing,Average_method,price_field,MODE_MAIN,2); 
    29.     double stoch_3=iStochastic(NULL,0,K,D,slowing,Average_method,price_field,MODE_MAIN,3); 
    30.     int Hour_curr=TimeHour(TimeCurrent()); 
    31.  
    32.     return(0); 
    33.   } 

    Теперь займемся правилами торговли. Реализуем следующее правило, вход в длинную позицию: «Покупаем, когда линия %К, находившаяся ниже уровня 30, пересекает уровень 50».

    Эту проверку нужно производить только в том случае, если еще не открыто ни одной позиции, т.е. OrdersTotal()<1, и не забываем, что торговля ведется строго с 13.00 по 21.00 CET:

    1. if(OrdersTotal()<1) 
    2.      { 
    3.        if((Hour_curr>=13)&&(Hour_curr<21))//проверка сигналов только в этот промежуток времени 
    4.          { 
    5.            // здесь будем проверять условия для входа в рынок 
    6.          } 
    7.      }   

    Ну а теперь, внутри этой конструкции, будем проводить проверку на выполнение условия для длинной позиции. Для этого нам потребуется переменная, которая говорила бы нам, что Стохастик находился ниже уровня 30, до того как пересек уровень 50. Добавляем строку, в которой переменная K_level будет приравнена к 30, когда Стохастик опустится ниже уровня 30. Добавим ее в начало функции start(), например, сразу после объявления переменной Hour_curr:

    1. if (stoch_1<30) K_level=30; 

    Не забываем добавить объявление переменной K_level. Она должна быть объявлена как глобальная, чтобы ее значение не обнулялось каждый раз при вызове функции start(). Поэтому объявляем ее сразу после внешних переменных:

    1. extern int K=9; 
    2. extern int D=3; 
    3. extern int slowing=5; 
    4. extern int Average_method=2; 
    5. extern int price_field=0; 
    6.  
    7. int K_level=0; 
    8.  
    9. int init() 
    10.   { 
    11.    return(0); 
    12.   }  

    Теперь, для входа в длинную позицию, достаточно проверить, что K_level = 30 и Стохастик имеет значение больше 50. Это и будет считаться приказом на покупку. На MQL4 это выглядит так:

    1. if((K_level==30)&&(stoch_1>50.0))//сигнал на покупку 
    2.  { 
    3.    RefreshRates(); 
    4.    ticket=OrderSend(Symbol(),OP_BUY,0.1,Ask,10,0,0,"buy_order1",1,0,Red); 
    5.    ticket=OrderSend(Symbol(),OP_BUY,0.1,Ask,10,0,Ask+TakeProfit*Point,"buy_order2",2,0,Red); 
    6.    K_level=50; 
    7.  }   

    Функция RefreshRates() в данном случае используется для того, чтобы обновить значение переменной Ask, которая используется в функции OrderSend(…). Этого можно было и не делать, так как в нашем случае, ввиду примитивных вычислений, переменная Ask вряд ли изменится за время проведения вычислений. Все же, я рекомендую использовать функцию RefreshRates() даже в этом случае, потому как вероятность того, что переменная Ask изменится, все же есть.

    Далее идут подряд две функции OrderSend(…). Первая открывает ту часть совокупной позиции, которая будет закрыта на втором снижении линии %К. Поэтому значения стоплосс и тейкпрофит в этой функции равны нулю. Вторая открывает часть позиции, которая будет закрываться при достижении профита равного 10 (это значение задается внешней переменной TakeProfit).

    Последней строчкой в этом блоке мы "обнуляем" пременную K_level, присвоив ей значение равное 50. Стохастик должен, теперь, снова опуститься ниже уровня 30, чтобы эксперт получил возможность в будущем совершить сделку.

    Не забываем объявить две переменные, одну локальную – ticket (объявляется внутри функции start()), другую внешнюю – TakeProfit (объявляется там же где и все внешние переменные).

    Аналогично добавляем блок для входа в короткую позицию. Он выглядит точно так же за исключением некоторых отличий. Описывать их не буду, потому что все понятно из кода MQL4-программы.

    На данный момент мы имеем следующий код:

    1. //+------------------------------------------------------------------+ 
    2. //|                                             stochastic_system.mq4| 
    3. //|                                                    Павел Смирнов | 
    4. //|                                                 www.autoforex.ru | 
    5. //+------------------------------------------------------------------+ 
    6. #property copyright "Павел Смирнов" 
    7. #property link      "www.autoforex.ru" 
    8.  
    9. extern int TakeProfit=10; 
    10.  
    11. extern int K=9; 
    12. extern int D=3; 
    13. extern int slowing=5; 
    14. extern int Average_method=2; 
    15. extern int price_field=0; 
    16.  
    17. int K_level=0; 
    18.  
    19. int init() 
    20.   { 
    21.    return(0); 
    22.   } 
    23.  
    24. int deinit() 
    25.   { 
    26.    return(0); 
    27.   } 
    28.  
    29. int start() 
    30.   { 
    31.     int ticket=0; 
    32.     double stoch_1=iStochastic(NULL,0,K,D,slowing,Average_method,price_field,MODE_MAIN,1); 
    33.     double stoch_2=iStochastic(NULL,0,K,D,slowing,Average_method,price_field,MODE_MAIN,2); 
    34.     double stoch_3=iStochastic(NULL,0,K,D,slowing,Average_method,price_field,MODE_MAIN,3); 
    35.     int Hour_curr=TimeHour(TimeCurrent()); 
    36.  
    37.     if (stoch_1>70) K_level=70; 
    38.     if (stoch_1<30) K_level=30; 
    39.     if(OrdersTotal()<1) 
    40.       { 
    41.         if((Hour_curr>=13)&&(Hour_curr<21))//проверка сигналов только в этот промежуток времени 
    42.           { 
    43.             if((K_level==30)&&(stoch_1>50.0))//сигнал на покупку 
    44.               { 
    45.                 RefreshRates(); 
    46.                 ticket=OrderSend(Symbol(),OP_BUY,0.1,Ask,10,0,0,"buy_order1",1,0,Red); 
    47.                 ticket=OrderSend(Symbol(),OP_BUY,0.1,Ask,10,0,Ask+TakeProfit*Point,"buy_order2",2,0,Red); 
    48.                 K_level=50; 
    49.               } 
    50.             if((K_level==70)&&(stoch_1<50.0))//сигнал на продажу 
    51.               { 
    52.                 RefreshRates(); 
    53.                 ticket=OrderSend(Symbol(),OP_SELL,0.1,Bid,10,0,0,"sell_order1",1,0,Blue); 
    54.                 ticket=OrderSend(Symbol(),OP_SELL,0.1,Bid,10,0,Bid-TakeProfit*Point,"sell_order2",2,0,Red); 
    55.                 K_level=50; 
    56.               } 
    57.           } 
    58.       } 
    59.  
    60.     return(0); 
    61.   }  

    Теперь давайте добавим в эксперта блок закрытия всех сделок в 22.00 CET, т.к. это одно из правил торговой системы, и его проще реализовать на MQL4, нежели другие правила для закрытия сделок:

    1. if (Hour_curr>=22)//безусловное закрытие всех позиций 
    2.  { 
    3.  while(OrdersTotal()>0) 
    4.    { 
    5.      CloseDirect(0,"Принудительное закрытие сделки в 22.00, ticket="); 
    6.    } 
    7.  }   

    С условием - Hour_curr>=22 все понятно - проверяем, что текущий час больше или равен 22, т.е. наступило время для закрытия всех сделок. Можно было проверять на строгое равенство 22 часам, но это хуже, так как возможна ситуация, когда ни одной котировки с таким значением времени не окажется. А так, мы и в 22, и в 23 часа сможем закрыть сделки. Если, произойдет так, что в период с 22.00 по 23.59 не придет ни одной котировки, или же, при тестировании на истории, в исторических данных не будет котировок в этот период, то наши сделки перенесутся на следующий день. При реальной торговле этого, в принципе, можно избежать, если добавить в эксперта проверку локального времени с помощью функции TimeLocal(). Но это, к сожалению, не поможет при тестировании эксперта на исторических данных.

    Далее идет цикл, в котором происходит вызов функции CloseDirect(…), которая закрывает первую позицию в списке открытых ордеров. Закрытие первого в списке ордера мы вынесли в отдельную функцию с той целью, что данная функция нам потребуется еще несколько раз, когда будет реализован алгоритм закрытия ордеров на 2-ом снижении (повышении) линии %К и при обратном движении Стохастика.

    Итак, функция CloseDirect(…):

    1. void CloseDirect(int cntr, string comm) 
    2.  { 
    3.    double closeprice; 
    4.    if(OrderSelect(cntr,SELECT_BY_POS,MODE_TRADES)) 
    5.      { 
    6.        RefreshRates(); 
    7.        if (OrderType()==OP_BUY) 
    8.          closeprice=Bid; 
    9.        else 
    10.          closeprice=Ask; 
    11.        if (OrderClose(OrderTicket(),OrderLots(),closeprice,10,Green)) 
    12.          { 
    13.            Print(comm, OrderTicket()); 
    14.          } 
    15.        else 
    16.          { 
    17.            Print("ОШИБКА в CloseDirect():OrderClose() - ",GetLastError()); 
    18.          } 
    19.      } 
    20.    else 
    21.      { 
    22.        Print("ОШИБКА в CloseDirect():OrderSelect() - ",GetLastError()); 
    23.      } 
    24.  }   

    Функция имеет два входных параметра, cntr – порядковый номер открытого ордера, который нужно закрыть и comm. – комментарий, который выводится в журнал для того, чтобы иметь возможность идентифицировать причину закрытия ордера.

    Алгоритм работы этой функции простой: сначала выбираем ордер с порядковым номером cntr из списка открытых ордеров при помощи функции OrderSelect(…):

    1.     if(OrderSelect(cntr,SELECT_BY_POS,MODE_TRADES)) 
    2.   { 
    3.     //Ордер выбран и здесь можно делать с ним все, что душе угодно 
    4.   } 
    5. else 
    6.   { 
    7.     Print("ОШИБКА в CloseDirect():OrderSelect() - ",GetLastError()); 
    8.   }  

    Затем, в зависимости от того, ордер какого типа мы будем закрывать, выбираем цену закрытия - Bid для длинной позиции, Ask – для короткой:

    1. RefreshRates(); 
    2. if (OrderType()==OP_BUY) 
    3.   closeprice=Bid; 
    4. else 
    5.   closeprice=Ask;    

    И, наконец, закрываем позицию:

    1.     if (OrderClose(OrderTicket(),OrderLots(),closeprice,10,Green)) 
    2.   { 
    3.     Print(comm, OrderTicket()); 
    4.   } 
    5. else 
    6.   { 
    7.     Print("ОШИБКА в CloseDirect():OrderClose() - ",GetLastError()); 
    8.   }  
    Рождение форекс эксперта. Стохастическая Система ч2

     
    Категория: Форекс Советники | Добавил: forex_s (2009-10-25)
    Просмотров: 3385 | Комментарии: 3 | Рейтинг: 0.0/0
    Всего комментариев: 1
    1 waiLiaDor  
    0
    ohio state university school of pharmacy http://sundrugstore.net/products/aldactone.htm top online pharmacy

    Имя *:
    Email *:
    Код *:
    СВЕРХПРИБЫЛЬНЫЕ СОВЕТНИКИ И ИНДИКАТОРЫ ДЛЯ ФОРЕКС >>>Торговые системы для Forex !