I have an EA that creates signals for possible buy/sell entries by placing an arrow above/under the signal candle.
my issue is, that depending on the chart wjere the EA is loaded thr arrows are placed too far away or too closely.
please review attached images for examples.
In case of a sell signal I want to position the arrow 20 pips above the High of the signal candle
and in case of a buy to place the arrow 20 pips below the Low of the signal candle.
I'm using followig approach for positioning:
// arrow creation
ObjectCreate(0, label_name, OBJ_TEXT, 0, 0, 0);
ObjectSet(label_name, OBJPROP_TIME1, some_time);
ObjectSet(label_name, OBJPROP_PRICE1, price_arr); // calculated price with 20 pips added or subtracted depending on sell/buy
// price calculation
// get digits to correctly add pips
double digs = 1 / MathPow(10, Digits-1);
int num_pips = 20;
// arrow price calculation
double price_arr = (type==SYMBOL_ARROWUP) ? iLow(Symbol(), time_frame, 1)-(num_pips*digs)
: iHigh(Symbol(), time_frame, 1)+(num_pips*digs);
as you can see for instance in de30-too-narrow.jpg the arrow sits too closely while in xauusd the distance is correct.
I just can't figure it out. tried to incorporate tick_value as well but obviously wrongly.
Can anybody help, please?
thanks in advance
double atr = iATR(NULL,0,10,i);
signal_up = low[i] - 0.5*atr
thank you for your reply. that's a great idea using the ATR.
@Marco vd Heijden
many thanks, this almost solved the issue as it seems.
now I'm only having issues with DE30 and US30
with these two pairs the distances remain all too narrow still(arrows almost sit on candles).
the strange thing is, in AUXUSD (2-digits) the distances are correct while
in DE30, US30 they are not, allthough they as well have 2 digits only.
I don't see the logic behind to generically compute the distances corretly for any pair.
any ideas are highly appreciated
currently I only see this isssue for DE30 and US30 but probably exists on other pairs as well,
that I'm currently not aware of.
I need a true generic solution for that so that the user might pick any possible chart
and see correct placements
thanks to @Marco vd Heijden
my best solution:
// for DE30 and US30 multiply by 1/tick_value for (hopefully) correct solution
double scale_factor = (_Digits==2 && MarketInfo(Symbol(), MODE_TICKVALUE) <= 0.01)
? 1/MarketInfo(Symbol(), MODE_TICKVALUE) : 1.0;
// realized that in higher TFs the distances are too narrow as well
scale_factor *= (time_frame >= PERIOD_H4) ? 10 : 1;
// determine signal price locations for arrow and label
double price_label =
(type==SYMBOL_ARROWUP) ? iLow(Symbol(), time_frame, 1) - (scale_factor*200*_Point)
: iHigh(Symbol(), time_frame, 1) + (scale_factor*200*_Point);
double price_arr = (type==SYMBOL_ARROWUP) ? iLow(Symbol(), time_frame, 1)-(scale_factor*80*_Point)
: iHigh(Symbol(), time_frame, 1)+(scale_factor*80*_Point);
as the tick value is the only thing where the pairs differ it must be somehow integrated into the calculation.
at least this produces acceptable results
Here's another option. You'd need to use OnChartEvent to rewrite the buffers when the chart scale changes, but this should give you a consistent gap in pixels...
double scale_factor(int pixels)
int chart_height = (int)ChartGetInteger(ChartID(), CHART_HEIGHT_IN_PIXELS);
double chart_range = (
ChartGetDouble(ChartID(), CHART_PRICE_MAX) - ChartGetDouble(ChartID(), CHART_PRICE_MIN)
return chart_range / chart_height * pixels;
awesome :) thanks a lot, I will test it out...
alright, sorry for the late response.
I tested it out and it seems, or at least for my demands, the suggestion from
works best and is most easy and scalable.
thank you all though for your contributions which solved my issue 100%.
so my final solution for positioning the arrows is:
// either up or down
double a_type = SYMBOL_ARROWUP;
// extra space for label
double label_factor = 1.25;
// raw ATR value
double atr_points = iATR(Symbol(), time_frame, period, candle_idx);
// arrow price-position below-low above-high
double price_arr = (a_type==SYMBOL_ARROWUP)
? NormalizeDouble(iLow(Symbol(), time_frame, candle_idx) - atr_points, Digits)
: NormalizeDouble(iHigh(Symbol(), time_frame, candle_idx) + atr_points, Digits);
// lable price-position below low-arrow above high-arrow
double label_arr = (a_type==SYMBOL_ARROWUP)
? NormalizeDouble(iLow(Symbol(), time_frame, candle_idx) - (label_factor * atr_points), Digits)
: NormalizeDouble(iHigh(Symbol(), time_frame, candle_idx) + (label_factor * atr_points), Digits);
// for adding the actual arrows to the chart -> see 1st post