Sort ATR by hour - mql4

Hello Im wondering if there is a way I can somehow view ATR by hour, so when it calculates results in has 24 different values from 00:00 to 23:00. I would like the average to be of the ranges for that hour only in the lookback period. (for example hour 02:00 compares it range to the other 02:00 ranges in the look back period)
Original ATR Code
//| ATR.mq4 |
//| Copyright 2005-2014, MetaQuotes Software Corp. |
//| http://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright "2005-2014, MetaQuotes Software Corp."
#property link "http://www.mql4.com"
#property description "Average True Range"
#property strict
//--- indicator settings
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue
//--- input parameter
input int InpAtrPeriod=14; // ATR Period
//--- buffers
double ExtATRBuffer[];
double ExtTRBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit(void)
{
string short_name;
//--- 1 additional buffer used for counting.
IndicatorBuffers(2);
IndicatorDigits(Digits);
//--- indicator line
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,ExtATRBuffer);
SetIndexBuffer(1,ExtTRBuffer);
//--- name for DataWindow and indicator subwindow label
short_name="ATR("+IntegerToString(InpAtrPeriod)+")";
IndicatorShortName(short_name);
SetIndexLabel(0,short_name);
//--- check for input parameter
if(InpAtrPeriod<=0)
{
Print("Wrong input parameter ATR Period=",InpAtrPeriod);
return(INIT_FAILED);
}
//---
SetIndexDrawBegin(0,InpAtrPeriod);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Average True Range |
//+------------------------------------------------------------------+
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[])
{
int i,limit;
//--- check for bars count and input parameter
if(rates_total<=InpAtrPeriod || InpAtrPeriod<=0)
return(0);
//--- counting from 0 to rates_total
ArraySetAsSeries(ExtATRBuffer,false);
ArraySetAsSeries(ExtTRBuffer,false);
ArraySetAsSeries(open,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(close,false);
//--- preliminary calculations
if(prev_calculated==0)
{
ExtTRBuffer[0]=0.0;
ExtATRBuffer[0]=0.0;
//--- filling out the array of True Range values for each period
for(i=1; i<rates_total; i++)
ExtTRBuffer[i]=MathMax(high[i],close[i-1])-MathMin(low[i],close[i-1]);
//--- first AtrPeriod values of the indicator are not calculated
double firstValue=0.0;
for(i=1; i<=InpAtrPeriod; i++)
{
ExtATRBuffer[i]=0.0;
firstValue+=ExtTRBuffer[i];
}
//--- calculating the first value of the indicator
firstValue/=InpAtrPeriod;
ExtATRBuffer[InpAtrPeriod]=firstValue;
limit=InpAtrPeriod+1;
}
else
limit=prev_calculated-1;
//--- the main loop of calculations
for(i=limit; i<rates_total; i++)
{
ExtTRBuffer[i]=MathMax(high[i],close[i-1])-MathMin(low[i],close[i-1]);
ExtATRBuffer[i]=ExtATRBuffer[i-1]+(ExtTRBuffer[i]-ExtTRBuffer[i-InpAtrPeriod])/InpAtrPeriod;
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+````

Related

MQL5 Heikin Ashi RSI Oscillator: error plotting candles

I was trying to convert this indicator from TradingView to MQL5 but it badly prints the candles, as in the attached photo, and i don't understand where is the problem.
From the TradingView indicator i want to convert only the Heiken Ashi code, not RSI and Stoch lines.
Here there is the code:
//+------------------------------------------------------------------+
//| Heiken_Ashi_RSI_Oscillator.mq5 |
//| Copyright 2009-2020, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009-2020, MetaQuotes Software Corp."
#property link "http://www.mql5.com"
//--- indicator settings
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots 1
#property indicator_type1 DRAW_COLOR_CANDLES
#property indicator_color1 DodgerBlue, Red
#property indicator_label1 "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close"
//--- indicator buffers
double ExtOBuffer[];
double ExtHBuffer[];
double ExtLBuffer[];
double ExtCBuffer[];
double ExtColorBuffer[];
input int periodoRSI=14;
input int smoothRSI=1;
int handle_harsi_close,handle_harsi_open,handle_harsi_low,handle_harsi_high;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double HA_RSI_CLOSE(int shift)
{
double value[];
if(handle_harsi_close!=INVALID_HANDLE)
{
if(CopyBuffer(handle_harsi_close,0,shift,1,value)>0)
return(value[0]);
}
return(WRONG_VALUE);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double HA_RSI_OPEN(int shift)
{
double value[];
if(handle_harsi_close!=INVALID_HANDLE)
{
if(CopyBuffer(handle_harsi_open,0,shift,1,value)>0)
return(value[0]);
}
return(WRONG_VALUE);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double HA_RSI_HIGH(int shift)
{
double value[];
if(handle_harsi_close!=INVALID_HANDLE)
{
if(CopyBuffer(handle_harsi_high,0,shift,1,value)>0)
return(value[0]);
}
return(WRONG_VALUE);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double HA_RSI_LOW(int shift)
{
double value[];
if(handle_harsi_close!=INVALID_HANDLE)
{
if(CopyBuffer(handle_harsi_low,0,shift,1,value)>0)
return(value[0]);
}
return(WRONG_VALUE);
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
handle_harsi_close=iRSI(_Symbol,PERIOD_CURRENT,periodoRSI,PRICE_CLOSE);
handle_harsi_open=iRSI(_Symbol,PERIOD_CURRENT,periodoRSI,PRICE_OPEN);
handle_harsi_high=iRSI(_Symbol,PERIOD_CURRENT,periodoRSI,PRICE_HIGH);
handle_harsi_low=iRSI(_Symbol,PERIOD_CURRENT,periodoRSI,PRICE_LOW);
//--- indicator buffers mapping
SetIndexBuffer(0,ExtOBuffer,INDICATOR_DATA);
SetIndexBuffer(1,ExtHBuffer,INDICATOR_DATA);
SetIndexBuffer(2,ExtLBuffer,INDICATOR_DATA);
SetIndexBuffer(3,ExtCBuffer,INDICATOR_DATA);
SetIndexBuffer(4,ExtColorBuffer,INDICATOR_COLOR_INDEX);
//---
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- sets first bar from what index will be drawn
IndicatorSetString(INDICATOR_SHORTNAME,"Heiken Ashi RSI Oscillator");
//--- sets drawing line empty value
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
}
//+------------------------------------------------------------------+
//| Heiken Ashi |
//+------------------------------------------------------------------+
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[])
{
int start;
//--- preliminary calculations
if(prev_calculated==0)
{
ExtLBuffer[0]=low[0];
ExtHBuffer[0]=high[0];
ExtOBuffer[0]=open[0];
ExtCBuffer[0]=close[0];
start=1;
}
else
start=prev_calculated-1;
//--- the main loop of calculations
for(int i=start; i<rates_total && !IsStopped(); i++)
{
double _closeRSI = HA_RSI_CLOSE(0);
double _openRSI = HA_RSI_CLOSE(1);
double _highRSI_raw = HA_RSI_HIGH(0);
double _lowRSI_raw = HA_RSI_LOW(0);
double _highRSI = MathMax(_highRSI_raw, _lowRSI_raw);
double _lowRSI = MathMin(_highRSI_raw, _lowRSI_raw);
double _close = (_openRSI + _highRSI + _lowRSI + _closeRSI) / 4;
double _open = (_openRSI + _closeRSI) / 2;
double _high = MathMax(_highRSI, MathMax(_open, _close));
double _low = MathMin(_lowRSI, MathMin(_open, _close));
ExtLBuffer[i]=_low;
ExtHBuffer[i]=_high;
ExtOBuffer[i]=_open;
ExtCBuffer[i]=_close;
//--- set candle color
if(_open<_close)
ExtColorBuffer[i]=0.0; // set color DodgerBlue
else
ExtColorBuffer[i]=1.0; // set color Red
}
//---
return(rates_total);
}
//+------------------------------------------------------------------+
THANK YOU!

What is the PineScript equivalent of MQL4's _Point?

I am trying to convert this indicator to PineScript. Couldn't figure out how to get Point variable. Is there any way to achieve the same thing in PineScript?
_Point official definition:
The _Point variable contains the point size of the current symbol in the quote currency.
https://docs.mql4.com/predefined/_point
Updated: Added the indicator code
//| Ticks Volume Indicator |
//| Copyright В© William Blau |
//| Coded/Verified by Profitrader |
//+------------------------------------------------------------------+
#property copyright "Copyright В© 2006, Profitrader."
#property link "profitrader#inbox.ru"
//-----
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Blue
//---- input parameters
extern int r=12;
extern int s=12;
extern int u=5;
//---- buffers
double TVI[];
double UpTicks[];
double DownTicks[];
double EMA_UpTicks[];
double EMA_DownTicks[];
double DEMA_UpTicks[];
double DEMA_DownTicks[];
double TVI_calculate[];
double MyPoint;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init() {
IndicatorShortName("TVI("+r+","+s+","+u+")");
IndicatorBuffers(8);
SetIndexBuffer(0,TVI);
SetIndexBuffer(1,UpTicks);
SetIndexBuffer(2,DownTicks);
SetIndexBuffer(3,EMA_UpTicks);
SetIndexBuffer(4,EMA_DownTicks);
SetIndexBuffer(5,DEMA_UpTicks);
SetIndexBuffer(6,DEMA_DownTicks);
SetIndexBuffer(7,TVI_calculate);
SetIndexStyle(0,DRAW_LINE);
SetIndexLabel(0,"TVI");
if (Digits == 5 || (Digits == 3 && StringFind(Symbol(), "JPY") != -1))
MyPoint = Point*10;
else if (Digits == 6 || (Digits == 4 && StringFind(Symbol(), "JPY") != -1))
MyPoint = Point*100;
else
MyPoint = Point;
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit() {
return(0);
}
//+------------------------------------------------------------------+
//| Ticks Volume Indicator |
//+------------------------------------------------------------------+
int start() {
int i,counted_bars=IndicatorCounted();
//---- check for possible errors
if(counted_bars<0) return(-1);
//---- last counted bar will be recounted
if(counted_bars>0) counted_bars--;
int limit=Bars-counted_bars;
//----
for(i=0; i=0; i--) {
EMA_UpTicks[i]=iMAOnArray(UpTicks,0,r,0,MODE_EMA,i);
EMA_DownTicks[i]=iMAOnArray(DownTicks,0,r,0,MODE_EMA,i);
}
for(i=limit-1; i>=0; i--) {
DEMA_UpTicks[i]=iMAOnArray(EMA_UpTicks,0,s,0,MODE_EMA,i);
DEMA_DownTicks[i]=iMAOnArray(EMA_DownTicks,0,s,0,MODE_EMA,i);
}
for(i=0; i=0; i--) {
if (iClose(NULL,0,i)==0)
TVI[i]=EMPTY_VALUE;
else
TVI[i]=iMAOnArray(TVI_calculate,0,u,0,MODE_EMA,i);
}
//----
return(0);
}
//+------------------------------------------------------------------+

How do i move the label behind to the current candle?

#property strict
#property indicator_chart_window
int OnInit(){
if( ObjectFind("MyLabel") == -1)
ObjectCreate(0, "MyLabel", OBJ_LABEL, 0, 0, 0);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason){
if( ObjectFind("MyLabel") >=0 )
ObjectDelete(0, "MyLabel");
}
//+------------------------------------------------------------------+
//| 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[])
{
ObjectSetText( "MyLabel", "$"+DoubleToString(((Close[0]-Close[4])*10000),1), 12, "Times New Roman", clrBlue);
ObjectMove( "MyLabel", OBJ_TEXT, Time[0], Close[0]);
return(rates_total);
}
i want to move the $72.9 to the cuurent candle where i placed the red arrow, not only that i want the label to moving to thee current candle immediately new candle appears?
Thanks you in advance
You have created a Label object that it's properties are x and y.
You should create Text object (using OBJ_TEXT) so you can move it in time/price axis

How to find day's first candle's HIGH, LOW in current Time frame

I am new to MT4, know little basic programming for MQL4. I am trading in UTC+5:30 in Indian Stocks. I just want a small piece of code to get today's First candles HIGH and LOW in current TimeFrame. Our trading starts at 9:15 AM IST and ends at 3:30 PM IST.
e.g. if I select PERIOD_M15 (15 min chart) then I need to have day's first candle (i.e. from 9:15AM to 9:30AM) HIGH and LOW.
thanks in advance.
welcome to SOF!
you need input parameters (time of the day start):
input int InpTimeStartHour=9;
input int InpTimeStartMinute=15;
this can be as a one string but for simplicity such fields
bool getHighLowFistCandle(double &high,double &low){
//check if first candle (zero-current) is after 9:15
datetime lastCandle=iTime(Symbol(),0,1);
if(TimeHour(lastCandle)<InpTimeStartHour ||
(TimeHour(lastCandle)==InpTimeStartHour && TimeMinute(lastCandle)<InpTimeStartMinute){
return(false);
}
//looking for that time candle starting from day start
datetime todayStart=iTime(Symbol(),PERIOD_D1,0);
int shift=iBarShift(Symbol(),0,todayStart);
for(int i=shift;i>0;i--){
datetime iCandleTime=iTime(Symbol(),0,i);
if(TimeHour(iCandleTime)==InpTimeStartHour &&
TimeMinute(iCandleTime)==InpTimeStartMinute){
high=iHigh(Symbol(),0,i);
low=iLow(Symbol(),0,i);
return(true);
}
}
return(false);
}
Below is my indicator code,
//+------------------------------------------------------------------+
//| ProjectName |
//| Copyright 2018, CompanyName |
//| http://www.companyname.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020,ANKUR SONI."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#property indicator_buffers 1
#property indicator_chart_window
#property indicator_width1 5
#property indicator_color1 clrYellow
double engulfing[];
input int InpTimeStartHour=8;
input int InpTimeStartMinute=45;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, engulfing);
SetIndexStyle(0, DRAW_ARROW);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
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[])
{
for(int i = (Bars - 2) ; i > 0 ; i--)
{
if(TimeHour(time[i]) == InpTimeStartHour && TimeMinute(time[i]) == InpTimeStartMinute)
{
double currentHigh = High[i];
double currentLow = Low[i];
double nextHigh = High[i-1];
double nextLow = Low[i-1];
if(nextHigh > currentHigh && nextLow < currentLow)
{
engulfing[i-1] = High[i-1] + 15;
}
}
}
return(rates_total);
}
//+------------------------------------------------------------------+

Why do I get array our of range in MQL4?

I am trying to make an indicator that shows when x candles of the same color appear on the chart. But I am getting an array out of range error.
There is a up and down array buffer (an arrow pointing up or down)
minCandles is an extern integer that determines after how many bars to point the arrow.
the bear part works but from right to left.
I think the problem may be in down[i] = Low[i] but I don't know why.
Here is the code:
//+------------------------------------------------------------------+
//| SlayEm.mq4 |
//| Copyright 2016, Sebastian Bonilla. |
//| https://www.sebastianbonilla.me |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Sebastian Bonilla."
#property link "https://www.sebastianbonilla.me"
#property description "show X amount of candles of the same color."
#property version "1.00"
#property strict
#property indicator_chart_window
//--- input parameters
extern int minCandles = 4;
double up[];
double down[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,up); //assign up to the first buffer
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0,233);
SetIndexLabel(0, "Up Arrow");
//stuff for 1
SetIndexBuffer(1,down); //assign down to the second buffer
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1,234);
SetIndexLabel(1, "Down Arrow");
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 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[])
{//------------------------------------------
int limit = MathMax(rates_total-prev_calculated,2);
int i;
int bull_count = 0;
int bear_count = 0;
for (i = 1; i < limit; i++){
//--bears-----------------------------------------------------------------------------------
if(Open[i] >= Open[i-1]){
bear_count++;
if (bear_count > minCandles) up[i] = High[i];
}
else bear_count = 0; // this by itself works but from right to left
// --- bulls ----------------------------------------
if(Open[i] < Open[i-1]){
bull_count++;
if (bull_count > minCandles) down[i] = Low[i];
}
else bull_count = 0; //this part creates the array out of range error*/
}
Comment((string)bear_count+ " --- ", (string)bull_count +" --- ", (string)i);
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
There are a few strange things behind the writing a fast and efficient [ Custom Indicator ] MQL4-code.
First, the real-time headache coming from a design decision to accumulate all the computational efforts from all the present [ Custom Indicator ] into a single thread.
While this is hidden, it increases the pressure to minimise all execution latencies at a cost of the colculus being operated in segmented mini-batches, from the deepest history ( the bars farthest back to the left ) proceeding iteratively forwards to the right, towards the current Bar.
One might get confused from the concept of reversed-numbering of the Bars, starting from [0]-for the most recent Bar ( the live Bar ), counting up, while going deeper and deeper towards the history on the far left.
If it were not enough, there are some additional prohibited things inside a [ Custom Indicator ], but as your web-page shows that you provide [ Custom Indicator ] programming on a commercial basis, it is worthless to repeat 'em here again.
Production-grade code for [Custom Indicator] ought have at least:
protective fuses
minimised main duty-cycle overheads
zero raw-Comment()-s to avoid damages to GUI/MMI
#property strict
//--- input parameters
extern int minCandles = 4;
//--- input PROTECTIVE FUSES:
int minCandlesFUSED = MathMax( 2, minCandles ); // assign no less than 2 irrespective of the extern
double up[];
double down[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit() {
// indicator buffers mapping
SetIndexBuffer( 0, up ); // assign up[] to the first buffer
SetIndexStyle( 0, DRAW_ARROW );
SetIndexArrow( 0, 233 );
SetIndexLabel( 0, "Up Arrow" );
// stuff for 1
SetIndexBuffer( 1, down ); // assign down[] to the second buffer
SetIndexStyle( 1, DRAW_ARROW );
SetIndexArrow( 1, 234 );
SetIndexLabel( 1, "Down Arrow" );
// RET
return( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+
//| 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[]
) {
// ------------------------------------------
int limit = rates_total
- prev_calculated
+ minCandlesFUSED;
if ( Bars + limit < minCandlesFUSED + 1 ) return( 0 ); // --> JIT/RET( 0 )
// ^--------------------^--- MEANING-FULL value, ref prev_calculated mechanisation
// makes no sense to start indicator w/o at least minCandlesFUSED + 1 Bars ready
int bull_count = 0;
int bear_count = 0;
for ( int i = limit + 1; // iterator .SET to start [limit + 1] Bars back in time (towards left), moving forwards -> [0]
i > 0; // iterator .PRE-CONDITION to keep looping while i > [0] points to already exist. Bars->[1], leaving [0] out
i-- // iterator .DEC on loop-end, before re-testing next loop .PRE-CONDITION
){
// --------------------------------------------------------------BEARS
if ( Open[i] >= Open[i-1] ){
bear_count++;
if ( bear_count > minCandlesFUSED ) up[i] = High[i]; // ref. above the
}
else bear_count = 0; // this by itself works
// --------------------------------------------------------------BULLS
if ( Open[i] < Open[i-1] ){
bull_count++;
if ( bull_count > minCandlesFUSED ) down[i] = Low[i];
}
else bull_count = 0; // this part creates the array out of range error*/
}
Comment( (string)bear_count // rather use StringFormat( "TEMPLATE: %d UP --- %d DN --- ", bear_count,
+ " --- ", // bull_count
(string)bull_count // )
+ " --- "
);
return( rates_total ); // return( rates_total ) value becomes -> prev_calculated for the next call
}
//+------------------------------------------------------------------+

Resources