Olá,
Estou tentando fazer um Livro de Ofertas no Gráfico, semelhante ao Livro Visual do ProfitChart, conforme imagem abaixo.
Eu já fiz um rascunho (código abaixo) e a maior dúvida é se esse histograma deve ser feito por um objeto do tipo OBJ_TREND ou de alguma outra maneira porque eu até estou conseguindo os dados do livro de ofertas mas não estou conseguindo plotá-los como um OBJ_TREND. Eu consigo por OBJ_HLINE mas, dessa forma, não é possível editar o comprimento da linha. Ou talvez seja de outro jeito e eu estou fazendo tudo errado. Agradeço qualquer ajuda para conseguir fazer esse indicador.
Olá amigo! Eu não sei nada ( ainda ) de programação, mas deixo meu incentivo e gratidão por estar fazendo algo excelente. Logo você vai conseguir e será muito bem sucedido. Deus te abençoe.
Pessoal, eu consegui fazer, mais ou menos, esse Livro Visual, conforme imagem e código abaixo. Mas ainda há um pequeno problema na determinação da largura desses retângulos. A minha ideia foi normalizar os volumes (entre o maior volume e o volume nulo) em uma quantidade fixa de pixels. Isso deu certo, mas há alguns momentos em que o comprimento desses retângulos fica oscilando bruscamente entre o valor correto e o valor máximo de pixels, sendo que o volume maior está em outros níveis (fiz a conferência do Livro de ofertas para ter a confirmação do caso). Acredito que o problema esteja na determinação do maior volume no array, e eu não devo ter feito da maneira mais adequada. Os volumes estão no bookArray[].volume e eu joguei esse array dentro de outro array (VolumeArray[]) para aí determinar o maior valor. Ao averiguar esse maior volume no script, parece que está tudo certo. Mas, em algumas ocasiões, esses retângulos continuam chacoalhando, rapidamente, pra lá e pra cá.
E outro pequeno problema, como vocês podem ver, é que eu devo estar escrevendo o código de maneira não adequada, pois eu faço tudo dentro do int OnCalculate, e acredito que essa não seja a melhor maneira, não é? Assim deve haver um maior uso de memória. Ainda não estou conseguindo escrever conforme a documentação, que declara as funções no espaço global. Mas isso vou melhorando com o tempo e gostaria de dicas de como otimizar esse código.
#property copyright "Marcus Mota" #property indicator_chart_window #property indicator_buffers 0 #property indicator_plots 0 #property strict input int InpWidBook = 255; //Largura do Book Visual input color InpClrBuy = C'17,134,225'; //Cor de Compra input color InpClrSell = C'196,55,0'; //Cor de Venda int OnInit() { if(MarketBookAdd(_Symbol)) return INIT_SUCCEEDED; return INIT_FAILED; } void OnDeinit(const int reason) { ObjectsDeleteAll(0,0,OBJ_LABEL); ObjectsDeleteAll(0,0,OBJ_RECTANGLE_LABEL); } int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //Variáveis necessárias aos cálculos double TickSize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE); double MaximumPrice = ChartGetDouble(0,CHART_PRICE_MAX); long ChartWidth = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0); double BidPrice, AskPrice, MinimunChange; MqlTick LastPrice; SymbolInfoTick(Symbol(),LastPrice); BidPrice = LastPrice.bid; AskPrice = LastPrice.ask; MinimunChange = MaximumPrice+TickSize; //Variação de 1 Tick em Pixels, para a altura do OBJ_RECTANGLE_LABEL int PixelX, PixelY, PixelYMax, PixelXMax, PixelYMaxPlus, PixelXMaxPlus; int MaximumPriceToPixel = ChartTimePriceToXY(0,0,TimeCurrent(),MaximumPrice,PixelXMax,PixelYMax); int MaximumPricePlusToPixel = ChartTimePriceToXY(0,0,TimeCurrent(),MinimunChange,PixelXMaxPlus,PixelYMaxPlus); int PixelTick = MathAbs(PixelYMaxPlus-PixelYMax); //Eventos do Book MqlBookInfo bookArray[]; bool getBook=MarketBookGet(_Symbol,bookArray); if(getBook) { int size=ArraySize(bookArray); double VolumeArray[]; ArrayResize(VolumeArray,size,0); for(int i=0;i<size;i++) { double Pixel = ChartTimePriceToXY(0,0,TimeCurrent(),bookArray[i].price,PixelX,PixelY); VolumeArray[i]=(int)bookArray[i].volume; double MaxBookVolume=VolumeArray[ArrayMaximum(VolumeArray,0,WHOLE_ARRAY)]; //Book Visual ObjectCreate(0,(string)i+"Rectangle",OBJ_RECTANGLE_LABEL,0,0,0); ObjectSetInteger(0,(string)i+"Rectangle",OBJPROP_BORDER_TYPE,BORDER_SUNKEN); ObjectSetInteger(0,(string)i+"Rectangle",OBJPROP_XSIZE,(int)(-(bookArray[i].volume/MaxBookVolume)*InpWidBook)); ObjectSetInteger(0,(string)i+"Rectangle",OBJPROP_YSIZE,PixelTick); ObjectSetInteger(0,(string)i+"Rectangle",OBJPROP_XDISTANCE,ChartWidth); ObjectSetInteger(0,(string)i+"Rectangle",OBJPROP_YDISTANCE,PixelY); if(bookArray[i].price > BidPrice) { ObjectSetInteger(0,(string)i+"Rectangle",OBJPROP_BGCOLOR,InpClrSell); } else if(bookArray[i].price < AskPrice){ ObjectSetInteger(0,(string)i+"Rectangle",OBJPROP_BGCOLOR,InpClrBuy); } } } return(rates_total); }
- 2016.03.07
- Vasiliy Sokolov
- www.mql5.com
Pessoal, eu consegui fazer, mais ou menos, esse Livro Visual, conforme imagem e código abaixo. Mas ainda há um pequeno problema na determinação da largura desses retângulos. A minha ideia foi normalizar os volumes (entre o maior volume e o volume nulo) em uma quantidade fixa de pixels. Isso deu certo, mas há alguns momentos em que o comprimento desses retângulos fica oscilando bruscamente entre o valor correto e o valor máximo de pixels, sendo que o volume maior está em outros níveis (fiz a conferência do Livro de ofertas para ter a confirmação do caso). Acredito que o problema esteja na determinação do maior volume no array, e eu não devo ter feito da maneira mais adequada. Os volumes estão no bookArray[].volume e eu joguei esse array dentro de outro array (VolumeArray[]) para aí determinar o maior valor. Ao averiguar esse maior volume no script, parece que está tudo certo. Mas, em algumas ocasiões, esses retângulos continuam chacoalhando, rapidamente, pra lá e pra cá.
E outro pequeno problema, como vocês podem ver, é que eu devo estar escrevendo o código de maneira não adequada, pois eu faço tudo dentro do int OnCalculate, e acredito que essa não seja a melhor maneira, não é? Assim deve haver um maior uso de memória. Ainda não estou conseguindo escrever conforme a documentação, que declara as funções no espaço global. Mas isso vou melhorando com o tempo e gostaria de dicas de como otimizar esse código.
Ola!
Espero que tenha evoluído com sucesso, promete ser um belo indicador ainda mais se for compartilhar conosco.
A propósito, como vc inseriu o nome do ativo + tempo gráfico no background?
Abs.
Ola!
Espero que tenha evoluído com sucesso, promete ser um belo indicador ainda mais se for compartilhar conosco.
A propósito, como vc inseriu o nome do ativo + tempo gráfico no background?
Abs.
Fala Japa. Não sei se foi dessa forma que ele fez. Mas é possível fazer um indicador ou script que plota um ObjectLabel com o texto sendo o "nome do ativo, timeframe". E alinhá-lo ao centro.
Fala Japa. Não sei se foi dessa forma que ele fez. Mas é possível fazer um indicador ou script que plota um ObjectLabel com o texto sendo o "nome do ativo, timeframe". E alinhá-lo ao centro.
Blz, foi o que pensei...e consegui fazer. heheh
Ola!
Espero que tenha evoluído com sucesso, promete ser um belo indicador ainda mais se for compartilhar conosco.
A propósito, como vc inseriu o nome do ativo + tempo gráfico no background?
Abs.
Japa, fiz essa marca d'água exatamente como o Samuel comentou. Coloquei aí o código abaixo. Quanto ao indicador do book no gráfico, usando ele ao longo do dia a dia eu modifiquei um pouco a ideia dele. Agora crio linhas horizontais somente nos preços que possuem uma quantidade maior ou igual a de interesse (tipo um filtro). E nos preços onde os lotes são muitos altos (filtro superior) há um label mostrando o número. São as necessidades que vamos vendo ao longo do dia a dia e adaptando, né. Se tiver interesse só dizer aí.
//+------------------------------------------------------------------+ //| MARCA D'AGUA | //| Marcus Mota | //+------------------------------------------------------------------+ #property copyright "Marcus Mota" #property indicator_chart_window #property indicator_buffers 0 #property indicator_plots 0 #property strict //--- inputs input string inputFonte="Tahoma"; //Fonte input ushort inputTamanho=100; //Tamanho input color inputCor=clrGray; //Cor input double inputAlpha=0.2; //Transparência //--- variáveis long Altura,Comprimento; //+------------------------------------------------------------------+ //| Inicialização | //+------------------------------------------------------------------+ int OnInit() { //--- possíveis erros if(inputTamanho<=0 || inputAlpha<0 || inputAlpha>1) { printf("Erro nos parâmetros de entrada!"); return INIT_FAILED; } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Deletar a marca d'água | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { ObjectDelete(0,"Marca D'Água"); } //+------------------------------------------------------------------+ //| Criação da marca d'água | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- dimensões do gráfico Altura=ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0); Comprimento=ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0); //--- criação da marca d'água ObjectCreate(0,"Marca D'Água",OBJ_LABEL,0,0,0); ObjectSetInteger(0,"Marca D'Água",OBJPROP_COLOR,0,CorDaMarcaDAgua()); ObjectSetInteger(0,"Marca D'Água",OBJPROP_FONTSIZE,inputTamanho); ObjectSetString(0,"Marca D'Água",OBJPROP_FONT,inputFonte); ObjectSetInteger(0,"Marca D'Água",OBJPROP_BACK,true); ObjectSetString(0,"Marca D'Água",OBJPROP_TEXT,Symbol()+", "+Periodo()); ObjectSetInteger(0,"Marca D'Água",OBJPROP_ANCHOR,ANCHOR_CENTER); ObjectSetInteger(0,"Marca D'Água",OBJPROP_XDISTANCE,(Comprimento/2)); ObjectSetInteger(0,"Marca D'Água",OBJPROP_YDISTANCE,(Altura/2)); return(rates_total); } //+------------------------------------------------------------------+ //| Cor da marca d'água, com cálculo da transparência | //+------------------------------------------------------------------+ color CorDaMarcaDAgua() { //--- processo de transparência color ChartBackColorGet=(color)ChartGetInteger(0,CHART_COLOR_BACKGROUND,0); uchar blueBack=(uchar)MathFloor(ChartBackColorGet/65536); uchar greenBack=(uchar)MathFloor((ChartBackColorGet-(blueBack*65536))/256); uchar redBack=(uchar)(ChartBackColorGet -(blueBack*65536) -(greenBack*256)); uchar blueObject=(uchar)MathFloor(inputCor/65536); uchar greenObject=(uchar)MathFloor((inputCor-(blueObject*65536))/256); uchar redObject=(uchar)(inputCor -(blueObject*65536) -(greenObject*256)); uchar redAlpha=(uchar)(redBack*(1-inputAlpha)+redObject*inputAlpha); uchar greenAlpha=(uchar)(greenBack*(1-inputAlpha)+greenObject*inputAlpha); uchar blueAlpha = (uchar)(blueBack*(1 - inputAlpha) + blueObject*inputAlpha); string ClrAlpha = (string)redAlpha+", "+(string)greenAlpha+", "+(string)blueAlpha; return (color)ClrAlpha; } //+------------------------------------------------------------------+ //| Período na marca d'água | //+------------------------------------------------------------------+ string Periodo() { string Periodo; int timeframe=Period(); switch(timeframe) { case PERIOD_M1 : Periodo="M1"; break; case PERIOD_M2 : Periodo="M2"; break; case PERIOD_M3 : Periodo="M3"; break; case PERIOD_M4 : Periodo="M4"; break; case PERIOD_M5 : Periodo="M5"; break; case PERIOD_M6 : Periodo="M6"; break; case PERIOD_M10 : Periodo="M10"; break; case PERIOD_M12 : Periodo="M12"; break; case PERIOD_M15 : Periodo="M15"; break; case PERIOD_M20 : Periodo="M20"; break; case PERIOD_M30 : Periodo="M30"; break; case PERIOD_H1 : Periodo="H1"; break; case PERIOD_H2 : Periodo="H2"; break; case PERIOD_H3 : Periodo="H3"; break; case PERIOD_H4 : Periodo="H4"; break; case PERIOD_H6 : Periodo="H6"; break; case PERIOD_H8 : Periodo="H8"; break; case PERIOD_H12 : Periodo="H12"; break; case PERIOD_D1 : Periodo="D1"; break; case PERIOD_W1 : Periodo="W1"; break; case PERIOD_MN1 : Periodo="MN1"; break; } return(Periodo); } //+------------------------------------------------------------------+
Japa, fiz essa marca d'água exatamente como o Samuel comentou. Coloquei aí o código abaixo. Quanto ao indicador do book no gráfico, usando ele ao longo do dia a dia eu modifiquei um pouco a ideia dele. Agora crio linhas horizontais somente nos preços que possuem uma quantidade maior ou igual a de interesse (tipo um filtro). E nos preços onde os lotes são muitos altos (filtro superior) há um label mostrando o número. São as necessidades que vamos vendo ao longo do dia a dia e adaptando, né. Se tiver interesse só dizer aí.
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
Olá,
Estou tentando fazer um Livro de Ofertas no Gráfico, semelhante ao Livro Visual do ProfitChart, conforme imagem abaixo.
Eu já fiz um rascunho (código abaixo) e a maior dúvida é se esse histograma deve ser feito por um objeto do tipo OBJ_TREND ou de alguma outra maneira porque eu até estou conseguindo os dados do livro de ofertas mas não estou conseguindo plotá-los como um OBJ_TREND. Eu consigo por OBJ_HLINE mas, dessa forma, não é possível editar o comprimento da linha. Ou talvez seja de outro jeito e eu estou fazendo tudo errado. Agradeço qualquer ajuda para conseguir fazer esse indicador.