Options/CSymbol.mqh

186 lines
15 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:14:55 +02:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| 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 <EFBFBD>_1)
virtual void _OPM4(double &c[], double &K[], double &func, CObject &obj); // An Option Pricing Model, 4-variate (r, <EFBFBD>_1, <EFBFBD>_1 and (<EFBFBD>_0 + <EFBFBD>_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);
};
//+------------------------------------------------------------------+