English 中文 Español Deutsch 日本語 Português
Комфортная пипсовка

Комфортная пипсовка

MetaTrader 4Трейдинг | 14 февраля 2008, 09:59
5 461 26
Eryomin Sergey
Eryomin Sergey

Введение

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

Пипсовка, сама по себе, считается очень нервным видом торговли. Значительную роль в этом играет необходимость каждый раз указывать лот, уровень TP и SL, отвлекаясь от ценового графика.

Данная статья является продолжением статьи "Моделирование беттинга как средство развития "чувства рынка"". Рекомендую ознакомиться с ней, прежде чем читать далее.

Хочется так же напомнить, что такое "пипсовка". Пипсовка это скоротечная торговля. Как правило, при таком подходе к торговле прибыль фиксируется в 1-10 пипсов (пунктов). Пипсовка славится своей сложностью, нервностью, потребностью в повышенном внимании. Кто-то относится к ней несерьёзно, кто-то считает высшим пилотажем. Однако оценку данной торговли я давать не буду. Об этом написано достаточно много и у каждого своё мнение.


Концепция

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

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

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

Значит, нужен инструмент, который по команде трейдера будет открывать сделку с фиксированным лотом и уровнем TP и SL. Инструмент этот должен работать достаточно просто и по-минимуму отвлекать трейдера от ценового графика.

Создать подобный инструмент достаточно просто средствами языка MQL4.


Реализация

За основу будет взята игра, о которой написано в статье "Моделирование беттинга как средство развития "чувства рынка"". Будет создан инструмент, благодаря которому будет возможно одновременно и играть в эту игру, и торговать.

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

Для реализации, будем рисовать ещё две стрелочки. На один бар назад от текущего. Текущий бар, по-прежнему, будет использоваться для игры. Удаление одной из стрелочек на предыдущем баре будет сигналом для советника к совершению сделки в указанном направлении. Кроме того, для торговли будет убрано ограничение выбора по времени. В изменяемые переменные будет вынесен уровень TP и SL, лот, допустимое проскальзывание и магическое число. Помимо этого, будет возможно через extern bool переменную отключать поддержку торговли, сводя советника только к игре.

Также, при открытии сделки, на график будет наноситься стрелка с именем buy или sell, в зависимости от того, какая сделка будет открыта в данный момент. Это будет делаться для того, чтобы  робот не открывал новых сделок на данной свече. Эта стрелка будет наноситься в 300 пунктов от цены открытия бара, так что пользователь её, скорее всего, даже не будет замечать.

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

В итоге код, со всеми добавлениями получился следующий:

//+------------------------------------------------------------------+
//|                                                       trener.mq4 |
//|                                       Copyright © 2008, FXRaider |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, FXRaider"
extern int gap=2;
extern bool Trading=true;
extern int TP=2;
extern int SL=20;
extern double Lots=0.02;
extern int slippage=1;
extern int MagicNumber=777;
extern int time_limit=30;
int start()
  {
//----
//#################################################################################
//####################################### ИГРА ####################################
//------------------------------
string solution="none"; 
int point, 
    point_neg, 
    point_pos;
//------------------------------    
//+---------------------------------------------------------------+
//|                      поиск выбора "вверх"                     | 
 if(
    ObjectGet("up", OBJPROP_PRICE1)==Open[1]+gap*Point
    &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==1
    &&ObjectFind("down") != 0
    &&ObjectFind("up") == 0
    )
    {
     solution="up";
    }
//|                      поиск выбора "вверх"                     |  
//+---------------------------------------------------------------+
  
//+---------------------------------------------------------------+
//|                      поиск выбора "вниз"                      |     
 if(
    ObjectGet("down", OBJPROP_PRICE1)==Open[1]-gap*Point
    &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==1    
    &&ObjectFind("up") != 0
    &&ObjectFind("down") == 0
    )
    {
     solution="down";
    }
//|                      поиск выбора "вниз"                      |       
//+---------------------------------------------------------------+    
 
//+---------------------------------------------------------------+
//|             расчёт очков при положительном ответе             |
    if((solution=="up"&&Open[1]<Close[1])
      ||(solution=="down"&&Open[1]>Close[1]))
    {
     point=1;
     point_pos=1;
     point_neg=0;     
    }  
//|             расчёт очков при положительном ответе             |   
//+---------------------------------------------------------------+
 
//+---------------------------------------------------------------+
//|             расчёт очков при отрицательном ответе             |    
    if((solution=="up"&&Open[1]>Close[1])
      ||(solution=="down"&&Open[1]<Close[1]))
    {
     point=-1;
     point_pos=0;
     point_neg=1;     
    } 
//|             расчёт очков при отрицательном ответе             |
//+---------------------------------------------------------------+
 
//+----------------------------------------------------------------------------------+
//|                              работа с внешним файлом                             |       
      int handle; 
      double points,     //общий счёт
             points_pos, //счёт положительных ответов
             points_neg; //счёт отрицательных ответов 
       handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv",
                       FILE_CSV|FILE_WRITE|FILE_READ,";");
       if(handle>0) //если файл есть, то читаем его
       { 
        points=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); 
        points_pos=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); 
        points_neg=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits);       
        FileClose(handle);
       } 
       
    if(solution!="none") //если выбор сделан 
    {        
      handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv",
                      FILE_CSV|FILE_WRITE|FILE_READ,";");
      FileWrite(handle ,points+point);         //записываем общий счёт
      FileWrite(handle ,points_pos+point_pos); //записываем счёт положительных ответов
      FileWrite(handle ,points_neg+point_neg); //записываем счёт отрицательных ответов                    
      FileClose(handle); 
    } 
