Author: Max Berilo
ModiSimple
Indicators Used
Indicator of the average true rangeMoving average indicatorRelative strength indexMACD HistogramMoving average indicator
Miscellaneous
Implements a curve of type %1
0 Views
0 Downloads
0 Favorites
ModiSimple
#property copyright "Max Berilo"
//----
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_color1 Red
#property indicator_color2 LimeGreen
#property indicator_color3 Black
#property indicator_color4 Red
#property indicator_color5 Green
#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 0
#property indicator_width4 1
#property indicator_width5 1
//---- input parameters
extern bool ShowBody     = True;
extern bool UseRSI       = True;
extern bool UseRSIaccel  = True;
extern bool UseRSIvalue  = False;
extern bool UseRSIdir    = True;
extern bool UseRSIhist   = True;
extern bool UseRSIisect  = True;
extern bool UseRSIsign   = False;
extern int  RSIperiod    = 14;
extern int  RSIfast      = 12;
extern int  RSIslow      = 26;
extern int  RSIsignal    = 9;
extern int  RSIbuyThreshold  = 40;
extern int  RSIsellThreshold = 60;
extern bool UseMACD      = True;
extern bool UseMACDaccel = True;
extern bool UseMACDvalue = False;
extern bool UseMACDdir   = True;
extern bool UseMACDhist  = False;
extern bool UseMACDisect = False;
extern bool UseMACDsign  = False;
extern int  FastMA       = 12;
extern int  SlowMA       = 26;
extern int  SignalMA     =  9;
//----
extern bool   ShowTrail   = True;
extern string TrlComment  = "SATL-1,FATL-2,EMA(HLC/3)-3,(HLC/3)-4,EMA(C)-5,C-6";
extern int    TrlMethod   = 5;
extern int    TrlPeriod   = 5;
extern double TrlInitMul  = 1.0;
extern double TrlMul      = 2.0;
extern int    TrlAtrPer   = 21;
extern int    TrlTrap     = 0;
extern bool   TrlUseMax   = False;
extern int    TrlMaxTrap  = 45;
//---- buffers
double ExtMap1[];
double ExtMap2[];
double TrlBegin[];
double TrlStopDn[];
double TrlStopUp[];
double RSI[];
double RSImacd[];
double MACD[];
//---- defines
int nFATL = 39;
int nSATL = 65;
//---- static parameters
double Spread;
static int nDrawBegin;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//----
    IndicatorBuffers(8);
    SetIndexStyle(0, DRAW_HISTOGRAM, EMPTY, 2);
    SetIndexStyle(1, DRAW_HISTOGRAM, EMPTY, 2);
    SetIndexStyle(2, DRAW_ARROW);
    SetIndexStyle(3, DRAW_LINE);
    SetIndexStyle(4, DRAW_LINE);
    SetIndexArrow(2, 159);
    SetIndexBuffer(0, ExtMap1);
    SetIndexBuffer(1, ExtMap2);
    SetIndexBuffer(2, TrlBegin);
    SetIndexBuffer(3, TrlStopDn);
    SetIndexBuffer(4, TrlStopUp);
    SetIndexBuffer(5, RSI);
    SetIndexBuffer(6, RSImacd);
    SetIndexBuffer(7, MACD);
//----
    nDrawBegin = TrlPeriod + TrlAtrPer;
    if(TrlMethod == 1) {
      nDrawBegin += nSATL;
    }
    SetIndexDrawBegin(2, nDrawBegin);
    SetIndexDrawBegin(3, nDrawBegin);
    SetIndexDrawBegin(4, nDrawBegin);
//---- labels
    string short_name = "Simple";
    SetIndexLabel(0, short_name);
    SetIndexLabel(1, short_name);
    SetIndexLabel(2, "TrlBegin");
    SetIndexLabel(3, "TrlStopDn");
    SetIndexLabel(4, "TrlStopUp");
//----
    return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator function                                        |
