mirror of
https://github.com/softwaredevelop/mql5.git
synced 2026-07-27 20:47:44 +00:00
Compare commits
6 Commits
c98182658d
...
71b4fed7e6
| Author | SHA1 | Date | |
|---|---|---|---|
| 71b4fed7e6 | |||
| 8b20798556 | |||
| 4f454a2ebd | |||
| 5f29fd75f2 | |||
| 3e3460c2b6 | |||
| 4353aa3b3a |
@@ -0,0 +1,294 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| VScore_Dual_Widget_Pro.mq5 |
|
||||
//| Copyright 2026, xxxxxxxx|
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2026, xxxxxxxx"
|
||||
#property version "1.00" // Unified Daily & Weekly V-Score MTF HUD Widget release
|
||||
#property description "Dual-Timeframe Volatility Deviation Chart HUD Widget."
|
||||
#property description "Displays Daily V-Score (M15) and Weekly V-Score (H1) side-by-side."
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 0
|
||||
#property indicator_plots 0
|
||||
|
||||
#include <MyIncludes\VScore_Calculator.mqh>
|
||||
|
||||
//--- Input Parameters ---
|
||||
input group "Heads-Up Display Settings"
|
||||
input int InpRefreshSeconds = 3; // Background Timer Fallback (Seconds)
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
input group "Daily V-Score Settings (M15)"
|
||||
input ENUM_TIMEFRAMES InpDailyTF = PERIOD_M15; // Daily Flow Timeframe
|
||||
input int InpDailyPeriod = 20; // Daily Lookback Period
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
input group "Weekly V-Score Settings (H1)"
|
||||
input ENUM_TIMEFRAMES InpWeeklyTF = PERIOD_H1; // Weekly Context Timeframe
|
||||
input int InpWeeklyPeriod = 20; // Weekly Lookback Period
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
input group "Widget Placement (Pixels)"
|
||||
input int InpTableX = 20; // Widget X Offset (From Left)
|
||||
input int InpTableY = 30; // Widget Y Offset (From Bottom)
|
||||
input int InpFontSize = 9; // UI Font Size
|
||||
|
||||
//--- Global Variables ---
|
||||
string g_prefix = "";
|
||||
bool g_updating = false;
|
||||
ulong g_last_update_ms = 0; // Throttle timestamp
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| EnsureDataReady (History sync helper) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool EnsureDataReady(const string symbol, const ENUM_TIMEFRAMES timeframe, const int required_bars)
|
||||
{
|
||||
ResetLastError();
|
||||
if(!SymbolInfoInteger(symbol, SYMBOL_SELECT))
|
||||
{
|
||||
SymbolSelect(symbol, true);
|
||||
}
|
||||
datetime times[];
|
||||
int copied = CopyTime(symbol, timeframe, 0, required_bars, times);
|
||||
return (copied >= required_bars);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| GetVScoreValue |
|
||||
//+------------------------------------------------------------------+
|
||||
double GetVScoreValue(string symbol, ENUM_TIMEFRAMES tf, ENUM_VWAP_PERIOD reset, int period)
|
||||
{
|
||||
int required_bars = period + 150;
|
||||
|
||||
if(!EnsureDataReady(symbol, tf, required_bars))
|
||||
return EMPTY_VALUE;
|
||||
|
||||
int htf_bars = iBars(symbol, tf);
|
||||
if(htf_bars < required_bars)
|
||||
return EMPTY_VALUE;
|
||||
|
||||
int count = MathMin(htf_bars, 300);
|
||||
|
||||
double h_open[], h_high[], h_low[], h_close[];
|
||||
long h_vol[];
|
||||
datetime h_time[];
|
||||
|
||||
ArrayResize(h_open, count);
|
||||
ArrayResize(h_high, count);
|
||||
ArrayResize(h_low, count);
|
||||
ArrayResize(h_close, count);
|
||||
ArrayResize(h_vol, count);
|
||||
ArrayResize(h_time, count);
|
||||
|
||||
if(CopyTime(symbol, tf, 0, count, h_time) != count ||
|
||||
CopyOpen(symbol, tf, 0, count, h_open) != count ||
|
||||
CopyHigh(symbol, tf, 0, count, h_high) != count ||
|
||||
CopyLow(symbol, tf, 0, count, h_low) != count ||
|
||||
CopyClose(symbol, tf, 0, count, h_close) != count ||
|
||||
CopyTickVolume(symbol, tf, 0, count, h_vol) != count)
|
||||
{
|
||||
return EMPTY_VALUE;
|
||||
}
|
||||
|
||||
CVScoreCalculator calc;
|
||||
if(!calc.Init(period, reset))
|
||||
return EMPTY_VALUE;
|
||||
|
||||
double h_res[];
|
||||
ArrayResize(h_res, count);
|
||||
ArrayInitialize(h_res, 0.0);
|
||||
|
||||
calc.Calculate(count, 0, h_time, h_open, h_high, h_low, h_close, h_vol, h_vol, h_res);
|
||||
|
||||
return h_res[count - 1];
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| CreateButton |
|
||||
//+------------------------------------------------------------------+
|
||||
void CreateButton(string name, string text, int x, int y, int w, int h, color bg_color, color text_color)
|
||||
{
|
||||
if(ObjectFind(0, name) < 0)
|
||||
{
|
||||
ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0);
|
||||
ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_LOWER); // Fixed Lower-Left Corner
|
||||
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, InpFontSize);
|
||||
ObjectSetString(0, name, OBJPROP_FONT, "Trebuchet MS");
|
||||
ObjectSetInteger(0, name, OBJPROP_BORDER_TYPE, BORDER_FLAT);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
|
||||
}
|
||||
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
|
||||
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
|
||||
ObjectSetInteger(0, name, OBJPROP_XSIZE, w);
|
||||
ObjectSetInteger(0, name, OBJPROP_YSIZE, h);
|
||||
ObjectSetString(0, name, OBJPROP_TEXT, text);
|
||||
ObjectSetInteger(0, name, OBJPROP_BGCOLOR, bg_color);
|
||||
ObjectSetInteger(0, name, OBJPROP_COLOR, text_color);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| RenderVScoreCell (Collision Free via Type Label) |
|
||||
//+------------------------------------------------------------------+
|
||||
void RenderVScoreCell(string symbol, double val, string type_label, int x, int y, int w, int h)
|
||||
{
|
||||
string name = g_prefix + "_" + symbol + "_" + type_label;
|
||||
string text = "";
|
||||
color bg_color = clrWhite;
|
||||
color text_color = clrBlack;
|
||||
|
||||
if(val == EMPTY_VALUE)
|
||||
{
|
||||
text = "Sync...";
|
||||
bg_color = clrWhite;
|
||||
text_color = clrSilver;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = DoubleToString(val, 3);
|
||||
|
||||
//--- Swapped 5-Zone Thermal Color Palette (Corrected Polarity)
|
||||
// Positive/Bullish -> Bluish (Cold)
|
||||
// Negative/Bearish -> Reddish (Hot)
|
||||
if(val >= 2.0)
|
||||
{
|
||||
bg_color = clrDeepSkyBlue; // Bull Extreme (Deep Blue)
|
||||
text_color = clrWhite;
|
||||
}
|
||||
else
|
||||
if(val >= 1.5)
|
||||
{
|
||||
bg_color = clrLightSkyBlue; // Bull Flow (Light Blue)
|
||||
text_color = clrBlack;
|
||||
}
|
||||
else
|
||||
if(val <= -2.0)
|
||||
{
|
||||
bg_color = clrOrangeRed; // Bear Extreme (Dark Red)
|
||||
text_color = clrWhite;
|
||||
}
|
||||
else
|
||||
if(val <= -1.5)
|
||||
{
|
||||
bg_color = clrCoral; // Bear Flow (Coral)
|
||||
text_color = clrBlack;
|
||||
}
|
||||
else
|
||||
{
|
||||
bg_color = clrWhite; // Neutral
|
||||
text_color = clrDarkGray;
|
||||
}
|
||||
}
|
||||
CreateButton(name, text, x, y, w, h, bg_color, text_color);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| RenderDashboard |
|
||||
//+------------------------------------------------------------------+
|
||||
void RenderDashboard()
|
||||
{
|
||||
if(g_updating)
|
||||
return;
|
||||
|
||||
g_updating = true;
|
||||
|
||||
int col_w_sym = 100;
|
||||
int col_w_vs = 100; // Expanded to fit full header labels cleanly
|
||||
int row_h = 22;
|
||||
|
||||
string sym = _Symbol; // Automatically lock to the current chart symbol
|
||||
|
||||
//--- 1. Render Table Header (Placed above the data row)
|
||||
int header_y = InpTableY + row_h + 2; // Y coordinates grow UPWARDS from bottom-left corner
|
||||
|
||||
string daily_tf_name = StringSubstr(EnumToString(InpDailyTF), 7);
|
||||
string weekly_tf_name = StringSubstr(EnumToString(InpWeeklyTF), 7);
|
||||
|
||||
CreateButton(g_prefix + "H_Sym", "Symbol", InpTableX, header_y, col_w_sym, row_h, clrDarkSlateGray, clrWhite);
|
||||
CreateButton(g_prefix + "H_VSD", "Daily (" + daily_tf_name + ")", InpTableX + col_w_sym + 2, header_y, col_w_vs, row_h, clrDarkSlateGray, clrWhite);
|
||||
CreateButton(g_prefix + "H_VSW", "Weekly (" + weekly_tf_name + ")", InpTableX + col_w_sym + col_w_vs + 4, header_y, col_w_vs, row_h, clrDarkSlateGray, clrWhite);
|
||||
|
||||
//--- 2. Calculate and Render Current Row (Placed at baseline Y)
|
||||
int row_y = InpTableY;
|
||||
|
||||
// Symbol display (Flat/unclickable label for the active chart symbol)
|
||||
CreateButton(g_prefix + "_SymLbl_" + sym, sym, InpTableX, row_y, col_w_sym, row_h, clrLightGray, clrBlack);
|
||||
|
||||
// Calculate Daily V-Score (Session Reset) on M15 Timeframe
|
||||
double vs_day = GetVScoreValue(sym, InpDailyTF, PERIOD_SESSION, InpDailyPeriod);
|
||||
|
||||
// Calculate Weekly V-Score (Weekly Reset) on H1 Timeframe
|
||||
double vs_week = GetVScoreValue(sym, InpWeeklyTF, PERIOD_WEEK, InpWeeklyPeriod);
|
||||
|
||||
// Render both cells side-by-side with collision-free naming
|
||||
RenderVScoreCell(sym, vs_day, "VSDay", InpTableX + col_w_sym + 2, row_y, col_w_vs, row_h);
|
||||
RenderVScoreCell(sym, vs_week, "VSWeek", InpTableX + col_w_sym + col_w_vs + 4, row_y, col_w_vs, row_h);
|
||||
|
||||
ChartRedraw();
|
||||
g_updating = false;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnInit |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
g_updating = false;
|
||||
g_last_update_ms = 0;
|
||||
g_prefix = StringFormat("VSDW_%I64d_", ChartID()); // Unified VScore-Dual dynamic prefix
|
||||
|
||||
ObjectsDeleteAll(0, g_prefix);
|
||||
|
||||
RenderDashboard();
|
||||
|
||||
EventSetTimer(InpRefreshSeconds);
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnDeinit |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
EventKillTimer();
|
||||
ObjectsDeleteAll(0, g_prefix);
|
||||
Comment("");
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnCalculate |
|
||||
//+------------------------------------------------------------------+
|
||||
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[])
|
||||
{
|
||||
//--- Real-time high frequency tick throttling (Max 5 updates per second / 200ms)
|
||||
ulong current_ms = GetTickCount64();
|
||||
if(current_ms - g_last_update_ms >= 200)
|
||||
{
|
||||
g_last_update_ms = current_ms;
|
||||
RenderDashboard();
|
||||
}
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnTimer |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTimer()
|
||||
{
|
||||
RenderDashboard();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,277 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| VScore_Widget_Pro.mq5 |
|
||||
//| Copyright 2026, xxxxxxxx|
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2026, xxxxxxxx"
|
||||
#property version "1.00" // Focused single-metric V-Score HUD Widget release
|
||||
#property description "Volatility Deviation Chart HUD Widget."
|
||||
#property description "Displays V-Score (VWAP Z-Score) for the current symbol in the bottom-left corner."
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 0
|
||||
#property indicator_plots 0
|
||||
|
||||
#include <MyIncludes\VScore_Calculator.mqh>
|
||||
|
||||
//--- Input Parameters ---
|
||||
input group "Heads-Up Display Settings"
|
||||
input ENUM_TIMEFRAMES InpTimeframe = PERIOD_M15; // Target Higher Timeframe (MTF)
|
||||
input int InpRefreshSeconds = 3; // Background Timer Fallback (Seconds)
|
||||
|
||||
input group "V-Score Settings"
|
||||
input int InpVScorePeriod = 21; // V-Score Period
|
||||
input ENUM_VWAP_PERIOD InpVWAPReset = PERIOD_SESSION; // VWAP Anchor Reset
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
input group "Widget Placement (Pixels)"
|
||||
input int InpTableX = 20; // Widget X Offset (From Left)
|
||||
input int InpTableY = 30; // Widget Y Offset (From Bottom)
|
||||
input int InpFontSize = 9; // UI Font Size
|
||||
|
||||
//--- Global Variables ---
|
||||
string g_prefix = "";
|
||||
bool g_updating = false;
|
||||
ulong g_last_update_ms = 0; // Throttle timestamp
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| EnsureDataReady (History sync helper) |
|
||||
//+------------------------------------------------------------------+
|
||||
bool EnsureDataReady(const string symbol, const ENUM_TIMEFRAMES timeframe, const int required_bars)
|
||||
{
|
||||
ResetLastError();
|
||||
if(!SymbolInfoInteger(symbol, SYMBOL_SELECT))
|
||||
{
|
||||
SymbolSelect(symbol, true);
|
||||
}
|
||||
datetime times[];
|
||||
int copied = CopyTime(symbol, timeframe, 0, required_bars, times);
|
||||
return (copied >= required_bars);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| GetVScoreValue |
|
||||
//+------------------------------------------------------------------+
|
||||
double GetVScoreValue(string symbol, ENUM_TIMEFRAMES tf, ENUM_VWAP_PERIOD reset, int period)
|
||||
{
|
||||
int required_bars = period + 150;
|
||||
|
||||
if(!EnsureDataReady(symbol, tf, required_bars))
|
||||
return EMPTY_VALUE;
|
||||
|
||||
int htf_bars = iBars(symbol, tf);
|
||||
if(htf_bars < required_bars)
|
||||
return EMPTY_VALUE;
|
||||
|
||||
int count = MathMin(htf_bars, 300);
|
||||
|
||||
double h_open[], h_high[], h_low[], h_close[];
|
||||
long h_vol[];
|
||||
datetime h_time[];
|
||||
|
||||
ArrayResize(h_open, count);
|
||||
ArrayResize(h_high, count);
|
||||
ArrayResize(h_low, count);
|
||||
ArrayResize(h_close, count);
|
||||
ArrayResize(h_vol, count);
|
||||
ArrayResize(h_time, count);
|
||||
|
||||
if(CopyTime(symbol, tf, 0, count, h_time) != count ||
|
||||
CopyOpen(symbol, tf, 0, count, h_open) != count ||
|
||||
CopyHigh(symbol, tf, 0, count, h_high) != count ||
|
||||
CopyLow(symbol, tf, 0, count, h_low) != count ||
|
||||
CopyClose(symbol, tf, 0, count, h_close) != count ||
|
||||
CopyTickVolume(symbol, tf, 0, count, h_vol) != count)
|
||||
{
|
||||
return EMPTY_VALUE;
|
||||
}
|
||||
|
||||
CVScoreCalculator calc;
|
||||
if(!calc.Init(period, reset))
|
||||
return EMPTY_VALUE;
|
||||
|
||||
double h_res[];
|
||||
ArrayResize(h_res, count);
|
||||
ArrayInitialize(h_res, 0.0);
|
||||
|
||||
calc.Calculate(count, 0, h_time, h_open, h_high, h_low, h_close, h_vol, h_vol, h_res);
|
||||
|
||||
return h_res[count - 1];
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| CreateButton |
|
||||
//+------------------------------------------------------------------+
|
||||
void CreateButton(string name, string text, int x, int y, int w, int h, color bg_color, color text_color)
|
||||
{
|
||||
if(ObjectFind(0, name) < 0)
|
||||
{
|
||||
ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0);
|
||||
ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_LOWER); // Fixed Lower-Left Corner
|
||||
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, InpFontSize);
|
||||
ObjectSetString(0, name, OBJPROP_FONT, "Trebuchet MS");
|
||||
ObjectSetInteger(0, name, OBJPROP_BORDER_TYPE, BORDER_FLAT);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
|
||||
}
|
||||
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
|
||||
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
|
||||
ObjectSetInteger(0, name, OBJPROP_XSIZE, w);
|
||||
ObjectSetInteger(0, name, OBJPROP_YSIZE, h);
|
||||
ObjectSetString(0, name, OBJPROP_TEXT, text);
|
||||
ObjectSetInteger(0, name, OBJPROP_BGCOLOR, bg_color);
|
||||
ObjectSetInteger(0, name, OBJPROP_COLOR, text_color);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| RenderVScoreCell |
|
||||
//+------------------------------------------------------------------+
|
||||
void RenderVScoreCell(string symbol, double val, int x, int y, int w, int h)
|
||||
{
|
||||
string name = g_prefix + "_" + symbol + "_VScore";
|
||||
string text = "";
|
||||
color bg_color = clrWhite;
|
||||
color text_color = clrBlack;
|
||||
|
||||
if(val == EMPTY_VALUE)
|
||||
{
|
||||
text = "Sync...";
|
||||
bg_color = clrWhite;
|
||||
text_color = clrSilver;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = DoubleToString(val, 3);
|
||||
|
||||
//--- Swapped 5-Zone Thermal Color Palette (Corrected Polarity)
|
||||
// Positive/Bullish -> Bluish (Cold)
|
||||
// Negative/Bearish -> Reddish (Hot)
|
||||
if(val >= 2.0)
|
||||
{
|
||||
bg_color = clrDeepSkyBlue; // Bull Extreme (Deep Blue)
|
||||
text_color = clrWhite;
|
||||
}
|
||||
else
|
||||
if(val >= 1.5)
|
||||
{
|
||||
bg_color = clrLightSkyBlue; // Bull Flow (Light Blue)
|
||||
text_color = clrBlack;
|
||||
}
|
||||
else
|
||||
if(val <= -2.0)
|
||||
{
|
||||
bg_color = clrOrangeRed; // Bear Extreme (Dark Red)
|
||||
text_color = clrWhite;
|
||||
}
|
||||
else
|
||||
if(val <= -1.5)
|
||||
{
|
||||
bg_color = clrCoral; // Bear Flow (Coral)
|
||||
text_color = clrBlack;
|
||||
}
|
||||
else
|
||||
{
|
||||
bg_color = clrWhite; // Neutral
|
||||
text_color = clrDarkGray;
|
||||
}
|
||||
}
|
||||
CreateButton(name, text, x, y, w, h, bg_color, text_color);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| RenderDashboard |
|
||||
//+------------------------------------------------------------------+
|
||||
void RenderDashboard()
|
||||
{
|
||||
if(g_updating)
|
||||
return;
|
||||
|
||||
g_updating = true;
|
||||
|
||||
int col_w_sym = 100;
|
||||
int col_w_vs = 80;
|
||||
int row_h = 22;
|
||||
|
||||
string sym = _Symbol; // Automatically lock to the current chart symbol
|
||||
|
||||
//--- 1. Render Table Header (Placed above the data row)
|
||||
int header_y = InpTableY + row_h + 2; // Y coordinates grow UPWARDS from bottom-left corner
|
||||
string tf_name = StringSubstr(EnumToString(InpTimeframe), 7);
|
||||
CreateButton(g_prefix + "H_Sym", "Symbol (" + tf_name + ")", InpTableX, header_y, col_w_sym, row_h, clrDarkSlateGray, clrWhite);
|
||||
CreateButton(g_prefix + "H_VS", "V-Score", InpTableX + col_w_sym + 2, header_y, col_w_vs, row_h, clrDarkSlateGray, clrWhite);
|
||||
|
||||
//--- 2. Calculate and Render Current Row (Placed at baseline Y)
|
||||
int row_y = InpTableY;
|
||||
|
||||
// Symbol display (Flat/unclickable label for the active chart symbol)
|
||||
CreateButton(g_prefix + "_SymLbl_" + sym, sym, InpTableX, row_y, col_w_sym, row_h, clrLightGray, clrBlack);
|
||||
|
||||
// Get V-Score Value
|
||||
double vs_val = GetVScoreValue(sym, InpTimeframe, InpVWAPReset, InpVScorePeriod);
|
||||
|
||||
// Render V-Score cell with corrected thermal palette
|
||||
RenderVScoreCell(sym, vs_val, InpTableX + col_w_sym + 2, row_y, col_w_vs, row_h);
|
||||
|
||||
ChartRedraw();
|
||||
g_updating = false;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnInit |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
g_updating = false;
|
||||
g_last_update_ms = 0;
|
||||
g_prefix = StringFormat("VSW_%I64d_", ChartID()); // Unified VScore-Widget dynamic prefix
|
||||
|
||||
ObjectsDeleteAll(0, g_prefix);
|
||||
|
||||
RenderDashboard();
|
||||
|
||||
EventSetTimer(InpRefreshSeconds);
|
||||
return(INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnDeinit |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
EventKillTimer();
|
||||
ObjectsDeleteAll(0, g_prefix);
|
||||
Comment("");
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnCalculate |
|
||||
//+------------------------------------------------------------------+
|
||||
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[])
|
||||
{
|
||||
//--- Real-time high frequency tick throttling (Max 5 updates per second / 200ms)
|
||||
ulong current_ms = GetTickCount64();
|
||||
if(current_ms - g_last_update_ms >= 200)
|
||||
{
|
||||
g_last_update_ms = current_ms;
|
||||
RenderDashboard();
|
||||
}
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnTimer |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTimer()
|
||||
{
|
||||
RenderDashboard();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,76 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Hardware_Diagnostic_Pro.mq5 |
|
||||
//| Copyright 2026, xxxxxxxx|
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2026, xxxxxxxx"
|
||||
#property version "1.20" // Benchmark and diagnostic utility
|
||||
#property description "QuantScan Hardware Diagnostic & Math Performance Script"
|
||||
#property script_show_inputs
|
||||
|
||||
//--- Input parameters
|
||||
input int InpStressIterations = 10000000; // Math Stress Test Iterations (e.g. 10M)
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnStart |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
Print("====================================================================");
|
||||
Print(" QUANTSCAN HARDWARE DIAGNOSTIC REPORT ");
|
||||
Print("====================================================================");
|
||||
|
||||
//--- Gather and print Terminal Information
|
||||
string terminal_company = TerminalInfoString(TERMINAL_COMPANY);
|
||||
string terminal_name = TerminalInfoString(TERMINAL_NAME);
|
||||
string terminal_path = TerminalInfoString(TERMINAL_PATH);
|
||||
int terminal_build = (int)TerminalInfoInteger(TERMINAL_BUILD);
|
||||
bool is_connected = (bool)TerminalInfoInteger(TERMINAL_CONNECTED);
|
||||
|
||||
PrintFormat("Terminal: %s | %s (Build %d)", terminal_company, terminal_name, terminal_build);
|
||||
PrintFormat("Data Path: %s", terminal_path);
|
||||
PrintFormat("Network Connection Status: %s", is_connected ? "CONNECTED" : "DISCONNECTED");
|
||||
|
||||
//--- Gather and print Environment Information
|
||||
string symbol = _Symbol;
|
||||
string timeframe = EnumToString(_Period);
|
||||
int digits = _Digits;
|
||||
double point = _Point;
|
||||
|
||||
PrintFormat("Active Chart: %s (%s) | Digits: %d | Point Size: %s",
|
||||
symbol, timeframe, digits, DoubleToString(point, digits));
|
||||
|
||||
Print("--------------------------------------------------------------------");
|
||||
Print(" MATH PERFORMANCE BENCHMARK (SIMD SPEED TEST) ");
|
||||
Print("--------------------------------------------------------------------");
|
||||
PrintFormat("Executing %d iterations of floating-point math operations...", InpStressIterations);
|
||||
|
||||
//--- Start high-precision microsecond timer
|
||||
ulong start_time = GetMicrosecondCount();
|
||||
|
||||
double accumulator = 1.23456789;
|
||||
|
||||
//--- Heavy mathematical loop to stress CPU vector registers
|
||||
for(int i = 0; i < InpStressIterations; i++)
|
||||
{
|
||||
accumulator = MathSin(accumulator) + MathCos(accumulator);
|
||||
accumulator = MathLog(MathAbs(accumulator) + 1.0001);
|
||||
|
||||
//--- Prevents loop optimizer from completely bypassing the calculation
|
||||
if(accumulator > 1000.0)
|
||||
accumulator = 1.23456789;
|
||||
}
|
||||
|
||||
ulong elapsed_time_us = GetMicrosecondCount() - start_time;
|
||||
double elapsed_time_ms = (double)elapsed_time_us / 1000.0;
|
||||
|
||||
PrintFormat("Benchmark Result: SUCCESS");
|
||||
PrintFormat("Accumulator Final Hash Value: %.8f", accumulator);
|
||||
PrintFormat("Total Execution Time: %.3f ms", elapsed_time_ms);
|
||||
Print("====================================================================");
|
||||
|
||||
//--- Visual Alert Summary
|
||||
string msg = StringFormat("Diagnostic Complete!\nExecution Time: %.2f ms\nHash: %.4f", elapsed_time_ms, accumulator);
|
||||
Alert(msg);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -4,7 +4,7 @@
|
||||
//| Copyright 2026, xxxxxxxx |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2026, xxxxxxxx"
|
||||
#property version "10.38" // Restored live Symbol BID pricing and dynamic live/historical Murrey price routing
|
||||
#property version "10.38" // Reorganized Weekly V-Score (v_score_week) strictly under the H1 Context Layer
|
||||
#property description "Exports 'QuantScan' dataset for LLM Analysis."
|
||||
#property description "Features High-Performance Object Caching and precise Historical Audits."
|
||||
#property script_show_inputs
|
||||
@@ -76,18 +76,22 @@ input int InpSqueezeMom = 12;
|
||||
input group "Output Settings"
|
||||
input int InpPrecision = 3; // Decimal places for CSV Output
|
||||
|
||||
//--- QuantData Struct
|
||||
//--- QuantData Struct (Updated Layout)
|
||||
struct QuantData
|
||||
{
|
||||
string timestamp;
|
||||
string symbol;
|
||||
double price;
|
||||
|
||||
// H1 Context (Layer 1)
|
||||
string alpha_str;
|
||||
string beta_str;
|
||||
double vhf;
|
||||
double r2;
|
||||
string zone;
|
||||
double v_score_week;
|
||||
double v_score_week; // MOVED HERE (Since it calculates strictly on H1)
|
||||
|
||||
// M15 Flow (Layer 2)
|
||||
double v_score_day;
|
||||
double autocorr;
|
||||
double vol_regime;
|
||||
@@ -97,13 +101,19 @@ struct QuantData
|
||||
double m15_r2;
|
||||
double dist_pdh;
|
||||
double dist_pdl;
|
||||
|
||||
// M5 Trigger (Layer 3)
|
||||
double velocity;
|
||||
double v_pressure;
|
||||
double vol_thrust;
|
||||
double cost_atr;
|
||||
|
||||
// Composites
|
||||
string absorption;
|
||||
string mtf_align;
|
||||
string vwap_align;
|
||||
|
||||
// TSI Hist Caches
|
||||
double h1_tsi_hist;
|
||||
double m15_tsi_hist;
|
||||
double m5_tsi_hist;
|
||||
@@ -314,7 +324,13 @@ bool CMarketScanner::RunAnalysis(string sym, QuantData &data)
|
||||
else
|
||||
data.zone = "N/A";
|
||||
|
||||
// 5. TSI H1 Metrics (H1)
|
||||
// 5. V-Score Week (Using H1 data with correct h1_total parameter and idx_l1 index)
|
||||
// MOVED HERE: Since this is evaluated strictly on the H1 Context Layer!
|
||||
ArrayResize(m_temp_buf3, h1_total);
|
||||
m_vscore_week.Calculate(h1_total, 0, slow_t, slow_o, slow_h, slow_l, slow_c, slow_v, slow_v, m_temp_buf3);
|
||||
data.v_score_week = m_temp_buf3[idx_l1];
|
||||
|
||||
// 6. TSI H1 Metrics (H1)
|
||||
ArrayResize(m_temp_buf1, h1_total);
|
||||
ArrayResize(m_temp_buf2, h1_total);
|
||||
ArrayResize(m_temp_buf3, h1_total);
|
||||
@@ -344,17 +360,12 @@ bool CMarketScanner::RunAnalysis(string sym, QuantData &data)
|
||||
m_vscore_day.Calculate(m15_total, 0, mid_t, mid_o, mid_h, mid_l, mid_c, mid_v, mid_v, m_temp_buf2);
|
||||
data.v_score_day = m_temp_buf2[idx_l2];
|
||||
|
||||
// 3. V-Score Week (Using H1 data with correct h1_total parameter and idx_l1 index)
|
||||
ArrayResize(m_temp_buf3, h1_total);
|
||||
m_vscore_week.Calculate(h1_total, 0, slow_t, slow_o, slow_h, slow_l, slow_c, slow_v, slow_v, m_temp_buf3);
|
||||
data.v_score_week = m_temp_buf3[idx_l1];
|
||||
|
||||
// 4. Autocorrelation Lag-1 (M15)
|
||||
// 3. Autocorrelation Lag-1 (M15)
|
||||
ArrayResize(m_temp_buf2, m15_total);
|
||||
m_autocorr.Calculate(m15_total, 0, PRICE_CLOSE, mid_o, mid_h, mid_l, mid_c, m_temp_buf2);
|
||||
data.autocorr = m_temp_buf2[idx_l2];
|
||||
|
||||
// 5. Volatility Regime (M15)
|
||||
// 4. Volatility Regime (M15)
|
||||
CATRCalculator atr_reg_calc;
|
||||
double atr_fast_buf[], atr_slow_buf[];
|
||||
atr_reg_calc.Init(5, ATR_POINTS);
|
||||
@@ -363,7 +374,7 @@ bool CMarketScanner::RunAnalysis(string sym, QuantData &data)
|
||||
atr_reg_calc.Calculate(m15_total, 0, mid_o, mid_h, mid_l, mid_c, atr_slow_buf);
|
||||
data.vol_regime = (atr_slow_buf[idx_l2] != 0.0) ? (atr_fast_buf[idx_l2] / atr_slow_buf[idx_l2]) : 1.0;
|
||||
|
||||
// 6. Squeeze (M15)
|
||||
// 5. Squeeze (M15)
|
||||
double sqz_mom[], sqz_val[], sqz_col[];
|
||||
ArrayResize(sqz_mom, m15_total);
|
||||
ArrayResize(sqz_val, m15_total);
|
||||
@@ -372,7 +383,7 @@ bool CMarketScanner::RunAnalysis(string sym, QuantData &data)
|
||||
data.sqz = (sqz_col[idx_l2] == 1.0) ? "ON" : "OFF";
|
||||
data.sqz_mom = sqz_mom[idx_l2];
|
||||
|
||||
// 7. VHF & R2 (M15)
|
||||
// 6. VHF & R2 (M15)
|
||||
ArrayResize(m_temp_buf1, m15_total);
|
||||
m_vhf.Calculate(m15_total, 0, PRICE_CLOSE, mid_o, mid_h, mid_l, mid_c, m_temp_buf1);
|
||||
data.m15_vhf = m_temp_buf1[idx_l2];
|
||||
@@ -383,7 +394,7 @@ bool CMarketScanner::RunAnalysis(string sym, QuantData &data)
|
||||
m_linreg.CalculateState(m15_total, 0, mid_o, mid_h, mid_l, mid_c, PRICE_CLOSE, m_temp_buf1, m_temp_buf2, m_temp_buf3);
|
||||
data.m15_r2 = m_temp_buf2[idx_l2];
|
||||
|
||||
// 8. Dist PDH / PDL (M15)
|
||||
// 7. Dist PDH / PDL (M15)
|
||||
SessionLevels sl;
|
||||
if(m_sess.GetLevels(sym, mid_t[idx_l2], sl))
|
||||
{
|
||||
@@ -396,14 +407,14 @@ bool CMarketScanner::RunAnalysis(string sym, QuantData &data)
|
||||
data.dist_pdl = 0.0;
|
||||
}
|
||||
|
||||
// 9. TSI M15 (M15)
|
||||
// 8. TSI M15 (M15)
|
||||
ArrayResize(m_temp_buf1, m15_total);
|
||||
ArrayResize(m_temp_buf2, m15_total);
|
||||
ArrayResize(m_temp_buf3, m15_total);
|
||||
m_tsi.Calculate(m15_total, 0, PRICE_CLOSE, mid_o, mid_h, mid_l, mid_c, m_temp_buf1, m_temp_buf2, m_temp_buf3);
|
||||
data.m15_tsi_hist = m_temp_buf1[idx_l2] - m_temp_buf2[idx_l2];
|
||||
|
||||
// 10. RVOL M15 for Thrust
|
||||
// 9. RVOL M15 for Thrust
|
||||
double rvol_m15 = m_rvol.CalculateSingle(m15_total, mid_v, idx_l2);
|
||||
|
||||
//----------------------------------------------------------------
|
||||
@@ -697,8 +708,8 @@ void OnStart()
|
||||
StringReplace(str_fast, "PERIOD_", "");
|
||||
|
||||
string header = "TIME (" + InpBrokerTimeZone + ");SYMBOL;PRICE;";
|
||||
header += StringFormat("ALPHA_%s;BETA_%s;VHF_%s;R2_%s;ZONE_%s;", str_slow, str_slow, str_slow, str_slow, str_slow);
|
||||
header += StringFormat("V_SCORE_W1_%s;V_SCORE_D1_%s;AUTOCORR_%s;VOL_REGIME_%s;SQZ_%s;SQZ_MOM_%s;VHF_%s;R2_%s;DIST_PDH;DIST_PDL;", str_mid, str_mid, str_mid, str_mid, str_mid, str_mid, str_mid, str_mid);
|
||||
header += StringFormat("ALPHA_%s;BETA_%s;VHF_%s;R2_%s;ZONE_%s;V_SCORE_W1_%s;", str_slow, str_slow, str_slow, str_slow, str_slow, str_slow); // MOVED V_SCORE_W1 to H1 Context!
|
||||
header += StringFormat("V_SCORE_D1_%s;AUTOCORR_%s;VOL_REGIME_%s;SQZ_%s;SQZ_MOM_%s;VHF_%s;R2_%s;DIST_PDH;DIST_PDL;", str_mid, str_mid, str_mid, str_mid, str_mid, str_mid, str_mid);
|
||||
header += StringFormat("VEL_%s;V_PRES_%s;VOL_THRUST;COST_ATR_%s;", str_fast, str_fast, str_fast);
|
||||
header += "ABSORPTION;MTF_ALIGN;VWAP_ALIGN";
|
||||
|
||||
@@ -716,7 +727,7 @@ void OnStart()
|
||||
DoubleToString(results[i].vhf, InpPrecision),
|
||||
DoubleToString(results[i].r2, InpPrecision),
|
||||
results[i].zone,
|
||||
DoubleToString(results[i].v_score_week, InpPrecision),
|
||||
DoubleToString(results[i].v_score_week, InpPrecision), // MOVED: Now writes directly after zone under H1
|
||||
DoubleToString(results[i].v_score_day, InpPrecision),
|
||||
DoubleToString(results[i].autocorr, InpPrecision),
|
||||
DoubleToString(results[i].vol_regime, InpPrecision),
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| PairsTrading_Check_Symbols.mq5 |
|
||||
//| Copyright 2026, xxxxxxxx|
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2026, xxxxxxxx"
|
||||
#property version "1.00" // Standard diagnostic utility for pairs trading symbols
|
||||
#property description "QuantScan Pairs Trading Broker Symbol Diagnostic Script"
|
||||
#property script_show_inputs
|
||||
|
||||
//--- Predefined common symbol candidates to search for
|
||||
string g_candidates[] =
|
||||
{
|
||||
"UKOIL", "BRENT", "UKOil", "XBRUSD", "COCOA",
|
||||
"USOIL", "WTI", "USOil", "XTIUSD", "CL",
|
||||
"US500", "SPY", "USSPX500", "S&P500",
|
||||
"US100", "QQQ", "USNDAQ100", "NASDAQ100",
|
||||
"DE40", "GER40", "DAX40",
|
||||
"EU50", "ESTX50", "EUR50",
|
||||
"XAUUSD", "GOLD",
|
||||
"XAGUSD", "SILVER",
|
||||
"EURUSD", "GBPUSD", "AUDUSD", "NZDUSD", "USDJPY", "USDCHF"
|
||||
};
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Script program start function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
Print("====================================================================");
|
||||
Print(" PAIRS TRADING COINTEGRATION SYMBOL DIAGNOSTIC REPORT ");
|
||||
Print("====================================================================");
|
||||
PrintFormat("Active Broker: %s", TerminalInfoString(TERMINAL_COMPANY));
|
||||
Print("Scanning broker's market database for valid pairs trading candidates...");
|
||||
Print("--------------------------------------------------------------------");
|
||||
|
||||
int candidates_total = ArraySize(g_candidates);
|
||||
int found_count = 0;
|
||||
|
||||
for(int i = 0; i < candidates_total; i++)
|
||||
{
|
||||
string target = g_candidates[i];
|
||||
bool is_custom = false;
|
||||
|
||||
// Check if symbol exists in the broker's database
|
||||
if(SymbolExist(target, is_custom))
|
||||
{
|
||||
found_count++;
|
||||
bool is_selected = (bool)SymbolInfoInteger(target, SYMBOL_SELECT);
|
||||
double bid = SymbolInfoDouble(target, SYMBOL_BID);
|
||||
string path = SymbolInfoString(target, SYMBOL_PATH);
|
||||
|
||||
PrintFormat("MATCH FOUND: Symbol: '%s' | Selected in Market Watch: %s | Current Bid: %f | Path: %s",
|
||||
target, (is_selected ? "YES" : "NO"), bid, path);
|
||||
}
|
||||
}
|
||||
|
||||
Print("--------------------------------------------------------------------");
|
||||
PrintFormat("Scan Complete. Found %d valid candidates out of %d tested.", found_count, candidates_total);
|
||||
Print("====================================================================");
|
||||
|
||||
string summary_msg = StringFormat("Diagnostic Complete!\nFound %d valid pairs trading symbols on your broker.\nCheck the Experts tab for the full report.", found_count);
|
||||
Alert(summary_msg);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,173 @@
|
||||
# QuantScan System: Institutional Market Scanner Pro (V10.38)
|
||||
|
||||
## 1. Summary (Introduction)
|
||||
|
||||
The **Market_Scanner_Pro (QuantScan V10.38)** is the flagship high-frequency data extraction, regime-classification, and statistical auditing engine of the **QuantScan System**.
|
||||
|
||||
Developed to operate as the primary bridge between the MetaTrader 5 trading terminal and advanced Large Language Models (LLMs) or quantitative machine learning pipelines, the scanner aggregates multi-timeframe (MTF) market microstructure data across dozens of financial instruments simultaneously.
|
||||
|
||||
Rather than relying on single-timeframe price action, the scanner utilizes an institutional-grade **Multi-Layered Statistical Architecture**:
|
||||
|
||||
* **Layer 1: Context (H1 - Macro Regime):** Identifies institutional market regime, cointegration, structural zones, and relative performance (Alpha, Beta, VHF, R-Squared, Murrey Math, Weekly Z-Score).
|
||||
* **Layer 2: Flow (M15 - Cycle & Volatility Squeezes):** Evaluates short-term liquidity deviations, cycle autocorrelation, momentum squeezing, and historical levels (Daily V-Score, Autocorrelation, Squeeze, Volatility Regime, PDH/PDL distance).
|
||||
* **Layer 3: Trigger (M5 - Micro-Execution Velocity):** Measures immediate price speed, tick volume delta proxy, institutional volume thrust, and transaction costs (Slope, Volume Pressure, Volume Thrust, Spread Cost).
|
||||
* **Layer 4: Composites (MTF Alignment):** Synthesizes multi-timeframe directional pressure and advanced Volume Spread Analysis (VSA) institutional absorption zones.
|
||||
|
||||
---
|
||||
|
||||
## 2. Software Architecture: Flyweight Engine-Caching Pattern
|
||||
|
||||
To scan dozens of symbols across three timeframes in milliseconds, the scanner was upgraded from a procedural allocation-heavy structure to an object-oriented **Flyweight / Engine-Caching Pattern**.
|
||||
|
||||
### A. The Allocation Bottleneck (Procedural vs. OO)
|
||||
|
||||
In legacy procedural architectures, analyzing a single symbol required the stack to instantiate, initialize, and destroy 11 independent calculator classes. In a loop of 20 symbols, this triggered **over 220 allocation and deallocation memory interrupts**, causing severe heap fragmentation, processor cache misses, and significant terminal lag.
|
||||
|
||||
### B. The Flyweight Master Class Solution
|
||||
|
||||
The refactored `CMarketScanner` master class instantiates all 11 indicators as private member variables **exactly once** during the script's `OnInit / OnStart` phase:
|
||||
|
||||
```text
|
||||
|
||||
[OnStart Script Init]
|
||||
│
|
||||
└──> [CMarketScanner::Init()]
|
||||
│
|
||||
├──> Instantiate CATRCalculator m_atr
|
||||
├──> Instantiate CVScoreCalculator m_vscore_day
|
||||
├──> Instantiate CLinearRegressionCalculator m_linreg
|
||||
└──> [Pre-Allocate Shared Buffers m_temp_buf1, m_temp_buf2]
|
||||
|
||||
```
|
||||
|
||||
During the symbol scanning loop, the scanner calls `RunAnalysis(sym, data)`. Instead of allocating new memory, the core engines reuse the pre-allocated persistent memory blocks (`m_temp_buf1[]`, etc.) and calculate the values. Memory pages remain resident in the **L1/L2 processor cache**, reducing CPU execution time by **up to 500%** and ensuring zero runtime memory leaks.
|
||||
|
||||
---
|
||||
|
||||
## 3. Mathematical & Statistical Foundations
|
||||
|
||||
The scanner's metrics are based on advanced quantitative formulas:
|
||||
|
||||
### A. Alpha and Beta (Capital Asset Pricing Model - CAPM)
|
||||
|
||||
Tracks the relative volatility (Beta) and idiosyncratic excess return (Alpha) of an asset relative to its regional benchmark (such as `US500` for Equities or `DXY` for Forex):
|
||||
|
||||
$$\beta = \frac{\text{Covariance}(R_{\text{asset}}, R_{\text{bench}})}{\text{Variance}(R_{\text{bench}})}$$
|
||||
|
||||
$$\alpha = R_{\text{asset}} - \beta \times R_{\text{bench}}$$
|
||||
|
||||
Where $R$ represents the logarithmic price returns over the specified lookback window $N$ (`InpBetaLookback`).
|
||||
|
||||
### B. Vertical Horizontal Filter (VHF)
|
||||
|
||||
VHF determines whether a market is in a trending or a congested range phase:
|
||||
|
||||
$$\text{VHF} = \frac{\max(P_{t \dots t-N}) - \min(P_{t \dots t-N})}{\sum_{j=0}^{N-1} |P_{t-j} - P_{t-j-1}|}$$
|
||||
|
||||
The scanner uses `VHF_MODE_HIGH_LOW` (replacing close prices with high-low ranges) to achieve a more sensitive volatility-adjusted result.
|
||||
|
||||
### C. Linear Regression R-Squared ($R^2$)
|
||||
|
||||
Measures the strength of the linear trend by evaluating the Coefficient of Determination. $R^2$ values close to `1.0` indicate a highly linear, efficient trend, while values close to `0.0` indicate random walk or consolidation:
|
||||
|
||||
$$R^2 = \frac{\big( N\sum XY - \sum X\sum Y \big)^2}{\big[ N\sum X^2 - (\sum X)^2 \big] \big[ N\sum Y^2 - (\sum Y)^2 \big]}$$
|
||||
|
||||
Where $X$ is mapped to chronological bar indexes ($0 \dots N-1$) and $Y$ represents the corresponding price.
|
||||
|
||||
### D. V-Score (VWAP Volume Z-Score)
|
||||
|
||||
V-Score measures price deviation relative to the Volume Weighted Average Price (VWAP) in units of volume-weighted standard deviation (Sigma). It is calculated on both Daily (Session) and Weekly resets:
|
||||
|
||||
$$\text{VWAP}_t = \frac{\sum (P_t \times V_t)}{\sum V_t}$$
|
||||
|
||||
$$\text{V-Score}_t = \frac{P_t - \text{VWAP}_t}{\sigma_{\text{VWAP}, N}}$$
|
||||
|
||||
### E. Volume Pressure (Tick Delta Proxy)
|
||||
|
||||
Acting as a high-frequency proxy for tick volume delta (buyer vs. seller aggression) without requiring raw order book L2 data, the Money Flow Multiplier is computed and smoothed:
|
||||
|
||||
$$\text{Volume Pressure}_t = \frac{(C_t - L_t) - (H_t - C_t)}{H_t - L_t} \times V_t$$
|
||||
|
||||
### F. Wyckoff Institutional Absorption (Effort vs. Result)
|
||||
|
||||
Natively integrated from the `Absorption_Pro` VSA engine, this logic detects institutional accumulation/distribution blocks by identifying bars where high volume (Effort) fails to produce directional price spread (Result):
|
||||
|
||||
$$\text{Effort} = \text{RVOL}_t > 2.0 \quad \text{AND} \quad \text{Result} = \text{Spread}_t < 0.35 \times \text{ATR}_t$$
|
||||
|
||||
$$\text{ClosePos} = \frac{C_t - L_t}{H_t - L_t} \implies \begin{cases}
|
||||
CP_t > 0.66 \implies \textbf{BULL\_ABS} \quad \text{(Demand absorbs Supply)} \\
|
||||
CP_t < 0.33 \implies \textbf{BEAR\_ABS} \quad \text{(Supply absorbs Demand)} \\
|
||||
\text{otherwise} \implies \textbf{NEUT\_ABS} \quad \text{(Balanced struggle)}
|
||||
\end{cases}$$
|
||||
|
||||
---
|
||||
|
||||
## 4. Historical Backtesting & Auditing Pipeline
|
||||
|
||||
To facilitate historical research, database creation, and comparative audits with past live runs, the scanner supports **precise historical temporal offset scanning**.
|
||||
|
||||
### A. Temporal Sliding Window Offset (`iBarShift`)
|
||||
When `InpUseTargetTime` is enabled, the scanner calculates the exact bar offset (`start_bar`) for the target evaluation minute on every timeframe:
|
||||
|
||||
$$\text{start\_bar}_{\text{tf}} = \text{iBarShift}(\text{Symbol}, \text{timeframe}, \text{InpTargetTime}, \text{false})$$
|
||||
|
||||
The `FetchData` engine shifts its copying window back in history by `start_bar` indexes:
|
||||
|
||||
```text
|
||||
|
||||
[Standard Mode] TimeCurrent() <── [ CopyInpScanHistory bars ]
|
||||
[Historical Audit] InpTargetTime <── [ CopyInpScanHistory bars ] (Shifted by start_bar)
|
||||
|
||||
```
|
||||
|
||||
Because of chronological array sorting, index `ArraySize - 1` in the copied array represents the exact target minute (e.g. `08:32` or `09:37`). The indicators calculate the historical state as if it were the live bar, eliminating all post-bar information leakage (no lookahead bias).
|
||||
|
||||
### B. High-Precision Timing & Live Pricing
|
||||
* **Exact Timestamp Mapping:** The exported CSV `TIME` column reflects the exact user-defined target minute (e.g., `09:37`) instead of being rounded to the hour.
|
||||
* **Exact Live Price Tracking:** The `PRICE` column prints the actual live BID price (`SymbolInfoDouble`) of the symbol at the moment of execution to maintain data alignment with the legacy execution pipeline.
|
||||
|
||||
---
|
||||
|
||||
## 5. Dataset Schema (The CSV Output Layout)
|
||||
|
||||
The scanner outputs a semi-colon-separated CSV file with a dynamic filename (e.g. `QuantScan_20260724_0937.csv`) containing the following dataset schema:
|
||||
|
||||
| Column Name | Data Type | Analytical Meaning |
|
||||
| :--- | :--- | :--- |
|
||||
| **`TIME`** | `string` | The exact evaluation timestamp (Broker Time, e.g., `2026.07.24 09:37`). |
|
||||
| **`SYMBOL`** | `string` | The symbol ticker name (e.g., `EURUSD`, `XAUUSD`). |
|
||||
| **`PRICE`** | `double` | The live BID price of the symbol. |
|
||||
| **`ALPHA_H1`** | `double` | CAPM Alpha relative to the benchmark (idiosyncratic excess return). |
|
||||
| **`BETA_H1`** | `double` | CAPM Beta relative to the benchmark (relative market sensitivity). |
|
||||
| **`VHF_H1`** | `double` | Vertical Horizontal Filter (Regime classifier: trending vs. range). |
|
||||
| **`R2_H1`** | `double` | Linear Regression $R^2$ (Linear trend strength). |
|
||||
| **`ZONE_H1`** | `string` | Murrey Math support/resistance zone name. |
|
||||
| **`V_SCORE_W1_H1`** | `double` | Weekly VWAP Z-Score (Weekly institutional price deviation). |
|
||||
| **`V_SCORE_D1_M15`**| `double` | Daily VWAP Z-Score (Daily institutional price deviation). |
|
||||
| **`AUTOCORR_M15`** | `double` | Lag-1 Autocorrelation (Cycle persistence vs. mean reversion). |
|
||||
| **`VOL_REGIME_M15`**| `double` | ATR(5)/ATR(55) ratio (Volatility expansion vs. compression). |
|
||||
| **`SQZ_M15`** | `string` | Volatility Squeeze State (`ON` = BB inside KC, `OFF` = normal). |
|
||||
| **`SQZ_MOM_M15`** | `double` | Squeeze momentum trend strength value. |
|
||||
| **`VHF_M15`** | `double` | Vertical Horizontal Filter on M15. |
|
||||
| **`R2_M15`** | `double` | Linear Regression $R^2$ on M15. |
|
||||
| **`DIST_PDH`** | `double` | Distance of close price to Previous Day High in ATR units. |
|
||||
| **`DIST_PDL`** | `double` | Distance of close price to Previous Day Low in ATR units. |
|
||||
| **`VEL_M5`** | `double` | Price displacement speed in ATR units on M5. |
|
||||
| **`V_PRES_M5`** | `double` | Volume Pressure (Tick Delta Proxy momentum) on M5. |
|
||||
| **`VOL_THRUST`** | `double` | Ratio of M5 RVOL / M15 RVOL (Micro volume injection strength). |
|
||||
| **`COST_ATR_M5`** | `double` | Live spread cost normalized in ATR units (Transaction friction). |
|
||||
| **`ABSORPTION`** | `string` | Institutional Wyckoff Absorption pattern (`BULL_ABS`, `BEAR_ABS`, `CLIMAX`, `NO`). |
|
||||
| **`MTF_ALIGN`** | `string` | Trend alignment direction across H1, M15, M5 (`FULL_BULL`, `MAJOR_BEAR`, etc.). |
|
||||
| **`VWAP_ALIGN`** | `string` | Alignment of Price relative to Daily and Weekly VWAP averages. |
|
||||
|
||||
---
|
||||
|
||||
## 6. LLM & Quant Ingestion Strategies
|
||||
|
||||
### A. Regional Market Sentiment Analysis
|
||||
By parsing the global header (`### GLOBAL_SENTIMENT | ... ###`), the LLM immediately grasps the macro regime across various assets. The relationship between `US500` (risk benchmark) and `DXY` (safe-haven dollar index) dictates whether the market is in a **Risk-On, Risk-Off, Stress, or Deflationary** state, which scales the model's global risk parameters.
|
||||
|
||||
### B. High-Probability Order-Flow Filters
|
||||
The LLM can combine `ABSORPTION`, `V_SCORE_D1`, and `VOL_THRUST` to identify high-probability institutional pools:
|
||||
* **Long Ingest:** When `ABSORPTION = BULL_ABS`, `V_SCORE_D1` is oversold ($<-2.0$), and `VOL_THRUST > 1.5`, the model identifies a high-volume institutional support block where sellers have exhausted and passive institutional limit buying has completed.
|
||||
* **Transaction Cost Safeguard:** Scalping strategies must inspect `COST_ATR_M5`. If cost is $> 0.30$ (30% of volatility), the LLM can veto execution due to excessive friction.
|
||||
Reference in New Issue
Block a user