//|                              работа с внешним файлом                             | 
//+----------------------------------------------------------------------------------+    
 
//+------------------------------------------------------------------------------------+
//|                                 работа с объектами                                 |   
  if(iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))>0
     ||ObjectGet("down",OBJPROP_PRICE1)!=Open[0]-gap*Point) 
    {
     ObjectDelete("down"); 
    }  
 if(iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))>0
    ||ObjectGet("up",OBJPROP_PRICE1)!=Open[0]+gap*Point)            
    { 
     ObjectDelete("up"); 
    } 
   
  int sec_lim;  
  if(!time_limit)
  {
   sec_lim=0; 
  }
  else
  {
   sec_lim=TimeCurrent()-time_limit;
  }
  if(sec_lim>ObjectGet("up",OBJPROP_TIME1)
     &&sec_lim>ObjectGet("down",OBJPROP_TIME1) 
     &&ObjectFind("down") == 0&&ObjectFind("up") == 0
     &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==0
     &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==0)            
    { 
     ObjectDelete("up"); 
     ObjectDelete("down");      
    } 
  
   if((ObjectFind("down") != 0&&ObjectFind("up") != 0) //если объектов нет
      &&sec_lim<Time[0])
   {
     ObjectCreate("down", OBJ_ARROW, 0, Time[0], Open[0]-gap*Point); //рисуем стрелку вниз
     ObjectSet("down", OBJPROP_STYLE, STYLE_DOT);
     ObjectSet("down", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN);
     ObjectSet("down", OBJPROP_COLOR, Red);
 
     ObjectCreate("up", OBJ_ARROW, 0, Time[0], Open[0]+gap*Point); //рисуем стрелку вверх
     ObjectSet("up", OBJPROP_STYLE, STYLE_DOT);
     ObjectSet("up", OBJPROP_ARROWCODE, SYMBOL_ARROWUP);
     ObjectSet("up", OBJPROP_COLOR, Blue);
    }      
//|                                 работа с объектами                                 |   
//+------------------------------------------------------------------------------------+
//####################################### ИГРА ####################################
//#################################################################################
 
 
//#################################################################################
//#################################### ТОРГОВЛЯ ###################################
//+------------------------------------------------------------------------------------+  
//|                                работа с объектами I                                | 
  if(iBarShift(NULL,0,ObjectGet("down_1",OBJPROP_TIME1))>1
  ||ObjectGet("down_1",OBJPROP_PRICE1)!=Open[0]-gap*Point
  ||!Trading)  
  {
   ObjectDelete("down_1"); 
  }  
  
  if(iBarShift(NULL,0,ObjectGet("up_1",OBJPROP_TIME1))>1
  ||ObjectGet("up_1",OBJPROP_PRICE1)!=Open[0]+gap*Point
  ||!Trading)  
  { 
   ObjectDelete("up_1"); 
  } 
  
  if(iBarShift(NULL,0,ObjectGet("sell",OBJPROP_TIME1))>0
  ||ObjectGet("sell",OBJPROP_PRICE1)!=Open[0]-300*Point
  ||!Trading) 
  {
   ObjectDelete("sell"); 
  }
  if(iBarShift(NULL,0,ObjectGet("buy",OBJPROP_TIME1))>0
  ||ObjectGet("buy",OBJPROP_PRICE1)!=Open[0]+300*Point 
  ||!Trading)
  
  {
   ObjectDelete("buy"); 
  } 
  
   if(ObjectFind("down_1") != 0&&ObjectFind("up_1") != 0 && Trading)
   {
     ObjectCreate("down_1", OBJ_ARROW, 0, Time[1], Open[0]-gap*Point);
     ObjectSet("down_1", OBJPROP_STYLE, STYLE_DOT);
     ObjectSet("down_1", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN);
     ObjectSet("down_1", OBJPROP_COLOR, Red);
 
     ObjectCreate("up_1", OBJ_ARROW, 0, Time[1], Open[0]+gap*Point);
     ObjectSet("up_1", OBJPROP_STYLE, STYLE_DOT);
     ObjectSet("up_1", OBJPROP_ARROWCODE, SYMBOL_ARROWUP);
     ObjectSet("up_1", OBJPROP_COLOR, Blue);
    }  
