Does not display RR
Akkapob Tankimyong #:
Which button to press to start drawing? I only see the reset box on the top left, but do not know how to start drawing.
Which button to press to start drawing? I only see the reset box on the top left, but do not know how to start drawing.
In my testing, a default sized box is drawn upon attachment to a chart. The default timeframe setting is H1. Try adjusting the indicator settings.
(To be clear, I modified the indicator prior to testing it).
I set up a RR switching from Red to Green if the RR is suitable, add another button to add other boxes and minimize transparency to get a better view.
Here is the code :
//+------------------------------------------------------------------+ //| riskrewardbox_V2.mq5 | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "2.00" #property indicator_chart_window #property strict input bool DrawAllChart = false; // Draw Box on all opened charts input ENUM_TIMEFRAMES TimeFrame = PERIOD_H1; // Cart timeframe input int BoxTransparency = 80; // (0=full, 100=invisible) string OBJprefix = "ziwoxRSRW"; int g_tradeCounter = 0; color BlendTransparency(const color baseColor, const int transparencyPct) { int r = (int)(baseColor & 0xFF); int g = (int)((baseColor >> 8) & 0xFF); int b = (int)((baseColor >> 16) & 0xFF); int bgR = 128, bgG = 128, bgB = 128; double alpha = 1.0 - (double)transparencyPct / 100.0; if(alpha < 0.05) alpha = 0.05; int outR = (int)(r * alpha + bgR * (1.0 - alpha)); int outG = (int)(g * alpha + bgG * (1.0 - alpha)); int outB = (int)(b * alpha + bgB * (1.0 - alpha)); return (color)(outR + (outG << 8) + (outB << 16)); } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { ButtonCreate(0,"DrawTrade",0,20,60,140,25,CORNER_LEFT_UPPER,"Draw a Trade","Trebuchet MS",10,clrWhite,clrDodgerBlue,clrDodgerBlue,false,false,false,true,1,""); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { long chartID = ChartFirst(); if (DrawAllChart) while(chartID>=0) { ObjectsDeleteAll(chartID,OBJprefix,-1,-1); chartID = ChartNext(chartID); } else ObjectsDeleteAll(0,OBJprefix,-1,-1); ObjectDelete(0,"Reset"); ObjectDelete(0,"DrawTrade"); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { //--- ButtonCreate(0,"Reset",0,20,30,110,25,CORNER_LEFT_UPPER,"Reset All Box","Trebuchet MS",10,clrWhite,clrMediumSeaGreen,clrMediumSeaGreen,false,false,false,true,1,""); return(1); } int ExtractTradeID(const string objName) { string withoutPrefix = StringSubstr(objName, StringLen(OBJprefix)+1); // retire "PREFIX." int dotPos = StringFind(withoutPrefix, "."); if(dotPos <= 0) return -1; string idStr = StringSubstr(withoutPrefix, 0, dotPos); return (int)StringToInteger(idStr); } void UpdateRR(const int tradeID) { string pinkName = OBJprefix+"."+IntegerToString(tradeID)+".Pink"; string greenName = OBJprefix+"."+IntegerToString(tradeID)+".Green"; string lblName = OBJprefix+"."+IntegerToString(tradeID)+".Label"; if(ObjectFind(0,pinkName)<0 || ObjectFind(0,greenName)<0) return; double pink1 = ObjectGetDouble(0, pinkName, OBJPROP_PRICE, 0); double pink2 = ObjectGetDouble(0, pinkName, OBJPROP_PRICE, 1); double green1 = ObjectGetDouble(0, greenName, OBJPROP_PRICE, 0); double green2 = ObjectGetDouble(0, greenName, OBJPROP_PRICE, 1); double riskSize = MathAbs(pink2 - pink1); double rewardSize = MathAbs(green2 - green1); double rr = (riskSize > 0.0) ? (rewardSize / riskSize) : 0.0; double maxPink = MathMax(pink1, pink2); double maxGreen = MathMax(green1, green2); double minPink = MathMin(pink1, pink2); double minGreen = MathMin(green1, green2); double topPrice = MathMax(maxPink, maxGreen); datetime t1 = (datetime)ObjectGetInteger(0, greenName, OBJPROP_TIME, 0); datetime t2 = (datetime)ObjectGetInteger(0, greenName, OBJPROP_TIME, 1); datetime labelTime = (t1 < t2) ? t1 : t2; string text = StringFormat("R:R 1:%.2f", rr); if(ObjectFind(0,lblName)<0) { ObjectCreate(0,lblName,OBJ_TEXT,0,labelTime,topPrice); ObjectSetInteger(0,lblName,OBJPROP_SELECTABLE,false); ObjectSetInteger(0,lblName,OBJPROP_HIDDEN,true); ObjectSetInteger(0,lblName,OBJPROP_FONTSIZE,10); ObjectSetString(0,lblName,OBJPROP_FONT,"Trebuchet MS"); ObjectSetInteger(0,lblName,OBJPROP_ANCHOR,ANCHOR_LOWER); } ObjectMove(0,lblName,0,labelTime,topPrice); ObjectSetString(0,lblName,OBJPROP_TEXT,text); ObjectSetInteger(0,lblName,OBJPROP_COLOR, rr>=1.0 ? clrLimeGreen : clrOrangeRed); } void OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam) { if(id==CHARTEVENT_OBJECT_CLICK) { if(sparam=="Reset") { ChartClean(); } if(sparam=="DrawTrade") { g_tradeCounter++; DrawOneTrade(g_tradeCounter); ObjectSetInteger(0,"DrawTrade",OBJPROP_STATE,false); ChartRedraw(0); } } if(id==CHARTEVENT_OBJECT_DRAG) { int tradeID = ExtractTradeID(sparam); if(tradeID < 0) return; string pinkName = OBJprefix+"."+IntegerToString(tradeID)+".Pink"; string greenName = OBJprefix+"."+IntegerToString(tradeID)+".Green"; double pricePink1 = ObjectGetDouble(0, pinkName, OBJPROP_PRICE, 0); double pricePink2 = ObjectGetDouble(0, pinkName, OBJPROP_PRICE, 1); double priceGreen1 = ObjectGetDouble(0, greenName, OBJPROP_PRICE, 0); double priceGreen2 = ObjectGetDouble(0, greenName, OBJPROP_PRICE, 1); double maxPink = MathMax(pricePink1, pricePink2); double minPink = MathMin(pricePink1, pricePink2); double maxGreen = MathMax(priceGreen1, priceGreen2); double minGreen = MathMin(priceGreen1, priceGreen2); if(sparam==greenName ) { double pinkSize = maxPink - minPink; int time1 = ObjectGetInteger (0, greenName,OBJPROP_TIME, 0); int time2 = ObjectGetInteger (0, greenName,OBJPROP_TIME, 1); if (maxPink > maxGreen ) { // Risk at top ObjectSetDouble (0, pinkName,OBJPROP_PRICE, 0, maxGreen); ObjectSetDouble (0, pinkName,OBJPROP_PRICE, 1, maxGreen+pinkSize); } else { // Risk at bottom ObjectSetDouble (0, pinkName,OBJPROP_PRICE, 1, minGreen); ObjectSetDouble (0, pinkName,OBJPROP_PRICE, 0, minGreen-pinkSize); } ObjectSetInteger(0, pinkName,OBJPROP_TIME, 0, time1); // mid ObjectSetInteger(0, pinkName,OBJPROP_TIME, 1, time2); // mid UpdateRR(tradeID); ChartRedraw(0); } if(sparam==pinkName ) { double greeSize = maxGreen - minGreen; int time1 = ObjectGetInteger (0, pinkName,OBJPROP_TIME, 0); int time2 = ObjectGetInteger (0, pinkName,OBJPROP_TIME, 1); if (maxGreen > maxPink ) { // Reward at top ObjectSetDouble (0, greenName, OBJPROP_PRICE, 0, maxPink); ObjectSetDouble (0, greenName,OBJPROP_PRICE, 1, maxPink+greeSize); } else { // Reward at bottom ObjectSetDouble (0, greenName,OBJPROP_PRICE, 1, minPink); ObjectSetDouble (0, greenName,OBJPROP_PRICE, 0, minPink-greeSize); } ObjectSetInteger(0, greenName, OBJPROP_TIME, 0, time1); ObjectSetInteger(0, greenName, OBJPROP_TIME, 1, time2); UpdateRR(tradeID); ChartRedraw(0); } } } //+------------------------------------------------------------------+ bool ButtonCreate(const long chart_ID=0, // chart's ID const string name="Button", // button name const int sub_window=0, // subwindow index const int x=0, // X coordinate const int y=0, // Y coordinate const int width=50, // button width const int height=18, // button height const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER, // chart corner for anchoring const string text="Button", // text const string font="Arial", // font const int font_size=10, // font size const color clr=clrBlack, // text color const color back_clr=C'236,233,216', // background color const color border_clr=clrNONE, // border color const bool state=false, // pressed/released const bool back=false, // in the background const bool selection=false, // highlight to move const bool hidden=true, // hidden in the object list const long z_order=0, // priority for mouse click const string tooltip="\n") // tooltip for mouse hover { //--- reset the error value ResetLastError(); //--- if(ObjectFind(chart_ID,name)!=0) { if(!ObjectCreate(chart_ID,name,OBJ_BUTTON,sub_window,0,0)) { Print(__FUNCTION__, ": failed to create the button! Error code = ",_LastError); return(false); } //--- SetObjects ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x); ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y); ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width); ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height); ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner); ObjectSetString(chart_ID,name,OBJPROP_TEXT,text); ObjectSetString(chart_ID,name,OBJPROP_FONT,font); ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size); ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr); ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_COLOR,border_clr); ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); ObjectSetInteger(chart_ID,name,OBJPROP_STATE,state); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order); ObjectSetString(chart_ID,name,OBJPROP_TOOLTIP,tooltip); } else { ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x); ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y); ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width); ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height); ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner); ObjectSetString(chart_ID,name,OBJPROP_TEXT,text); ObjectSetString(chart_ID,name,OBJPROP_FONT,font); ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size); ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr); ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_COLOR,border_clr); ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); ObjectSetInteger(chart_ID,name,OBJPROP_STATE,state); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order); ObjectSetString(chart_ID,name,OBJPROP_TOOLTIP,tooltip); } //--- return(true); } void ChartClean() { long chartID = ChartFirst(); if (DrawAllChart) while(chartID>=0) { ObjectsDeleteAll(chartID,OBJprefix,-1,-1); chartID = ChartNext(chartID); } else ObjectsDeleteAll(0,OBJprefix,-1,-1); ObjectSetInteger(0,"Reset",OBJPROP_STATE,false); g_tradeCounter = 0; } int GetVisibleCenterShift(const long chart_ID, const string symbl, const ENUM_TIMEFRAMES chartperiod) { int firstVisible = (int)ChartGetInteger(chart_ID, CHART_FIRST_VISIBLE_BAR, 0); int visibleBars = (int)ChartGetInteger(chart_ID, CHART_WIDTH_IN_BARS, 0); int centerShift = firstVisible - visibleBars/2; int totalBars = iBars(symbl, chartperiod); if(centerShift < 0) centerShift = 0; if(centerShift > totalBars-1) centerShift = totalBars-1; return centerShift; } void DrawOneTrade(const int tradeID) { long chart_ID = ChartFirst(); string symbl = ""; ENUM_TIMEFRAMES chartperiod = 0; int xOffsetBars = (tradeID-1)*4; // léger décalage anti-superposition entre clics rapprochés if (DrawAllChart) while(chart_ID>=0) { symbl = ChartSymbol(chart_ID); chartperiod = ChartPeriod(chart_ID); DrawTradePairOnChart(chart_ID, symbl, chartperiod, tradeID, xOffsetBars); chart_ID = ChartNext(chart_ID); } else { chart_ID = 0; symbl = Symbol(); chartperiod = PERIOD_CURRENT; DrawTradePairOnChart(chart_ID, symbl, chartperiod, tradeID, xOffsetBars); } } void DrawTradePairOnChart(const long chart_ID, const string symbl, const ENUM_TIMEFRAMES chartperiod, const int tradeID, const int xOffsetBars) { string name = OBJprefix+"."+IntegerToString(tradeID)+".Pink"; int centerShift = GetVisibleCenterShift(chart_ID, symbl, chartperiod); datetime baseTime = iTime(symbl, chartperiod, centerShift) + PeriodSeconds(chartperiod)*xOffsetBars; int windowStart = MathMax(centerShift-10, 0); int windowCount = MathMin(20, iBars(symbl,chartperiod)-windowStart); double top = iHigh(symbl,chartperiod,iHighest(symbl,chartperiod,MODE_HIGH,windowCount,windowStart)); double low = iLow(symbl,chartperiod,iLowest(symbl,chartperiod,MODE_LOW,windowCount,windowStart)); double mid = iClose(symbl,chartperiod,centerShift); if (ObjectFind(chart_ID,name)<0) { ObjectCreate(chart_ID,name,OBJ_RECTANGLE,0,baseTime,low,baseTime+PeriodSeconds(chartperiod)*25,mid); ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,BlendTransparency(clrPink, BoxTransparency)); ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,STYLE_SOLID); ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,2); ObjectSetInteger(chart_ID,name,OBJPROP_FILL,true); ObjectSetInteger(chart_ID,name,OBJPROP_BACK,true); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,true); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,true); ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,false); ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,0); } name = OBJprefix+"."+IntegerToString(tradeID)+".Green"; if (ObjectFind(chart_ID,name)<0) { ObjectCreate(chart_ID,name,OBJ_RECTANGLE,0,baseTime,mid,baseTime+PeriodSeconds(chartperiod)*25,top); ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,BlendTransparency(clrLightGreen, BoxTransparency)); ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,STYLE_SOLID); ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,2); ObjectSetInteger(chart_ID,name,OBJPROP_FILL,true); ObjectSetInteger(chart_ID,name,OBJPROP_BACK,true); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,true); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,true); ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,false); ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,0); } if(chart_ID == 0 || chart_ID == ChartID()) UpdateRR(tradeID); }
Discover new MetaTrader 5 opportunities with MQL5 community and services
- 2026.08.28
- www.mql5.com
MQL5: language of trade strategies built-in the MetaTrader 5 Trading Platform, allows writing your own trading robots, technical indicators, scripts and libraries of functions
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
Risk reward box:
This Indicator creates automatically a Risk/Reward Box on you all opened chart base on High, Low price with the old candles. You can use it easily to drag and change size and price to your desire wanted.
Author: Livio Alves