Послушал опытных людей. Все переделал.
Посмотрите, пожалуйста, в чем дело. Не понимаю, почему вообще ничего не рисует.
Все в одном файле. Все пояснения и формулы в комментариях. Для работы нужна probability.dll & probability.mqh (mql4.zip в посте выше).
//+------------------------------------------------------------------+
//| 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>
#include <Probability.mqh>
#property indicator_chart_window
#property indicator_buffers 9
#property indicator_color1 LightSeaGreen
#property indicator_color2 LightSeaGreen
#property indicator_color3 LightSeaGreen
//--- indicator parameters
input int InpBandsPeriod=20; // Bands Period
input int InpBandsShift=0; // Bands Shift
input double InpBandsDeviations=2.0; // Bands Deviations
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+----------------------------------------------------------------
extern string ExpDate = "2018.02.10"; //Дата экспирации месячного опциона http://cmegroup.quikstrike.net
extern double DaysInYear=365; // Количество дней в году, в зависимости от системы расчета, чаще число раб. дней в году
extern double DaysInMonth=30; // Тоже в месяце
extern double RFreeRate = 1.15;
/*Risk free rate - безрисковая процентная ставка. Cоответствует % ставке по казначейским облигациям соответствующего срока
(т. е. 1 месяц), так как опционы/фьючерсы покупаются за доллары. Ее берут здесь:
https://www.treasury.gov/resource-c...interest-rates/Pages/TextView.aspx?data=yield
*/
extern string CurrencySymbol = ""; //
//--- buffers
double ExtUpperBuffer[]; //Верхняя линия
double ExtLowerBuffer[]; //Нижняя линия
double ExtStdDevBuffer[]; //Волатильность для соответствующего бара
double ExtCallBuffer[]; //Коллы для соответствующего бара
double ExtPutBuffer[]; //Путы для соответствующего бара
double ExtDeFirstBuffer[]; //D1 для формулы Блэка-Шоулза для соответствующего бара
double ExtStrikeBuffer[]; //Страйк, ближайший к текущей цене для соответствующего бара
double ExtMovingBuffer[]; //Средняя линия
double DTEBuffer[]; //DTE -число дней до экспирации для соответствующего бара
int OnInit(void)
{
//--- 1 additional buffer used for counting.
IndicatorBuffers(9);
IndicatorDigits(Digits);
//--- middle line
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,ExtMovingBuffer);
SetIndexShift(0,InpBandsShift);
SetIndexLabel(0,"Bands SMA");
//--- upper band
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1,ExtUpperBuffer);
SetIndexShift(1,InpBandsShift);
SetIndexLabel(1,"Bands Upper");
//--- lower band
SetIndexStyle(2,DRAW_LINE);
SetIndexBuffer(2,ExtLowerBuffer);
SetIndexShift(2,InpBandsShift);
SetIndexLabel(2,"Bands Lower");
//--- work buffer -- Массивы данных для расчетов, не отображаются на графике.
SetIndexBuffer(3,ExtStdDevBuffer);
SetIndexBuffer(4,ExtCallBuffer);
SetIndexBuffer(5,ExtPutBuffer);
SetIndexBuffer(6,ExtDeFirstBuffer);
SetIndexBuffer(7,ExtStrikeBuffer);
SetIndexBuffer(8,DTEBuffer);
//--- check for input parameter
if(InpBandsPeriod<=0)
{
Print("Wrong input parameter Bands Period=",InpBandsPeriod);
return(INIT_FAILED);
}
//---
SetIndexDrawBegin(0,InpBandsPeriod+InpBandsShift);
SetIndexDrawBegin(1,InpBandsPeriod+InpBandsShift);
SetIndexDrawBegin(2,InpBandsPeriod+InpBandsShift);
//--- 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;
double TFCoeff;
//---
if(rates_total<=InpBandsPeriod || InpBandsPeriod<=0)
return(0);
//--- counting from 0 to rates_total --- Т.е. бары считаем от самого раннего до самого последнего, самого свежего (так что ли?)
ArraySetAsSeries(ExtMovingBuffer,false);
ArraySetAsSeries(ExtUpperBuffer,false);
ArraySetAsSeries(ExtLowerBuffer,false);
ArraySetAsSeries(ExtStdDevBuffer,false);
ArraySetAsSeries(ExtCallBuffer,false);
ArraySetAsSeries(ExtPutBuffer,false);
ArraySetAsSeries(ExtDeFirstBuffer,false);
ArraySetAsSeries(ExtStrikeBuffer,false);
ArraySetAsSeries(DTEBuffer,false);
ArraySetAsSeries(close,false);
ArraySetAsSeries(open,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
//--- initial zero
TFCoeff=PERIOD_D1/Period(); //Коэффициент для пересчета баров с текущего ТФ на дневной, т.к. волатильность нужна дневная
if(prev_calculated<1)
{
for(i=0; i<InpBandsPeriod; i++)
{
ExtMovingBuffer[i]=EMPTY_VALUE;
ExtUpperBuffer[i]=EMPTY_VALUE;
ExtLowerBuffer[i]=EMPTY_VALUE;
}
}
//--- starting calculation
if(prev_calculated>1)
pos=prev_calculated-1;
else
pos=0;
//--- main cycle
for(i=pos; i<rates_total && !IsStopped(); i++)
{
//--- middle line
ExtMovingBuffer[i]=SimpleMA(i,InpBandsPeriod,close);
//--- calculate and write down StdDev
//ExtStdDevBuffer[i]=StdDev_Func(i,close,ExtMovingBuffer,TFCoeff*InpBandsPeriod); - исходный вариант образца * TFCoeff
//Два варианта волатильности. Одну из двух последующих строк включить/исключить.
//ExtStdDevBuffer[i]=StdDev_Func(i,open,close,high,low,TFCoeff*InpBandsPeriod)/ExtMovingBuffer[i]*sqrt(DaysInYear*TFCoeff);//Метод Роджерса-Сатчела - Альтернативный вариант волатильности
ExtStdDevBuffer[i]=iATR(NULL,PERIOD_D1,InpBandsPeriod,round(i/TFCoeff))/ExtMovingBuffer[i]*sqrt(DaysInYear); //Волатильность для каждого бара, выраженная в долях и в годах
//Взято с http://bin-brokers.com/simon52.html - Вайн Саймон. Опционы. Полный курс для профессионалов
ExtStrikeBuffer[i]=Strike(ExtMovingBuffer[i]);
DTEBuffer[i]=DTE(time[i]);
ExtDeFirstBuffer[i]= DF(ExtMovingBuffer[i],ExtStrikeBuffer[i], ExtStdDevBuffer[i],DTEBuffer[i]);
//Формулы для коллов и путов см. https://en.wikipedia.org/wiki/Black–Scholes_model
//ndtr - кумулятивная функция распределения стандартного нормального распределения из Probability.mqh
ExtCallBuffer[i]=ExtMovingBuffer[i]* ndtr(ExtDeFirstBuffer[i])- ExtStrikeBuffer[i]*MathExp(-RFreeRate/100*DTEBuffer[i])*ndtr(ExtDeFirstBuffer[i]-ExtStdDevBuffer[i]*MathSqrt(DTEBuffer[i]));
ExtPutBuffer[i]=ExtStrikeBuffer[i]*MathExp(-RFreeRate/100*DTEBuffer[i])*ndtr(ExtStdDevBuffer[i]*MathSqrt(DTEBuffer[i])- ExtDeFirstBuffer[i])-ndtr(-ExtDeFirstBuffer[i])*ExtMovingBuffer[i] ;
//--- upper line
//ExtUpperBuffer[i]=ExtMovingBuffer[i]+InpBandsDeviations*ExtStdDevBuffer[i]; - исходный вариант образца
ExtUpperBuffer[i]=ExtMovingBuffer[i]+ExtCallBuffer[i];
//lower line
//ExtLowerBuffer[i]=ExtMovingBuffer[i]-InpBandsDeviations*ExtStdDevBuffer[i]; - исходный вариант образца
ExtUpperBuffer[i]=ExtMovingBuffer[i]-ExtPutBuffer[i];
//---
}
//---- OnCalculate done. Return new prev_calculated.
return(rates_total);
}
//+------------------------------------------------------------------+
//| Calculate Standard Deviation |
//+------------------------------------------------------------------+
//Метод Роджерса-Сатчела - Альтернативный вариант волатильности
//https://research-journal.org/economical/analiz-razlichnyx-metodov-ocenki-istoricheskoj-volatilnosti-dlya-opcionnoj-torgovli/
double StdDev_Func(int position,const double &open[],const double &close[],const double &high[],const double &low[],int period)
{
//--- variables
double StdDev_rs=0.0;
//--- check for position
if(position>=period)
{
//--- calcualte StdDev
for(int i=0; i<period; i++)
StdDev_rs+=log(high[position-i]*high[position-i]/close[position-i])*log(high[position-i]/open[position-i])+log(low[position-i]/close[position-i])*log(low[position-i]/open[position-i]);
StdDev_rs=MathSqrt(StdDev_rs/period);
}
//--- return calculated value
return(StdDev_rs);
}
/* Исходный вариант образца
double StdDev_Func(int position,const double &price[],const double &MAprice[],int period)
{
//--- variables
double StdDev_dTmp=0.0;
//--- check for position
if(position>=period)
{
//--- calcualte StdDev
for(int i=0; i<period; i++)
StdDev_dTmp+=MathPow(price[position-i]-MAprice[position],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 DF (double spot, double strk, double s, double dte) // D1 из формулы Блэка-Шоулза https://en.wikipedia.org/wiki/Black–Scholes_model
{
return (log(spot/strk)+(RFreeRate/100+s*s/2)*dte)/(s*sqrt(dte));
}
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;
}
//+------------------------------------------------------------------+
Нашел любопытный индикатор по теме.
Осциллятор Блэка-Шоулза. Правда, он не работает у меня. Может, кто-нибудь подскажет, в чем дело?
Cделал два новых варианта на основе предыдущих. Увы, все по-старому...
Волатильность считается как доходность дневная в процентах (т.е. из сегодняшней цены вычитается вчерашняя и все делится на вчерашнюю; затем находится станд. квадратичное отклонение этих доходностей; далее переводится в годовую умножением на корень из числа дней в году).
Возникла проблема, не могу решить. Еще до введения линий СМ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); }
ищу программиста есть уровни с 100% отработкой нужно написать индикатор в ручную надоело каждый день писать***
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
В последнее время у меня возникла идея создания индикатора опционных уровней, основанного на системе Ильдара Нургалиева. В общем-то я никого не рекламирую и коммерческого интереса не имею, мои скромные наработки основаны на материалах, находящихся в открытом доступе.
Yotube: https://www.youtube.com/channel/UClZo081odiV1tVTnXPLY13w
Методичка по ТС https://yadi.sk/i/MAF5UJS63PGsqX
Excel файл для расчетов
https://vk.com/doc2034145_453816131?hash=a5e52256e0251b482c&dl=279f30310d4aa2ee4e
Группа Вконтакте https://vk.com/traderbar_lenta
Методику объяснять в деталях я не стану, все желающие могут ознакомиться на ютуб-канале автора.
В общем методика основывается на следующем.
С сайта http://cmegroup.quikstrike.net ежедневно необходимо брать данные по ценам опционов текущего страйка по выбранным фьючерсам (валюты, нефть, золото и т. д.) Используются данные либо по месячным опционам (больше по нефти и золоту), или по по недельным опционам с экспирацией через 3 недели ("3-ехнедельные опционы"). Данные необходимо брать со вкладки Pricing Sheets.
Данные получаются вчерашние, по формулам в файле эксель по ним пересчитываются сегодняшние показатели.
Рассчитываются точки безубыточности по колл и пут опционам для текущего страйка, а также верхний и нижний уровни стрэддла для этого же страйка. Они принимаются за уровни вероятного дисбаланса. Т.е. рассматриваются как возможные уровни пробоя/отбоя. Уровни стрэддла автор рекомендует использовать скорее для постановки стоп-лоссов.
Конечно, эти уровни следует использовать вместе с другими - POC недели, месяца, тенденции и/или иными уровнями повышенного объема.
Иными словами, в этой методике ежедневно используются расчетные уровни, не привязанные напрямую к каким-то объемам.
Кроме всего прочего, за несколько недель я обнаружил, что эти уровни Нургалиева (назовем их так условно), часто примерно соответствуют положению лент Боллинджера с периодом 200-300 (+/- 2 СКО) на часовом графике (т. е. период скользящих примерно соответствует тем же 3 неделям, как у Нургалиева).
Поскольку эти уровни рассчитываются по известной формуле (модель Блэка-Шоулза), у меня возникла идея создать индикатор, напоминающий ленты Боллинджера (только верхняя лента представляет собой точку безубыточности для колл опциона, а нижняя - для пут опциона).
Кое-что по этой теме я уже собрал и попробовал сделать.
Bands Probability.zip - моя переделка стандартного индикатора.
Источники информации:
https://en.wikipedia.org/wiki/Black–Scholes_model
Русский вариант, но формулы с неточностями https://ru.wikipedia.org/wiki/Модель_Блэка_—_Шоулза
https://ru.wikipedia.org/wiki/Волатильность
Парочку примечаний по коду.
Формула для определения страйка рассчитана на пары типа EURUSD, GBPUSD, AUDUSD.
У них страйки выглядят типа 1,1250 - 1,1300 - 1,1350.
Потому для определения текущего страйка я использовал формулу в mt4:
Для других пар (перевернутые JPYUSD, CHFUSD, CADUSD и XAU, WTI) формулы немного будут отличаться коэффициентами, если я не ошибаюсь.
Risk free rate - безрисковая процентная ставка. По словам автора второго эксель-файла, она соответствует % ставке по казначейским облигациям соответствующего срока (т. е. 1 месяц), так как опционы/фьючерсы покупаются за доллары. Ее берут здесь:
ExpDate - дата экспирации месячного валютно опциона (одинаковая для все валют, взята с cmegroup.quikstrike.net).
Конечно, мне могут возразить, что у меня не учитываются форвард-пойнты, но это всего лишь модель ориентировочных уровней. Стоит заметить, даже у Нургалиева его уровни не отрабатываются точно пункт в пункт.
В архиве mql4 внешняя библиотека со стат. функциями. Распаковать в соответствующие папки mql4.
Visual Option - файлы с формулами для образца.
Принцип расчета волатильности брал отсюда. Волатильность я считал через среднее квадратичное отклонение с пересчетом (условно) на месяц и дальше в проценты за месяц, затем -пересчитывал на год. Наверно,здесь ошибка. Подскажите, как правильно.
Может, кто-нибудь подскажет, почему вообще ничего не рисует?
Подскажите, пожалуйста. Буду очень благодарен.