//|                                работа с объектами I                                |    
//+------------------------------------------------------------------------------------+     
 if(Trading)
 {
//+----------------------------------------------------------------------------------------------+
//|                              поиск открытых ордеров по паре                                  |
    int pos_sell=0, bar_op_buy, bar_op_sell;
  for (int i_op_sell=OrdersTotal()-1; i_op_sell>=0; i_op_sell--) 
  { 
   if (!OrderSelect(i_op_sell,SELECT_BY_POS,MODE_TRADES)) break; 
   if (Symbol()==OrderSymbol()
   &&(OrderType()==OP_SELLSTOP||OrderType()==OP_SELL)
   &&(OrderMagicNumber()==MagicNumber)
   &&iBarShift(NULL,0,OrderOpenTime())==0)
   {
    pos_sell=1; break;   
   } 
  }
    
    int pos_buy=0;
  for (int i_op_buy=OrdersTotal()-1; i_op_buy>=0; i_op_buy--) 
  { 
   if (!OrderSelect(i_op_buy,SELECT_BY_POS,MODE_TRADES)) break; 
   if (Symbol()==OrderSymbol()
   &&(OrderType()==OP_BUYSTOP||OrderType()==OP_BUY)
   &&(OrderMagicNumber()==MagicNumber)
   &&iBarShift(NULL,0,OrderOpenTime())==0)
   {
    pos_buy=1; break;   
   } 
  }    
//|                              поиск открытых ордеров по паре                                  |
//+----------------------------------------------------------------------------------------------+ 
 
//+------------------------------------------------------------------------------------+  
//|                                работа с объектами II                               |   
 if(pos_buy==1)
 {   
      ObjectCreate("buy", OBJ_ARROW, 0, Time[0], Open[0]+300*Point);
      ObjectSet("buy", OBJPROP_STYLE, STYLE_DOT);
      ObjectSet("buy", OBJPROP_ARROWCODE, SYMBOL_ARROWUP);
      ObjectSet("buy", OBJPROP_COLOR, Red);
 }
 
 if(pos_sell==1)
 {
      ObjectCreate("sell", OBJ_ARROW, 0, Time[0], Open[0]-300*Point);
      ObjectSet("sell", OBJPROP_STYLE, STYLE_DOT);
      ObjectSet("sell", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN);
      ObjectSet("sell", OBJPROP_COLOR, Red);    
 }
//|                                работа с объектами II                               |   
//+------------------------------------------------------------------------------------+ 
  
//+------------------------------------------------------------------------------------+ 
//|                                   открытие сделок                                  |
double sl_buy, sl_sell;
 if(!SL)
 { 
  sl_buy=0;
  sl_sell=0;
 }
 else
 {
  sl_buy=Ask-SL*Point;
  sl_sell=Bid+SL*Point;
 }
  if(
     ObjectGet("up_1", OBJPROP_PRICE1)==Open[0]+gap*Point
     &&iBarShift(NULL,0,ObjectGet("up_1",OBJPROP_TIME1))==1
     &&ObjectFind("down_1") != 0
     &&ObjectFind("up_1") == 0
     &&!pos_buy
     &&ObjectFind("buy") != 0    
     )
     {
      OrderSend(Symbol(),OP_BUY, Lots,Ask,slippage,sl_buy,Ask+TP*Point,"trener",MagicNumber,0,Blue);            
     }
  if(
     ObjectGet("down_1", OBJPROP_PRICE1)==Open[0]-gap*Point
     &&iBarShift(NULL,0,ObjectGet("down_1",OBJPROP_TIME1))==1
     &&ObjectFind("up_1") != 0
     &&ObjectFind("down_1") == 0
     &&!pos_sell
     &&ObjectFind("sell") != 0
     )
     {
      OrderSend(Symbol(),OP_SELL, Lots,Bid,slippage,sl_sell,Bid-TP*Point,"trener",MagicNumber,0,Red);  
     }
//|                                   открытие сделок                                  |  
//+------------------------------------------------------------------------------------+   
 }
//#################################### ТОРГОВЛЯ ###################################
//#################################################################################
 
Comment("Score: ", points," (",points_pos,"/",points_neg,   //выводим счёт
        ") | Time: ", Hour(),":", Minute(),":", Seconds()); //выводим время (для удобства) 
     
   return(0);
  }
//+------------------------------------------------------------------+

Код снабжён всеми необходимыми комментариями.

После нанесения советника на график, будет получена следующая картина:

