OptionsPrime_v00/OptionsPrime_v00.mq5

506 lines
48 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:15:03 +02:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| OptionsPrime_v00.mq5 |
//| Copyright 2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#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) }
//+------------------------------------------------------------------+
//| Vari<EFBFBD>veis Globais |
//+------------------------------------------------------------------+
enum CalcMode
{
calcOPM, // Arthur Option Price Model
calcMedian, // Median
calcLast, // Watch: Last
calcHalfAskBid, // Watch: (Ask+Bid)/2
calcAWP, // Watch: AWP
};
//+------------------------------------------------------------------+
//| Setup |
//+------------------------------------------------------------------+
double iAlavangabem = 2.0; // Cotas para cada Adjacente:
//+------------------------------------------------------------------+
//| Inputs |
//+------------------------------------------------------------------+
sinput datetime inMaxExpiration = D'2024.12.31 23:59:59'; //Expira<EFBFBD><EFBFBD>o m<EFBFBD>xima:
sinput CalcMode inCalcMode = calcMedian; // Modo de Calculo:
sinput double inR0 = 10.75; // Taxa de Retorno Seguro:
sinput int iFrequency = 2000; // Frequencia de execucao (milisegundos):
sinput double inPcDownB = 0.0; // Porcentagem que o B pode baixar (%):
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- create timer
ChartSetInteger(0,CHART_SHOW_DATE_SCALE,1);
ChartSetInteger(0,CHART_SHOW_PRICE_SCALE,1);
EventSetMillisecondTimer(iFrequency);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- destroy timer
EventKillTimer();
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
//| Timer function |
//+------------------------------------------------------------------+
void OnTimer()
{
datetime timeStart = TimeLocal();
double dbCall_Volume=0.0;
double dbCall_B0m=0.0;
double dbCall_K0m=0.0;
double dbCall_Km=0.0;
double dbCall_Xm=0.0;
double dbPut_Volume=0.0;
double dbPut_B0m=0.0;
double dbPut_K0m=0.0;
double dbPut_Km=0.0;
double dbPut_Xm=0.0;
double dbSobraTotal=0.0;
string strComment = StringFormat(
">>Expiration: %s | Calc Mode: %s | R0: %.2f%% | Frequency: %d | Down B: %.2f%%\n",
TimeToString(inMaxExpiration, TIME_DATE),
EnumToString((CalcMode)inCalcMode),
inR0 * 100,
iFrequency,
inPcDownB
);
strComment+="\nSymbol T S K0 X0 B0 Xr(OPM) --> Roll to T K X(OPM) B E a.a.(E) = dT dK dX0 dX dB By --> dR$\n";
ulong ulPositionTicket=0;
for(int i=0;i<PositionsTotal();i++)
{
ulPositionTicket=PositionGetTicket(i);
double dbS = 0.0;
double dbK = 0.0;
double dbX0 = 0.0;
double dbB0 = 0.0;
double dbX = 0.0;
double dbZ = 0.0;
string strPositonSymbol = PositionGetSymbol(i);
if(
(SymbolInfoDouble(strPositonSymbol, SYMBOL_OPTION_STRIKE) > 0.0) &&
((SymbolInfoInteger(strPositonSymbol, SYMBOL_OPTION_RIGHT) == SYMBOL_OPTION_RIGHT_CALL) || (SymbolInfoInteger(strPositonSymbol, SYMBOL_OPTION_RIGHT) == SYMBOL_OPTION_RIGHT_PUT))
)
{
dbZ=(SymbolInfoInteger(strPositonSymbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL?1.0:(SymbolInfoInteger(strPositonSymbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT?-1.0:0.0));
dbS=SymbolPrice(OptionBasis(PositionGetSymbol(i)),inCalcMode);
dbK=SymbolInfoDouble(PositionGetSymbol(i),SYMBOL_OPTION_STRIKE);
dbX0=PositionGetDouble(POSITION_PRICE_OPEN);
dbB0=dbK+dbX0*dbZ;
//dbX=SymbolPrice(strPositonSymbol,inCalcMode);
dbX=(SymbolPrice(strPositonSymbol,inCalcMode)>0.0?SymbolPrice(strPositonSymbol,inCalcMode):ArthurOptionPriceModel(strPositonSymbol));
if(SymbolInfoInteger(strPositonSymbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL)
{
dbCall_Volume+=PositionGetDouble(POSITION_VOLUME);
dbCall_B0m+=(dbB0*PositionGetDouble(POSITION_VOLUME));
dbCall_K0m+=(dbK*PositionGetDouble(POSITION_VOLUME));
}
else
if(SymbolInfoInteger(strPositonSymbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT)
{
dbPut_Volume+=PositionGetDouble(POSITION_VOLUME);
dbPut_B0m+=(dbB0*PositionGetDouble(POSITION_VOLUME));
dbPut_K0m+=(dbK*PositionGetDouble(POSITION_VOLUME));
}
for(int s=0;s<=SymbolsTotal(false);s++)
{
if(
(SymbolInfoDouble(SymbolName(s,false),SYMBOL_OPTION_STRIKE)>0.0)
&& (OptionBasis(SymbolName(s,false))==OptionBasis(strPositonSymbol))
&& ( (SymbolInfoInteger(SymbolName(s,false),SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL)||(SymbolInfoInteger(SymbolName(s,false),SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT) )
&& SymbolInfoInteger(SymbolName(s,false),SYMBOL_EXPIRATION_TIME)>=(TimeLocal()+(24*60*60))
&& SymbolInfoInteger(SymbolName(s,false),SYMBOL_EXPIRATION_TIME)<=inMaxExpiration
)
{
SymbolSelect(SymbolName(s,false),true);
}
}
double _BestEBaa=0.0;
double _BestE=0.0;
string _BestEBaaSymbol="";
double _S[]; ArrayResize(_S,SymbolsTotal(true));
long _T[]; ArrayResize(_T,SymbolsTotal(true));
double _Z[]; ArrayResize(_Z,SymbolsTotal(true));
double _K[]; ArrayResize(_K,SymbolsTotal(true));
double _X[]; ArrayResize(_X,SymbolsTotal(true));
double _r[]; ArrayResize(_r,SymbolsTotal(true));
double _B[]; ArrayResize(_B,SymbolsTotal(true));
double _I[]; ArrayResize(_I,SymbolsTotal(true));
double _E[]; ArrayResize(_E,SymbolsTotal(true));
double _EBaa[]; ArrayResize(_EBaa,SymbolsTotal(true));
double _Xopm[]; ArrayResize(_Xopm,SymbolsTotal(true));
for(int s=0;s<=SymbolsTotal(true);s++)
{
if(
(SymbolInfoDouble(SymbolName(s,true),SYMBOL_OPTION_STRIKE)>0.0)
&& (OptionBasis(SymbolName(s,true))==OptionBasis(strPositonSymbol))
&& SymbolInfoInteger(SymbolName(s,true),SYMBOL_EXPIRATION_TIME)>TimeLocal()
&& SymbolInfoInteger(SymbolName(s,true),SYMBOL_EXPIRATION_TIME)<=inMaxExpiration
)
{
_S[s]=SymbolPrice(OptionBasis(SymbolName(s,true)),inCalcMode);
_T[s]=SymbolInfoInteger(SymbolName(s,true),SYMBOL_EXPIRATION_TIME);
_Z[s]=(SymbolInfoInteger(SymbolName(s,true),SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL?1.0:(SymbolInfoInteger(SymbolName(s,true),SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT?-1.0:0.0));
_K[s]=SymbolInfoDouble(SymbolName(s,true),SYMBOL_OPTION_STRIKE);
_X[s]=SymbolPrice(SymbolName(s,true),inCalcMode);
_r[s]=_X[s]/_S[s]; //_r[s]=_X[s]/_K[s];
_B[s]=_K[s]+_X[s]*_Z[s];
if(SymbolInfoInteger(SymbolName(s,true),SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL) _I[s]=MathMax(_S[s]-_K[s],0.0); // _I[s]=(_S[s]>_K[s]?_S[s]-_K[s]:0.0);
if(SymbolInfoInteger(SymbolName(s,true),SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT) _I[s]=MathMax(_K[s]-_S[s],0.0); //(_K[s]>_S[s]?_K[s]-_S[s]:0.0);
_E[s]=MathMax(_X[s]-_I[s],0.0);
// ((_X[s]-(_I[s]>0.0?_I[s]:0.0))>0.0?_X[s]-(_I[s]>0.0?_I[s]:0.0):0.0); // _E[s]=_E[s]*2.0;;_E[s]=0.0;
if(SymbolInfoInteger(SymbolName(s,true),SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL)
{
_EBaa[s]=pow(1.0+(2.0*_E[s])/_S[s],252.0/((double)(_T[s]-TimeLocal())/86000.0))-1.0;
}
else
if(SymbolInfoInteger(SymbolName(s,true),SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT)
{
_EBaa[s]=pow(1.0+_E[s]/_S[s],252.0/((double)(_T[s]-TimeLocal())/86000.0))-1.0;
}
_Xopm[s]=ArthurOptionPriceModel(SymbolName(s,true));
/*
if(_Z[s]==(SymbolInfoInteger(strPositonSymbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL?1.0:-1.0))
if((SymbolInfoInteger(strPositonSymbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL)?_B[s]>(dbB0*(1.0-inPcDownB/100)):(SymbolInfoInteger(strPositonSymbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT?_B[s]<(dbB0*(1.0+inPcDownB/100)) : false ) )
if(_X[s]>dbX)
//if(dbX0>dbX)
{
_BestEBaaSymbol=SymbolName(s,true);
_BestEBaa=_EBaa[s];
_BestE=_E[s];
}
*/
if( SymbolName(s,true)!=strPositonSymbol)
if(SymbolInfoInteger(SymbolName(s,true),SYMBOL_EXPIRATION_TIME)>=SymbolInfoInteger(strPositonSymbol,SYMBOL_EXPIRATION_TIME))
if(_X[s]>dbX)
if(SymbolInfoInteger(strPositonSymbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL )
{
if(_B[s]>=dbB0)
if(_Z[s]>0.0)
{
if(_EBaa[s]>_BestEBaa)
{
_BestEBaaSymbol=SymbolName(s,true);
_BestEBaa=_EBaa[s];
_BestE=_E[s];
}
}
}
else
if(SymbolInfoInteger(strPositonSymbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT )
{
if(_B[s]<=dbB0)
if(_Z[s]<=0.0)
{
_BestEBaaSymbol=SymbolName(s,true);
_BestEBaa=_EBaa[s];
_BestE=_E[s];
}
}
}
}
strComment+=strPositonSymbol+(strPositonSymbol.Length()==8?" ":"")+": ";
strComment+=IntegerToString( ( SymbolInfoInteger(strPositonSymbol,SYMBOL_EXPIRATION_TIME) - TimeLocal() )/86400 )+"d "; // " 73d ";
strComment+=DoubleToString(dbS,2)+" ";
strComment+=DoubleToString(dbK,2)+" ";
strComment+=DoubleToString(dbX0,2)+" ";
strComment+=DoubleToString(dbB0,2)+" ";
strComment+=DoubleToString(dbX,2)+"(";
strComment+=DoubleToString(ArthurOptionPriceModel(strPositonSymbol),2)+") ";
if(_BestEBaaSymbol.Length()>0)
{
if(SymbolInfoInteger(_BestEBaaSymbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL)
{
dbCall_Km+=SymbolInfoDouble(_BestEBaaSymbol, SYMBOL_OPTION_STRIKE)*PositionGetDouble(POSITION_VOLUME);
dbCall_Xm+=SymbolPrice(_BestEBaaSymbol,inCalcMode)*PositionGetDouble(POSITION_VOLUME);
}
else
if(SymbolInfoInteger(_BestEBaaSymbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT)
{
dbPut_Km+=SymbolInfoDouble(_BestEBaaSymbol, SYMBOL_OPTION_STRIKE)*PositionGetDouble(POSITION_VOLUME);
dbPut_Xm+=SymbolPrice(_BestEBaaSymbol,inCalcMode)*PositionGetDouble(POSITION_VOLUME);
}
strComment+=" --> ";
strComment+=_BestEBaaSymbol+(_BestEBaaSymbol.Length()==8?" ":"")+" ";
strComment+=DoubleToString( (double)( (SymbolInfoInteger(_BestEBaaSymbol,SYMBOL_EXPIRATION_TIME) - TimeLocal() ) / 86000.0 ) , 0 ) + "d ";
strComment+=DoubleToString(SymbolInfoDouble(_BestEBaaSymbol, SYMBOL_OPTION_STRIKE),2) + " ";
strComment+=DoubleToString(SymbolPrice(_BestEBaaSymbol,inCalcMode), 2 ) + "(";
strComment+=DoubleToString(ArthurOptionPriceModel(_BestEBaaSymbol), 2 ) + ") ";
strComment+=DoubleToString(SymbolInfoDouble(_BestEBaaSymbol, SYMBOL_OPTION_STRIKE)+SymbolPrice(_BestEBaaSymbol,inCalcMode)*dbZ,2)+ " ";
if(SymbolInfoInteger(_BestEBaaSymbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL)
{
strComment+=DoubleToString(
//(SymbolPrice(_BestEBaaSymbol,inCalcMode)-(dbS-SymbolInfoDouble(_BestEBaaSymbol, SYMBOL_OPTION_STRIKE)>0.0?dbS-SymbolInfoDouble(_BestEBaaSymbol, SYMBOL_OPTION_STRIKE):0.0)>0.0?SymbolPrice(_BestEBaaSymbol,inCalcMode)-(dbS-SymbolInfoDouble(_BestEBaaSymbol, SYMBOL_OPTION_STRIKE)>0.0?dbS-SymbolInfoDouble(_BestEBaaSymbol, SYMBOL_OPTION_STRIKE):0.0):0.0)
_BestE
, 2 ) + " ";
}
else
if(SymbolInfoInteger(_BestEBaaSymbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT)
{
strComment+=DoubleToString(
//SymbolPrice(_BestEBaaSymbol,inCalcMode)-
//((SymbolInfoDouble(_BestEBaaSymbol, SYMBOL_OPTION_STRIKE)-dbS)>0.0?(SymbolInfoDouble(_BestEBaaSymbol, SYMBOL_OPTION_STRIKE)-dbS):0.0)
_BestE
, 2 ) + " ";
}
//strComment+="("+DoubleToString(100*( (_BestE/dbS) ), 2 )+"%) ";
strComment+="("+DoubleToString(100*( pow(1.0+((_BestE*2.0)/dbS),252.0/((double)(SymbolInfoInteger(_BestEBaaSymbol,SYMBOL_EXPIRATION_TIME)-TimeLocal())/86000.0))-1.0 ), 2 )+"%) ";
strComment+=" = ";
strComment+=DoubleToString( (( (SymbolInfoInteger(_BestEBaaSymbol,SYMBOL_EXPIRATION_TIME) - TimeLocal() ) / 86000.0 ))-(( SymbolInfoInteger(strPositonSymbol,SYMBOL_EXPIRATION_TIME) - TimeLocal() )/86400 ), 0 )+"d ";
if(SymbolInfoInteger(_BestEBaaSymbol, SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL)
{
strComment+=DoubleToString( SymbolInfoDouble(_BestEBaaSymbol, SYMBOL_OPTION_STRIKE)-dbK, 2) + " ";
}
else
if(SymbolInfoInteger(_BestEBaaSymbol, SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT)
{
strComment+=DoubleToString( dbK-SymbolInfoDouble(_BestEBaaSymbol, SYMBOL_OPTION_STRIKE), 2) + " ";
}
strComment+=DoubleToString( dbX0-dbX, 2 ) + " ";
strComment+=DoubleToString(SymbolPrice(_BestEBaaSymbol,inCalcMode)-dbX,2)+" ";
if(SymbolInfoInteger(_BestEBaaSymbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL) strComment+=DoubleToString((SymbolInfoDouble(_BestEBaaSymbol, SYMBOL_OPTION_STRIKE)+SymbolPrice(_BestEBaaSymbol,inCalcMode))-dbB0,2)+" ";
if(SymbolInfoInteger(_BestEBaaSymbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT) strComment+=DoubleToString(dbB0-(SymbolInfoDouble(_BestEBaaSymbol, SYMBOL_OPTION_STRIKE)-SymbolPrice(_BestEBaaSymbol,inCalcMode)),2)+" ";
double dbYB=(SymbolInfoDouble(_BestEBaaSymbol, SYMBOL_OPTION_STRIKE)+SymbolPrice(_BestEBaaSymbol,inCalcMode))-dbB0;
strComment+="("+DoubleToString(dbYB,2)+"%)";
dbSobraTotal+=(SymbolPrice(_BestEBaaSymbol,inCalcMode)-dbX)*PositionGetDouble(POSITION_VOLUME);
strComment+=" --> "+DoubleToString( (SymbolPrice(_BestEBaaSymbol,inCalcMode)-dbX)*PositionGetDouble(POSITION_VOLUME),2);
}
else
{
if( SymbolInfoInteger(PositionGetSymbol(i),SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL)
{
dbCall_Km+=(dbK*PositionGetDouble(POSITION_VOLUME));
dbCall_Xm+=(dbX0*PositionGetDouble(POSITION_VOLUME));
}
else
if( SymbolInfoInteger(PositionGetSymbol(i),SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT)
{
dbPut_Km+=(dbK*PositionGetDouble(POSITION_VOLUME));
dbPut_Xm+=(dbX0*PositionGetDouble(POSITION_VOLUME));
}
}
strComment+="\n";
}
else
{
}
}
dbCall_K0m=dbCall_K0m/dbCall_Volume;
dbCall_B0m=dbCall_B0m/dbCall_Volume;
dbCall_Km=dbCall_Km/dbCall_Volume;
dbCall_Xm=dbCall_Xm/dbCall_Volume;
strComment+="------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n";
strComment+="CALL: ";
strComment+=DoubleToString(dbCall_K0m,2)+" ";
strComment+=DoubleToString(dbCall_B0m-dbCall_K0m,2)+" ";
strComment+=DoubleToString(dbCall_B0m,2)+" ";
strComment+=" --> ";
strComment+=" "+DoubleToString(dbCall_Km,2)+" ";
strComment+=""+DoubleToString(dbCall_Xm,2)+" ";
strComment+=" ";
strComment+=DoubleToString(dbCall_Km+dbCall_Xm,2)+" ";
strComment+="\n";
dbPut_K0m=dbPut_K0m/dbPut_Volume;
dbPut_B0m=dbPut_B0m/dbPut_Volume;
dbPut_Km=dbPut_Km/dbPut_Volume;
dbPut_Xm=dbPut_Xm/dbPut_Volume;
strComment+="PUT: ";
strComment+=DoubleToString(dbPut_K0m,2)+" ";
strComment+=DoubleToString(dbPut_K0m-dbPut_B0m,2)+" ";
strComment+=DoubleToString(dbPut_B0m,2)+" ";
strComment+=" --> ";
strComment+=" "+DoubleToString(dbPut_Km,2)+" ";
strComment+=""+DoubleToString(dbPut_Xm,2)+" ";
strComment+=" ";
strComment+=DoubleToString(dbPut_Km-dbPut_Xm,2)+" ";
strComment+=" --> "+DoubleToString(dbSobraTotal,2);
strComment+="\n";
strComment+="------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n";
// Condi<EFBFBD><EFBFBD>es para identificar Fundos de Investimento Imobili<EFBFBD>rio (FII) e FIIs com <EFBFBD>ltimo pre<EFBFBD>o maior que o pre<EFBFBD>o m<EFBFBD>nimo definido
int fii_count = 0; // Inicializa a contagem de Fundos de Investimento Imobili<EFBFBD>rio (FII)
double dbSpotVolum=0.0;
double dbOptionsVolume= 0.0;
for(int i = 0; i < PositionsTotal(); i++)
{
ulPositionTicket=PositionGetTicket(i);
string symbol_name = PositionGetSymbol(i);
if((StringSubstr(SymbolInfoString(symbol_name, SYMBOL_ISIN),6,3) == "CTF") &&
(StringLen(symbol_name) == 6) &&
(StringSubstr(symbol_name, 4, 2) == "11") &&
(StringSubstr(SymbolInfoString(symbol_name, SYMBOL_DESCRIPTION),0,3) == "FII") &&
(SymbolInfoDouble(symbol_name, SYMBOL_LAST) > 0.0))
{
fii_count++;
}
if(
(PositionGetSymbol(i)=="BOVA11")||(SymbolInfoInteger(symbol_name, SYMBOL_OPTION_RIGHT) == SYMBOL_OPTION_RIGHT_PUT)
)
{
dbSpotVolum+=PositionGetDouble(POSITION_VOLUME);
}
if((SymbolInfoDouble(symbol_name, SYMBOL_OPTION_STRIKE) > 0.0) &&
((SymbolInfoInteger(symbol_name, SYMBOL_OPTION_RIGHT) == SYMBOL_OPTION_RIGHT_CALL) ) && //|| (SymbolInfoInteger(symbol_name, SYMBOL_OPTION_RIGHT) == SYMBOL_OPTION_RIGHT_PUT)) &&
(SymbolInfoInteger(symbol_name, SYMBOL_EXPIRATION_TIME) < D'2025.12.31 23:00:00') &&
(SymbolInfoInteger(symbol_name, SYMBOL_EXPIRATION_TIME) > TimeLocal()) )
{
dbOptionsVolume+=PositionGetDouble(POSITION_VOLUME);
}
}
if(fii_count>0)
{
strComment+="\nALERT: "+IntegerToString(fii_count)+" FII's\n";
}
if(dbSpotVolum*2==dbOptionsVolume)
{
}
else
{
if((dbSpotVolum*2)>dbOptionsVolume)
{
strComment+="\nALERT: Falta vender " + DoubleToString( (dbSpotVolum*2)-dbOptionsVolume, 0 ) + " op<00><00>es!\n\n";
}
else
{
strComment+="\nALERT: Falta comprar " + DoubleToString( dbOptionsVolume-(dbSpotVolum*2), 0 ) + " op<00><00>es!\n\n";
}
}
datetime timeEnd = TimeLocal();
long timeElapsed = timeEnd - timeStart;
strComment+=TimeToString(TimeLocal(),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+". Executado em " + IntegerToString(timeElapsed) + "s\n";
Comment(strComment);
}
//+------------------------------------------------------------------+
//| Ativo subjacente da op<EFBFBD><EFBFBD>o |
//+------------------------------------------------------------------+
string OptionBasis(const string strSymbol)
{
string strReturn=StringSubstr(SymbolInfoString(strSymbol,SYMBOL_ISIN),2,4);
if(StringSubstr(SymbolInfoString(strSymbol, SYMBOL_ISIN), 6, 1)=="9")
{
strReturn+="11";
}
else
{
strReturn+=StringSubstr(SymbolInfoString(strSymbol,SYMBOL_ISIN),6,1);
}
return strReturn;
}
//+------------------------------------------------------------------+
//| Mediana |
//+------------------------------------------------------------------+
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)));
};
//+------------------------------------------------------------------+
//| Pre<EFBFBD>o do S<EFBFBD>mbolo |
//+------------------------------------------------------------------+
double SymbolPrice(const string SYMBOL, const CalcMode CALCMODE)
{
double result = 0.0;
switch(CALCMODE)
{
case calcOPM:
if(SymbolInfoDouble(SYMBOL,SYMBOL_OPTION_STRIKE)>0.0)
{
return ArthurOptionPriceModel(SYMBOL);
}
else
{
return(TrueMedian(SymbolInfoDouble(SYMBOL,SYMBOL_BID),SymbolInfoDouble(SYMBOL,SYMBOL_ASK),SymbolInfoDouble(SYMBOL,SYMBOL_LAST)));
}
break;
case calcLast:
result=SymbolInfoDouble(SYMBOL,SYMBOL_LAST);
break;
case calcHalfAskBid:
if((SymbolInfoDouble(SYMBOL,SYMBOL_ASK)>0.0)&&(SymbolInfoDouble(SYMBOL,SYMBOL_BID)>0.0))
result=(SymbolInfoDouble(SYMBOL,SYMBOL_ASK)+SymbolInfoDouble(SYMBOL,SYMBOL_BID))/2.0;
break;
case calcAWP:
result=SymbolInfoDouble(SYMBOL,SYMBOL_SESSION_AW);
break;
case calcMedian:
result=TrueMedian(SymbolInfoDouble(SYMBOL,SYMBOL_BID),SymbolInfoDouble(SYMBOL,SYMBOL_ASK),SymbolInfoDouble(SYMBOL,SYMBOL_LAST));
break;
}
//if(SymbolInfoDouble(SYMBOL,SYMBOL_OPTION_STRIKE)>0.0) if(result<=0.0) result=ArthurOptionPriceModel(SYMBOL);
return(result);
}
//+------------------------------------------------------------------+
//| Arthur Options Price Model |
//+------------------------------------------------------------------+
double ArthurOptionPriceModel(string SYMBOL)
{
double _z = (SymbolInfoInteger(SYMBOL,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL?1.0:-1.0);
double _S = SymbolPrice( OptionBasis( SYMBOL ), inCalcMode );
double _K = SymbolInfoDouble(SYMBOL,SYMBOL_OPTION_STRIKE);
double _T = MathMax(0.0,(SymbolInfoInteger(SYMBOL,SYMBOL_EXPIRATION_TIME)-TimeLocal())/86400.0);
double _r0 = inR0;
double term1 = pow(_K - _S, 2.0);
double term2 = 4 * (_T/365.0) * pow( _r0 * _S, 2.0 );
double sqrt_term = sqrt( term1 + term2 );
return 0.5 * ( sqrt_term - _z*(_K - _S) );
}