I use histograms a lot as a visual reference, but what seems like a simple issue has me stumped.
For this simple histogram I don't need a wave form, but simply a green or red bar showing whether or not one MA is above the other. For some reason in MT5, the histogram bar is only showing 50% of the window height, even though technically adding a "1" should make the histogram full height:
ExtMapBufGreen[i] = 1
ExtMapBufRed[i] = 1
Is there something obvious I'm missing?
Do I need to somehow dynamically calculate the height of the indy window and factor that into the equation somehow?
//+------------------------------------------------------------------+
//| Full Height Histogram.mq5 |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 2
//---- Indicator plots
#property indicator_label1 "Green"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 Green
#property indicator_width1 3
#property indicator_label2 "Red"
#property indicator_type2 DRAW_HISTOGRAM
#property indicator_color2 Red
#property indicator_width2 3
//---- Buffers
double ExtMapBufGreen[];
double ExtMapBufRed[];
//---- Moving Average settings
input int FastMAPeriod = 12; // Fast MA period
input int SlowMAPeriod = 26; // Slow MA period
// Moving average handles
int FastMAHandle;
int SlowMAHandle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---- Assign buffers
SetIndexBuffer(0, ExtMapBufGreen, INDICATOR_DATA);
SetIndexBuffer(1, ExtMapBufRed, INDICATOR_DATA);
// Create moving average handles
FastMAHandle = iMA(NULL, PERIOD_CURRENT, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
SlowMAHandle = iMA(NULL, PERIOD_CURRENT, SlowMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
if (FastMAHandle == INVALID_HANDLE || SlowMAHandle == INVALID_HANDLE)
{
Print("Failed to create moving average handles");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Release indicator handles
if (FastMAHandle != INVALID_HANDLE)
IndicatorRelease(FastMAHandle);
if (SlowMAHandle != INVALID_HANDLE)
IndicatorRelease(SlowMAHandle);
}
//+------------------------------------------------------------------+
//| 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 start = prev_calculated > 0 ? prev_calculated - 1 : 0;
// Temporary buffers for moving average data
double FastMA[], SlowMA[];
// Copy moving average data
if (CopyBuffer(FastMAHandle, 0, 0, rates_total, FastMA) <= 0 ||
CopyBuffer(SlowMAHandle, 0, 0, rates_total, SlowMA) <= 0)
{
Print("Failed to copy moving average data");
return(0);
}
// Calculate histogram
for (int i = start; i < rates_total; i++)
{
// Reset both buffers to EMPTY_VALUE
ExtMapBufGreen[i] = EMPTY_VALUE;
ExtMapBufRed[i] = EMPTY_VALUE;
// If Fast MA is above Slow MA (green bar)
if (FastMA[i] > SlowMA[i])
{
ExtMapBufGreen[i] = 1; // Green histogram (full height)
}
// If Slow MA is above Fast MA (red bar)
else if (FastMA[i] < SlowMA[i])
{
ExtMapBufRed[i] = 1; // Red histogram (full height)
}
}
return(rates_total);
}
For this simple histogram I don't need a wave form, but simply a green or red bar showing whether or not one MA is above the other. For some reason in MT5, the histogram bar is only showing 50% of the window height, even though technically adding a "1" should make the histogram full height:
ExtMapBufGreen[i] = 1
ExtMapBufRed[i] = 1
Is there something obvious I'm missing?
Do I need to somehow dynamically calculate the height of the indy window and factor that into the equation somehow?
//+------------------------------------------------------------------+
//| Full Height Histogram.mq5 |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 2
//---- Indicator plots
#property indicator_label1 "Green"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 Green
#property indicator_width1 3
#property indicator_label2 "Red"
#property indicator_type2 DRAW_HISTOGRAM
#property indicator_color2 Red
#property indicator_width2 3
//---- Buffers
double ExtMapBufGreen[];
double ExtMapBufRed[];
//---- Moving Average settings
input int FastMAPeriod = 12; // Fast MA period
input int SlowMAPeriod = 26; // Slow MA period
// Moving average handles
int FastMAHandle;
int SlowMAHandle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---- Assign buffers
SetIndexBuffer(0, ExtMapBufGreen, INDICATOR_DATA);
SetIndexBuffer(1, ExtMapBufRed, INDICATOR_DATA);
// Create moving average handles
FastMAHandle = iMA(NULL, PERIOD_CURRENT, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
SlowMAHandle = iMA(NULL, PERIOD_CURRENT, SlowMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
if (FastMAHandle == INVALID_HANDLE || SlowMAHandle == INVALID_HANDLE)
{
Print("Failed to create moving average handles");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Release indicator handles
if (FastMAHandle != INVALID_HANDLE)
IndicatorRelease(FastMAHandle);
if (SlowMAHandle != INVALID_HANDLE)
IndicatorRelease(SlowMAHandle);
}
//+------------------------------------------------------------------+
//| 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 start = prev_calculated > 0 ? prev_calculated - 1 : 0;
// Temporary buffers for moving average data
double FastMA[], SlowMA[];
// Copy moving average data
if (CopyBuffer(FastMAHandle, 0, 0, rates_total, FastMA) <= 0 ||
CopyBuffer(SlowMAHandle, 0, 0, rates_total, SlowMA) <= 0)
{
Print("Failed to copy moving average data");
return(0);
}
// Calculate histogram
for (int i = start; i < rates_total; i++)
{
// Reset both buffers to EMPTY_VALUE
ExtMapBufGreen[i] = EMPTY_VALUE;
ExtMapBufRed[i] = EMPTY_VALUE;
// If Fast MA is above Slow MA (green bar)
if (FastMA[i] > SlowMA[i])
{
ExtMapBufGreen[i] = 1; // Green histogram (full height)
}
// If Slow MA is above Fast MA (red bar)
else if (FastMA[i] < SlowMA[i])
{
ExtMapBufRed[i] = 1; // Red histogram (full height)
}
}
return(rates_total);
}