Проверяется Индикатор опционных уровней

Тема в разделе "Идея - Реализация", создана пользователем Mikas Saksanen, 25 дек 2017.

  1. pabbotnik

    pabbotnik Осваиваюсь
    Проверенный

    Регистрация:
    26.07.17
    Сообщения:
    21
    Симпатии:
    31
    9cUpMn60RsmO94AVQkI_ig.png

    скомпилировал с такими значениями индюк заработал, только что эта линия дает?
     
  2. Mikas Saksanen

    Mikas Saksanen Осваиваюсь
    Проверенный

    Регистрация:
    30.05.17
    Сообщения:
    51
    Симпатии:
    22
    R -Riskfree rate, V -volatility.
    В общем-то мне тоже не известно, что это все дает. Я попробовал из него сделать свой индикатор. Увы, нерабочий.
    Синтаксических ошибок, вроде бы нет, но не рисует.
    P.S. Добавил тоже самое с функциями probability.dll (Black_Scholes3.zip)
     

    Вложения:

    #22 Mikas Saksanen, 28 янв 2018
    Последнее редактирование: 28 янв 2018
  3. PacMan

    PacMan Осваиваюсь
    Почетный член клуба

    Регистрация:
    05.06.16
    Сообщения:
    90
    Симпатии:
    22
  4. Mikas Saksanen

    Mikas Saksanen Осваиваюсь
    Проверенный

    Регистрация:
    30.05.17
    Сообщения:
    51
    Симпатии:
    22
    В общем-то версия Энигмы у меня пошла на eurusd. Показывает и коллы, и путы (если менять true/false) в настройках. Я поставил там x - 1.24 (strike), v- 0.15 (15% volatility), r - 0.015 (risk free rate 1,5%), t -0.08 (30days/365).
     
  5. Mikas Saksanen

    Mikas Saksanen Осваиваюсь
    Проверенный

    Регистрация:
    30.05.17
    Сообщения:
    51
    Симпатии:
    22
    Подскажите, я ведь не знаю, где смотреть ошибки, логи, чтобы отлаживать индикатор. Ведь не только после компиляции в нижнем окне?
     
  6. PacMan

    PacMan Осваиваюсь
    Почетный член клуба

    Регистрация:
    05.06.16
    Сообщения:
    90
    Симпатии:
    22
    Это в самом терминале при попытке установить индикатор на график.

    111.png
     
    Mikas Saksanen нравится это.
  7. Mikas Saksanen

    Mikas Saksanen Осваиваюсь
    Проверенный

    Регистрация:
    30.05.17
    Сообщения:
    51
    Симпатии:
    22
    Доброго времени суток. Мой индикатор начал рисовать. Согласно задумке, в нем есть скользящая средняя (оставил пока), lower&upper bands - уровни цен ближайших к деньгам опционов (страйк +/- колл/пут), уровни стрэддла (желтые, страйк+колл+пут, страйк-колл-пут), СМE expected range (ожидаемый диапазон, формула СМЕ).
    Волатильность считается как доходность дневная в процентах (т.е. из сегодняшней цены вычитается вчерашняя и все делится на вчерашнюю; затем находится станд. квадратичное отклонение этих доходностей; далее переводится в годовую умножением на корень из числа дней в году).
    Возникла проблема, не могу решить. Еще до введения линий СМE expected range индикатор перестал рисовать upper bands независимо от того, какие там присвоены в массиве значения.
    Посоветуйте, кто понимает. Видно проблема какая-то с индикаторным буферами, но ошибок в логе компиляции и в "экспертах" в МТ4 нет.
    (Волатильность Роджерса пока отключена, позже посмотрю насчет нее.)
    Код:
    //+------------------------------------------------------------------+
    //|                                                        Bands.mq4 |
    //|                   Copyright 2005-2014, MetaQuotes Software Corp. |
    //|                                              http://www.mql4.com |
    //+------------------------------------------------------------------+
    #property copyright   "2005-2014, MetaQuotes Software Corp."
    #property link        "http://www.mql4.com"
    #property description "Bollinger Bands"
    #property strict
    
    //#include <MovingAverages.mqh>
    #define Pi 3.141592653589793238462643
    #define a1  0.31938153
    #define a2 -0.356563782
    #define a3 1.781477937
    #define a4 -1.821255978
    #define a5 1.330274429
    #property indicator_chart_window
    #property indicator_buffers 8
    #property indicator_color1 LightSeaGreen
    #property indicator_color2 LightSeaGreen
    #property indicator_color3 LightSeaGreen
    #property indicator_color4 clrGold
    #property indicator_color5 clrGold
    #property indicator_color6 LightSeaGreen
    #property indicator_color7 LightSeaGreen
    //--- indicator parameters
    input int    InpBandsPeriod=20;                      //Bands Period (bars)
    input int    InpBandsShift=0;                        //Bands Shift (days)
    input double InpBandsDeviations=2.0;                 //Bands Deviations
    extern string ExpDate = "2018.02.10";                //Option expiration date
    extern string X="http://cmegroup.quikstrike.net";    //Look at
    extern double DaysInYear=250;                        //Working days in year
    extern double DaysInMonth=22;                        //Working days in month
    extern string CurrencySymbol = "";                   //
    extern double RFreeRate = 1.15;                      //Risk free rate
    extern string Y="https://www.treasury.gov/resource-center/data-chart-center/interest-rates/Pages/TextView.aspx?data=yield";    //Looka at
    /*Risk free rate - безрисковая процентная ставка. Cоответствует % ставке по казначейским облигациям соответствующего срока
    (т. е. 1 месяц), так как опционы/фьючерсы покупаются за доллары.*/
    double TFCoeff;
    int shift;
    //--- buffers
    double ExtMovingBuffer[];
    double ExtUpperBuffer[];
    double ExtLowerBuffer[];
    double ExtUpStrdlBuffer[];
    double ExtLoStrdlBuffer[];
    double ExtStdDevBuffer[];
    double UpERBuffer[];
    double LoERBuffer[];
    //double ExtStrikeBuffer[];
    //double ExtCallBuffer[];
    //double ExtPutBuffer[];
    //+------------------------------------------------------------------+
    //| Custom indicator initialization function                         |
    //+------------------------------------------------------------------+
    int OnInit(void)
      {
       TFCoeff=PERIOD_D1/Period();  //Коэффициент для пересчета баров с текущего ТФ на дневной, т.к. волатильность нужна дневная
       shift=TFCoeff*InpBandsShift; //Смещение на дни, а не на бары
    //--- 1 additional buffer used for counting.
       IndicatorBuffers(6);
       IndicatorDigits(Digits);
    //--- middle line
       SetIndexStyle(0,DRAW_LINE);
       SetIndexBuffer(0,ExtMovingBuffer);
       SetIndexShift(0,shift);
       SetIndexLabel(0,"Bands SMA");
    //--- upper band
       SetIndexStyle(1,DRAW_LINE);
       SetIndexBuffer(1,ExtUpperBuffer);
       SetIndexShift(1,shift);
       SetIndexLabel(1,"Bands Upper");
    //--- lower band
       SetIndexStyle(2,DRAW_LINE);
       SetIndexBuffer(2,ExtLowerBuffer);
       SetIndexShift(2,shift);
       SetIndexLabel(2,"Bands Lower");
    //---upper straddle 
       SetIndexStyle(3,DRAW_LINE);
       SetIndexBuffer(3,ExtUpStrdlBuffer);
       SetIndexShift(3,shift);
       SetIndexLabel(3,"Upper Straddle");
    //---lower straddle 
       SetIndexStyle(4,DRAW_LINE);
       SetIndexBuffer(4,ExtLoStrdlBuffer);
       SetIndexShift(4,shift);
       SetIndexLabel(4,"Lower Straddle");
    //---upper CME expected range   
       SetIndexStyle(5,DRAW_LINE,STYLE_DOT);
       SetIndexBuffer(5,UpERBuffer);
       SetIndexShift(5,shift);
       SetIndexLabel(5,"Upper CME ER"); 
    //---lower CME expected range   
       SetIndexStyle(6,DRAW_LINE,STYLE_DOT);
       SetIndexBuffer(6,LoERBuffer);
       SetIndexShift(6,shift);
       SetIndexLabel(6,"Lower CME ER");
          
    //--- work buffer
       SetIndexBuffer(7,ExtStdDevBuffer);
       //SetIndexBuffer(5,ExtStrikeBuffer);
       //SetIndexBuffer(5,ExtCallBuffer);
       //SetIndexBuffer(6,ExtPutBuffer);
    //--- check for input parameter
       if(InpBandsPeriod<=0)
         {
          Print("Wrong input parameter Bands Period=",InpBandsPeriod);
          return(INIT_FAILED);
         }
    //---
       SetIndexDrawBegin(0,InpBandsPeriod+shift);
       SetIndexDrawBegin(1,InpBandsPeriod+shift);
       SetIndexDrawBegin(2,InpBandsPeriod+shift);
       SetIndexDrawBegin(3,InpBandsPeriod+shift);
       SetIndexDrawBegin(4,InpBandsPeriod+shift);
       SetIndexDrawBegin(5,InpBandsPeriod+shift);
       SetIndexDrawBegin(6,InpBandsPeriod+shift);
    //--- initialization done
       return(INIT_SUCCEEDED);
      }
    //+------------------------------------------------------------------+
    //| Bollinger Bands                                                  |
    //+------------------------------------------------------------------+
    int OnCalculate(const int rates_total,
                    const int prev_calculated,
                    const datetime &time[],
                    const double &open[],
                    const double &high[],
                    const double &low[],
                    const double &close[],
                    const long &tick_volume[],
                    const long &volume[],
                    const int &spread[])
      {
       int i,pos,daybar;
       double call,put,strike,prw,StdDev,timebar,vltl;
    //---
       if(rates_total<=InpBandsPeriod || InpBandsPeriod<=0)
          return(0);
    //--- counting from 0 to rates_total
       ArraySetAsSeries(ExtMovingBuffer,false);
       ArraySetAsSeries(ExtUpperBuffer,false);
       ArraySetAsSeries(ExtLowerBuffer,false);
       ArraySetAsSeries(ExtUpStrdlBuffer,false);
       ArraySetAsSeries(ExtLoStrdlBuffer,false);
       ArraySetAsSeries(ExtStdDevBuffer,false);
       ArraySetAsSeries(UpERBuffer,false);
       ArraySetAsSeries(LoERBuffer,false);
      //ArraySetAsSeries(ExtStrikeBuffer,false);
      //ArraySetAsSeries(ExtCallBuffer,false);
      //ArraySetAsSeries(ExtPutBuffer,false);
       ArraySetAsSeries(close,false);
       ArraySetAsSeries(open,false);
       ArraySetAsSeries(high,false);
       ArraySetAsSeries(low,false);
    //--- initial zero
       if(prev_calculated<1)
         {
          for(i=0; i<InpBandsPeriod; i++)
            {
             ExtMovingBuffer[i]=EMPTY_VALUE;
             ExtUpperBuffer[i]=EMPTY_VALUE;
             ExtLowerBuffer[i]=EMPTY_VALUE;
             ExtUpStrdlBuffer[i]=EMPTY_VALUE;
             ExtLoStrdlBuffer[i]=EMPTY_VALUE;
             UpERBuffer[i]=EMPTY_VALUE;
             LoERBuffer[i]=EMPTY_VALUE;
            }
         }
    //--- starting calculation
       if(prev_calculated>1)
          pos=prev_calculated-1;
       else
          pos=0;
          //TFCoeff=PERIOD_D1/Period(); //Коэффициент для пересчета баров с текущего ТФ на дневной, т.к. волатильность нужна дневная
    //--- main cycle
       for(i=pos; i<rates_total && !IsStopped(); i++)
         {
          //--- middle line
          ExtMovingBuffer[i]=iMA(NULL,0,InpBandsPeriod,0,MODE_SMA,PRICE_WEIGHTED,rates_total-i);
          //--- calculate and write down StdDev
          //ExtStdDevBuffer[i]=StdDev_Func(i,open,close,high,low,round(TFCoeff*InpBandsPeriod));
          daybar=round((rates_total-i)/TFCoeff); //Номер дневного бара в таймсерии
          if (pos>1)
          ExtStdDevBuffer[i]=(iClose(NULL,PERIOD_D1,daybar)- iClose(NULL,PERIOD_D1,daybar+1))/iClose(NULL,PERIOD_D1,daybar+1);
          //https://studfiles.net/preview/4240292/page:2/
          //https://www.fool.com/knowledge-center/how-to-calculate-annualized-volatility.aspx
          else  ExtStdDevBuffer[i]=0;
          prw=(close[i]+high[i]+low[i]+close[i])/4;
          //StdDev=StdDev_Func(i,open,close,high,low,round(InpBandsPeriod));
          StdDev=StdDev_Func(i,ExtStdDevBuffer,InpBandsPeriod);
          strike=Strike(prw);
          timebar=DTE(time[i]); //DTE для каждого бара
          vltl=StdDev*sqrt(DaysInYear); //Перевод волатильности из дневной в годовую
          //На основе   http://bin-brokers.com/simon52.html - Вайн Саймон. Опционы. Полный курс для профессионалов
          //https://en.wikipedia.org/wiki/Volatility_(finance)
          call=BlackScholes(prw,strike,timebar,vltl,1); //call 1
          put=BlackScholes(prw,strike,timebar,vltl,0);  //put 0
          //ExtStrikeBuffer[i]=Strike(ExtMovingBuffer[i]);
          //--- upper line
          ExtUpperBuffer[i]=strike+call;
          //--- lower line
          ExtLowerBuffer[i]=strike-put;
          //--- Straddles
          ExtUpStrdlBuffer[i]=strike+call+put;
          ExtLoStrdlBuffer[i]=strike-call-put;
          UpERBuffer[i]=strike+ strike* vltl*vltl/2* timebar/365 - ((-1)*vltl*timebar/365);
          LoERBuffer[i]=strike+ strike* vltl*vltl/2* timebar/365 - (vltl*timebar/365);
          //---
          }
           return(rates_total);
     }   
        
    //+------------------------------------------------------------------+
    /*double StdDev_Func(int position,const double &hopen[],const double &hclose[],const double &hhigh[],const double &hlow[],int period)
      {
    //--- variables
       double StdDev_rs=MathPow(10,-10);
    //--- check for position
       if(position>=period)
         {
          //--- calcualte StdDev
          for(int i=0; i<period; i++)
               StdDev_rs+=log(hhigh[position-i]/hclose[position-i])*log(hhigh[position-i]/hopen[position-i])+log(hlow[position-i]/hclose[position-i])*log(hlow[position-i]/hopen[position-i]);
             StdDev_rs=MathSqrt(StdDev_rs/period);
             //StdDev_dTmp+=MathPow(price[position-i]-MAprice[position],2);
             //StdDev_dTmp=MathSqrt(StdDev_dTmp/period);
         }
    //--- return calculated value
       return(StdDev_rs);
      }
    */
    
    double StdDev_Func(int position,const double &dev[],int period)
      {
    //--- variables
       double StdDev_dTmp, mean;
       StdDev_dTmp=MathPow(10,-10);
       mean=MathPow(10,-10);
    //--- check for position
       if(position>=period)
         {
          //--- calcualte StdDev
          for(int i=0; i<period; i++)
              mean+=dev[i];
          mean=mean/period;
          for(int x=0; x<period; x++) 
              StdDev_dTmp+=MathPow(dev[position-x]-mean,2);
          StdDev_dTmp=MathSqrt(StdDev_dTmp/period);
         }
    //--- return calculated value
       return(StdDev_dTmp);
      }
    //+------------------------------------------------------------------+
    double Strike (double x)
       {
         string currency;
      
         if (CurrencySymbol=="") currency=Symbol(); //Если нет названия инструмента, берем с текущего графика
            else currency=CurrencySymbol;           //Иначе - любую строку с любым названием
      
        //Определяем ближайший страйк путем округления.
        //USDCAD,USDCHF - перевернутые пары. На СМЕ CADUSD, CHFUSD  и страйки идут соответственно типа (CADUSD) 0,7950-0,8000-0,8050
        //Пример: 1/(round(1/1.334*200)/200)=1.33 Переворот сделан с перспективой для внедрений форвард-пойнта.
        //Золото. Страйки вида 1320-1325-1300. Пример: round(0.2*1322)/0.2=1320
        //Нефть. Страйки вида 63,0-63,5-64. Пример: round(2*63.3)/2=63.5
        //USDJPY. Страйки вида (JPYUSD) 0,00900-0,00905-0,00910. Пример: 1/(round(1/110,7*20000)/20000)=110,497
        //Остальные валютные пары типа eurusd, audusd. У них страйки идут так: 1,2250 - 1,2200 - 1,2150
        //Примеры: round(1,2260*200)/200 = 1,2250; round(1,2190*200)/200=1,2200
                        
        if (currency == "USDCAD" || currency == "usdcad" || currency == "USDCHF" || currency == "usdchf" ) return 1/(round(1/x*200)/200);
            else if (currency == "GOLD" || currency == "XAUUSD" || currency == "gold" || currency == "xauusd") return round(0.2*x)/0.2;
                  else if (currency == "OIL" || currency == "USOIL" || currency == "oil" || currency == "usoil" || currency == "BRENT" || currency == "brent" || currency == "WTI" || currency == "wti") return round(2*x)/2;
                       else if (currency == "USDJPY" || currency == "usdjpy") return 1/(round(1/x*20000)/20000);
                            else return round(200*x)/200;                                                                                                                                                                                                           
                        
       }
    
    double DTE (datetime days)    //DTE -число дней до экспирации опциона, рассчитывается для каждого бара с учетом даты экспирации опциона
        {
          double d; 
          if (((StrToTime(ExpDate)- days)/86400)/DaysInYear>0) d=((StrToTime(ExpDate)-days)/86400)/DaysInYear;
          else d=MathPow(10,-10);
          return d;
        } 
                                  
    
    double BlackScholes(double spot, double strike, double dte,  double vol, int type)
    //Формулы для коллов и путов см. https://en.wikipedia.org/wiki/Black–Scholes_model
    {
        double d1, d2;
        double res;
      
        d1=(MathLog(spot/strike)+(RFreeRate/100+vol*vol/2)*dte)/(vol*MathSqrt(dte));
        d2=d1-vol*MathSqrt(dte);
    
        if(type==1) //call
        {
            res=  spot *CumulDistrib(d1)-strike * MathExp(-RFreeRate/100*dte)*CumulDistrib(d2);
            return(res);
    }
        else
            if(type==0) //put
            {
                res= strike * MathExp(-RFreeRate/100 * dte) * CumulDistrib(-d2) - spot * CumulDistrib(-d1);
                return(res);         
            }
            else
                {
                res = 0;
                return(0);
                }
    }
    
    // The cumulative normal distribution function
    double CumulDistrib( double a_X )
    {
    
        double L, K, w ;
    
        L = MathAbs(a_X);
        K = 1.0 / (1.0 + 0.2316419 * L);
        w = 1.0 - 1.0 / (MathSqrt(2 * Pi)) * (MathExp(-L *L / 2)) * ((a1 * K) + (a2 * K *K) + (a3 * MathPow(K,3)) +( a4 * MathPow(K,4) )+ (a5 * MathPow(K,5)));
    
    if (a_X < 0 )
           {
           w= 1.0 - w;
           }
      return(w);
    }
    
     
    
     

    Вложения:

    • indicator.ZIP
      Размер файла:
      25,6 КБ
      Показов:
      29
  8. Mikas Saksanen

    Mikas Saksanen Осваиваюсь
    Проверенный

    Регистрация:
    30.05.17
    Сообщения:
    51
    Симпатии:
    22
    Немного обновил. Два варианта - самостоятельный и с функцией из probability.dll (выкладывал раньше). Уменьшил число итераций при подсчете дневной волатильности.
    Может ли кто-нибудь посмотреть, почему не рисуются линии bands lower, CME ER lower & upper?
    Явных ошибок вроде бы нет (согласно компилятору и вкладке "эксперты").
     

    Вложения:

    • Indicators.zip
      Размер файла:
      10,2 КБ
      Показов:
      25
  9. Mikas Saksanen

    Mikas Saksanen Осваиваюсь
    Проверенный

    Регистрация:
    30.05.17
    Сообщения:
    51
    Симпатии:
    22
    Приветствую. Получился более или менее рабочий вариант. Для сравнения наложены уровни, рассчитанные по методу автора ТС (Нургалиева).
    Индикатор считает историческую дневную волатильность по формуле Янг-Жанга, а по ней - уровни ближайших коллов и путов, а также стрэддла и CME expected range.
    Форвард пойнтов пока нет.

    [ 27aa801e524ba1e34e06a3be79560c2d-full.png
     

    Вложения:

  10. PlatinumTrader

    PlatinumTrader Администратор
    Команда форума

    Регистрация:
    19.12.17
    Сообщения:
    157
    Симпатии:
    82
    Добрый вечер. Скажите пожалуйста, а какое практическое применение имеет данный индикатор и методика в целом, если посмотрев лишь на график, я смею предположить, что все линии, черточки и тд - это как возу третье колесо. То есть они находятся так далеко от текущей цены, что я не знаю как ими воспользоваться. Может объясните? Спасибо.
     
  11. Mikas Saksanen

    Mikas Saksanen Осваиваюсь
    Проверенный

    Регистрация:
    30.05.17
    Сообщения:
    51
    Симпатии:
    22
    Методика описана в методичке автора ТС в первом посте. Согласен, что до практического применения пока далеко, индикатор еще предстоит совершенствовать.
     
  12. grundik1981

    grundik1981 Я здесь новичок

    Регистрация:
    02.04.18
    Сообщения:
    1
    Симпатии:
    0
    Приветствую, не добавили еще форвард поинт? Как успехи?
     
  13. Mikas Saksanen

    Mikas Saksanen Осваиваюсь
    Проверенный

    Регистрация:
    30.05.17
    Сообщения:
    51
    Симпатии:
    22
    Технически это не сложно. Для расчетных форвард-поинтов нужны ставки соответствующих валютной паре центробанков, дата экспирации фьючерса. А формула не сложная. Просто нет пока времени. Затем для этих полос - уровней надо выставить будет смещение вперед на 12 - 24 ч. Посмотрим, потом, что выйдет.
     
  14. Mikas Saksanen

    Mikas Saksanen Осваиваюсь
    Проверенный

    Регистрация:
    30.05.17
    Сообщения:
    51
    Симпатии:
    22
    Наконец-то нашлось немного времени. Я добавил расчет форвард-пойнтов по формуле из видео Нургалиева. Для этого в настройках индикатора надо вручную вносить межбанковские процентные ставки (ссылки указаны в настройках индикатора). Естественно, нужны даты экспирации фьючерсов и опционов.
    Несколько уточнил формулу волатильности Янга-Жанга. Подсчет ведется сразу месячной волатильности по текущим барам.
    Конечно, есть проблемы. Верхняя линия (коллов) "улетает" вверх. Хотелось бы как то-оптимизировать расчет волатильности (нужен какой-то массив), чтобы на каждом баре все не пересчитывалось.
    В общем, как есть, так и есть.:)
     

    Вложения:

    • Indicators.zip
      Размер файла:
      32,5 КБ
      Показов:
      24
  15. Mikas Saksanen

    Mikas Saksanen Осваиваюсь
    Проверенный

    Регистрация:
    30.05.17
    Сообщения:
    51
    Симпатии:
    22
    Доброго времени суток. Очередная версия индикатора. Теперь с полосами все обстоит получше. В остальном - мелкие улучшения.
    f17eaf3607d0cd3ef1ee7676eed3b95b-full.png
     

    Вложения:

Поделиться этой страницей