// More information about this indicator can be found at:
// https://fxcodebase.com/code/viewtopic.php?f=38&p=147153#p147153

//+------------------------------------------------------------------------------------------------+
//|                                                            Copyright © 2025, Gehtsoft USA LLC  |
//|                                                                         http://fxcodebase.com  |
//+------------------------------------------------------------------------------------------------+
//|                                                              Support our efforts by donating   |
//|                                                                 Paypal: https://goo.gl/9Rj74e  |
//+------------------------------------------------------------------------------------------------+
//|                                                                   Developed by : Mario Jemic   |
//|                                                                       mario.jemic@gmail.com    |
//|                                                        https://AppliedMachineLearning.systems  |
//|                                                             Patreon :  https://goo.gl/GdXWeN   |
//+------------------------------------------------------------------------------------------------+

//Your donations will allow the service to continue onward.
//+------------------------------------------------------------------------------------------------+
//|BitCoin                    : 15VCJTLaz12Amr7adHSBtL9v8XomURo9RF                                 |
//|Ethereum                   : 0x8C110cD61538fb6d7A2B47858F0c0AaBd663068D                         |
//|SOL Address                : 4tJXw7JfwF3KUPSzrTm1CoVq6Xu4hYd1vLk3VF2mjMYh                       |
//|Cardano/ADA                : addr1v868jza77crzdc87khzpppecmhmrg224qyumud6utqf6f4s99fvqv         |
//|Dogecoin Address           : DBGXP1Nc18ZusSRNsj49oMEYFQgAvgBVA8                                 |
//|SHIB Address               : 0x1817D9ebb000025609Bf5D61E269C64DC84DA735                         |
//|Binance(ERC20 & BSC only)  : 0xe84751063de8ade7c5fbff5e73f6502f02af4e2c                         |
//|BitCoin Cash               : 1BEtS465S3Su438Kc58h2sqvVvHK9Mijtg                                 |
//|LiteCoin                   : LLU8PSY2vsq7B9kRELLZQcKf5nJQrdeqwD                                 |
//+------------------------------------------------------------------------------------------------+

#property copyright "Copyright © 2025, Gehtsoft USA LLC"
#property link      "http://fxcodebase.com"
#property version   "1.10"
#property strict

#define EANAME "SSL+Kijun_EA"
string custom_indicator = "ssl-channel-chart-alert-indicator";
string custom_indicator2 = "kijun-sen";
input string is = "==========  Entry Settings  =========="; // ==========  Entry Settings  ==========
input int  Lb           = 10;
enum kijunFilter
  {
   kijunOff = 0,           // Off
   kijunDirect = 1,            // Direct ON
   kijunReverse = 2           // Reverse ON
  };
input kijunFilter kijunFilterMode = kijunOff;     // Kijun-sen filter mode
input int Kijun = 26;
input int KijunShift = 9;
#define CUSTOM_INDICATOR_PARAMS Lb
#define CUSTOM_INDICATOR_PARAMS2 Kijun, KijunShift
#define CUSTOM_INDICATOR_PARAMS3 ""
enum cOpposite
  {
   oppc0 = 0,           // false
   oppc1 = 1            // true
  };
enum eOpposite
  {
   oppe0 = 0,           // false
   oppe1 = 1            // true
  };
enum openPosition
  {
   immediately = 0,     // Immediately
   afterClose = 1,      // After candle closed
   afterClose2 = 2,     // After candle closed + 1 bar
   afterClose3 = 3,     // After candle closed + 2 bars
   afterClose4 = 4,     // After candle closed + 3 bars
   afterClose5 = 5,     // After candle closed + 4 bars
   afterClose6 = 6,     // After candle closed + 5 bars
   afterClose7 = 7,     // After candle closed + 6 bars
   afterClose8 = 8      // After candle closed + 7 bars
  };
enum closeAllBy
  {
   off = 0,             // Off
   pip = 1,             // Pip/point (as set in "Pip/Point Mode" setting)
   currency = 2,        // Deposit currency
   percentage = 3       // Percentage of the equity
  };
enum cMode
  {
   pips = 0,            // Pips
   points = 1           // Points
  };
enum globalPL
  {
   live = 0,            // Running
   liveGrid = 2,        // Running and closed (from the first opened)
  };
enum trailingAndBe
  {
   disabled = 0,                             // Off
   normal = 1                                // On
  };
enum partialClose
  {
   disabledPC = 0,                             // Off
   normalPC = 1                                // On
  };
enum lMode
  {
   lotMoney = 0,                             // Money (depends on exact SL value)
   lotAccountPercent = 1,                    // Percent of equity (depends on exact SL value)
   lotAccountBalance = 2,                    // Percent of balance (depends on exact SL value)
   lotFixLots = 3,                           // Fixed lots
   lotMoneyMargin = 4,                       // Money / margin requirement
   lotPercentMargin = 5                      // Percent / margin requirement
  };
enum slMode
  {
   slOff = 0,                                // Don't use (depends on fixed or margin determined lots)
   slMoney = 1,                              // Money (depends on fixed or margin determined lots)
   slAccountPercent = 2,                     // Percent of equity (depends on fixed or margin determined lots)
   slFix = 3,                                // Pip/point (as set in "Pip/Point Mode" setting)
   slAbsolute = 4,                           // Absolute Value (for buy = value, for sell = value 2)
   slATR = 5,                                // ATR (period = value, multiplicator = value 2)
   slBars = 6,                               // Highest/lowest of (value) bars, +/- (value 2) offset pip/point
   slPricePercent = 7                        // Percent of price
  };
enum tpMode
  {
   tpOff = 0,                                // Don't use (depends on fixed or margin determined lots)
   tpMoney = 1,                              // Money (depends on fixed or margin determined lots)
   tpAccountPercent = 2,                     // Percent of equity (depends on fixed or margin determined lots)
   tpFix = 3,                                // Pip/point (as set in "Pip/Point Mode")
   tpPricePercent = 7,                       // Percent of price
   tpAbsolute = 4,                           // Absolute Value (for buy = value, for sell = value 2)
   tpATR = 5,                                // ATR (period = value, multiplicator = value 2)
   tpBars = 6,                               // Highest /lowest of (value) bars, +/- (value 2) offset pip/point
   tpSlRatio = 100                           // Stop loss distance ratio (R:R)
  };
enum entlogic
  {
   Direct = 0,
   Reversal = 1
  };
enum ENUM_timeZone
  {
   timeGMT = 0,                              // GMT
   timeLocal = 1,                            // Local
   timeCurrent = 2                           // Server
  };
