//+------------------------------------------------------------------+ //| osc_minion_trade_estatistica.| //| Copyright 2020,oficina de software.| //| http://www.metaquotes.net/marcoc.| //+------------------------------------------------------------------+ #property copyright "2020, Oficina de Software." #property link "http://www.os.net" //--- #include #include class osc_minion_trade_estatistica{ private: CDealInfo m_deal ; CSymbolInfo m_symbol ; double m_profitDiaLiquido ; double m_profitDiaLiquidoWDO; double m_profitDiaLiquidoWIN; double m_profitPorContratoWDO; double m_profitPorContratoWIN; double m_profitPorContrato ; double m_profitDia ; double m_profitDiaWDO ; double m_profitDiaWIN ; double m_volumeDia ; double m_volumeDiaWDO ; double m_volumeDiaWIN ; double m_tarifaDia ; double m_tarifaDiaWDO ; double m_tarifaDiaWIN ; double m_cotacaoMoedaTarifa ; double m_cotacaoMoedaTarifaWDO; double m_cotacaoMoedaTarifaWIN; double m_taxaLiqWIN; double m_taxaLiqWDO; //string m_str_symbol ; double m_valWinsDia; // valor bruto das vitorias no dia double m_valLossDia; // valor bruto das perdas no dia double m_payOut; // fator de lucro no dia double m_qtdWinsDia; // quantidade de trades vencedores no dia; double m_qtdLossDia; // quantidade de trades perdedores no dia; double m_probAcerto; // probabilidade de acertos, baseada no historico de transacoes; double m_coefKelly ; // coeficente de Kelly; double m_rebaixamentoSld; // rebaixamento de saldo ao final do dia. //string getSymbol (){ return m_str_symbol ;} double calcTarifaWIN (const double pVolume); double calcTarifaWDO (const double pVolume); double calcTarifa (const double pVolume); bool ehMiniDolar (const string pSymbol){ return (StringFind(pSymbol,"WDO") > -1); } bool ehMiniIndice(const string pSymbol){ return (StringFind(pSymbol,"WIN") > -1); } void calcPayOut (); void calcProbAcertos(); void calcCoefKelly (); protected: double extrair_var_independente( const string comentario, const string letra_var ); public: void osc_minion_trade_estatistica(); //void setStrSymbol (const string strSymbol ){ m_str_symbol = strSymbol; } void initialize(){ m_rebaixamentoSld=0; m_taxaLiqWIN=0.0; m_taxaLiqWDO=0.12; m_symbol.Name(_Symbol); } void setCotacaoMoedaTarifaWDO(const double cotacao ) { m_cotacaoMoedaTarifa = cotacao ; } void refresh (const datetime from, const datetime to); void print_posicoes(const datetime from, const datetime to); double getProfitDia (){ return m_profitDia ;} double getProfitDiaWDO (){ return m_profitDiaWDO ;} double getProfitDiaWIN (){ return m_profitDiaWIN ;} double getTarifaDia (){ return m_tarifaDia ;} double getTarifaDiaWDO (){ return m_tarifaDiaWDO ;} double getTarifaDiaWIN (){ return m_tarifaDiaWIN ;} double getProfitDiaLiquido (){ return m_profitDiaLiquido ;} double getProfitDiaLiquidoWDO (){ return m_profitDiaLiquidoWDO ;} double getProfitDiaLiquidoWIN (){ return m_profitDiaLiquidoWIN ;} double getProfitPorContrato (){ return m_profitPorContrato ;} double getProfitPorContratoWDO(){ return m_profitPorContratoWDO ;} double getProfitPorContratoWIN(){ return m_profitPorContratoWIN ;} double getVolumeDia (){ return m_volumeDia ;} double getVolumeDiaWDO (){ return m_volumeDiaWDO ;} double getVolumeDiaWIN (){ return m_volumeDiaWIN ;} double getProbAcerto (){ return m_probAcerto ;} double getPayOut (){ return m_payOut ;} double getCoefKelly (){ return m_coefKelly ;} double getRebaixamentoSld (){ return m_rebaixamentoSld ;} }; void osc_minion_trade_estatistica::osc_minion_trade_estatistica(){ m_profitDiaLiquido = 0; m_profitDiaLiquidoWDO = 0; m_profitDiaLiquidoWIN = 0; m_profitPorContrato = 0; m_profitPorContratoWDO = 0; m_profitPorContratoWIN = 0; m_volumeDia = 0; m_volumeDiaWDO = 0; m_volumeDiaWIN = 0; m_cotacaoMoedaTarifa = 0; m_cotacaoMoedaTarifaWDO = 5; m_cotacaoMoedaTarifaWIN = 1; } double osc_minion_trade_estatistica::extrair_var_independente( const string comentario, const string letra_var ){ string var_independente[]; int pos1 = 0; double retorno = 0; ushort sep = StringGetCharacter(" ",0); int qtd_var = StringSplit( comentario, sep, var_independente ); if( qtd_var == 0 ){ Print(__FUNCTION__, ":Caractere separador nao encontrado na string:", comentario); return 0; } if( qtd_var < 0 ){ Print(__FUNCTION__, ":Erro ", GetLastError()," extraindo variavel independente da string:", comentario); return 0; } for( int i=1; i -1 ) return StringToDouble( StringSubstr(var_independente[i],1) ); } return 0; } int openArqPosicoes(datetime from, datetime to){ // data inicial. farah parte do nome do arquivo... string strFrom = TimeToString(from,TIME_DATE); StringReplace(strFrom,".",""); // data final. farah parte do nome do arquivo... string strTo = TimeToString(to,TIME_DATE); StringReplace(strTo,".",""); string nameArqPos = strFrom + "-" + strTo + "-" + "posicoes.csv"; Print("Criando arquivo de posicoes ", nameArqPos, " no diretorio comum de arquivos..."); int file = FileOpen(nameArqPos, FILE_WRITE|FILE_TXT|FILE_ANSI|FILE_COMMON); if( file<0 ){ Print("Falha para abrir o arquivo de posicoes: ", file ); Print("Codigo de erro: " , GetLastError() ); } return file; } void closeArqPosicoes(int arqPos){ Print("Fechando arquivo de posicoes", arqPos, " ..."); FileClose(arqPos); Print("Arquivo de posicoes fechado!!!"); } //+------------------------------------------------------------------+ //| | //| Escreve o resumo de cada posicao no arquivo de posicoes. | //| | //+------------------------------------------------------------------+ void osc_minion_trade_estatistica::print_posicoes(const datetime from, const datetime to){ Print(":-| Montando historico de posicoes..."); int posFile = openArqPosicoes(from,to); HistorySelect(from,to); uint totalDeals=HistoryDealsTotal(); // quantidade de ofertas no historico... datetime time_ini=0,time_fim=0 ; string time_ini_str, time_fim_str ; long tempo_posicao_em_segundos = 0; long posicao_ant = 0; double posicao_profit = 0; double posicao_volume = 0; int posicao_tipo_buy_sell = 0; double posicao_draw_down = 0; string comentario ; double probabilidade_updw = 0; //p double entrelacamento_coef = 0; //e double entrelacamento_canal = 0; //d double entrelacamento_regiao_compra = 0; //c double volatilidade_4_seg_media = 0; //t double GMMAInst = 0; //i double GMMATrader = 0; //r double va = 0; double vb = 0; double vc = 0; double vd = 0; double ve = 0; Print(":-| Processando ofertas do historico..."); // cabecalho do arquivo string linhaArq = "inicio" +";"+ "fim" +";"+ "seg" +";"+ // duracao da posicao em segundos "id" +";"+ // id da posicao (eh igual em todos os deals da posicao "buysell" +";"+ // buy eh 0, sell eh 1 "vol" +";"+ // volume da posicao "pft" +";"+ // profit da posicao "drawd" +";"+ // draw down da posicao "comentario" +";"+ "a" +";"+ // GMMA institucional "b" +";"+ // GMMA trader "c" +";"+ // volatilidade por segundo media "d" +";"+ // probabilidade do preco subir ou descer "e" ; // coeficiente de entrelacamento //"canal_e" +";"+ // canal de entrelacamento //"rcmp_e" +";"+ // regiao de compra no canal de entrelacamento //"rvnd_e" ; // regiao de venda no canal de entrelacamento FileWrite(posFile,linhaArq); for(uint i=0;i 0 ){ m_valWinsDia += m_deal.Profit(); m_qtdWinsDia++; }else{ m_valLossDia += m_deal.Profit(); m_qtdLossDia++; // se o resultado da transacao for zero, ainda assim considera loss, pois paga as tarifas. } // calculando o rebaixamento de saldo... sldAtu += m_deal.Profit(); if( sldAtu > maiorSldAtu ) maiorSldAtu = sldAtu; if( sldAtu < maiorSldAtu ) rebaixamentoSld = maiorSldAtu-sldAtu; } }// final do laco for com as transacoes do dia... // atualizando o rebaixamento de saldo calculado acima... m_rebaixamentoSld = rebaixamentoSld; // calculando o Payout... if( m_valLossDia != 0 ){ m_payOut = m_valWinsDia/MathAbs(m_valLossDia); }else{ m_payOut = 1; // Quando ainda nao tem perda no dia, fica em 100% por enquanto ateh eu melhorar o entendimento. } // calculando a probabilidade de acertos, baseado no historico de transacoes do periodo... calcProbAcertos(); // calculando o coeficiente de Kelly, baseado no historico de transacoes do periodo... calcCoefKelly(); m_profitDiaWDO = profitDiaWDO ; m_volumeDiaWDO = volumeDiaWDO ; m_tarifaDiaWDO = calcTarifaWDO(m_volumeDiaWDO)*m_volumeDiaWDO; m_profitDiaLiquidoWDO = profitDiaWDO - m_tarifaDiaWDO; m_profitDiaWIN = profitDiaWIN ; m_volumeDiaWIN = volumeDiaWIN ; m_tarifaDiaWIN = calcTarifaWIN(m_volumeDiaWIN)*m_volumeDiaWIN; m_profitDiaLiquidoWIN = profitDiaWIN - m_tarifaDiaWIN; m_profitDia = profitDia+profitDiaWIN+profitDiaWDO ; // ok m_volumeDia = volumeDia+volumeDiaWIN+volumeDiaWDO ; // ok //m_tarifaDia = calcTarifa(m_volumeDia); m_tarifaDia = 0 + m_tarifaDiaWIN + m_tarifaDiaWDO; m_profitDiaLiquido = m_profitDia - m_tarifaDia; if( m_volumeDia > 0 ) m_profitPorContrato = m_profitDiaLiquido /(m_volumeDia/m_symbol.LotsStep()) ; if( m_volumeDiaWDO > 0 ) m_profitPorContratoWDO = m_profitDiaLiquidoWDO/m_volumeDiaWDO; if( m_volumeDiaWIN > 0 ) m_profitPorContratoWIN = m_profitDiaLiquidoWIN/m_volumeDiaWIN; } //double osc_minion_trade_estatistica::calcTarifa(const double pVolume){ // // if ( StringFind(m_str_symbol,"WDO") > -1 ){ // return calcTarifaWDO(m_volumeDia)*m_volumeDia; // }else if( StringFind(m_str_symbol,"WIN") > -1 ){ // return calcTarifaWIN(m_volumeDia)*m_volumeDia; // }else{ // return 0; // } //} double osc_minion_trade_estatistica::calcTarifaWDO(const double pVolume){ if( pVolume < 21) return 1.00*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; if( pVolume < 251) return 0.89*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; if( pVolume < 601) return 0.62*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; if( pVolume < 1001) return 0.52*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; if( pVolume < 2001) return 0.49*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; if( pVolume < 2501) return 0.45*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; if( pVolume < 5001) return 0.42*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; if( pVolume < 6001) return 0.37*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; if( pVolume < 10001) return 0.35*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; if( pVolume < 15001) return 0.31*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; if( pVolume < 20001) return 0.30*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; if( pVolume < 25001) return 0.28*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; if( pVolume < 35001) return 0.26*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; if( pVolume < 45001) return 0.25*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; if( pVolume < 60001) return 0.23*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; if( pVolume < 80001) return 0.22*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; return 0.20*m_cotacaoMoedaTarifaWDO+m_taxaLiqWDO; } double osc_minion_trade_estatistica::calcTarifaWIN(const double pVolume){ if( pVolume < 21) return 1.48+m_taxaLiqWIN; if( pVolume < 251) return 1.11+m_taxaLiqWIN; if( pVolume < 751) return 0.77+m_taxaLiqWIN; if( pVolume < 2501) return 0.48+m_taxaLiqWIN; if( pVolume < 7501) return 0.44+m_taxaLiqWIN; if( pVolume < 17501) return 0.33+m_taxaLiqWIN; if( pVolume < 37501) return 0.29+m_taxaLiqWIN; if( pVolume < 75001) return 0.26+m_taxaLiqWIN; return 0.24+m_taxaLiqWIN; } //+------------------------------------------------------------------+ //| | //| Calcula o Payout baseado no historico de transacoes do dia. | //| | //+------------------------------------------------------------------+ void osc_minion_trade_estatistica::calcPayOut(){ // calculando o Payout... if( m_valLossDia != 0 ){ m_payOut = m_valWinsDia/MathAbs(m_valLossDia); }else{ m_payOut = 1; // Quando ainda nao tem perda no dia, fica em 100% por enquanto ateh eu melhorar o entendimento. } } //+------------------------------------------------------------------+ //| | //| Calcula a probabilidade de acertos, baseado no historico de | //| transacoes do periodo. | //| | //+------------------------------------------------------------------+ void osc_minion_trade_estatistica::calcProbAcertos(){ if( m_qtdWinsDia>0 ){ m_probAcerto = m_qtdWinsDia / (m_qtdWinsDia+m_qtdLossDia); }else{ m_probAcerto = 0; } } //+------------------------------------------------------------------+ //| | //| Calcula o coeficiente de Kelly. | //| | //| Definicao: Percentual maximo de capital a ser alocado a cada | //| trade. | //| | //| Forrmula: | //| K = ( P.B - (1-P) ) / B | //| | //| sendo: | //| K = Coefiente de Kelly. | //| P = Probabilidade de acerto. | //| B = Payout. | //| | //+------------------------------------------------------------------+ void osc_minion_trade_estatistica::calcCoefKelly(){ if( m_payOut != 0 ){ m_coefKelly = ( (m_probAcerto*m_payOut) - (1-m_probAcerto) ) / m_payOut; }else{ m_coefKelly = 0; } }