//+------------------------------------------------------------------+
double CalcTrailStop(int shift, bool uptrend, bool initial)
  {
    double res, atr, sl = TrlTrap;
    if(!initial) {
      shift++;
    }
    atr = iATR(NULL, 0, TrlAtrPer, shift) / Point;
    if(initial) {
      sl  += TrlInitMul * atr;
    } else {
      sl  += TrlMul * atr;
    }
    if(TrlUseMax && sl > TrlMaxTrap) {
      sl = TrlMaxTrap;
    }
    switch(TrlMethod) {
      case 1:
        res = CalcSATLonMedian(shift);
        break;
      case 2:
        res = CalcFATLonMedian(shift);
        break;
      case 3:
        res = iMA(NULL, 0, TrlPeriod, 0, MODE_EMA, PRICE_TYPICAL, shift);
        break;
      case 4:
        res = (High[shift] + Low[shift] + Close[shift]) / 3.0;
        break;
      case 5:
        res = iMA(NULL, 0, TrlPeriod, 0, MODE_EMA, PRICE_CLOSE, shift);
        break;
      case 6:
      default:
        res = Close[shift];
        break;
    }
    if(uptrend) {
      res -= sl * Point;
    } else {
      res += (sl + Spread) * Point;
    }
    res = NormalizeDouble(res, Digits);
    return(res);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
    int    limit, shift, counted_bars = IndicatorCounted();
    double val1, val2, ma, signal, prevsign, atr;
    bool   buy, sell, bRSIbuy, bRSIsell, bMACDbuy, bMACDsell;
//----
    double StopLoss;
    bool   TrlLong, TrlPrevLong, TrlShort, TrlPrevShort;
//----
    Spread = MarketInfo(Symbol(), MODE_SPREAD);
    if(!ShowTrail) {
      SetIndexDrawBegin(2, Bars);
      SetIndexDrawBegin(3, Bars);
      SetIndexDrawBegin(4, Bars);
    }
//---- last counted bar will be recounted
    if(Bars <= RSIperiod) return(0);
    if(counted_bars > 0) {
      counted_bars--;
    } else {
      ArrayInitialize(TrlBegin,  EMPTY_VALUE);
      ArrayInitialize(TrlStopDn, EMPTY_VALUE);
      ArrayInitialize(TrlStopUp, EMPTY_VALUE);
    }
    limit = Bars - counted_bars - 1;
//----
    for(shift = limit; shift >= 0; shift--) {
      if(UseRSI) {
        RSI[shift] = iRSI(NULL, 0, RSIperiod, PRICE_CLOSE, shift);
      } else {
        RSI[shift] = 0;
      }
      if(UseMACD) {
        MACD[shift] = iMACD(NULL, 0, FastMA, SlowMA, SignalMA, PRICE_CLOSE, MODE_MAIN, shift);
      } else {
        MACD[shift] = 0;
      }
    }
//----
    for(shift = limit; UseRSI && (shift >= 0); shift--) {
      if(shift < Bars - (RSIperiod + RSIslow)) {
        RSImacd[shift] = iMAOnArray(RSI,0,RSIfast,0,MODE_EMA,shift)-iMAOnArray(RSI,0,RSIslow,0,MODE_EMA,shift);
      } else {
        RSImacd[shift] = 0;
      }
    }
//----
    for(shift = limit; shift >= 0; shift--) {
      val1 = EMPTY_VALUE; val2 = EMPTY_VALUE;
      if(UseRSI) {
        bRSIbuy  = False; bRSIsell = False;
        if(shift < Bars - (RSIperiod+RSIslow+2)) {
          if(UseRSIaccel) {
            prevsign = iMAOnArray(RSImacd,0,RSIsignal,0,MODE_EMA,shift+1);
            signal   = iMAOnArray(RSImacd,0,RSIsignal,0,MODE_EMA,shift);
            bRSIbuy  = (RSImacd[shift] - signal) > (RSImacd[shift+1] - prevsign);
            bRSIsell = (RSImacd[shift] - signal) < (RSImacd[shift+1] - prevsign);
          }
          if(UseRSIvalue) {
            buy  = RSI[shift] > RSIbuyThreshold;
            sell = RSI[shift] < RSIsellThreshold;
            if(UseRSIaccel) {
              bRSIbuy  = bRSIbuy  && buy;
              bRSIsell = bRSIsell && sell;
            } else {
              bRSIbuy  = buy;
              bRSIsell = sell;
            }
          }
          if(UseRSIdir) {
            buy  = (RSImacd[shift] > RSImacd[shift+1]);
            sell = (RSImacd[shift] < RSImacd[shift+1]);
            if(UseRSIaccel || UseRSIvalue) {
              bRSIbuy  = bRSIbuy  && buy;
              bRSIsell = bRSIsell && sell;
            } else {
              bRSIbuy  = buy;
              bRSIsell = sell;
            }
          }
          if(UseRSIhist) {
            buy  = RSImacd[shift] > RSImacd[shift+2];
            sell = RSImacd[shift] < RSImacd[shift+2];
            if(UseRSIaccel || UseRSIvalue || UseRSIdir) {
              bRSIbuy  = bRSIbuy  && buy;
              bRSIsell = bRSIsell && sell;
            } else {
              bRSIbuy  = buy;
              bRSIsell = sell;
            }
          }
          if(UseRSIisect) {
            if(!UseRSIaccel) {
              signal = iMAOnArray(RSImacd,0,RSIsignal,0,MODE_EMA,shift);
            }
            buy  = RSImacd[shift] > signal;
            sell = RSImacd[shift] < signal;
            if(UseRSIaccel || UseRSIvalue || UseRSIdir || UseRSIhist) {
              bRSIbuy  = bRSIbuy  && buy;
              bRSIsell = bRSIsell && sell;
            } else {
              bRSIbuy  = buy;
              bRSIsell = sell;
            }
          }
          if(UseRSIsign) {
            bRSIbuy  = bRSIbuy  && (RSImacd[shift] >= 0);
            bRSIsell = bRSIsell && (RSImacd[shift] <= 0);
            if(UseRSIaccel || UseRSIvalue || UseRSIdir || UseRSIhist || UseRSIisect) {
              bRSIbuy  = bRSIbuy  && buy;
              bRSIsell = bRSIsell && sell;
            } else {
              bRSIbuy  = buy;
              bRSIsell = sell;
            }
          }
        }
      }
      if(UseMACD) {
        bMACDbuy  = False; bMACDsell = False;
        if(shift <= Bars - (SlowMA+2)) {
          if(UseMACDaccel) {
            prevsign  = iMAOnArray(MACD,0,SignalMA,0,MODE_EMA,shift+1);
            signal    = iMAOnArray(MACD,0,SignalMA,0,MODE_EMA,shift);
            bMACDbuy  = (MACD[shift] - signal) > (MACD[shift+1] - prevsign);
            bMACDsell = (MACD[shift] - signal) < (MACD[shift+1] - prevsign);
          }
          if(UseMACDvalue) {
            atr = iATR(NULL, 0, 21, shift);
            buy  = MACD[shift] > -atr;
            sell = MACD[shift] <  atr;
            if(UseMACDaccel) {
              bMACDbuy  = bMACDbuy  && buy;
              bMACDsell = bMACDsell && sell;
            } else {
              bMACDbuy  = buy;
              bMACDsell = sell;
            }
          }
          if(UseMACDdir) {
            buy  = (MACD[shift] > MACD[shift+1]);
            sell = (MACD[shift] < MACD[shift+1]);
            if(UseMACDaccel || UseMACDvalue) {
              bMACDbuy  = bMACDbuy  && buy;
              bMACDsell = bMACDsell && sell;
            } else {
              bMACDbuy  = buy;
              bMACDsell = sell;
            }
          }
          if(UseMACDhist) {
            buy  = MACD[shift] > MACD[shift+2];
            sell = MACD[shift] < MACD[shift+2];
            if(UseMACDaccel || UseMACDvalue || UseMACDdir) {
              bMACDbuy  = bMACDbuy  && buy;
              bMACDsell = bMACDsell && sell;
            } else {
              bMACDbuy  = buy;
              bMACDsell = sell;
            }
          }
          if(UseMACDisect) {
            if(!UseMACDaccel) {
              signal = iMAOnArray(MACD,0,SignalMA,0,MODE_EMA,shift);
            }
            buy  = MACD[shift] > signal;
            sell = MACD[shift] < signal;
            if(UseMACDaccel || UseMACDvalue || UseMACDdir || UseMACDhist) {
              bMACDbuy  = bMACDbuy  && buy;
              bMACDsell = bMACDsell && sell;
            } else {
              bMACDbuy  = buy;
              bMACDsell = sell;
            }
          }
          if(UseMACDsign) {
            buy  = MACD[shift] >= 0;
            sell = MACD[shift] <= 0;
            if(UseMACDaccel || UseMACDvalue || UseMACDdir || UseMACDhist || UseMACDsign) {
              bMACDbuy  = bMACDbuy  && buy;
              bMACDsell = bMACDsell && sell;
            } else {
              bMACDbuy  = buy;
              bMACDsell = sell;
            }
          }
        }
      }
//----
      if((!UseRSI || (UseRSI && bRSIbuy)) && (!UseMACD || (UseMACD && bMACDbuy))) {
        if(ShowBody) {
          if(Open[shift] < Close[shift]) {
            val1 = Open[shift];
            val2 = Close[shift];
          } else {
            val2 = Open[shift];
            val1 = Close[shift];
          }
        }
        TrlLong = True;
      } else {
        TrlLong = False;
      }
      if((!UseRSI || (UseRSI && bRSIsell)) && (!UseMACD || (UseMACD && bMACDsell))) {
        if(ShowBody) {
          if(Open[shift] > Close[shift]) {
            val1 = Open[shift];
            val2 = Close[shift];
          } else {
            val2 = Open[shift];
            val1 = Close[shift];
          }
        }
        TrlShort = True;
      } else {
        TrlShort = False;
      }
      ExtMap1[shift] = val1;
      ExtMap2[shift] = val2;
//----
      if(shift < Bars - nDrawBegin) {
        TrlPrevLong  = (TrlStopUp[shift+1] != EMPTY_VALUE) &&
          ((TrlStopUp[shift+1] < Low[shift+1]) || (TrlStopUp[shift+1] == TrlBegin[shift+1]));
        TrlPrevShort = (TrlStopDn[shift+1] != EMPTY_VALUE) &&
          ((TrlStopDn[shift+1] > High[shift+1] + Spread * Point) || (TrlStopDn[shift+1] == TrlBegin[shift+1]));
        if(TrlLong || TrlPrevLong) {
          StopLoss = CalcTrailStop(shift, true, !TrlPrevLong);
          if(TrlPrevLong && StopLoss < TrlStopUp[shift+1]) {
            TrlStopUp[shift] = TrlStopUp[shift+1];
          } else {
            TrlStopUp[shift] = StopLoss;
            if(!TrlPrevLong) {
              TrlBegin[shift] = StopLoss;
            }
          }
        } else {
          TrlStopUp[shift] = EMPTY_VALUE;
        }
        if(TrlShort || TrlPrevShort) {
          StopLoss = CalcTrailStop(shift, false, !TrlPrevShort);
          if(TrlPrevShort && StopLoss > TrlStopDn[shift+1]) {
            TrlStopDn[shift] = TrlStopDn[shift+1];
          } else {
            TrlStopDn[shift] = StopLoss;
            if(!TrlPrevShort) {
              TrlBegin[shift] = StopLoss;
            }
          }
        } else {
          TrlStopDn[shift] = EMPTY_VALUE;
        }
        if((TrlBegin[shift] != EMPTY_VALUE)&&(TrlBegin[shift] != TrlStopUp[shift])&&(TrlBegin[shift] != TrlStopDn[shift])) {
          TrlBegin[shift] = EMPTY_VALUE;
        }
      }
    }
//----
    return(0);
  }