enum ModeEntry
  {
   Market
  };

input string ea = "==========  EA Settings  =========="; // ==========  EA Settings  ==========
input string inpEAName = EANAME;             // Custom comment / EA name (max. 16 characters)
string EAName = StringSubstr(inpEAName, 0, 15);
input int slp = 30;                          // Slippage in points
input cMode calcMode = 0;                    // Pip/Point mode (for SL, TP, etc.)
input int MagicNumber = 3535;                // Magic number
input bool ecn_broker = false;               // ECN Broker?
input bool alertAlgoOff = true;              // Alert when signal but Auto Trading off
input openPosition whenOpen = 1;             // Open position at
int posDir = 0;
input  entlogic entryLogic = 0;              // Entry logic
input cOpposite closeAtOpposite = true;           // Close position at opposite signal
ModeEntry modeEntry = Market;
bool deletePendingOnCloseAll = false;
input string mp = "==========  Max Positions at Same Time  =========="; // ==========  Max Positions at Same Time  ==========
input int maxPos = 2;                        // Max sell-buy positions at same time (0=unlimited)
input int maxBuyPos = 1;                     // Max buy positions at same time (0=unlimited)
input int maxSellPos = 1;                    // Max sell positions at same time (0=unlimited)
input string ps = "==========  Position Size Settings  =========="; // ==========  Position Size Settings  ==========
input lMode lotMode = 3;                     // Lot calculation mode
input double Lot = 0.01;                     // Lot value (as set in "Lot calculation mode")
input double maxLot = 1.00;                  // Maximum size of lots (All positions)
input string sltp = "==========  SL / TP Settings  =========="; // ==========  SL / TP Settings  ==========
input slMode SlMode = 3;                     // SL by
input double SlVal = 40;                     // SL value
input double SlVal2 = 1;                     // SL value 2 (if required in the "SL by" setting
input double SlMin = 10;                     // Min SL distance pip/point (as set in "Pip/Point mode")
input tpMode TpMode = 3;                     // TP by
input double TpVal = 40;                     // TP value
input double TpVal2 = 1;                     // TP value 2 (if required in the "TP by" setting)
input double TpMin = 10;                     // Min TP distance pip/point (as set in "Pip/Point mode")
input bool addSpread = true;                 // Add current spread to SL/TP calculation
input string tsl = "==========  Trailing Stop  =========="; // ==========  Trailing Stop  ==========
input trailingAndBe trailing_sl = 0;         // Trailing stop loss
input double trailing_stop_start = 20;       // Trailing stop loss start
input double trailing_stop_dist = 40;        // Trailing stop loss distance
input double trailing_stop_step = 5;         // Trailing stop loss step
input string bev = "==========  Breakeven =========="; // ==========  Breakeven  ==========
input trailingAndBe be = 0;                  // Breakeven
input double be_trigger = 10;                // Beakeven trigger
input double be_level = 0;                   // Breakeven target
input string ts = "==========  Trading Session  =========="; // ==========  Trading Session  ==========
input ENUM_timeZone timeZone = timeGMT;      // Time zone
input string startTime = "00:00";            // Start time (hh:mm)
input string finishTime = "00:00";           // Finish time (hh:mm)
input bool mandatoryClose = false;           // Mandatory Close all positions at the end of session
bool initOK = true;
string symbols[];

int globalCalcMode = 0;

