//+------------------------------------------------------------------+ //| RollingVWAP.mq5 | //| VWAP Dynamique - FIFO O(1) + Écart-Type + Coloration Ternaire | //+------------------------------------------------------------------+ #property copyright "t00nster" #property link "https://heretik666.free.fr/brousoufs" #property version "3.00" #property indicator_chart_window #property indicator_buffers 9 // 3 Data + 1 Color + 5 Calculs #property indicator_plots 3 // --- Apparence visuelle (DRAW_COLOR_LINE) --- #property indicator_label1 "Rolling VWAP" #property indicator_type1 DRAW_COLOR_LINE // Index des couleurs : 0 = Vert (Hausse), 1 = Rouge (Baisse), 2 = Bleu (Neutre) #property indicator_color1 clrLime,clrRed,clrDodgerBlue #property indicator_style1 STYLE_SOLID #property indicator_width1 2 //--- Plot Upper Band (+2.0 SD) #property indicator_label2 "Rolling VWAP Upper" #property indicator_type2 DRAW_LINE #property indicator_color2 clrGray #property indicator_style2 STYLE_DASH //--- Plot Lower Band (-2.0 SD) #property indicator_label3 "Rolling VWAP Lower" #property indicator_type3 DRAW_LINE #property indicator_color3 clrGray #property indicator_style3 STYLE_DASH // --- Paramètres --- input int InpVWAPPeriod = 15; // Taille du Buffer LIFO/FIFO input double InpTolerance = 0.05; // Tolérance au bruit (Delta) // --- Buffers d'affichage --- double VWAPBuffer[]; int VWAPColorBuffer[]; // Buffer qui stocke l'état (0, 1 ou 2) double BufferUpper[]; double BufferLower[]; // --- Buffers de calcul (Invisibles) --- double StdDevBuffer[]; // Index 4 (Lu par l'EA) double SumPVBuffer[]; // Index 5 double SumVBuffer[]; // Index 4 double SumPBuffer[]; // Index 5 double SumP2Buffer[]; // Index 6 //+------------------------------------------------------------------+ int OnInit() { // Buffers visibles SetIndexBuffer(0, VWAPBuffer, INDICATOR_DATA); SetIndexBuffer(1, VWAPColorBuffer, INDICATOR_COLOR_INDEX); SetIndexBuffer(2, BufferUpper, INDICATOR_DATA); SetIndexBuffer(3, BufferLower, INDICATOR_DATA); // Buffers de calcul SetIndexBuffer(4, StdDevBuffer, INDICATOR_CALCULATIONS); SetIndexBuffer(5, SumPVBuffer, INDICATOR_CALCULATIONS); SetIndexBuffer(6, SumVBuffer, INDICATOR_CALCULATIONS); SetIndexBuffer(7, SumPBuffer, INDICATOR_CALCULATIONS); SetIndexBuffer(8, SumP2Buffer, INDICATOR_CALCULATIONS); IndicatorSetInteger(INDICATOR_DIGITS, _Digits); IndicatorSetString(INDICATOR_SHORTNAME, "RVWAP(" + IntegerToString(InpVWAPPeriod) + ")"); 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[]) { if(rates_total < InpVWAPPeriod) return 0; int limit = prev_calculated == 0 ? InpVWAPPeriod : prev_calculated - 1; // --- INITIALISATION DE LA TOUTE PREMIÈRE FENÊTRE --- if(prev_calculated == 0) { double s_pv = 0, s_v = 0, s_p = 0, s_p2 = 0; for(int j = 0; j < InpVWAPPeriod; j++) { double typ = (high[j] + low[j] + close[j]) / 3.0; double vol = (double)tick_volume[j]; s_pv += typ * vol; s_v += vol; s_p += typ; s_p2 += typ * typ; } int init_idx = InpVWAPPeriod - 1; SumPVBuffer[init_idx] = s_pv; SumVBuffer[init_idx] = s_v; SumPBuffer[init_idx] = s_p; SumP2Buffer[init_idx] = s_p2; VWAPBuffer[init_idx] = (s_v > 0) ? NormalizeDouble((s_pv / s_v), _Digits) : NormalizeDouble(close[init_idx], _Digits); VWAPColorBuffer[init_idx] = 2.0; // État initial = Neutre double vwap = VWAPBuffer[init_idx]; double var = (s_p2 / InpVWAPPeriod) - 2 * vwap * (s_p / InpVWAPPeriod) + (vwap * vwap); StdDevBuffer[init_idx] = MathSqrt(MathMax(0.0, var)); BufferUpper[init_idx] = NormalizeDouble(vwap + (1.618 * StdDevBuffer[init_idx]), _Digits); BufferLower[init_idx] = NormalizeDouble(vwap - (1.618 * StdDevBuffer[init_idx]), _Digits); } // --- LE MOTEUR FIFO O(1) & LOGIQUE TERNAIRE --- for(int i = limit; i < rates_total; i++) { if (i < InpVWAPPeriod) continue; double head_typ = (high[i] + low[i] + close[i]) / 3.0; double head_vol = (double)tick_volume[i]; int tail_idx = i - InpVWAPPeriod; double tail_typ = (high[tail_idx] + low[tail_idx] + close[tail_idx]) / 3.0; double tail_vol = (double)tick_volume[tail_idx]; // Mise à jour de la mémoire FIFO SumPVBuffer[i] = NormalizeDouble(SumPVBuffer[i - 1] + (head_typ * head_vol) - (tail_typ * tail_vol), _Digits); SumVBuffer[i] = NormalizeDouble(SumVBuffer[i - 1] + head_vol - tail_vol, _Digits); SumPBuffer[i] = NormalizeDouble(SumPBuffer[i - 1] + head_typ - tail_typ, _Digits); SumP2Buffer[i] = NormalizeDouble(SumP2Buffer[i - 1] + (head_typ * head_typ) - (tail_typ * tail_typ), _Digits); // Calcul VWAP VWAPBuffer[i] = NormalizeDouble((SumVBuffer[i] > 0) ? (SumPVBuffer[i] / SumVBuffer[i]) : close[i], _Digits); // --- ARCHITECTURE TERNAIRE (Coloration de la pente) --- double delta = VWAPBuffer[i] - VWAPBuffer[i - 1]; if(delta > InpTolerance) VWAPColorBuffer[i] = 0; // Pente haussière franche (Vert) else if(delta < -InpTolerance) VWAPColorBuffer[i] = 1; // Pente baissière franche (Rouge) else VWAPColorBuffer[i] = 2; // Stagnation, bruit absorbé (Bleu) // Calcul Écart-Type double vwap = VWAPBuffer[i]; double var = (SumP2Buffer[i] / InpVWAPPeriod) - 2 * vwap * (SumPBuffer[i] / InpVWAPPeriod) + (vwap * vwap); StdDevBuffer[i] = NormalizeDouble(MathSqrt(MathMax(0.0, var)), _Digits); BufferUpper[i] = NormalizeDouble(vwap + (1.618 * StdDevBuffer[i]), _Digits); BufferLower[i] = NormalizeDouble(vwap - (1.618 * StdDevBuffer[i]), _Digits); } return rates_total; }