//+------------------------------------------------------------------+ //| OptionConvert.mq5 | //| Copyright 2022, Allan Serotini | //| 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) } //+------------------------------------------------------------------+ //| Estruturas | //+------------------------------------------------------------------+ enum CalcMode { VWAP,//Session Average Weighted Last,//Last deal quote AskBidWatch,//Watch(Ask+Bid)/2 Median//Mediana }; struct sOption { string strSymbol; ENUM_SYMBOL_OPTION_RIGHT enRight; double dbK; double dbP; double dbC; ulong dtExpiration; ulong dtLastDeal; }; //+------------------------------------------------------------------+ //| Entradas | //+------------------------------------------------------------------+ sinput group "Globais"; sinput CalcMode inpCalcMode=Median;// Modo de Cálculo: sinput datetime inpMaxExpiration=D'2022.12.31 23:00:00';//Máxima expiração: sinput int inpSecondPlane=5;//Atualizações em segundo plano (s): sinput string inpSymbolConvert="BOVA11";//Converter posição para o Símbolo: sinput string inpSymbolToConvert=""; //+------------------------------------------------------------------+ //| Globais | //+------------------------------------------------------------------+ string strStatus=""; string strComment=""; sOption arrBruteOptions[];//Usado como basse para carregar o arrOptions ( localmente em EA() ) já ordenado //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- create timer LoadBruteOptions(); EventSetTimer(1); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- destroy timer EventKillTimer(); Comment(""); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //| Timer function | //+------------------------------------------------------------------+ void OnTimer() { //--- EA(); } //+------------------------------------------------------------------+ //| Função Principal | //+------------------------------------------------------------------+ void EA() { if(SymbolInfoInteger(_Symbol,SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT) { if((MathMod((double)TimeLocal(),inpSecondPlane)==0.0))LoadBruteOptions(); ulong vSort[][2]; ZeroMemory(vSort); ArrayResize(vSort,ArraySize(arrBruteOptions)); for(int i=0;i0.0)||(dbCaixa>0.0) ) //&&(arrOptions[i].dbK>=dbEquivalentK) //&&(arrOptions[i].dbP>0.0) &&((StringLen(inpSymbolToConvert)>0?inpSymbolToConvert==arrOptions[i].strSymbol:true)) ) { strComment+=StringFormat("%8s %4.0f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %.4f\n", arrOptions[i].strSymbol, dbQ, arrOptions[i].dbK, arrOptions[i].dbP, arrOptions[i].dbK-arrOptions[i].dbP, dbQ*arrOptions[i].dbK, dbQ*arrOptions[i].dbP, dbQ*(arrOptions[i].dbK-arrOptions[i].dbP), dbCaixa, dbBreak, dbCaixa+dbBreak, arrOptions[i].dbK/SymbolPrice(OptionBasis(arrOptions[i].strSymbol),inpCalcMode) ); } } Comment(strStatus+"\n"+strComment); } else { Comment(""); } } //+------------------------------------------------------------------+ //| Converte Código ISIN para Symbol | //+------------------------------------------------------------------+ string ISINtoSymbol(const string strISIN) { string strSymbol=StringSubstr(strISIN,2,4); if(StringSubstr(strISIN,9,2)=="PR") strSymbol+="4"; if(StringSubstr(strISIN,9,2)=="OR") strSymbol+="3"; if(StringSubstr(strISIN,9,2)=="00") strSymbol+="9"; return strSymbol; } //+------------------------------------------------------------------+ //| Carrega a Matriz de Opções (Bruta) | //+------------------------------------------------------------------+ void LoadBruteOptions() { string strISIN = SymbolInfoString(inpSymbolConvert, SYMBOL_ISIN); ArrayFree(arrBruteOptions); ZeroMemory(arrBruteOptions); strStatus="Carregando opções....\n"; Comment(strStatus+strComment); for(int i=0;i0.0) &&((SymbolInfoInteger(SymbolName(i,false),SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL)||(SymbolInfoInteger(SymbolName(i,false),SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT)) &&((StringSubstr(SymbolInfoString(SymbolName(i,false),SYMBOL_ISIN),2,5)==ISINtoSymbol(SymbolInfoString(inpSymbolConvert,SYMBOL_ISIN)))||((StringSubstr(SymbolInfoString(SymbolName(i,false),SYMBOL_ISIN),2,5)==StringSubstr(SymbolInfoString(inpSymbolConvert,SYMBOL_ISIN),2,5)))) &&(SymbolInfoInteger(SymbolName(i,false),SYMBOL_EXPIRATION_TIME)TimeLocal()) ) { SymbolSelect(SymbolName(i,false),true); ArrayResize(arrBruteOptions,ArraySize(arrBruteOptions)+1); arrBruteOptions[ArraySize(arrBruteOptions)-1].strSymbol=SymbolName(i,false); arrBruteOptions[ArraySize(arrBruteOptions)-1].enRight=(ENUM_SYMBOL_OPTION_RIGHT)SymbolInfoInteger(SymbolName(i,false),SYMBOL_OPTION_RIGHT); arrBruteOptions[ArraySize(arrBruteOptions)-1].dtExpiration=SymbolInfoInteger(SymbolName(i,false),SYMBOL_EXPIRATION_TIME); arrBruteOptions[ArraySize(arrBruteOptions)-1].dbK=SymbolInfoDouble(SymbolName(i,false),SYMBOL_OPTION_STRIKE); if(SymbolInfoInteger(SymbolName(i,false),SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_CALL) arrBruteOptions[ArraySize(arrBruteOptions)-1].dbC=SymbolPrice(SymbolName(i,false),inpCalcMode); if(SymbolInfoInteger(SymbolName(i,false),SYMBOL_OPTION_RIGHT)==SYMBOL_OPTION_RIGHT_PUT) arrBruteOptions[ArraySize(arrBruteOptions)-1].dbP=SymbolPrice(SymbolName(i,false),inpCalcMode); arrBruteOptions[ArraySize(arrBruteOptions)-1].dtLastDeal=SymbolInfoInteger(SymbolName(i,false),SYMBOL_TIME); } } strStatus=""; Comment(strStatus+"\n"+strComment); } //+------------------------------------------------------------------+ //| Ativo subjacente da opção | //+------------------------------------------------------------------+ double SymbolPrice(const string SYMBOL, const CalcMode CALCMODE) { double result = 0.0; switch(CALCMODE) { case Last: return(SymbolInfoDouble(SYMBOL,SYMBOL_LAST)); break; case VWAP: return(SymbolInfoDouble(SYMBOL,SYMBOL_SESSION_AW)); break; case Median: return(TrueMedian(SymbolInfoDouble(SYMBOL,SYMBOL_BID),SymbolInfoDouble(SYMBOL,SYMBOL_ASK),SymbolInfoDouble(SYMBOL,SYMBOL_LAST))); break; case AskBidWatch: return(SymbolInfoDouble(SYMBOL,SYMBOL_ASK)+SymbolInfoDouble(SYMBOL,SYMBOL_BID))/2; break; } return(result); } 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))); } //+------------------------------------------------------------------+ //| Ativo subjacente da opçã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; } //+------------------------------------------------------------------+