//----
double ATLprice(int i)
  {
    return((High[i] + Low[i]) / 2.0);
  }
//----
double CalcFATLonMedian(int i)
  {
    double res =
      0.4360409450*ATLprice(i+0) +0.3658689069*ATLprice(i+1) +0.2460452079*ATLprice(i+2) +0.1104506886*ATLprice(i+3)
     -0.0054034585*ATLprice(i+4) -0.0760367731*ATLprice(i+5) -0.0933058722*ATLprice(i+6) -0.0670110374*ATLprice(i+7) -0.0190795053*ATLprice(i+8)
     +0.0259609206*ATLprice(i+9) +0.0502044896*ATLprice(i+10)+0.0477818607*ATLprice(i+11)+0.0249252327*ATLprice(i+12)
     -0.0047706151*ATLprice(i+13)-0.0272432537*ATLprice(i+14)-0.0338917071*ATLprice(i+15)-0.0244141482*ATLprice(i+16)-0.0055774838*ATLprice(i+17)
     +0.0128149838*ATLprice(i+18)+0.0226522218*ATLprice(i+19)+0.0208778257*ATLprice(i+20)+0.0100299086*ATLprice(i+21)
     -0.0036771622*ATLprice(i+22)-0.0136744850*ATLprice(i+23)-0.0160483392*ATLprice(i+24)-0.0108597376*ATLprice(i+25)-0.0016060704*ATLprice(i+26)
     +0.0069480557*ATLprice(i+27)+0.0110573605*ATLprice(i+28)+0.0095711419*ATLprice(i+29)+0.0040444064*ATLprice(i+30)
     -0.0023824623*ATLprice(i+31)-0.0067093714*ATLprice(i+32)-0.0072003400*ATLprice(i+33)-0.0047717710*ATLprice(i+34)
     +0.0005541115*ATLprice(i+35)+0.0007860160*ATLprice(i+36)+0.0130129076*ATLprice(i+37)+0.0040364019*ATLprice(i+38);
    return(res);
  }
