mirror of
https://github.com/softwaredevelop/mql5.git
synced 2026-07-27 20:47:44 +00:00
306 lines
10 KiB
Plaintext
306 lines
10 KiB
Plaintext
//+------------------------------------------------------------------+
|
|
//| Currency_Strength_Pro.mq5 |
|
|
//| Copyright 2025, xxxxxxxx|
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2025, xxxxxxxx"
|
|
#property version "2.30" // Fixed smoothing overflow bug
|
|
#property description "Displays the relative strength of 8 major currencies."
|
|
|
|
#property indicator_separate_window
|
|
#property indicator_buffers 8
|
|
#property indicator_plots 8
|
|
#property indicator_level1 0.0
|
|
#property indicator_levelstyle STYLE_DOT
|
|
|
|
//--- Plot Settings
|
|
#property indicator_label1 "USD"
|
|
#property indicator_type1 DRAW_LINE
|
|
#property indicator_color1 clrGreen
|
|
#property indicator_width1 2
|
|
|
|
#property indicator_label2 "EUR"
|
|
#property indicator_type2 DRAW_LINE
|
|
#property indicator_color2 clrDodgerBlue
|
|
#property indicator_width2 2
|
|
|
|
#property indicator_label3 "GBP"
|
|
#property indicator_type3 DRAW_LINE
|
|
#property indicator_color3 clrRed
|
|
#property indicator_width3 2
|
|
|
|
#property indicator_label4 "JPY"
|
|
#property indicator_type4 DRAW_LINE
|
|
#property indicator_color4 clrGold
|
|
#property indicator_width4 2
|
|
|
|
#property indicator_label5 "AUD"
|
|
#property indicator_type5 DRAW_LINE
|
|
#property indicator_color5 clrOrange
|
|
#property indicator_width5 1
|
|
|
|
#property indicator_label6 "CAD"
|
|
#property indicator_type6 DRAW_LINE
|
|
#property indicator_color6 clrMagenta
|
|
#property indicator_width6 1
|
|
|
|
#property indicator_label7 "CHF"
|
|
#property indicator_type7 DRAW_LINE
|
|
#property indicator_color7 clrSlateGray
|
|
#property indicator_width7 1
|
|
|
|
#property indicator_label8 "NZD"
|
|
#property indicator_type8 DRAW_LINE
|
|
#property indicator_color8 clrTurquoise
|
|
#property indicator_width8 1
|
|
|
|
#include <MyIncludes\Currency_Strength_Calculator.mqh>
|
|
|
|
//--- Input Parameters
|
|
input int InpPeriod = 14; // ROC Period
|
|
input ENUM_TIMEFRAMES InpTimeframe = PERIOD_CURRENT; // Calculation Timeframe
|
|
input bool InpSmooth = true; // Smooth Results?
|
|
input int InpSmoothPer = 5; // Smoothing Period
|
|
input bool InpShowPanel = true; // Show Dashboard Panel?
|
|
|
|
input group "Visibility Settings"
|
|
input bool InpShowUSD = true; // Show USD
|
|
input bool InpShowEUR = true; // Show EUR
|
|
input bool InpShowGBP = true; // Show GBP
|
|
input bool InpShowJPY = true; // Show JPY
|
|
input bool InpShowAUD = true; // Show AUD
|
|
input bool InpShowCAD = true; // Show CAD
|
|
input bool InpShowCHF = true; // Show CHF
|
|
input bool InpShowNZD = true; // Show NZD
|
|
|
|
//--- Buffers
|
|
double BufUSD[], BufEUR[], BufGBP[], BufJPY[], BufAUD[], BufCAD[], BufCHF[], BufNZD[];
|
|
|
|
//--- Global Objects
|
|
CCurrencyStrengthCalculator *g_calculator;
|
|
string g_prefix;
|
|
int g_window_idx;
|
|
bool g_show_flags[8];
|
|
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
SetIndexBuffer(0, BufUSD, INDICATOR_DATA);
|
|
SetIndexBuffer(1, BufEUR, INDICATOR_DATA);
|
|
SetIndexBuffer(2, BufGBP, INDICATOR_DATA);
|
|
SetIndexBuffer(3, BufJPY, INDICATOR_DATA);
|
|
SetIndexBuffer(4, BufAUD, INDICATOR_DATA);
|
|
SetIndexBuffer(5, BufCAD, INDICATOR_DATA);
|
|
SetIndexBuffer(6, BufCHF, INDICATOR_DATA);
|
|
SetIndexBuffer(7, BufNZD, INDICATOR_DATA);
|
|
|
|
// Initialize with EMPTY_VALUE to detect uncalculated areas
|
|
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
|
PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
|
PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
|
PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
|
PlotIndexSetDouble(4, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
|
PlotIndexSetDouble(5, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
|
PlotIndexSetDouble(6, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
|
PlotIndexSetDouble(7, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
|
|
|
// Store flags
|
|
g_show_flags[0] = InpShowUSD;
|
|
g_show_flags[1] = InpShowEUR;
|
|
g_show_flags[2] = InpShowGBP;
|
|
g_show_flags[3] = InpShowJPY;
|
|
g_show_flags[4] = InpShowAUD;
|
|
g_show_flags[5] = InpShowCAD;
|
|
g_show_flags[6] = InpShowCHF;
|
|
g_show_flags[7] = InpShowNZD;
|
|
|
|
for(int i=0; i<8; i++)
|
|
{
|
|
PlotIndexSetInteger(i, PLOT_DRAW_BEGIN, InpPeriod + (InpSmooth ? InpSmoothPer : 0));
|
|
|
|
if(!g_show_flags[i])
|
|
PlotIndexSetInteger(i, PLOT_DRAW_TYPE, DRAW_NONE);
|
|
}
|
|
|
|
g_calculator = new CCurrencyStrengthCalculator();
|
|
ENUM_TIMEFRAMES tf = (InpTimeframe == PERIOD_CURRENT) ? (ENUM_TIMEFRAMES)Period() : InpTimeframe;
|
|
g_calculator.Init(InpPeriod, tf);
|
|
|
|
g_prefix = "CS_Pro_" + IntegerToString(ChartID()) + "_";
|
|
g_window_idx = ChartWindowFind();
|
|
ObjectsDeleteAll(0, g_prefix);
|
|
|
|
IndicatorSetString(INDICATOR_SHORTNAME, "Currency Strength");
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
if(CheckPointer(g_calculator) != POINTER_INVALID)
|
|
delete g_calculator;
|
|
ObjectsDeleteAll(0, g_prefix);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
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[])
|
|
{
|
|
g_window_idx = ChartWindowFind();
|
|
|
|
if(!g_calculator.IsDataReady())
|
|
return 0;
|
|
|
|
int start_index;
|
|
if(prev_calculated == 0)
|
|
{
|
|
start_index = 0;
|
|
// Explicitly clear buffers on full recalc
|
|
ArrayInitialize(BufUSD, EMPTY_VALUE);
|
|
ArrayInitialize(BufEUR, EMPTY_VALUE);
|
|
ArrayInitialize(BufGBP, EMPTY_VALUE);
|
|
ArrayInitialize(BufJPY, EMPTY_VALUE);
|
|
ArrayInitialize(BufAUD, EMPTY_VALUE);
|
|
ArrayInitialize(BufCAD, EMPTY_VALUE);
|
|
ArrayInitialize(BufCHF, EMPTY_VALUE);
|
|
ArrayInitialize(BufNZD, EMPTY_VALUE);
|
|
}
|
|
else
|
|
start_index = prev_calculated - 1;
|
|
|
|
if(start_index == 0 && rates_total > 500)
|
|
start_index = rates_total - 500;
|
|
|
|
// --- 1. Calculate Raw Strength ---
|
|
for(int i = start_index; i < rates_total; i++)
|
|
{
|
|
int shift = rates_total - 1 - i;
|
|
double strengths[8];
|
|
g_calculator.CalculateStep(shift, strengths);
|
|
|
|
BufUSD[i] = strengths[0];
|
|
BufEUR[i] = strengths[1];
|
|
BufGBP[i] = strengths[2];
|
|
BufJPY[i] = strengths[3];
|
|
BufAUD[i] = strengths[4];
|
|
BufCAD[i] = strengths[5];
|
|
BufCHF[i] = strengths[6];
|
|
BufNZD[i] = strengths[7];
|
|
}
|
|
|
|
// --- 2. Apply Smoothing ---
|
|
if(InpSmooth && InpSmoothPer > 1)
|
|
{
|
|
double alpha = 2.0 / (InpSmoothPer + 1.0);
|
|
|
|
// Determine start of smoothing loop
|
|
int i = start_index;
|
|
|
|
// If this is the very first bar of the calculation (e.g. index 0 or index 1000 after limit),
|
|
// we cannot smooth it with the previous bar because the previous bar is EMPTY or non-existent.
|
|
// So we skip the first bar of the batch (leaving it raw) and start smoothing from the next.
|
|
|
|
if(i == 0)
|
|
i = 1;
|
|
else
|
|
if(BufUSD[i-1] == EMPTY_VALUE)
|
|
i++;
|
|
|
|
for(; i < rates_total; i++)
|
|
{
|
|
// Safety check: if prev value is empty, we can't smooth.
|
|
if(BufUSD[i-1] == EMPTY_VALUE)
|
|
continue;
|
|
|
|
BufUSD[i] = BufUSD[i] * alpha + BufUSD[i-1] * (1.0 - alpha);
|
|
BufEUR[i] = BufEUR[i] * alpha + BufEUR[i-1] * (1.0 - alpha);
|
|
BufGBP[i] = BufGBP[i] * alpha + BufGBP[i-1] * (1.0 - alpha);
|
|
BufJPY[i] = BufJPY[i] * alpha + BufJPY[i-1] * (1.0 - alpha);
|
|
BufAUD[i] = BufAUD[i] * alpha + BufAUD[i-1] * (1.0 - alpha);
|
|
BufCAD[i] = BufCAD[i] * alpha + BufCAD[i-1] * (1.0 - alpha);
|
|
BufCHF[i] = BufCHF[i] * alpha + BufCHF[i-1] * (1.0 - alpha);
|
|
BufNZD[i] = BufNZD[i] * alpha + BufNZD[i-1] * (1.0 - alpha);
|
|
}
|
|
}
|
|
|
|
// --- 3. Update Dashboard ---
|
|
if(InpShowPanel)
|
|
DrawDashboard(rates_total - 1);
|
|
|
|
return(rates_total);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Draw Dashboard Panel |
|
|
//+------------------------------------------------------------------+
|
|
void DrawDashboard(int last_idx)
|
|
{
|
|
string currencies[] = {"USD", "EUR", "GBP", "JPY", "AUD", "CAD", "CHF", "NZD"};
|
|
color colors[] = {clrGreen, clrDodgerBlue, clrRed, clrGold, clrOrange, clrMagenta, clrSlateGray, clrTurquoise};
|
|
double values[8];
|
|
|
|
values[0] = BufUSD[last_idx];
|
|
values[1] = BufEUR[last_idx];
|
|
values[2] = BufGBP[last_idx];
|
|
values[3] = BufJPY[last_idx];
|
|
values[4] = BufAUD[last_idx];
|
|
values[5] = BufCAD[last_idx];
|
|
values[6] = BufCHF[last_idx];
|
|
values[7] = BufNZD[last_idx];
|
|
|
|
// Handle NaN/Empty
|
|
for(int i=0; i<8; i++)
|
|
if(!MathIsValidNumber(values[i]) || values[i] == EMPTY_VALUE)
|
|
values[i] = 0.0;
|
|
|
|
// Sort
|
|
int indices[] = {0, 1, 2, 3, 4, 5, 6, 7};
|
|
for(int i=0; i<8; i++)
|
|
for(int j=0; j<7-i; j++)
|
|
if(values[indices[j]] < values[indices[j+1]])
|
|
{
|
|
int temp = indices[j];
|
|
indices[j] = indices[j+1];
|
|
indices[j+1] = temp;
|
|
}
|
|
|
|
int x_base = 10;
|
|
int x_step = 95;
|
|
int y_pos = 20;
|
|
int drawn_count = 0;
|
|
|
|
for(int i=0; i<8; i++)
|
|
{
|
|
int idx = indices[i];
|
|
|
|
if(!g_show_flags[idx])
|
|
continue;
|
|
|
|
string name = g_prefix + "Label_" + IntegerToString(i);
|
|
|
|
string val_str;
|
|
if(values[idx] == 0.0 && (BufUSD[last_idx] == EMPTY_VALUE || BufUSD[last_idx] == 0.0))
|
|
val_str = "N/A";
|
|
else
|
|
val_str = StringFormat("%.3f", values[idx]);
|
|
|
|
string text = StringFormat("%s: %s", currencies[idx], val_str);
|
|
|
|
if(ObjectFind(0, name) < 0)
|
|
{
|
|
ObjectCreate(0, name, OBJ_LABEL, g_window_idx, 0, 0);
|
|
ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_LOWER);
|
|
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y_pos);
|
|
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 9);
|
|
ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_LEFT_LOWER);
|
|
}
|
|
|
|
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x_base + drawn_count * x_step);
|
|
ObjectSetString(0, name, OBJPROP_TEXT, text);
|
|
ObjectSetInteger(0, name, OBJPROP_COLOR, colors[idx]);
|
|
|
|
drawn_count++;
|
|
}
|
|
|
|
ChartRedraw();
|
|
}
|
|
//+------------------------------------------------------------------+
|