//+------------------------------------------------------------------+ //| CSymbol.mqh | //| Arthur Albano | //| https://www.mql5.com/en/articles/351 | //+------------------------------------------------------------------+ #property copyright "Arthur Albano" #property link "https://www.mql5.com/en/articles/351" #define SWAP(A, B) { A += B; B = A - B; A -= B; } #define SORT(a,b,c) {if(a > b) SWAP(a,b) if(a > c) SWAP(a,c) if (b>c) SWAP(b,c) } #include //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double TrueMedian(double first, double second,double third) { SORT(first,second,third); return((third<=0.0)?0.0:((second<=0.0)?third:((first<=0.0)?((third+second)/2.0):second))); }; enum ENUM_PRICE_MODE { PRICE_MODE_LAST = SYMBOL_LAST, PRICE_MODE_BID = SYMBOL_BID, PRICE_MODE_ASK = SYMBOL_ASK, PRICE_MODE_BIDASK, PRICE_MODE_MEDIAN }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CSymbol : public CNDimensional_PFunc { private: string aSymbol; double _S; //Underlying security price; double _K; //Strike price double _X; //Premium price double _z; //+1 for calls, -1 for puts, 0 for assets double _r; //return double _B; //Break-even: B = K + z X double _T; //time to expiration string _BASIS; // Underlying Security virtual void _OPM1(double &c[], double &K[], double &func, CObject &obj); // An Option Pricing Model, univariate (r) virtual void _OPM2(double &c[], double &K[], double &func, CObject &obj); // An Option Pricing Model, bivariate (r and ς_1) virtual void _OPM4(double &c[], double &K[], double &func, CObject &obj); // An Option Pricing Model, 4-variate (r, ς_1, κ_1 and (ς_0 + κ_0)) public: bool SetSymbol(const string symbol_name); double InfoDouble(const ENUM_SYMBOL_INFO_DOUBLE _ENUM_SYMBOL_INFO_DOUBLE); string InfoString(const ENUM_SYMBOL_INFO_STRING _ENUM_SYMBOL_INFO_STRING); double Price(const ENUM_PRICE_MODE _ENUM_PRICE_MODE); double OPM(); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CSymbol::_OPM1(double &m[],double &K[],double &func, CObject &obj) { double c = 4.0*(_T)*pow(m[0]*_S,2.0); double d = K[0] - _S; func = (1.0/2.0)*sqrt(pow(d,2.0)+c) - _Z * d / 2.0; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CSymbol::_OPM2(double &m[],double &K[],double &func, CObject &obj) { double c = 4.0*(_T)*pow(m[0]*_S,2.0); double d = K[0] - m[1]*_S; func = (1.0/2.0)*sqrt(pow(d,2.0)+c) - _Z * d / 2.0; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CSymbol::_OPM4(double &m[],double &K[],double &func, CObject &obj) { double c = 4.0*(_T)*pow(m[0]*_S,2.0); double d = m[3] + m[2]*K[0] - m[1]*_S; func = (1.0/2.0)*sqrt(pow(d,2.0)+c) - _Z * d / 2.0; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CSymbol::SetSymbol(const string symbol_name) { if(!SymbolSelect(symbol_name,true)) return(false); aSymbol = symbol_name; switch((int)SymbolInfoInteger(aSymbol,SYMBOL_OPTION_RIGHT)) { case SYMBOL_OPTION_RIGHT_CALL: _z = +1.0; break; case SYMBOL_OPTION_RIGHT_PUT: _z = -1.0; break; default: _z = 0.0; _r = 0.0; _T = 0.0; break; }; if(SymbolInfoString(aSymbol,SYMBOL_BASIS)!="") _BASIS = SymbolInfoString(aSymbol,SYMBOL_BASIS); return(true); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CSymbol::InfoDouble(const ENUM_SYMBOL_INFO_DOUBLE _ENUM_SYMBOL_INFO_DOUBLE) { return(SymbolInfoDouble(aSymbol,_ENUM_SYMBOL_INFO_DOUBLE)); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string CSymbol::InfoString(const ENUM_SYMBOL_INFO_STRING _ENUM_SYMBOL_INFO_STRING) { return(SymbolInfoString(aSymbol,_ENUM_SYMBOL_INFO_STRING)); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CSymbol::Price(const ENUM_PRICE_MODE _ENUM_PRICE_MODE) { if(_ENUM_PRICE_MODE==PRICE_MODE_LAST) return(SymbolInfoDouble(aSymbol,SYMBOL_LAST)); if(_ENUM_PRICE_MODE==PRICE_MODE_BID) return(SymbolInfoDouble(aSymbol,SYMBOL_BID)); if(_ENUM_PRICE_MODE==PRICE_MODE_ASK) return(SymbolInfoDouble(aSymbol,SYMBOL_ASK)); if(_ENUM_PRICE_MODE==PRICE_MODE_BIDASK) return((SymbolInfoDouble(aSymbol,SYMBOL_ASK)+SymbolInfoDouble(aSymbol,SYMBOL_BID))/2.0); if(_ENUM_PRICE_MODE==PRICE_MODE_MEDIAN) return(TrueMedian(SymbolInfoDouble(aSymbol,SYMBOL_BID),SymbolInfoDouble(aSymbol,SYMBOL_ASK),SymbolInfoDouble(aSymbol,SYMBOL_LAST))); return(SymbolInfoDouble(aSymbol,SYMBOL_LAST)); }; //+------------------------------------------------------------------+ double CSymbol::OPM() { CMatrixDouble K; //strikes (K) double y[]; //premiums (X0) double c[]; //overfitting coeffs double w[]; //weights (deals, for day close) CObject obj; CSymbol Model; CNDimensional_Rep frep; CSymbol _CSymbol; _CSymbol.SetSymbol(aSymbol); SymbolSelect(_BASIS,true); for(int i=0; i0.0)&& (SymbolInfoInteger(SymbolName(i,false),SYMBOL_EXPIRATION_TIME)==SymbolInfoInteger(aSymbol,SYMBOL_EXPIRATION_TIME))&& (SymbolInfoInteger(SymbolName(i,false),SYMBOL_OPTION_MODE)==SymbolInfoInteger(aSymbol,SYMBOL_OPTION_MODE)) ) { SymbolSelect(SymbolName(i,false),true); }; }; MqlTick _MqlTicks[]; int iCopyTicks = 0; for(int i = 0; SymbolsTotal(true); i++) { CopyTicks(SymbolName(i,true),_MqlTicks,COPY_TICKS_ALL,86400*int(SymbolInfoInteger(_BASIS,SYMBOL_TIME)/86400)); }; return(0.0); }; //+------------------------------------------------------------------+