Где две последние стрелочки - для игры, две стрелочки на предыдущей свече - для открытия ордеров.

Удаление стрелочки на предыдущей свече вызовет выполнение функции OrderSend(), и будет открыт необходимый ордер:



Окно изменения входных параметров будет выглядеть следующим образом:


Переменная "gap" отвечает за количество пунктов, на которые отдалены стрелочки от цены открытия свечи. Переменная "Trading" отвечает за поддержку функции торговли. Переменная "TP" - отвечает за величину уровня TP, в пунктах. Переменная "SL" - отвечает за величину уровня SL, в пунктах. Переменная "Lots" отвечает за размер лота открываемых позиций. Переменная "slippage" отвечает за допустимое проскальзывание в пунктах, который мы готовы принять. Переменная "MagicNunber" отвечает за магическое число, которое присваивается советником открываемым сделкам (нужно для слежения роботом за "своими" ордерами). Переменная "time_limit" отвечает за количество секунд, в течение которых пользователь должен успеть сделать выбор. Если поставить значение "0", то ограничения не будет, т.е. можно делать выбор в течение всей свечи.

Заключение

В итоге получен инструмент для комфортной торговли ордерами с типовыми параметрами (TP, SL, Slippage, лот). Данное средство может быть полезно в любой торговле. Однако наиболее эффективно оно может быть в случаях, когда открывается достаточно большое число сделок за короткий промежуток времени. Например, при пипсовке.

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

Прикрепленные файлы |
trener.mq4 (11.66 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (26)
Eryomin Sergey
Eryomin Sergey | 10 мар. 2008 в 10:57
santjay:
FXraider:
santjay:

Было бы вообще замечательно, если бы была возможность закрывать ордера тем же способом, а не выставлять ТП и СЛ.
Тогда можно было бы торговать на истории используя для торговли свои индикаторы. Может кто-нибудь доработает данный индикатор?
То бишь нужна возможность закрытия советником "своих" сделок, открытых этим роботом, так?
Если да, то впринципе можно сделать. Добавить ещё какой-нибудь графический элемент, и удаление этого элемента будет сигналом для закрытия позиций, открытах роботом. Правда мне пока на ум приходит, как сделать, чтобы закрывало "всё сразу"...
Да, именно это я и имел в виду. Я пробовал использовать скрипт для закрытия поз в реальном времени, но почему-то в тестере стратегий он не закрывает позиции.
Стукни(те) мне в асю - 463847561, там обговорим и сделаю...
Aleksey Sleptsov
Aleksey Sleptsov | 7 сент. 2008 в 20:44

пипсовка - зло!

[Удален] | 6 окт. 2008 в 08:01
Подскажите как прикрепить этот тренер к графику? Я новичёк в этом деле.
[Удален] | 16 дек. 2008 в 00:48

Zdrastvuite Sergey, ja xotela sprosit, pochemu mne ne otkryvaetsia poziciji na live trading. Ja vpuskaju trener neminiaja parametry. No otkrylas tolko odna pozicija i vsio.. Esli mozhite, pozhaluista otvette na rutaskin@hotmail.com

Victor Lukashuck
Victor Lukashuck | 11 апр. 2009 в 16:03

А я бы назвал советник "тренажером для пипсовщика".

Добавлена проверка на минимальность допустимых стопов по данной валюте. Данная модификация для современных систем с 5-ю знаками после запятой.

Индикатор трендовых линий с учетом подхода Т.Демарка Индикатор трендовых линий с учетом подхода Т.Демарка
Индикатор показывает линии тренда отражая самые последние события на рынке. Индикатор построен по рекомендациям и с учетом подхода Томаса Демарка к техническому анализу. Индикатор отображает не только последнее направление тренда, но и предпоследнее противоположное направление тренда.
Использование платформы MetaTrader 4 для выявления благоприятных временных окон (паттернов времени) Использование платформы MetaTrader 4 для выявления благоприятных временных окон (паттернов времени)
Анализ паттернов времени может применяться для рынка Форекс с целью определения наилучшего времени для открытия сделок, а также периодов, когда не следует торговать вовсе. В данном случае мы используем торговую платформу MetaTrader 4 для анализа истории и оптимизации результатов, которые могут быть использованы в механических торговых системах.
Охота за трендами Охота за трендами
В статье описан алгоритм наращивания объёма прибыльной сделки и представлена его реализация посредством MQL.
Предсказание финансовых временных рядов Предсказание финансовых временных рядов
Предсказание финансовых временных рядов - необходимый элемент любой инвестиционной деятельности. Сама идея инвестиций - вложения денег сейчас с целью получения дохода в будущем - основывается на идее прогнозирования будущего. Соответственно, предсказание финансовых временных рядов лежит в основе деятельности всей индустрии инвестиций - всех бирж и небиржевых систем торговли ценными бумагами.