//----
double CalcSATLonMedian(int i)
  {
    double res = 0.0982862174*ATLprice(i+0)
      +0.0975682269*ATLprice(i+1) +0.0961401078*ATLprice(i+2) +0.0940230544*ATLprice(i+3) +0.0912437090*ATLprice(i+4) +0.0878391006*ATLprice(i+5)
      +0.0838544303*ATLprice(i+6) +0.0793406350*ATLprice(i+7) +0.0743569346*ATLprice(i+8) +0.0689666682*ATLprice(i+9) +0.0632381578*ATLprice(i+10)
      +0.0572428925*ATLprice(i+11)+0.0510534242*ATLprice(i+12)+0.0447468229*ATLprice(i+13)+0.0383959950*ATLprice(i+14)+0.0320735368*ATLprice(i+15)
      +0.0258537721*ATLprice(i+16)+0.0198005183*ATLprice(i+17)+0.0139807863*ATLprice(i+18)+0.0084512448*ATLprice(i+19)+0.0032639979*ATLprice(i+20)
      -0.0015350359*ATLprice(i+21)-0.0059060082*ATLprice(i+22)-0.0098190256*ATLprice(i+23)-0.0132507215*ATLprice(i+24)-0.0161875265*ATLprice(i+25)
      -0.0186164872*ATLprice(i+26)-0.0205446727*ATLprice(i+27)-0.0219739146*ATLprice(i+28)-0.0229204861*ATLprice(i+29)-0.0234080863*ATLprice(i+30)
      -0.0234566315*ATLprice(i+31)-0.0231017777*ATLprice(i+32)-0.0223796900*ATLprice(i+33)-0.0213300463*ATLprice(i+34)-0.0199924534*ATLprice(i+35)
      -0.0184126992*ATLprice(i+36)-0.0166377699*ATLprice(i+37)-0.0147139428*ATLprice(i+38)-0.0126796776*ATLprice(i+39)-0.0105938331*ATLprice(i+40)
      -0.0084736770*ATLprice(i+41)-0.0063841850*ATLprice(i+42)-0.0043466731*ATLprice(i+43)-0.0023956944*ATLprice(i+44)-0.0005535180*ATLprice(i+45)
      +0.0011421469*ATLprice(i+46)+0.0026845693*ATLprice(i+47)+0.0040471369*ATLprice(i+48)+0.0052380201*ATLprice(i+49)+0.0062194591*ATLprice(i+50)
      +0.0070340085*ATLprice(i+51)+0.0076266453*ATLprice(i+52)+0.0080376628*ATLprice(i+53)+0.0083037666*ATLprice(i+54)+0.0083694798*ATLprice(i+55)
      +0.0082901022*ATLprice(i+56)+0.0080741359*ATLprice(i+57)+0.0077543820*ATLprice(i+58)+0.0073260526*ATLprice(i+59)+0.0068163569*ATLprice(i+60)
      +0.0062325477*ATLprice(i+61)+0.0056078229*ATLprice(i+62)+0.0049516078*ATLprice(i+63)+0.0161380976*ATLprice(i+64); 
    return(res);
  }
//+------------------------------------------------------------------+

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---