185 lines
15 KiB
MQL5
185 lines
15 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| 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 <Math\Alglib\alglib.mqh>
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
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; i<SymbolsTotal(false); i++)
|
|
{
|
|
if(
|
|
(SymbolInfoDouble(SymbolName(i,false),SYMBOL_OPTION_STRIKE)>0.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);
|
|
|
|
};
|
|
//+------------------------------------------------------------------+
|