#define MT4_WMCMD_EXPERTS 33020
int OnInit()
  {
   if(!MQLInfoInteger(MQL_TRADE_ALLOWED))
      Alert("Automated trading is disabled in the settings.");
   EAName = StringSubstr(inpEAName, 0, 16);
   ArrayResize(symbols, 1);
   symbols[0] = Symbol();
   ResetLastError();
   if(custom_indicator != "")
     {
      double temp = iCustom(NULL, 0, custom_indicator, CUSTOM_INDICATOR_PARAMS, 0, 0);
      if(GetLastError() == ERR_INDICATOR_CANNOT_LOAD)
        {
         Alert("Please install the: " + custom_indicator + " indicator to the MQL4/Indicators folder");
         initOK = false;
        }
     }
   ResetLastError();
   if(custom_indicator2 != "")
     {
      double temp = iCustom(NULL, 0, custom_indicator2, CUSTOM_INDICATOR_PARAMS2, 0, 0);
      if(GetLastError() == ERR_INDICATOR_CANNOT_LOAD)
        {
         Alert("Please install the: " + custom_indicator2 + " indicator to the MQL4/Indicators folder");
         initOK = false;
        }
     }
   if(lotMode < 3 && SlMode < 3)
     {
      Alert("Incompatible \"Lot calculation mode\" and \"Stop loss by\" settings. Please check the dependencies.");
      initOK = false;
     }
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OP(string sym, int entrysig = 0, double lot = 0.0, double price = 0.0, double slPrice = 0.0, double tpPrice = 0.0)
  {
   if(!trade)
      return;
   int logic = entryLogic;
   int ticket = 0;
   string orderComment = EAName;
   int multi = multi(sym);
   int dig = (int)MarketInfo(sym, MODE_DIGITS);
   double sLevel = MarketInfo(sym, MODE_STOPLEVEL);
   double poi = MarketInfo(sym, MODE_POINT);
   double bid = MarketInfo(sym, MODE_BID);
   double ask = MarketInfo(sym, MODE_ASK);
   double spread = MarketInfo(sym, MODE_SPREAD);
   int entrySignal;
   if(entrysig == 0)
      entrySignal = checkEntry(whenOpen, sym);
   else
      entrySignal = entrysig;
   if((entrySignal > 0 && logic == 0) || (entrySignal < 0 && logic == 1))
     {
      if(alertAlgoOff && !TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
         Alert(EAName + ": Auto Trading turned OFF");
      if(posDir == 2)
         return;
      if(numberOfPositions(2, sym, entrySignal * (-1)) > 0 && closeAtOpposite == 2)
         closeAll(2, sym, entrysig * (-1));
      if(closeAtOpposite == 1)
         closeAll(2, sym);
      if((numberOfPositions(1, sym) < maxBuyPos || maxBuyPos == 0) &&
         (numberOfPositions(0, sym) < maxPos || maxPos == 0)  && lastOpenedPosition(1, sym) < Time[0])
        {
         if(numberOfPositions(0, "") == 0)
            orderComment += "_fp";
         orderComment += "_ip(" + (string)entrySignal + ")#" + (string)(numberOfPositions(1, sym) + 1);
         ResetLastError();
         RefreshRates();
         if(modeEntry == Market)
            price = ask;
         if(slPrice == 0.0)
            slPrice = calcSL(1, price, sym, Lot);
         else
            slPrice = NormalizeDouble(MathMin(slPrice, ask - sLevel * poi), Digits());
         if(tpPrice == 0.0)
            tpPrice = calcTP(1, price, sym, Lot, slPrice);
         else
            tpPrice = NormalizeDouble(MathMax(tpPrice, ask + sLevel * poi), Digits());
         if(lot == 0.0)
            lot = calcLot(1, sym, slPrice);
         else
            lot = calcLot(0, sym, lot);
         price = NormalizeDouble(price, Digits());
         if(modeEntry == Market)
           {
            if(ecn_broker)
              {
               ticket = OrderSend(sym, OP_BUY, lot, price, slp, 0, 0, orderComment, MagicNumber, 0, clrGreen);
               ticket = OrderModify(ticket, OrderOpenPrice(), slPrice, tpPrice, 0, 0);
              }
            else
              {
               ticket = OrderSend(sym, OP_BUY, lot, price, slp, slPrice, tpPrice, orderComment, MagicNumber, 0, clrGreen);
              }
           }
         if(ticket < 0)
           {
            Alert(EAName + ":OrderSend PENDING BUY on " + sym + " failed with error #", GetLastError(),
                  " lot: " + DoubleToString(lot, 2) +
                  " price: " + DoubleToString(ask, dig) +
                  " sl: " + DoubleToString(slPrice, dig) +
                  " tp: " + DoubleToString(tpPrice, dig));
           }
        }
     }
   if((entrySignal < 0 && logic == 0) || (entrySignal > 0 && logic == 1))
     {
      if(posDir == 1)
         return;
      if(numberOfPositions(1, sym, entrySignal * (-1)) > 0 && closeAtOpposite == 2)
         closeAll(1, sym, entrysig * (-1));
      if(closeAtOpposite == 1)
         closeAll(1, sym);
      if((numberOfPositions(2, sym)  < maxSellPos || maxSellPos == 0) &&
         (numberOfPositions(0, sym) < maxPos || maxPos == 0) && lastOpenedPosition(2, sym) < Time[0])
        {
         if(numberOfPositions(0, "") == 0)
            orderComment += "_fp";
         orderComment += "_ip(" + (string)entrySignal + ")#" + (string)(numberOfPositions(2, sym) + 1);
         ResetLastError();
         RefreshRates();
         if(modeEntry == Market)
            price = bid;
         if(slPrice == 0.0)
            slPrice = calcSL(2, price, sym, Lot);
         else
            slPrice = NormalizeDouble(MathMax(slPrice, bid + sLevel * poi), Digits());
         if(tpPrice == 0.0)
            tpPrice = calcTP(2, price, sym, Lot, slPrice);
         else
            tpPrice = NormalizeDouble(MathMin(tpPrice, bid - sLevel * poi), Digits());
         if(lot == 0.0)
            lot = calcLot(2, sym, slPrice);
         else
            lot = calcLot(0, sym, lot);
         price = NormalizeDouble(price, Digits());
         if(modeEntry == Market)
           {
            if(ecn_broker)
              {
               ticket = OrderSend(sym, OP_SELL, lot, price, slp, 0, 0, orderComment, MagicNumber, 0, clrRed);
               ticket = OrderModify(ticket, OrderOpenPrice(), slPrice, tpPrice, 0, 0);
              }
            else
              {
               ticket = OrderSend(sym, OP_SELL, lot, price, slp, slPrice, tpPrice, orderComment, MagicNumber, 0, clrRed);
              }
           }
         if(ticket < 0)
           {
            Alert(EAName + ": OrderSend SELL on " + sym + " failed with error #", GetLastError(),
                  " lot: " + DoubleToString(lot, 2) +
                  " price: " + DoubleToString(bid, dig) +
                  " sl: " + DoubleToString(slPrice, dig) +
                  " tp: " + DoubleToString(tpPrice, dig));
           }
        }
     }
  }

bool trade = true;
void OnTick()
  {
   if(!initOK)
      return;
   bool newBar = IsNewBar();
   trade = checkTime();
   if(mandatoryClose && !trade)
      closeAll(0, "");
   int whenClose = 1;
   if((whenOpen > 0 && newBar) || (whenOpen == 0))
     {
      for(int i = 0; i < ArraySize(symbols); i++)
        {
         string sym = symbols[i];
         if(posLastOpened(sym) < Time[0])
            OP(sym);
        }
     }
   if(mandatoryClose && !checkTime())
     {
      closeAll(0, "");
     }
   if(trailing_sl > 0)
      SetTrailingStop();
   if(be > 0)
      SetBreakeven();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double calcSL(int dir, double p, string sym, double lot)
  {
   int dig = (int)MarketInfo(sym, MODE_DIGITS);
   double sLevel = MarketInfo(sym, MODE_STOPLEVEL);
   double poi = MarketInfo(sym, MODE_POINT);
   double spread = MarketInfo(sym, MODE_SPREAD);
   double tickval = MarketInfo(sym, MODE_TICKVALUE);
   double eq = AccountInfoDouble(ACCOUNT_EQUITY);
   double val = 0.0;
   int bar = 0;
   double aSpread = 0.0;
   if(addSpread)
      aSpread = (spread * poi);
   if(SlMode == 1)
     {
      val = MathMax(((SlVal * pipc(sym)) / (tickval * Lot)), (sLevel + spread + slp) * poi);
      val = MathMax(SlMin * pipc(sym), val) + aSpread;
      if(dir == 1)
         return NormalizeDouble(p - val, dig);
      if(dir == 2)
         return NormalizeDouble(p + val, dig);
     }
   if(SlMode == 2)
     {
      val = MathMax((((eq * SlVal * 0.01) * pipc(sym)) / (tickval * Lot)), (sLevel + spread + slp) * poi);
      val = MathMax(SlMin * pipc(sym), val) + aSpread;
      if(dir == 1)
         return NormalizeDouble(p - val, dig);
      if(dir == 2)
         return NormalizeDouble(p + val, dig);
     }
   if(SlMode == 3)
     {
      val = MathMax(SlVal * multi(sym), sLevel + spread + slp) * poi;
      val = MathMax(SlMin * pipc(sym), val) + aSpread;
      if(dir == 1)
         return NormalizeDouble(p - val, dig);
      if(dir == 2)
         return NormalizeDouble(p + val, dig);
     }
   if(SlMode == 4)
     {
      val = SlMin * pipc(sym);
      if(dir == 1)
         return NormalizeDouble(MathMin(SlVal, p - val), dig);
      if(dir == 2)
         return NormalizeDouble(MathMax(SlVal, p + val), dig);
     }
   if(SlMode == 5)
     {
      val = MathMax(iATR(sym, Period(), (int)SlVal, 1) * SlVal2, (sLevel + spread + slp) * poi);
      val = MathMax(SlMin * pipc(sym), val) + aSpread;
      if(dir == 1)
         return NormalizeDouble(p - val, dig);
      if(dir == 2)
         return NormalizeDouble(p + val, dig);
     }
   if(SlMode == 6)
     {
      if(dir == 1)
        {
         bar = iLowest(sym, Period(), MODE_LOW, (int)SlVal, 0);
         val = MathMin(p - MathMax((sLevel + spread + slp) * poi, SlMin * pipc(sym)), (iLow(sym, Period(), bar) + aSpread) - SlVal2 * pipc(sym) - spread * poi);
         return NormalizeDouble(val, dig);
        }
      if(dir == 2)
        {
         bar = iHighest(sym, Period(), MODE_HIGH, (int)SlVal, 0);
         val = MathMax(p + MathMax((sLevel + spread + slp) * poi, SlMin * pipc(sym)), (iHigh(sym, Period(), bar) + aSpread) + SlVal2 * pipc(sym) + spread * poi);
         return NormalizeDouble(val, dig);
        }
     }
   if(SlMode == 7)
     {
      val = MathMax((p * (SlVal / 100)) * pipc(sym), sLevel + spread + slp) * poi;
      val = MathMax(SlMin * pipc(sym), val) + aSpread;
      if(dir == 1)
         return NormalizeDouble(p - val, dig);
      if(dir == 2)
         return NormalizeDouble(p + val, dig);
     }
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double calcTP(int dir, double p, string sym, double lot, double slprice)
  {
   int dig = (int)MarketInfo(sym, MODE_DIGITS);
   double sLevel = MarketInfo(sym, MODE_STOPLEVEL);
   double poi = MarketInfo(sym, MODE_POINT);
   double spread = MarketInfo(sym, MODE_SPREAD);
   double tickval = MarketInfo(sym, MODE_TICKVALUE);
   double eq = AccountInfoDouble(ACCOUNT_EQUITY);
   double val = 0.0;
   double aSpread = 0.0;
   if(addSpread)
      aSpread = (spread * poi);
   int bar = 0;
   if(TpMode == 1)
     {
      val = MathMax(((TpVal * pipc(sym)) / (tickval * Lot)), (sLevel + spread + slp) * poi);
      val = MathMax(TpMin * pipc(sym), val) + aSpread;
      if(dir == 1)
         return NormalizeDouble(p + val, dig);
      if(dir == 2)
         return NormalizeDouble(p - val, dig);
     }
   if(TpMode == 2)
     {
      val = MathMax((((eq * TpVal * 0.01) * pipc(sym)) / (tickval * Lot)), (sLevel + spread + slp) * poi);
      val = MathMax(TpMin * pipc(sym), val) + aSpread;
      if(dir == 1)
         return NormalizeDouble(p + val, dig);
      if(dir == 2)
         return NormalizeDouble(p - val, dig);
     }
   if(TpMode == 3)
     {
      val = MathMax(TpVal * multi(sym), sLevel + spread + slp) * poi;
      val = MathMax(TpMin * pipc(sym), val) + aSpread;
      if(dir == 1)
         return NormalizeDouble(p + val, dig);
      if(dir == 2)
         return NormalizeDouble(p - val, dig);
     }
   if(TpMode == 4)
     {
      val = TpMin * pipc(sym);
      if(dir == 1)
         return NormalizeDouble(TpVal, dig);
      if(dir == 2)
         return NormalizeDouble(TpVal2, dig);
     }
   if(TpMode == 5)
     {
      val = MathMax(iATR(sym, Period(), (int)TpVal, 1) * TpVal2, (sLevel + spread + slp) * poi);
      val = MathMax(TpMin * pipc(sym), val + aSpread);
      if(dir == 1)
         return NormalizeDouble(p + val, dig);
      if(dir == 2)
         return NormalizeDouble(p - val, dig);
     }
   if(TpMode == 6)
     {
      if(dir == 1)
        {
         bar = iHighest(sym, Period(), MODE_HIGH, (int)TpVal, 0);
         val = MathMax(p + MathMax((sLevel + spread + slp) * poi, TpMin * pipc(sym)), (iHigh(sym, Period(), bar) + aSpread) + TpVal2 * pipc(sym) + spread * poi);
         return NormalizeDouble(val, dig);
        }
      if(dir == 2)
        {
         bar = iLowest(sym, Period(), MODE_LOW, (int)TpVal, 0);
         val = MathMin(p - MathMax((sLevel + spread + slp) * poi, TpMin * pipc(sym)), (iLow(sym, Period(), bar) + aSpread) - TpVal2 * pipc(sym) - spread * poi);
         return NormalizeDouble(val, dig);
        }
     }
   if(TpMode == 7)
     {
      val = MathMax((p * (TpVal / 100)) * pipc(sym), sLevel + spread + slp) * poi;
      val = MathMax(TpMin * pipc(sym), val) + aSpread;
      if(dir == 1)
         return NormalizeDouble(p + val, dig);
      if(dir == 2)
         return NormalizeDouble(p - val, dig);
     }
   if(TpMode == 100 && slprice > 0.0)
     {
      if(dir == 1)
        {
         return NormalizeDouble(p + (p - slprice) * TpVal, dig);
        }
      if(dir == 2)
        {
         return NormalizeDouble(p - (slprice - p) * TpVal, dig);
        }
     }
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double PLOfPositions(int mode, int dir, string sym)
  {
   double countPip = 0.0;
   double countCur = 0.0;
   for(int pos = OrdersTotal() - 1; pos >= 0 ; pos--)
     {
      bool s = OrderSelect(pos, SELECT_BY_POS, MODE_TRADES);
      string ordersym = OrderSymbol();
      string comment = OrderComment();
      if((ordersym == sym || sym == "") && OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0)
        {
         if(OrderType() == OP_BUY)
            if(dir == 1 || dir == 0)
              {
               countPip += (MarketInfo(ordersym, MODE_BID) - OrderOpenPrice()) / pipc(ordersym);
               countCur += OrderProfit();
              }
         if(OrderType() == OP_SELL)
            if(dir == 2 || dir == 0)
              {
               countPip += (OrderOpenPrice() - MarketInfo(ordersym, MODE_ASK)) / pipc(ordersym);
               countCur += OrderProfit();
              }
        }
     }
   if(mode == 1)
      return countPip;
   if(mode == 2)
      return countCur;
   if(mode == 3 && countCur != 0 && AccountEquity() != 0)
      return 1 / (AccountEquity() * countCur) * 100;
   return countCur;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double PLOfPositionsHistory(int mode, int dir, string sym, datetime from)
  {
   double countPip = 0.0;
   double countCur = 0.0;
   for(int pos = OrdersHistoryTotal() - 1; pos >= 0 ; pos--)
     {
      bool s = OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY);
      string ordersym = OrderSymbol();
      datetime openTime = OrderOpenTime();
      string comment = OrderComment();
      if((ordersym == sym || sym == "") && OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0 && openTime >= from)
        {
         if(OrderType() == OP_BUY)
            if(dir == 1 || dir == 0)
              {
               countPip += (MarketInfo(ordersym, MODE_BID) - OrderOpenPrice()) / pipc(ordersym);
               countCur += OrderProfit();
              }
         if(OrderType() == OP_SELL)
            if(dir == 2 || dir == 0)
              {
               countPip += (OrderOpenPrice() - MarketInfo(ordersym, MODE_ASK)) / pipc(ordersym);
               countCur += OrderProfit();
              }
        }
     }
   if(mode == 1)
      return countPip;
   if(mode == 2)
      return countCur;
   if(mode == 3 && countCur != 0 && AccountEquity() != 0)
      return 1 / (AccountEquity() * countCur) * 100;
   return countCur;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime findFirstPosDate()
  {
   datetime firstPos = 0;
   for(int pos = OrdersTotal() - 1; pos >= 0 ; pos--)
     {
      bool s = OrderSelect(pos, SELECT_BY_POS, MODE_TRADES);
      string comment = OrderComment();
      datetime openTime = OrderOpenTime();
      if(OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0 && StringFind(comment, "_fp", 0) >= 0)
        {
         return openTime;
        }
     }
   for(int pos = OrdersHistoryTotal() - 1; pos >= 0 ; pos--)
     {
      bool s = OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY);
      string comment = OrderComment();
      datetime openTime = OrderOpenTime();
      if(OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0 && StringFind(comment, "_fp", 0) >= 0)
        {
         if(openTime > firstPos)
            firstPos = openTime;
        }
     }
   return firstPos;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool checkTime()
  {
   datetime curTime = TimeGMT();
   if(timeZone == timeGMT)
      curTime = TimeGMT();
   if(timeZone == timeLocal)
      curTime = TimeLocal();
   if(timeZone == timeCurrent)
      curTime = TimeCurrent();
   datetime s_time = StringToTime(TimeToString(curTime, TIME_DATE) + " " + startTime);
   datetime f_time = StringToTime(TimeToString(curTime, TIME_DATE) + " " + finishTime);
   if((startTime == "00:00" || startTime == "0") && (finishTime == "00:00" || finishTime == "0"))
      return true;
   if(curTime >=  s_time && curTime < f_time)
      return true;
   return false;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double pipc(string sy)
  {
   sy == "" ? sy = Symbol() :;
   double po = MarketInfo(sy, MODE_POINT);
   int di = (int)MarketInfo(sy, MODE_DIGITS);
   if(calcMode == 1)
     {
      return po;
     }
   return (di % 2 == 1 ? po * 10 : po);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int multi(string sy)
  {
   sy == "" ? sy = Symbol() :;
   if(calcMode == 1)
     {
      return 1;
     }
   int di = (int)MarketInfo(sy, MODE_DIGITS);
   return (di % 2 == 1 ? 10 : 1);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsNewBar()
  {
   static datetime lastbar;
   datetime curbar = (datetime)SeriesInfoInteger(_Symbol, _Period, SERIES_LASTBAR_DATE);
   if(lastbar != curbar)
     {
      lastbar = curbar;
      return true;
     }
   return false;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsNewDay()
  {
   static datetime lastday;
   datetime curday = (datetime)iTime(Symbol(), PERIOD_D1, 0);
   if(lastday != curday)
     {
      lastday = curday;
      return true;
     }
   return false;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void alertMessage(string msg)
  {
   if(msg == "")
     {
      ObjectDelete(0, EAName + "_message");
      return;
     }
   ObjectCreate(0, EAName + "_message", OBJ_LABEL, 0, 0, 0);
   ObjectSetInteger(0, EAName + "_message", OBJPROP_CORNER, CORNER_RIGHT_LOWER);
   ObjectSetInteger(0, EAName + "_message", OBJPROP_ANCHOR, ANCHOR_RIGHT_LOWER);
   ObjectSetInteger(0, EAName + "_message", OBJPROP_XDISTANCE, 20);
   ObjectSetInteger(0, EAName + "_message", OBJPROP_YDISTANCE, 20);
   ObjectSetInteger(0, EAName + "_message", OBJPROP_BACK, false);
   ObjectSetString(0, EAName + "_message", OBJPROP_TEXT, msg);
   ObjectSetString(0, EAName + "_message", OBJPROP_FONT, "Arial");
   ObjectSetInteger(0, EAName + "_message", OBJPROP_COLOR, clrRed);
   ObjectSetInteger(0, EAName + "_message", OBJPROP_FONTSIZE, 20);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime posLastOpened(string sym, int fp = 0, int dir = 0)
  {
   datetime maxDate = 0;
   datetime openDate = 0;
   for(int pos = OrdersTotal() - 1; pos >= 0; pos--)
     {
      bool s = OrderSelect(pos, SELECT_BY_POS, MODE_TRADES);
      ulong ticket = OrderTicket();
      string comment = OrderComment();
      openDate = OrderOpenTime();
      if(OrderSymbol() == sym && OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0 && StringFind(comment, "_ip(", 0) >= 0)
        {
         if(dir == 0 || (dir == 1 && OrderType() == OP_BUY) || (dir == 2 && OrderType() == OP_SELL))
            if(fp == 0 || StringFind(comment, "_ip(" + (string)fp + ")", 0) >= 0)
               maxDate = MathMax(maxDate, openDate);
        }
     }
   for(int pos = OrdersHistoryTotal() - 1; pos >= 0; pos--)
     {
      bool s = OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY);
      ulong ticket = OrderTicket();
      string comment = OrderComment();
      openDate = OrderOpenTime();
      if(dir == 0 || (dir == 1 && OrderType() == OP_BUY) || (dir == 2 && OrderType() == OP_SELL))
         if(fp == 0 || StringFind(comment, "_ip(" + (string)fp + ")", 0) >= 0)
            maxDate = MathMax(maxDate, openDate);
     }
   return maxDate;
  }


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int numberOfPositions(int dir, string sym, int fp = 0, bool pending = false)
  {
   int countPos = 0;
   for(int pos = OrdersTotal() - 1; pos >= 0 ; pos--)
     {
      bool s = OrderSelect(pos, SELECT_BY_POS, MODE_TRADES);
      string comment = OrderComment();
      if((OrderSymbol() == sym || sym == "") && OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0 && (StringFind(comment, "_ip", 0) >= 0 || StringFind(comment, "from", 0) >= 0))
        {
         if(StringFind(comment, "_gr#", 0) >= 0)
            continue;
         if(fp == 0 || StringFind(comment, "_ip(" + (string)fp + ")", 0) >= 0)
           {
            if(OrderType() == OP_BUY)
               if(dir == 1 || dir == 0)
                  countPos++;
            if(OrderType() == OP_SELL)
               if(dir == 2 || dir == 0)
                  countPos++;
            if(pending)
              {
               if(OrderType() == OP_BUYLIMIT || OrderType() == OP_BUYSTOP)
                  if(dir == 1 || dir == 0)
                     countPos++;
               if(OrderType() == OP_SELLLIMIT || OrderType() == OP_SELLSTOP)
                  if(dir == 2 || dir == 0)
                     countPos++;
              }
           }
        }
     }
   return countPos;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double lastOpenedPositionPL(int dir, string sym, bool hist = false)
  {
   datetime maxDate  = 0;
   datetime openDate = 0;
   double   pl       = 0.0;
   bool s;
   for(int pos = OrdersTotal() - 1; pos >= 0; pos--)
     {
      s = OrderSelect(pos, SELECT_BY_POS, MODE_TRADES);
      if((OrderSymbol() == sym || sym == "") && OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0)
        {
         openDate = OrderOpenTime();
         if(OrderType() == OP_BUY)
           {
            if(dir == 1 || dir == 0)
              {
               if(openDate > maxDate)
                 {
                  maxDate = openDate;
                  pl      = OrderProfit();
                 }
              }
           }
         if(OrderType() == OP_SELL)
           {
            if(dir == 2 || dir == 0)
              {
               if(openDate > maxDate)
                 {
                  maxDate = openDate;
                  pl      = OrderProfit();
                 }
              }
           }
        }
     }
   if(hist)
     {
      for(int pos = OrdersHistoryTotal() - 1; pos >= 0; pos--)
        {
         s = OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY);
         if((OrderSymbol() == sym || sym == "") && OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0)
           {
            openDate = OrderOpenTime();
            if(OrderType() == OP_BUY)
              {
               if(dir == 1 || dir == 0)
                 {
                  if(openDate > maxDate)
                    {
                     maxDate = openDate;
                     pl      = OrderProfit();
                    }
                 }
              }
            if(OrderType() == OP_SELL)
              {
               if(dir == 2 || dir == 0)
                 {
                  if(openDate > maxDate)
                    {
                     maxDate = openDate;
                     pl      = OrderProfit();
                    }
                 }
              }
           }
        }
     }
   return pl;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime lastOpenedPosition(int dir, string sym, bool hist = false)
  {
   datetime maxDate  = 0;
   datetime openDate = 0;
   bool s;
   for(int pos = OrdersTotal() - 1; pos >= 0; pos--)
     {
      s = OrderSelect(pos, SELECT_BY_POS, MODE_TRADES);
      if((OrderSymbol() == sym || sym == "") && OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0)
        {
         openDate = OrderOpenTime();
         if(OrderType() == OP_BUY)
            if(dir == 1 || dir == 0)
               maxDate = MathMax(maxDate, openDate);
         if(OrderType() == OP_SELL)
            if(dir == 2 || dir == 0)
               maxDate = MathMax(maxDate, openDate);
        }
     }
   if(hist)
     {
      for(int pos = OrdersHistoryTotal() - 1; pos >= 0; pos--)
        {
         s = OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY);
         if((OrderSymbol() == sym || sym == "") && OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0)
           {
            openDate = OrderOpenTime();
            if(OrderType() == OP_BUY)
               if(dir == 1 || dir == 0)
                  maxDate = MathMax(maxDate, openDate);
            if(OrderType() == OP_SELL)
               if(dir == 2 || dir == 0)
                  maxDate = MathMax(maxDate, openDate);
           }
        }
     }
   return maxDate;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime lastDailyClosedPosition(int dir, string sym)
  {
   datetime maxDate = 0;
   datetime closeDate = 0;
   for(int pos = OrdersTotal() - 1; pos >= 0 ; pos--)
     {
      bool s = OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY);
      if((OrderSymbol() == sym || sym == "") && OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0)
        {
         closeDate = OrderCloseTime();
         if(OrderType() == OP_BUY && closeDate > iTime(sym, PERIOD_D1, 0))
            if(dir == 1 || dir == 0)
               maxDate = MathMax(maxDate, closeDate);
         if(OrderType() == OP_SELL && closeDate > iTime(sym, PERIOD_D1, 0))
            if(dir == 2 || dir == 0)
               maxDate = MathMax(maxDate, closeDate);
        }
     }
   return maxDate;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void closeAll(int dir, string sym, int fp = 0)
  {
   int succ;
   for(int pos = OrdersTotal() - 1; pos >= 0 ; pos--)
     {
      bool s = OrderSelect(pos, SELECT_BY_POS);
      string symbol = OrderSymbol();
      string comment = OrderComment();
      RefreshRates();
      ResetLastError();
      if((symbol == sym || sym == "") && OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0)
        {
         if(dir == 0 || (dir == 1 && OrderType() == OP_BUY) || (dir == 2 && OrderType() == OP_SELL))
           {
            if(fp == 0 || StringFind(comment, "_ip(" + (string)fp + ")", 0) >= 0)
              {
               succ = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), slp, 0);
               if(succ < 0)
                 {
                  Alert(EAName + ": OrderClose on " + sym + " failed with error #", GetLastError());
                 }
              }
           }
        }
     }
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void SetTrailingStop()
  {
   int  succ;
   string sym, comment;
   double buyTrailingStop, sellTrailingStop;
   for(int pos = OrdersTotal() - 1; pos >= 0; pos--)
     {
      bool s = OrderSelect(pos, SELECT_BY_POS);
      if(OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0)
        {
         ResetLastError();
         RefreshRates();
         sym = OrderSymbol();
         comment = OrderComment();
         if(StringFind(comment, "_gr#", 0) >= 0 && trailing_sl < 2)
            continue;
         if(OrderType() == OP_BUY)
           {
            buyTrailingStop = MathMin(MarketInfo(sym, MODE_BID) - trailing_stop_dist * pipc(sym), MarketInfo(sym, MODE_BID) - MarketInfo(sym, MODE_STOPLEVEL) * MarketInfo(sym, MODE_POINT));
            buyTrailingStop = NormalizeDouble(buyTrailingStop, (int)MarketInfo(sym, MODE_DIGITS));
            if(buyTrailingStop - trailing_stop_step * pipc(sym) > OrderStopLoss() && MarketInfo(sym, MODE_BID) - OrderOpenPrice() > trailing_stop_start * pipc(sym))
              {
               succ = OrderModify(OrderTicket(), OrderOpenPrice(), buyTrailingStop, OrderTakeProfit(), 0);
               if(succ < 0)
                 {
                  Alert(EAName + " (" + OrderSymbol() + " SL_MODIFY): OrderSend on " + sym + " failed with error #", (string)GetLastError());
                 }
              }
           }
         if(OrderType() == OP_SELL)
           {
            sellTrailingStop = MathMax(MarketInfo(sym, MODE_ASK) + trailing_stop_dist * pipc(sym), MarketInfo(sym, MODE_ASK) + MarketInfo(sym, MODE_STOPLEVEL) * MarketInfo(sym, MODE_POINT));
            sellTrailingStop = NormalizeDouble(sellTrailingStop, (int)MarketInfo(sym, MODE_DIGITS));
            if(sellTrailingStop + trailing_stop_step * pipc(sym) < (OrderStopLoss() == 0 ? OrderOpenPrice() + trailing_stop_dist * pipc(sym) : OrderStopLoss()) &&
               OrderOpenPrice() - MarketInfo(sym, MODE_ASK) > trailing_stop_start * pipc(sym))
              {
               succ = OrderModify(OrderTicket(), OrderOpenPrice(), sellTrailingStop, OrderTakeProfit(), 0);
               if(succ < 0)
                 {
                  Alert(EAName + " (" + OrderSymbol() + " SL_MODIFY): OrderSend on " + sym + " failed with error #", (string)GetLastError());
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void SetBreakeven()
  {
   int  succ;
   string sym, comment;
   double buySL, sellSL;
   for(int pos = OrdersTotal() - 1; pos >= 0; pos--)
     {
      bool s = OrderSelect(pos, SELECT_BY_POS);
      if(OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0)
        {
         ResetLastError();
         RefreshRates();
         sym = OrderSymbol();
         comment = OrderComment();
         if(StringFind(comment, "_gr#", 0) >= 0 && be < 2)
            continue;
         if(OrderType() == OP_BUY)
           {
            buySL = MathMin(OrderOpenPrice() + be_level * pipc(sym), MarketInfo(sym, MODE_BID) - MarketInfo(sym, MODE_STOPLEVEL) * MarketInfo(sym, MODE_POINT));
            buySL = NormalizeDouble(buySL, (int)MarketInfo(sym, MODE_DIGITS));
            if(buySL > OrderStopLoss() && MarketInfo(sym, MODE_BID) > OrderOpenPrice() + be_trigger * pipc(sym))
              {
               succ = OrderModify(OrderTicket(), OrderOpenPrice(), buySL, OrderTakeProfit(), 0);
               if(succ < 0)
                 {
                  Alert(EAName + " (" + OrderSymbol() + " Breakeven): OrderSend on " + sym + " failed with error #", (string)GetLastError());
                 }
              }
           }
         if(OrderType() == OP_SELL)
           {
            sellSL = MathMax(OrderOpenPrice() - be_level * pipc(sym), MarketInfo(sym, MODE_ASK) + MarketInfo(sym, MODE_STOPLEVEL) * MarketInfo(sym, MODE_POINT));
            sellSL = NormalizeDouble(sellSL, (int)MarketInfo(sym, MODE_DIGITS));
            if(sellSL < OrderStopLoss() && MarketInfo(sym, MODE_ASK) < OrderOpenPrice() - be_trigger * pipc(sym))
              {
               succ = OrderModify(OrderTicket(), OrderOpenPrice(), sellSL, OrderTakeProfit(), 0);
               if(succ < 0)
                 {
                  Alert(EAName + " (" + OrderSymbol() + " Breakeven): OrderSend on " + sym + " failed with error #", (string)GetLastError());
                 }
              }
           }
        }
     }
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double calcLot(int dir, string sym, double priceLotVal)
  {
   double tickValue = SymbolInfoDouble(sym, SYMBOL_TRADE_TICK_VALUE);
   double step = SymbolInfoDouble(sym, SYMBOL_VOLUME_STEP);
   double poi = MarketInfo(sym, MODE_POINT);
   double ask =  SymbolInfoDouble(sym, SYMBOL_ASK);
   double bid =  SymbolInfoDouble(sym, SYMBOL_BID);
   double minlot = MarketInfo(sym, MODE_MINLOT);
   double maxlot = MarketInfo(sym, MODE_MAXLOT);
   double marginReq = MathMax(MarketInfo(sym, MODE_MARGINREQUIRED), 0.001);
   double maxlotMargin = (AccountEquity() / marginReq) * 0.95;
   double final_lot = minlot;
   double distance = 0.0, risk = 0.0, val = 0.0;
   if(dir == 0)
     {
      final_lot =  priceLotVal;
     }
   if(dir == 1 || dir == 2)
     {
      if(dir == 1)
         distance = (ask - priceLotVal) / poi;
      if(dir == 2)
         distance = (priceLotVal - bid) / poi;
      if(lotMode == 0)
        {
         risk = fabs(Lot);
         final_lot = risk / distance / tickValue;
        }
      if(lotMode == 1)
        {
         risk =  AccountInfoDouble(ACCOUNT_EQUITY) * Lot / 100;
         final_lot = risk / distance / tickValue;
        }
      if(lotMode == 2)
        {
         risk =  AccountInfoDouble(ACCOUNT_BALANCE) * Lot / 100;
         final_lot = risk / distance / tickValue;
        }
      if(lotMode == 3)
        {
         final_lot =  Lot;
        }
      if(lotMode == 4)
        {
         final_lot =  Lot / marginReq;
        }
      if(lotMode == 5)
        {
         final_lot = (AccountInfoDouble(ACCOUNT_EQUITY) * Lot / 100) / marginReq;
        }
     }
   final_lot = MathMin(final_lot, maxLot);
   final_lot = MathMin(final_lot, maxlotMargin);
   final_lot = MathMax(final_lot, minlot);
   final_lot = MathMin(final_lot, maxlot);
   final_lot = MathRound(final_lot / step) * step;
   return final_lot;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int lastLossPosAmount(string sym, datetime from, bool consecutive)
  {
   int count = 0;
   for(int pos = OrdersHistoryTotal() - 1; pos >= 0 ; pos--)
     {
      bool s = OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY);
      string ordersym = OrderSymbol();
      string comment = OrderComment();
      datetime openTime = OrderOpenTime();
      if(openTime < from)
         break;
      double PL = OrderProfit();
      if(StringFind(comment, "_gr#", 0) >= 0)
         continue;
      if((ordersym == sym || sym == "") && OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0 && OrderType() < 2)
        {
         if(PL < 0)
            count++;
         else
           {
            if(consecutive)
               return count;
           }
        }
     }
   return count;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int lastWinPosAmount(string sym, datetime from, bool consecutive)
  {
   int count = 0;
   for(int pos = OrdersHistoryTotal() - 1; pos >= 0 ; pos--)
     {
      bool s = OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY);
      string ordersym = OrderSymbol();
      string comment = OrderComment();
      datetime openTime = OrderOpenTime();
      if(openTime < from)
         break;
      double PL = OrderProfit();
      if(StringFind(comment, "_gr#", 0) >= 0)
         continue;
      if((ordersym == sym || sym == "") && OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0 && OrderType() < 2)
        {
         if(PL > 0)
            count++;
         else
           {
            if(consecutive)
               return count;
           }
        }
     }
   return count;
  }



//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool posOpenPrice(int fp, string sym, double p)
  {
   for(int pos = OrdersTotal() - 1; pos >= 0 ; pos--)
     {
      bool s = OrderSelect(pos, SELECT_BY_POS, MODE_TRADES);
      double oprice = OrderOpenPrice();
      string comment = OrderComment();
      if(OrderSymbol() == sym && p == oprice && OrderMagicNumber() == (int)MagicNumber && MagicNumber > 0 && (StringFind(comment, "_ip(" + (string)fp + ")", 0) >= 0 || fp == 0))
         return true;
     }
   return false;
  }


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int checkEntry(int bar, string sym)
  {
   int dir = 0;
   double val0_0 = iCustom(sym, Period(), custom_indicator, CUSTOM_INDICATOR_PARAMS, 0, bar);
   double val0_1 = iCustom(sym, Period(), custom_indicator, CUSTOM_INDICATOR_PARAMS, 0, bar + 1);
   double val1_0 = iCustom(sym, Period(), custom_indicator, CUSTOM_INDICATOR_PARAMS, 1, bar);
   double val1_1 = iCustom(sym, Period(), custom_indicator, CUSTOM_INDICATOR_PARAMS, 1, bar + 1);
   if(val0_0 < val1_0 && val0_1 > val1_1)
      dir = 1;
   if(val0_0 > val1_0 && val0_1 < val1_1)
      dir = 2;
   if(kijunFilterMode > 0)
     {
      double kijun0 = iCustom(sym, Period(), custom_indicator2, CUSTOM_INDICATOR_PARAMS2, 1, bar);
      if(kijunFilterMode == 1 && iClose(sym, Period(), bar) > kijun0 && dir == 1)
         return 1;
      if(kijunFilterMode == 1 && iClose(sym, Period(), bar) < kijun0 && dir == 2)
         return -1;
      if(kijunFilterMode == 2 && iClose(sym, Period(), bar) < kijun0 && dir == 1)
         return 1;
      if(kijunFilterMode == 2 && iClose(sym, Period(), bar) > kijun0 && dir == 2)
         return -1;
     }
   else
     {
      if(dir == 1)
         return 1;
      if(dir == 2)
         return -1;
     }
   return 0;
  }
//+------------------------------------------------------------------+
// More information about this indicator can be found at:
// https://fxcodebase.com/code/viewtopic.php?f=38&p=147153#p147153

//+------------------------------------------------------------------------------------------------+
//|                                                            Copyright © 2025, Gehtsoft USA LLC  |
//|                                                                         http://fxcodebase.com  |
//+------------------------------------------------------------------------------------------------+
//|                                                              Support our efforts by donating   |
//|                                                                 Paypal: https://goo.gl/9Rj74e  |
//+------------------------------------------------------------------------------------------------+
//|                                                                   Developed by : Mario Jemic   |
//|                                                                       mario.jemic@gmail.com    |
//|                                                        https://AppliedMachineLearning.systems  |
//|                                                             Patreon :  https://goo.gl/GdXWeN   |
//+------------------------------------------------------------------------------------------------+

//Your donations will allow the service to continue onward.
//+------------------------------------------------------------------------------------------------+
//|BitCoin                    : 15VCJTLaz12Amr7adHSBtL9v8XomURo9RF                                 |
//|Ethereum                   : 0x8C110cD61538fb6d7A2B47858F0c0AaBd663068D                         |
//|SOL Address                : 4tJXw7JfwF3KUPSzrTm1CoVq6Xu4hYd1vLk3VF2mjMYh                       |
//|Cardano/ADA                : addr1v868jza77crzdc87khzpppecmhmrg224qyumud6utqf6f4s99fvqv         |
//|Dogecoin Address           : DBGXP1Nc18ZusSRNsj49oMEYFQgAvgBVA8                                 |
//|SHIB Address               : 0x1817D9ebb000025609Bf5D61E269C64DC84DA735                         |
//|Binance(ERC20 & BSC only)  : 0xe84751063de8ade7c5fbff5e73f6502f02af4e2c                         |
//|BitCoin Cash               : 1BEtS465S3Su438Kc58h2sqvVvHK9Mijtg                                 |
//|LiteCoin                   : LLU8PSY2vsq7B9kRELLZQcKf5nJQrdeqwD                                 |
//+------------------------------------------------------------------------------------------------+