Моделирование беттинга как средство развития «чувства рынка»

Автор: lexy Вторник, Сентябрь 9th, 2014 Нет комментариев

Рубрика: Разное

В данной статье рассказывается о простом механизме моделирования беттинга в режиме реального времени. Что же такое беттинг? Финансовый беттинг – от англ. Bet – ставка, пари: прогноз относительно дальнейшего хода (увеличения или уменьшения) курса того или иного финансового инструмента и получение вознаграждения, если прогноз сбывается(источник - беттинг).

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

Если использовать подобие беттинга, в форме игры, на малых таймфреймах, то можно развить «чувство рынка». Можно научиться «видеть» вырастет пара или упадёт. Об этом и пойдёт речь.

Концепция

Принято считать, что для трейдера очень важно знание технического анализа, фундаментального анализа, знание правил управления капиталом и многого другого. Безусловно, это всё очень важно. Однако есть ещё такое понятие, как «чувство рынка». Когда трейдер смотрит на голый ценовой график (без нанесённых индикаторов), и примерно представляет, в какую сторону далее пойдёт валютная пара. Разумеется, не всегда такое «видение» является правильным, но ошибки возможны при любом подходе к торговле. Но умение «видеть» рынок очень полезно, особенно в ситуациях, когда нужно быстро оценить ситуацию на рынке.

Обычно «чувство рынка» людям приходит с опытом, ценой многочасовых торговых экспериментов. Не редко цена этих экспериментов также исчисляется не одной тысячей долларов США.

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

Умения человека тренируемы, это не поддаётся сомнению. Мы можем научиться рисовать, петь, играть на музыкальных инструментах. Я уверен, что научиться «видеть» рынок так же можно научиться. Как можно играть в компьютерные игры, так можно научиться играть в игру «предскажи направление». Однако нужно знать, с чего начать, как это умение развивать. Для начала, нужна сама игра.

Постановка задачи

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

Под эти критерии мог бы подойти беттинг, о котором уже писалось ранее. Однако на практике это не самый лучший вариант. Существует достаточно мало Диллинговых Центров, которые предоставляют такую возможность своим клиентам. Даже если и использовать такой вариант, можно столкнуться с неудобствами. Использовать демо-счета не очень практично, т.к. это может мешать реальной торговле (отвлекать), а на реальных счетах это уже будет более опасная игра. Также, обычно, ставки при торговле через беттинг невозможно сделать на период, меньший, чем один час.

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

Реализация

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

Реализация выбора, как я считаю, лучше всего будет исполнена через объекты — SYMBOL_ARROWDOWN и SYMBOL_ARROWUP (стрелочка вниз и стрелочка вверх). Можно предложить пользователю наносить нужную стрелочку на график. Но так будет много времени и внимания уходить на само нанесение стрелочки и на указание её имени. Этот вариант не подходит.

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

Звучит достаточно просто, также весьма просто реализуемо.

//+------------------------------------------------------------------+
//|                                                       trener.mq4 |
//|                                       Copyright © 2008, FXRaider |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, FXRaider"

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
extern int gap=5;
int init()
  {
//----

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
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");
    } 

   if(ObjectFind("down") != 0&&ObjectFind("up") != 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);
    }
//|                                 работа с объектами                                 |
//+------------------------------------------------------------------------------------+

Comment("Счёт: ", points," (",points_pos,"/",points_neg,   //выводим счёт
        ") | Time: ", Hour(),":", Minute(),":", Seconds());//выводим время (для удобства)
//----
   return(0);
  }
//+------------------------------------------------------------------+

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

 

После присоединения к графику мы получим такой результат:

На последнем баре видны две стрелочки. Одна вверх, другая вниз. Слева-вверху комментарием выводится счёт игры и терминальное время последнего тика. Счёт отображается тремя числами. Первое — общий счёт, второе (первое в скобочках) — количество положительных ответов (сбывшихся прогнозов), третье (второе в скобках) — количество отрицательных ответов (несбывшихся прогнозов). Время я решил выводить для удобства работы в полнооконном режиме (F11).

 

Для того, чтобы «сыграть», нужно выделить «лишнюю» стрелку двойным (по умолчанию) кликом и нажать Delete (удалить её). Останется одна, которая будет символизировать наш прогноз:

Теперь останется только ждать начала следующей свечи. Если прогноз сбудется, то «Счёт» получит вид «Счёт: 1(1/0)». Если прогноз не сбудется, то «Счёт» получит вид «Счёт: -1(0/1)». Если же цена открытия будет равна цене закрытия, то счёт не изменится. В приведённом примере прогноз не оправдался:

Усовершенствование

Поставленная задача выполнена. Однако стоит отметить один недостаток этой реализации. Выбор можно сделать на протяжении всей свечи, в том числе и в последние секунды. А это ставит под сомнение всю концепцию. Намного лучше, если выбор можно сделать, например, в течение первых 30-ти секунд после начала свечи. Введём для этого extern int переменную – «time_limit». Её значение будет представлять количество секунд, в течение которых нужно успеть сделать выбор. Если в течение указанного времени пользователь не успел сделать выбор, то обе стрелочки удаляются и не наносятся на график до следующей свечи.

Изменения затронут блок «работа с объектами» (выделено комментариями). Получившийся код:

//+------------------------------------------------------------------+
//|                                                       trener.mq4 |
//|                                       Copyright © 2008, FXRaider |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, FXRaider"

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
extern int gap=5;
extern int time_limit=30;
int init()
  {
//----

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
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);
    }
//|                                 работа с объектами                                 |
//+------------------------------------------------------------------------------------+

Comment("Счёт: ", points," (",points_pos,"/",points_neg,   //выводим счёт
        ") | Time: ", Hour(),":", Minute(),":", Seconds());//выводим время (для удобства)
//----
   return(0);
  }
//+------------------------------------------------------------------+

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

Переменная «gap» отвечает за количество пунктов, на которые отдалены стрелочки от цены открытия свечи. Переменная «time_limit» отвечает за количество секунд, в течение которых пользователь должен успеть сделать выбор. Если поставить значение «0″, то ограничения не будет, т.е. можно делать выбор в течение всей свечи.

Заключение

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

Хотелось бы сказать о результатах применения игры. Мной были достигнуты результаты в успешном прогнозировании 5-10 свечей подряд. Использовалось на пятиминутном графике.

Применяя эту игру, трейдер может научиться отвечать на один из важных вопросов. Куда именно пойдёт данный торговый инструмент? Однако есть ещё множество других важных вопросов. Сюда входит вопрос о фиксации прибыли, вопрос о фиксации убытка, вопрос об объёме открываемой сделки и многие другие вопросы. Лишь умение отвечать на все эти вопросы может дать трейдеру уверенный результат.

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

Прикрепленные файлы:
 trener.mq4 (6.7 Kb)
Источник: mql4.com

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты