211 lines
7.0 KiB
Plaintext
211 lines
7.0 KiB
Plaintext
//+------------------------------------------------------------------+
|
|
//| BuySellVolumes.mq5 |
|
|
//| Copyright © 2023, YourName |
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "YourName"
|
|
#property link "https://www.yourwebsite.com"
|
|
#property version "1.00"
|
|
|
|
//
|
|
#property indicator_separate_window
|
|
#property indicator_buffers 4
|
|
#property indicator_plots 4
|
|
|
|
//--- Plot settings for Buy Volume
|
|
#property indicator_label1 "Buy Volume"
|
|
#property indicator_type1 DRAW_HISTOGRAM
|
|
#property indicator_color1 clrLime
|
|
|
|
//--- Plot settings for Sell Volume
|
|
#property indicator_label2 "Sell Volume"
|
|
#property indicator_type2 DRAW_HISTOGRAM
|
|
#property indicator_color2 clrRed
|
|
|
|
//--- Plot settings for Buy Volume MA
|
|
#property indicator_label3 "Buy Volume MA"
|
|
#property indicator_type3 DRAW_LINE
|
|
#property indicator_color3 clrGreen
|
|
|
|
//--- Plot settings for Sell Volume MA
|
|
#property indicator_label4 "Sell Volume MA"
|
|
#property indicator_type4 DRAW_LINE
|
|
#property indicator_color4 clrRed
|
|
|
|
//--- Input parameters
|
|
input int MAPeriod = 14; // Period for the moving average
|
|
|
|
//--- Indicator buffers
|
|
double BuyVolumeBuffer[]; // Buffer for Buy Volume
|
|
double SellVolumeBuffer[]; // Buffer for Sell Volume
|
|
double BuyVolumeMABuffer[]; // Buffer for Buy Volume Moving Average
|
|
double SellVolumeMABuffer[]; // Buffer for Sell Volume Moving Average
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Custom indicator initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
//
|
|
// Attach buffers to the indicator
|
|
SetIndexBuffer(0, BuyVolumeBuffer, INDICATOR_DATA);
|
|
SetIndexBuffer(1, SellVolumeBuffer, INDICATOR_DATA);
|
|
SetIndexBuffer(2, BuyVolumeMABuffer, INDICATOR_DATA);
|
|
SetIndexBuffer(3, SellVolumeMABuffer, INDICATOR_DATA);
|
|
|
|
//
|
|
// Set short name for the indicator
|
|
IndicatorSetString(INDICATOR_SHORTNAME, "Buy and Sell Volumes");
|
|
|
|
//
|
|
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[] //
|
|
)
|
|
{
|
|
//
|
|
// Start from the first uncalculated bar
|
|
int start = MathMax(prev_calculated - 1, 0);
|
|
|
|
//
|
|
// Loop through bars
|
|
for (int i = start; i < rates_total; i++)
|
|
{
|
|
//
|
|
// Calculate Buy and Sell Volumes based on bar-level data
|
|
double buyVolume = 0.0;
|
|
double sellVolume = 0.0;
|
|
|
|
//
|
|
if (close[i] > open[i])
|
|
{
|
|
//
|
|
buyVolume = (double)tick_volume[i]; // Buying pressure (bullish bar)
|
|
sellVolume = 0.0;
|
|
}
|
|
else if (close[i] < open[i])
|
|
{
|
|
//
|
|
sellVolume = (double)tick_volume[i]; // Selling pressure (bearish bar)
|
|
buyVolume = 0.0;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Neutral bar: split volume equally between buy and sell
|
|
buyVolume = tick_volume[i] / 2.0;
|
|
sellVolume = tick_volume[i] / 2.0;
|
|
}
|
|
|
|
//
|
|
// Store Buy and Sell Volumes in their respective buffers
|
|
BuyVolumeBuffer[i] = buyVolume;
|
|
SellVolumeBuffer[i] = sellVolume;
|
|
|
|
//
|
|
// Calculate Moving Averages for Buy and Sell Volumes
|
|
if (i >= MAPeriod - 1)
|
|
{
|
|
//
|
|
// Calculate Simple Moving Average for Buy Volume
|
|
double buySum = 0.0;
|
|
for (int j = 0; j < MAPeriod; j++)
|
|
buySum += BuyVolumeBuffer[i - j];
|
|
BuyVolumeMABuffer[i] = buySum / MAPeriod;
|
|
|
|
//
|
|
// Calculate Simple Moving Average for Sell Volume
|
|
double sellSum = 0.0;
|
|
for (int j = 0; j < MAPeriod; j++)
|
|
sellSum += SellVolumeBuffer[i - j];
|
|
SellVolumeMABuffer[i] = sellSum / MAPeriod;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Not enough data for MA
|
|
BuyVolumeMABuffer[i] = EMPTY_VALUE;
|
|
SellVolumeMABuffer[i] = EMPTY_VALUE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Normalize all values between 0 and 100
|
|
// NormalizeValues(rates_total);
|
|
|
|
//
|
|
return (rates_total);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Normalize all values between 0 and 100 |
|
|
//+------------------------------------------------------------------+
|
|
void NormalizeValues(int rates_total)
|
|
{
|
|
//
|
|
// Find the maximum and minimum values across all buffers
|
|
double maxValue = 0.0;
|
|
double minValue = DBL_MAX;
|
|
|
|
//
|
|
for (int i = 0; i < rates_total; i++)
|
|
{
|
|
//
|
|
if (BuyVolumeBuffer[i] != EMPTY_VALUE && BuyVolumeBuffer[i] > maxValue)
|
|
maxValue = BuyVolumeBuffer[i];
|
|
if (SellVolumeBuffer[i] != EMPTY_VALUE && SellVolumeBuffer[i] > maxValue)
|
|
maxValue = SellVolumeBuffer[i];
|
|
if (BuyVolumeMABuffer[i] != EMPTY_VALUE && BuyVolumeMABuffer[i] > maxValue)
|
|
maxValue = BuyVolumeMABuffer[i];
|
|
if (SellVolumeMABuffer[i] != EMPTY_VALUE && SellVolumeMABuffer[i] > maxValue)
|
|
maxValue = SellVolumeMABuffer[i];
|
|
|
|
//
|
|
if (BuyVolumeBuffer[i] != EMPTY_VALUE && BuyVolumeBuffer[i] < minValue)
|
|
minValue = BuyVolumeBuffer[i];
|
|
if (SellVolumeBuffer[i] != EMPTY_VALUE && SellVolumeBuffer[i] < minValue)
|
|
minValue = SellVolumeBuffer[i];
|
|
if (BuyVolumeMABuffer[i] != EMPTY_VALUE && BuyVolumeMABuffer[i] < minValue)
|
|
minValue = BuyVolumeMABuffer[i];
|
|
if (SellVolumeMABuffer[i] != EMPTY_VALUE && SellVolumeMABuffer[i] < minValue)
|
|
minValue = SellVolumeMABuffer[i];
|
|
}
|
|
|
|
//
|
|
// Avoid division by zero
|
|
if (maxValue == minValue)
|
|
return;
|
|
|
|
//
|
|
// Normalize all values
|
|
for (int i = 0; i < rates_total; i++)
|
|
{
|
|
//
|
|
if (BuyVolumeBuffer[i] != EMPTY_VALUE)
|
|
BuyVolumeBuffer[i] = ((BuyVolumeBuffer[i] - minValue) / (maxValue - minValue)) * 100.0;
|
|
|
|
if (SellVolumeBuffer[i] != EMPTY_VALUE)
|
|
SellVolumeBuffer[i] = ((SellVolumeBuffer[i] - minValue) / (maxValue - minValue)) * 100.0;
|
|
|
|
if (BuyVolumeMABuffer[i] != EMPTY_VALUE)
|
|
BuyVolumeMABuffer[i] = ((BuyVolumeMABuffer[i] - minValue) / (maxValue - minValue)) * 100.0;
|
|
|
|
if (SellVolumeMABuffer[i] != EMPTY_VALUE)
|
|
SellVolumeMABuffer[i] = ((SellVolumeMABuffer[i] - minValue) / (maxValue - minValue)) * 100.0;
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|