//+------------------------------------------------------------------+ //| GainzAlgo Alpha v2 — Clean-Room Approximation | //| Public baseline: EMA trend + ATR volatility + RSI momentum | //| This source does not copy or claim the proprietary calculation. | //+------------------------------------------------------------------+ #property copyright "Clean-room approximation" #property version "0.1.0" #property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 4 #property indicator_label1 "BUY_Buffer" #property indicator_type1 DRAW_ARROW #property indicator_color1 clrLimeGreen #property indicator_label2 "SELL_Buffer" #property indicator_type2 DRAW_ARROW #property indicator_color2 clrTomato #property indicator_label3 "TP_Buffer" #property indicator_type3 DRAW_LINE #property indicator_color3 clrDeepSkyBlue #property indicator_style3 STYLE_DASH #property indicator_label4 "SL_Buffer" #property indicator_type4 DRAW_LINE #property indicator_color4 clrOrange #property indicator_style4 STYLE_DASH enum ENUM_DISTANCE_MODEL { DISTANCE_ATR, DISTANCE_SWING }; input int InpFastEMA=21; input int InpSlowEMA=55; input int InpATRPeriod=14; input double InpATRMultiplier=2.0; input int InpRSIPeriod=14; input double InpRSIMidline=50.0; input ENUM_TIMEFRAMES InpHigherTimeframe=PERIOD_CURRENT; input bool InpDisableRepeats=true; input ENUM_DISTANCE_MODEL InpDistanceModel=DISTANCE_ATR; input double InpRiskReward=2.0; input bool InpPopupAlert=true; input bool InpSoundAlert=false; input bool InpPushAlert=false; input bool InpEmailAlert=false; input string InpObjectPrefix="GAZ_CR_"; double BuyBuffer[]; double SellBuffer[]; double TPBuffer[]; double SLBuffer[]; int atrHandle=INVALID_HANDLE; int fastHandle=INVALID_HANDLE; int slowHandle=INVALID_HANDLE; int rsiHandle=INVALID_HANDLE; datetime lastAlertBar=0; int lastDirection=0; int OnInit() { SetIndexBuffer(0,BuyBuffer,INDICATOR_DATA); SetIndexBuffer(1,SellBuffer,INDICATOR_DATA); SetIndexBuffer(2,TPBuffer,INDICATOR_DATA); SetIndexBuffer(3,SLBuffer,INDICATOR_DATA); PlotIndexSetInteger(0,PLOT_ARROW,233); PlotIndexSetInteger(1,PLOT_ARROW,234); ArraySetAsSeries(BuyBuffer,true); ArraySetAsSeries(SellBuffer,true); ArraySetAsSeries(TPBuffer,true); ArraySetAsSeries(SLBuffer,true); atrHandle=iATR(_Symbol,_Period,InpATRPeriod); fastHandle=iMA(_Symbol,_Period,InpFastEMA,0,MODE_EMA,PRICE_CLOSE); slowHandle=iMA(_Symbol,_Period,InpSlowEMA,0,MODE_EMA,PRICE_CLOSE); rsiHandle=iRSI(_Symbol,_Period,InpRSIPeriod,PRICE_CLOSE); if(atrHandle==INVALID_HANDLE || fastHandle==INVALID_HANDLE || slowHandle==INVALID_HANDLE || rsiHandle==INVALID_HANDLE) return INIT_FAILED; ObjectsDeleteAll(0,InpObjectPrefix); IndicatorSetString(INDICATOR_SHORTNAME,"GAZ Alpha v2 Clean Room"); return INIT_SUCCEEDED; } void OnDeinit(const int reason) { ObjectsDeleteAll(0,InpObjectPrefix); IndicatorRelease(atrHandle); IndicatorRelease(fastHandle); IndicatorRelease(slowHandle); IndicatorRelease(rsiHandle); } void DrawLevel(const string suffix,const datetime barTime,const double price,const color lineColor) { const string name=InpObjectPrefix+suffix+IntegerToString((long)barTime); if(ObjectFind(0,name)<0) ObjectCreate(0,name,OBJ_HLINE,0,0,price); ObjectSetInteger(0,name,OBJPROP_COLOR,lineColor); ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DASH); ObjectSetInteger(0,name,OBJPROP_BACK,true); } void FireAlert(const int direction,const datetime barTime,const double entry) { if(barTime==lastAlertBar) return; lastAlertBar=barTime; const string side=direction>0 ? "BUY" : "SELL"; const string message=StringFormat("GAZ Alpha v2 %s | %s | %s | %.5f",side,_Symbol,EnumToString((ENUM_TIMEFRAMES)_Period),entry); if(InpPopupAlert) Alert(message); if(InpSoundAlert) PlaySound("alert.wav"); if(InpPushAlert) SendNotification(message); if(InpEmailAlert) SendMail("GAZ Alpha v2 signal",message); } 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_total0 ? MathMin(rates_total-prev_calculated+2,rates_total-2) : rates_total-2; for(int i=start;i>=1;i--) { BuyBuffer[i]=EMPTY_VALUE; SellBuffer[i]=EMPTY_VALUE; TPBuffer[i]=EMPTY_VALUE; SLBuffer[i]=EMPTY_VALUE; const int now=fast[i]>slow[i] && rsi[i]>=InpRSIMidline ? 1 : fast[i]slow[i+1] && rsi[i+1]>=InpRSIMidline ? 1 : fast[i+1]0) { BuyBuffer[i]=low[i]-atr[i]*0.25; TPBuffer[i]=entry+risk*InpRiskReward; SLBuffer[i]=entry-risk; DrawLevel("TP_",time[i],TPBuffer[i],clrDeepSkyBlue); DrawLevel("SL_",time[i],SLBuffer[i],clrOrange); } else { SellBuffer[i]=high[i]+atr[i]*0.25; TPBuffer[i]=entry-risk*InpRiskReward; SLBuffer[i]=entry+risk; DrawLevel("TP_",time[i],TPBuffer[i],clrDeepSkyBlue); DrawLevel("SL_",time[i],SLBuffer[i],clrOrange); } if(i==1) FireAlert(now,time[i],entry); lastDirection=now; } return rates_total; } //+------------------------------------------------------------------+