Fixing 6 Compile Errors in cAlgo code

50 USD  Payment method:  Direct Payment
Closed

I have taken a MT4 EA and converted it through the MQ4 to cAlgo Code Converter and it came up with 6 errors in the compilation.

Below is the code cAlgo code for you to use and see if you can fix the errors:-

 

using System;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using cAlgo.API.Requests;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.FileSystem)]
    public class ConvertedRobot : Robot
    {
Mq4Double Mq4Init()
{
if(ReadCSVFileFunc())
     {
      if(ArraySize(inputsAct)<=0)
         return INIT_FAILED;
     }
   else
     {
      return INIT_FAILED ;
     }
   return 0;
  return 0;}
Mq4Double Mq4Start()
{
Mq4String sym = "";
Mq4Double lots = 0;
Mq4Double type = 0;
Mq4Double ticket = 0;
Mq4Double _Sell_2 = false;
Mq4Double _Buy_2 = false;
Mq4Double _Buy = false;
Mq4Double _Sell = false;
Mq4Double _Close_Position_1 = false;
Mq4Double i = 0;

   for(i=0; i<ArraySize(inputsAct); i++)
     {
      SetSettingsFunc(inputsAct[i]_Currency);
      
      _Close_Position_1 = false;
      _Sell = false;
      _Buy = false;
      _Buy_2 = false;
      _Sell_2 = false;
      _Momentum = iMomentum(_Currency,_TimeFrame, _Whole_Number_Input, 0, 0);
      _Stochastic_3 = iStochastic(_Currency, _TimeFrame, _Whole_Number_Input, _D_Period, _Slowing, 0, 0, 0, 0);
      _RSI = iRSI(_Currency, _TimeFrame, _Whole_Number_Input,0, 0);

      _Compare_7 = (_RSI > _RSI_Sell_Limit);
      _Compare_10 = (_Momentum > _Mom_Sell_Limit);
      _Compare_1 = (_RSI < _RSI_Buy_Limit);
      _Compare_9 = (_Momentum < _Mom_Buy_Limit);
      _Compare_11 = (Number_of_Open_TradesFunc(1,_Currency) < _Max_Open_Trades);
      _Arithmetic = ((_Grid_Points *
                      (-1)) *
                     (Number_of_Open_TradesFunc(1,_Currency)));
      _Compare_12 = (_Stochastic_3 > _Stoc_Sell_Limit);
      _Compare_2 = (_Stochastic_3 < _Stoc_Buy_Limit);


      if((__OpenTimeFunc(1, _Currency) + 24*60*60 * (_Max_Days) < TimeCurrent()))
        {
         _Close_Position_1 = __isOpenedPositionFunc(1, _Currency);
         if(_Close_Position_1)
           {
            ticket = OrderTicket();
            type = OrderType();
            lots = OrderLots();
            sym = OrderSymbol();
            _Close_Position_1 = OrderClose(ticket, lots, MarketInfo(sym, MODE_BID) + MarketInfo(sym, MODE_SPREAD) * MarketInfo(sym, MODE_POINT) * (type==1 u63_0 1:0), 0);
           }
        }

      if(GetGlobalOrdersFunc()>=_GlobalMaxOrders)
         return 0 ;

      if(((_Compare_7 &&
           (_Compare_12 &&
            !__selectOrderBySymbolFunc(_Currency))) &&
          _Compare_10))
          
         _Sell = SellFunc(_Currency,1, ((_Lot_Percentage *
                           (AccountFreeMargin())) /
                          (100000)), 0, ((AccountFreeMargin() /
                                          ((100 /
                                            (_SL_Percentage)))) /
                                         (((_Lot_Percentage *
                                            (AccountFreeMargin())) /
                                           (100000)))), 0, _Sell_TP_in_Points, 5, _Max_Open_Trades, 0, "");

      if((((_Compare_2 &&
            !__selectOrderBySymbolFunc(_Currency)) &&
           _Compare_1) &&
          _Compare_9))
          
         _Buy = BuyFunc(_Currency,1, ((_Lot_Percentage *
                         (AccountFreeMargin())) /
                        (100000)), 0, ((AccountFreeMargin() /
                                        ((100 /
                                          (_SL_Percentage)))) /
                                       (((_Lot_Percentage *
                                          (AccountFreeMargin())) /
                                         (100000)))), 0, _Buy_TP_in_Points, 5, _Max_Open_Trades, 0, "");


      if((((((__selectOrderBySymbolFunc(_Currency) &&
              ((_Arithmetic < 0) &&
               (__ProfitPointsFunc(1, _Currency) < _Arithmetic))) &&
             _Compare_11) &&
            _Compare_2) &&
           _Compare_1) &&
          _Compare_9))
          
         _Buy_2 = BuyFunc(_Currency,1, ((_Lot_Percentage *
                           (AccountFreeMargin())) /
                          (100000)), 0, ((AccountFreeMargin() /
                                          ((100 /
                                            (_SL_Percentage)))) /
                                         (((_Lot_Percentage *
                                            (AccountFreeMargin())) /
                                           (100000)))), 0, _Buy_TP_in_Points, 5, _Max_Open_Trades, 0, "");

      if((((((__selectOrderBySymbolFunc(_Currency) &&
              ((_Arithmetic < 0) &&
               (__ProfitPointsFunc(1, _Currency) < _Arithmetic))) &&
             _Compare_11) &&
            _Compare_12) &&
           _Compare_7) &&
          _Compare_10))
         _Sell_2 = SellFunc(_Currency,1, ((_Lot_Percentage *
                             (AccountFreeMargin())) /
                            (100000)), 0, ((AccountFreeMargin() /
                                            ((100 /
                                              (_SL_Percentage)))) /
                                           (((_Lot_Percentage *
                                              (AccountFreeMargin())) /
                                             (100000)))), 0, _Sell_TP_in_Points, 5, _Max_Open_Trades, 0, "");
     }


   return 0;
  return 0;}
Mq4Double __selectOrderBySymbolFunc(Mq4String symbol)
{
Mq4Double i = 0;
   for(i = 0; i < OrdersTotal(); i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderSymbol() == symbol)
         return true;
     }
   return false;
  return true;}
Mq4Double __selectOrderByMagicFunc(Mq4Double magic, Mq4String symbol)
{
Mq4Double i = 0;
   for(i = 0; i < OrdersTotal(); i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == 1001000000 + magic && OrderSymbol() == symbol)
         return true;
     }
   return false;
  return true;}
Mq4Double __OpenTimeFunc(Mq4Double magic, Mq4String symbol)
{
if(!__selectOrderByMagicFunc(magic, symbol))
      return 0;
   return OrderOpenTime();
  return 0;}
Mq4Double __ProfitPointsFunc(Mq4Double magic, Mq4String symbol)
{
if(!__selectOrderByMagicFunc(magic, symbol))
      return 0;
   if(OrderType() == OP_BUY)
      return (MarketInfo(OrderSymbol(),MODE_BID) - OrderOpenPrice())/MarketInfo(OrderSymbol(),MODE_POINT);
   else
      if(OrderType() == OP_SELL)
         return (OrderOpenPrice() - (MarketInfo(OrderSymbol(),MODE_ASK)))/MarketInfo(OrderSymbol(),MODE_POINT);
   return 0;
  return 0;}
Mq4Double __isOpenedPositionFunc(Mq4Double magic, Mq4String symbol)
{
if(!__selectOrderByMagicFunc(magic, symbol))
      return false;
   return OrderType()==OP_BUY || OrderType()==OP_SELL;
  return true;}
Mq4Double __TicketFunc(Mq4Double magic, Mq4String symbol)
{
if(!__selectOrderByMagicFunc(magic, symbol))
      return 0;
   return OrderTicket();
  return 0;}
Mq4Double Number_of_Open_TradesFunc(Mq4Double MagicIndex, Mq4String symbol)
{
Mq4Double i = 0;
Mq4Double res = 0;
   res = 0;
   for(i=OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i, SELECT_BY_POS))
         continue;
      if(OrderMagicNumber() != 1001000000 + MagicIndex || OrderSymbol() != symbol)
         continue;
      res ++;
     }
   return res;
  return 0;}
Mq4Double SellFunc(Mq4String symbol, Mq4Double MagicIndex, Mq4Double Lots, Mq4Double StopLossMethod, Mq4Double StopLossPoints, Mq4Double TakeProfitMethod, Mq4Double TakeProfitPoints, Mq4Double Slippage, Mq4Double MaxOpenTrades, Mq4Double MaxFrequencyMins, Mq4String TradeComment)
{
Mq4Double result = 0;
Mq4Double stopLevel = 0;
Mq4Double i = 0;
Mq4Double hstTotal = 0;
Mq4Double i = 0;
Mq4Double recentSeconds = 0;
Mq4Double i = 0;
Mq4Double numberOfOpenTrades = 0;
Mq4Double takeProfitPoints = 0;
Mq4Double stopLossPoints = 0;
Mq4Double tp = 0;
Mq4Double sl = 0;
Mq4Double ask = 0;
Mq4Double bid = 0;
Mq4Double points = 0;
Mq4Double digits = 0;
   digits=(Mq4Double)MarketInfo(symbol,MODE_DIGITS);
   points=MarketInfo(symbol,MODE_POINT);
   bid=MarketInfo(symbol,MODE_BID);
   ask=MarketInfo(symbol,MODE_ASK);
   
   
   if(pipSize == 0)
      pipSize = points * (1 + 9 * (digits == 3 || digits == 5));

   sl = 0;
tp = 0;
   stopLossPoints = 0;
takeProfitPoints = 0;

   numberOfOpenTrades = 0;

   for(i=OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i, SELECT_BY_POS))
         continue;
      if(OrderMagicNumber() != 1001000000 + MagicIndex || OrderSymbol() != symbol)
         continue;
      numberOfOpenTrades ++;
     }

   if(MaxOpenTrades > 0 && numberOfOpenTrades >= MaxOpenTrades)
      return false;

   if(MaxFrequencyMins  > 0)
     {
      recentSeconds = MaxFrequencyMins * 60;

      for(i=OrdersTotal()-1; i>=0; i--)
        {
         if(!OrderSelect(i, SELECT_BY_POS))
            continue;
         if(OrderMagicNumber() != 1001000000 + MagicIndex || OrderSymbol() !=symbol)
            continue;
         if(TimeCurrent() - OrderOpenTime() < recentSeconds)
            return false;
        }

      hstTotal=OrdersHistoryTotal();

      for(i=hstTotal-1; i>=0; i--)
        {
         if(!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
            continue;
         if(OrderMagicNumber() != 1001000000 + MagicIndex || OrderSymbol() != symbol)
            continue;
         if(TimeCurrent() - OrderOpenTime() < recentSeconds)
            return false;
         break;
        }
     }

   if(Lots < MarketInfo(symbol,MODE_MINLOT))
      return false;

   if(AccountFreeMarginCheck(symbol, OP_SELL,Lots) <= 0)
     {
      Mq4Print("Sell order error: insufficient capital");
      return false;
     }

   if(StopLossPoints > 0)
     {
      if(StopLossMethod == 0)
        {
         sl = NormalizeDouble(bid + StopLossPoints * points, digits);
         stopLossPoints = StopLossPoints;
        }
      else
         if(StopLossMethod == 1)
           {
            sl = NormalizeDouble(bid + StopLossPoints * pipSize, digits);
            stopLossPoints = StopLossPoints * (1 + 9 * (digits == 3 || digits == 5));
           }
         else
           {
            sl = StopLossPoints;
            stopLossPoints = (sl - bid)/points;
           }
     }

   if(TakeProfitPoints > 0)
     {
      if(TakeProfitMethod == 0)
        {
         tp = NormalizeDouble(bid - TakeProfitPoints * points, digits);
         takeProfitPoints = TakeProfitPoints;
        }
      else
         if(TakeProfitMethod == 1)
           {
            tp = NormalizeDouble(bid - TakeProfitPoints * pipSize, digits);
            takeProfitPoints = TakeProfitPoints * (1 + 9 * (digits == 3 || digits == 5));
           }
         else
           {
            tp = TakeProfitPoints;
            takeProfitPoints = (bid - tp)/Point;
           }
     }

   stopLevel = MarketInfo(symbol,MODE_STOPLEVEL) + MarketInfo(symbol,MODE_SPREAD);

   if((sl > 0 && stopLossPoints <= stopLevel) || (tp > 0 && takeProfitPoints <= stopLevel))
     {
      Mq4Print("Cannot Sell: StopMq4 loss and take profit must be at least "
            + DoubleToStr(MarketInfo(symbol,MODE_STOPLEVEL) + MarketInfo(symbol,MODE_SPREAD),0)
            + " points away from the current price");
      return false;
     }

   RefreshRates();
   result = OrderSend(symbol, OP_SELL, Lots, bid, Slippage, sl, tp, "FxProQuant" + "(" + WindowExpertName() + ") " + TradeComment,1001000000 + MagicIndex);

   if(result == -1)
     {
      Mq4Print("Failed to Sell: " + IntegerToString(GetLastError()));
      Sleep(400);
      return false;
     }

   return true;
  return true;}
Mq4Double BuyFunc(Mq4String symbol, Mq4Double MagicIndex, Mq4Double Lots, Mq4Double StopLossMethod, Mq4Double StopLossPoints, Mq4Double TakeProfitMethod, Mq4Double TakeProfitPoints, Mq4Double Slippage, Mq4Double MaxOpenTrades, Mq4Double MaxFrequencyMins, Mq4String TradeComment)
{
Mq4Double result = 0;
Mq4Double stopLevel = 0;
Mq4Double i = 0;
Mq4Double hstTotal = 0;
Mq4Double i = 0;
Mq4Double recentSeconds = 0;
Mq4Double i = 0;
Mq4Double numberOfOpenTrades = 0;
Mq4Double takeProfitPoints = 0;
Mq4Double stopLossPoints = 0;
Mq4Double tp = 0;
Mq4Double sl = 0;
Mq4Double ask = 0;
Mq4Double bid = 0;
Mq4Double points = 0;
Mq4Double digits = 0;
    digits=(Mq4Double)MarketInfo(symbol,MODE_DIGITS);
   points=MarketInfo(symbol,MODE_POINT);
   bid=MarketInfo(symbol,MODE_BID);
   ask=MarketInfo(symbol,MODE_ASK);
   
   
   if(pipSize == 0)
      pipSize = points * (1 + 9 * (digits == 3 || digits == 5));

   sl = 0;
tp = 0;
   stopLossPoints = 0;
takeProfitPoints = 0;

   numberOfOpenTrades = 0;

   for(i=OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i, SELECT_BY_POS))
         continue;
      if(OrderMagicNumber() != 1001000000 + MagicIndex || OrderSymbol() != symbol)
         continue;
      numberOfOpenTrades ++;
     }

   if(MaxOpenTrades > 0 && numberOfOpenTrades >= MaxOpenTrades)
      return false;

   if(MaxFrequencyMins  > 0)
     {
      recentSeconds = MaxFrequencyMins * 60;

      for(i=OrdersTotal()-1; i>=0; i--)
        {
         if(!OrderSelect(i, SELECT_BY_POS))
            continue;
         if(OrderMagicNumber() != 1001000000 + MagicIndex || OrderSymbol() != symbol)
            continue;
         if(TimeCurrent() - OrderOpenTime() < recentSeconds)
            return false;
        }

      hstTotal=OrdersHistoryTotal();

      for(i=hstTotal-1; i>=0; i--)
        {
         if(!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
            continue;
         if(OrderMagicNumber() != 1001000000 + MagicIndex || OrderSymbol() !=symbol)
            continue;
         if(TimeCurrent() - OrderOpenTime() < recentSeconds)
            return false;
         break;
        }
     }

   if(Lots < MarketInfo(symbol,MODE_MINLOT))
      return false;

   if(AccountFreeMarginCheck(symbol, OP_SELL,Lots) <= 0)
     {
      Mq4Print("Buy error: insufficient capital");
      return false;
     }

   if(StopLossPoints > 0)
     {
      if(StopLossMethod == 0)
        {
         sl = NormalizeDouble(ask - StopLossPoints * points, digits);
         stopLossPoints = StopLossPoints;
        }
      else
         if(StopLossMethod == 1)
           {
            sl = NormalizeDouble(ask - StopLossPoints * pipSize, digits);
            stopLossPoints = StopLossPoints * (1 + 9 * (digits == 3 || digits == 5));
           }
         else
           {
            sl  = StopLossPoints;
            stopLossPoints = (ask - sl)/Point;
           }
     }

   if(TakeProfitPoints > 0)
     {
      if(TakeProfitMethod == 0)
        {
         tp = NormalizeDouble(ask + TakeProfitPoints * points, digits);
         takeProfitPoints = TakeProfitPoints;
        }
      else
         if(TakeProfitMethod == 1)
           {
            tp = NormalizeDouble(ask + TakeProfitPoints * pipSize, digits);
            takeProfitPoints = TakeProfitPoints * (1 + 9 * (digits == 3 || digits == 5));
           }
         else
           {
            tp = TakeProfitPoints;
            takeProfitPoints = (tp - ask)/Point;
           }
     }

   stopLevel = MarketInfo(symbol,MODE_STOPLEVEL) + MarketInfo(symbol,MODE_SPREAD);

   if((sl > 0 && stopLossPoints <= stopLevel) || (tp > 0 && takeProfitPoints <= stopLevel))
     {
      Mq4Print("Cannot Buy: StopMq4 loss and take profit must be at least "
            + DoubleToStr(MarketInfo(symbol,MODE_STOPLEVEL) + MarketInfo(symbol,MODE_SPREAD),0)
            + " points away from the current price");
      return false;
     }

   RefreshRates();
   result = OrderSend(symbol, OP_BUY, Lots, ask, Slippage, sl, tp, "FxProQuant" + "(" + WindowExpertName() + ") " + TradeComment, 1001000000 + MagicIndex);

   if(result == -1)
     {
      Mq4Print("Failed to Buy: " + IntegerToString(GetLastError()));
      Sleep(400);
      return false;
     }

   return true;
  return true;}
Mq4Double ReadCSVFileFunc()
{
Mq4Double i = 0;
Mq4Double line = 0;
Mq4Double handle = 0;
   if(!FileIsExist(_FileName))
      return false ;

   handle=FileOpen(_FileName,FILE_CSV|FILE_READ,";") ;
   line=0;
   if(handle!=INVALID_HANDLE)
     {
      while(!FileIsEnding(handle))
        {
         ArrayResize(inputs,line+1);
         inputs[line]_Currency=FileReadString(handle);
         inputs[line]_TimeFrame=FileReadString(handle);
         inputs[line]_Slowing=FileReadString(handle);
         inputs[line]_Whole_Number_Input=FileReadString(handle);
         inputs[line]_Grid_Points=FileReadString(handle);
         inputs[line]_SL_Percentage=FileReadString(handle);
         inputs[line]_RSI_Buy_Limit=FileReadString(handle);
         inputs[line]_Sell_TP_in_Points=FileReadString(handle);
         inputs[line]_Max_Days=FileReadString(handle);
         inputs[line]_Stoc_Buy_Limit=FileReadString(handle);
         inputs[line]_Mom_Buy_Limit=FileReadString(handle);
         inputs[line]_D_Period=FileReadString(handle);
         inputs[line]_Stoc_Sell_Limit=FileReadString(handle);
         inputs[line]_RSI_Sell_Limit=FileReadString(handle); ;
         inputs[line]_Mom_Sell_Limit=FileReadString(handle);
         inputs[line]_Buy_TP_in_Points=FileReadString(handle);
         inputs[line]_Max_Open_Trades=FileReadString(handle);
         inputs[line]_Lot_Percentage=FileReadString(handle);
         line++ ;
        }
      FileClose(handle);
     }
   else
     {
      return false ;
     }

   ArrayResize(inputsAct,ArraySize(inputs)-1);
   for(i=0; i<ArraySize(inputsAct); i++)
     {
      inputsAct[i]_Currency=inputs[i+1]_Currency;
      inputsAct[i]_TimeFrame=inputs[i+1]_TimeFrame;
      inputsAct[i]_Slowing=(Mq4Double)inputs[i+1]_Slowing;
      inputsAct[i]_Whole_Number_Input=(Mq4Double)inputs[i+1]_Whole_Number_Input;
      inputsAct[i]_Grid_Points=(Mq4Double)inputs[i+1]_Grid_Points;
      inputsAct[i]_SL_Percentage=StringToDouble(inputs[i+1]_SL_Percentage);
      inputsAct[i]_RSI_Buy_Limit=(Mq4Double)inputs[i+1]_RSI_Buy_Limit;
      inputsAct[i]_Sell_TP_in_Points=(Mq4Double)inputs[i+1]_Sell_TP_in_Points;
      inputsAct[i]_Max_Days=(Mq4Double)inputs[i+1]_Max_Days;
      inputsAct[i]_Stoc_Buy_Limit=(Mq4Double)inputs[i+1]_Stoc_Buy_Limit;
      inputsAct[i]_Mom_Buy_Limit=StringToDouble(inputs[i+1]_Mom_Buy_Limit);
      inputsAct[i]_D_Period=(Mq4Double)inputs[i+1]_D_Period;
      inputsAct[i]_Stoc_Sell_Limit=(Mq4Double)inputs[i+1]_Stoc_Sell_Limit;
      inputsAct[i]_RSI_Sell_Limit=(Mq4Double)inputs[i+1]_RSI_Sell_Limit;
      inputsAct[i]_Mom_Sell_Limit=StringToDouble(inputs[i+1]_Mom_Sell_Limit);
      inputsAct[i]_Buy_TP_in_Points=(Mq4Double)inputs[i+1]_Buy_TP_in_Points;
      inputsAct[i]_Max_Open_Trades=(Mq4Double)inputs[i+1]_Max_Open_Trades;
      inputsAct[i]_Lot_Percentage=StringToDouble(inputs[i+1]_Lot_Percentage) ;
     }
   return true ;
  return true;}
Mq4Double StringToTimeFrameFunc(Mq4String tf)
{
if(tf=="M1")
      return PERIOD_M1 ;
   else
      if(tf=="M5")
         return PERIOD_M5 ;
      else
         if(tf=="M15")
            return PERIOD_M15 ;
         else
            if(tf=="M30")
               return PERIOD_M30 ;
            else
               if(tf=="H1")
                  return PERIOD_H1 ;
               else
                  if(tf=="H4")
                     return PERIOD_H4 ;
                  else
                     if(tf=="D1")
                        return PERIOD_D1 ;
                     else
                        if(tf=="W1")
                           return PERIOD_W1 ;
                        else
                           if(tf=="MN1")
                              return PERIOD_MN1 ;

   return PERIOD_CURRENT ;
  return 0;}
void SetSettingsFunc(Mq4String symbol)
{
Mq4Double i = 0;
Mq4Double found = false;
   found=false;
   for(i=0; i<ArraySize(inputsAct); i++)
     {
      if(inputsAct[i]_Currency==symbol)
        {
         _Currency=inputsAct[i]_Currency ;
         _TimeFrame=StringToTimeFrameFunc(inputsAct[i]_TimeFrame);
         _Slowing = inputsAct[i]_Slowing;
         _Whole_Number_Input = inputsAct[i]_Whole_Number_Input;
         _Grid_Points = inputsAct[i]_Grid_Points;
         _SL_Percentage = inputsAct[i]_SL_Percentage;
         _RSI_Buy_Limit = inputsAct[i]_RSI_Buy_Limit;
         _Sell_TP_in_Points = inputsAct[i]_Sell_TP_in_Points;
         _Max_Days = inputsAct[i]_Max_Days;
         _Stoc_Buy_Limit = inputsAct[i]_Stoc_Buy_Limit;
         _Mom_Buy_Limit = inputsAct[i]_Mom_Buy_Limit;
         _D_Period = inputsAct[i]_D_Period;
         _Stoc_Sell_Limit = inputsAct[i]_Stoc_Sell_Limit;
         _RSI_Sell_Limit = inputsAct[i]_RSI_Sell_Limit;
         _Mom_Sell_Limit = inputsAct[i]_Mom_Sell_Limit;
         _Buy_TP_in_Points = inputsAct[i]_Buy_TP_in_Points;
         _Max_Open_Trades = inputsAct[i]_Max_Open_Trades;
         _Lot_Percentage =inputsAct[i]_Lot_Percentage;
         found=true ;
         break ;
        }
      else
        {
         continue ;
        }
     }

   if(!found)
     {
      _Currency=symbol;
      _TimeFrame=PERIOD_CURRENT ; 
      _Slowing = 3;       
      _Whole_Number_Input = 10;       
      _Grid_Points = 200;       
      _SL_Percentage = 1;       
      _RSI_Buy_Limit = 25;         
      _Sell_TP_in_Points = 300;       
      _Max_Days = 14;        
      _Stoc_Buy_Limit = 15;        
      _Mom_Buy_Limit = 99.5;       
      _D_Period = 3;         
      _Stoc_Sell_Limit = 85;       
      _RSI_Sell_Limit = 75;        
      _Mom_Sell_Limit = 100.5;        
      _Buy_TP_in_Points = 300;        
      _Max_Open_Trades = 6;        
      _Lot_Percentage = 0.5;       
     }
  return;}
Mq4Double GetGlobalOrdersFunc()
{
Mq4Double i = 0;
Mq4Double cnt = 0;
   cnt=0;
   for(i=0; i<OrdersTotal(); i++)
     {
      if(OrderSelect(i,SELECT_BY_POS) && OrderMagicNumber()==1001000000+1)
         cnt ++;
     }
   return cnt ;
  return 0;}


     
Mq4Double _GlobalMaxOrders=20;
Mq4String _FileName="MRS14.0csv";
Mq4Double _Compare_2;
Mq4Double _Compare_12;
Mq4Double _Arithmetic;
Mq4Double _Compare_11;
Mq4Double _Compare_9;
Mq4Double _Compare_1;
Mq4Double _Compare_10;
Mq4Double _Compare_7;
Mq4Double _RSI;
Mq4Double _Stochastic_3;
Mq4Double _Momentum;
Mq4Double _Lot_Percentage;
Mq4Double _Max_Open_Trades;
Mq4Double _Buy_TP_in_Points;
Mq4Double _Mom_Sell_Limit;
Mq4Double _RSI_Sell_Limit;
Mq4Double _Stoc_Sell_Limit;
Mq4Double _D_Period;
Mq4Double _Mom_Buy_Limit;
Mq4Double _Stoc_Buy_Limit;
Mq4Double _Max_Days;
Mq4Double _Sell_TP_in_Points;
Mq4Double _RSI_Buy_Limit;
Mq4Double _SL_Percentage;
Mq4Double _Grid_Points;
Mq4Double _Whole_Number_Input;
Mq4Double _Slowing;
Mq4Double _TimeFrame;
Mq4String _Currency;

Mq4Double _Max_Open_Trades;


Mq4Double _RSI_Sell_Limit;

Mq4Double _Stoc_Buy_Limit;
Mq4Double _Max_Days;

Mq4Double _RSI_Buy_Limit;
Mq4Double _SL_Percentage;
Mq4Double _Grid_Points;


Mq4String _TimeFrame;
Mq4String _Currency;
Mq4String _Lot_Percentage;
Mq4String _Max_Open_Trades;
Mq4String _Buy_TP_in_Points;
Mq4String _Mom_Sell_Limit;
Mq4String _RSI_Sell_Limit;
Mq4String _Stoc_Sell_Limit;
Mq4String _D_Period;
Mq4String _Mom_Buy_Limit;
Mq4String _Stoc_Buy_Limit;
Mq4String _Max_Days;
Mq4String _Sell_TP_in_Points;
Mq4String _RSI_Buy_Limit;
Mq4String _SL_Percentage;
Mq4String _Grid_Points;
Mq4String _Whole_Number_Input;
Mq4String _Slowing;
Mq4String _TimeFrame;
Mq4String _Currency;


struct_ InputsStr
  {
          
         
          
          
          
          
            
          
           
           
          
            
          
           
           
           
           
          
  };
struct_ Inputs
  {
          
         
          
          
          
          
            
          
           
           
          
            
          
           
           
           
           
          
  };

Inputs inputsAct[] ;
InputsStr inputs[];

input  
input
Mq4Double pipSize = 0;
Mq4Double pipSize = 0;
        
int indicator_buffers = 0;

                
Mq4Double indicator_width1 = 1;
Mq4Double indicator_width2 = 1;
Mq4Double indicator_width3 = 1;
Mq4Double indicator_width4 = 1;
Mq4Double indicator_width5 = 1;
Mq4Double indicator_width6 = 1;
Mq4Double indicator_width7 = 1;
Mq4Double indicator_width8 = 1;


     

List<Mq4OutputDataSeries> AllBuffers = new List<Mq4OutputDataSeries>();     
public List<DataSeries> AllOutputDataSeries = new List<DataSeries>();
        
    protected override void OnStart()
    {

        
        CommonInitialize();                        
                   

        try
        {
            Mq4Init();
        }
        catch(Exception e)
        {
            
        }  
    }

    protected override void OnTick()
    {        
        var index = MarketSeries.Close.Count - 1;
                

        try
        {
            Mq4Start();
        }
        catch(Exception e)
        {
            
        }    
    }

    private bool IsLastBar
    {
        get { return true; }
    }

void Sleep(Mq4Double milliseconds)
    {        
        if (!IsBacktesting)
            Thread.Sleep(milliseconds);
    }
int _currentIndex;
CachedStandardIndicators _cachedStandardIndicators;
Mq4ChartObjects _mq4ChartObjects;
Mq4ArrayToDataSeriesConverterFactory _mq4ArrayToDataSeriesConverterFactory;
Mq4MarketDataSeries Open;
Mq4MarketDataSeries High;
Mq4MarketDataSeries Low;
Mq4MarketDataSeries Close;
Mq4MarketDataSeries Median;
Mq4MarketDataSeries Volume;
Mq4TimeSeries Time;

private void CommonInitialize()
{
    Open = new Mq4MarketDataSeries(MarketSeries.Open);
    High = new Mq4MarketDataSeries(MarketSeries.High);
    Low = new Mq4MarketDataSeries(MarketSeries.Low);
    Close = new Mq4MarketDataSeries(MarketSeries.Close);
    Volume = new Mq4MarketDataSeries(MarketSeries.TickVolume);
    Median = new Mq4MarketDataSeries(MarketSeries.Median);
    Time = new Mq4TimeSeries(MarketSeries.OpenTime);

    _cachedStandardIndicators = new CachedStandardIndicators(Indicators);
    _mq4ChartObjects = new Mq4ChartObjects(ChartObjects, MarketSeries.OpenTime);
    _mq4ArrayToDataSeriesConverterFactory = new Mq4ArrayToDataSeriesConverterFactory(() => CreateDataSeries());
}
    private int Bars
    {
        get { return MarketSeries.Close.Count; }
    }
private int Digits
    {
        get
        {
            if (Symbol == null)
                return 0;
            return Symbol.Digits;
        }
    }

Mq4Double Point
    {
        get
        {
            if (Symbol == null)
                return 0.00001;

            return Symbol.TickSize;
        }
    }
private int Period()
    {         
        if (TimeFrame == TimeFrame.Minute)
            return 1;
        if (TimeFrame == TimeFrame.Minute2)
            return 2;
        if (TimeFrame == TimeFrame.Minute3)
            return 3;
        if (TimeFrame == TimeFrame.Minute4)
            return 4;
        if (TimeFrame == TimeFrame.Minute5)
            return 5;
        if (TimeFrame == TimeFrame.Minute10)
            return 10;
        if (TimeFrame == TimeFrame.Minute15)
            return 15;
        if (TimeFrame == TimeFrame.Minute30)
            return 30;
        if (TimeFrame == TimeFrame.Hour)
            return 60;
        if (TimeFrame == TimeFrame.Hour4)
            return 240;
        if (TimeFrame == TimeFrame.Hour12)
            return 720;                    
        if (TimeFrame == TimeFrame.Daily)
            return 1440;
        if (TimeFrame == TimeFrame.Weekly)
            return 10080;
        
        return 43200;
    }

    public TimeFrame PeriodToTimeFrame(int period)
    {
        switch (period) 
        {        
            case 0:             
                return TimeFrame;
            case 1:
                return TimeFrame.Minute;
            case 2:
                return TimeFrame.Minute2;
            case 3:
                return TimeFrame.Minute3;
            case 4:
                return TimeFrame.Minute4;
            case 5:
                return TimeFrame.Minute5;
            case 10:
                return TimeFrame.Minute10;
            case 15:
                return TimeFrame.Minute15;
            case 30:
                return TimeFrame.Minute30;
            case 60:
                return TimeFrame.Hour;
            case 240:
                return TimeFrame.Hour4;
            case 720:
                return TimeFrame.Hour12;
            case 1440:
                return TimeFrame.Daily;
            case 10080:
                return TimeFrame.Weekly;
            case 43200:
                return TimeFrame.Monthly;
            default:
                throw new NotSupportedException(string.Format("TimeFrame {0} minutes isn't supported by cAlgo", period));
        }
    }

Mq4String DoubleToStr(double value, int digits)
    {
      return value.ToString("F" + digits);
    }

Mq4Double NormalizeDouble(double value, int digits)
    {
      return Math.Round(value, digits);
    }

int ToMq4ErrorCode(ErrorCode errorCode)
    {
        switch (errorCode)
        {
                case ErrorCode.BadVolume:
                    return ERR_INVALID_TRADE_VOLUME; 
                case ErrorCode.NoMoney:
                    return ERR_NOT_ENOUGH_MONEY;
                case ErrorCode.MarketClosed:
                    return ERR_MARKET_CLOSED;
                case ErrorCode.Disconnected:
                    return ERR_NO_CONNECTION;
                case ErrorCode.Timeout:
                    return ERR_TRADE_TIMEOUT;
                default:
                    return ERR_COMMON_ERROR;
        }
    }

Mq4Double RefreshRates()
{
    RefreshData();
    return true;
}

Mq4String WindowExpertName()
{
    return "ConvertedRobot";
}


int TimeCurrent()
    {
      return Mq4TimeSeries.ToInteger(Server.Time);
    }

const string NotSupportedMaShift = "Converter supports only ma_shift = 0";

Mq4Double MarketInfo(Mq4String symbol, int type)
{
    var symbolObject = GetSymbol(symbol);
    switch (type)
    {
        case MODE_LOW:
            return GetSeries(symbol, PERIOD_D1).Low.LastValue;
        case MODE_HIGH:
            return GetSeries(symbol, PERIOD_D1).High.LastValue;
        case MODE_DIGITS:
            return symbolObject.Digits;
        case MODE_TIME:
            return TimeCurrent();
        case MODE_ASK:
            return symbolObject.Ask;
        case MODE_BID:
            return symbolObject.Bid;
        case MODE_SPREAD:
            return symbolObject.Spread / symbolObject.TickSize;
        case MODE_PROFITCALCMODE:
            return 0;
        case MODE_FREEZELEVEL:
            return 0;
        case MODE_TRADEALLOWED:
            return 1;
        case MODE_POINT:
            return symbolObject.TickSize;
        case MODE_TICKSIZE:
            return symbolObject.TickSize;
        case MODE_SWAPTYPE:
            return 0;
        case MODE_MARGINCALCMODE:
            return 0;
        case MODE_STOPLEVEL:
            return symbolObject.TickSize;    
        case MODE_MINLOT:
            return symbolObject.ToLotsVolume(symbolObject.VolumeMin);    
        case MODE_MAXLOT:
            return symbolObject.ToLotsVolume(symbolObject.VolumeMax);  
        case MODE_LOTSTEP:
            return symbolObject.ToLotsVolume(symbolObject.VolumeStep);   
        case MODE_TICKVALUE:
            return symbolObject.TickValue;    
        case MODE_LOTSIZE:
            return symbolObject.ToNotNormalizedUnitsVolume(1);
        case MODE_MARGINREQUIRED:
            return symbolObject.ToNotNormalizedUnitsVolume(1) / Account.Leverage * symbolObject.Ask * symbolObject.TickValue / symbolObject.TickSize;
    }
    return 0;
}

Mq4Double Bid
{
    get 
    {
    if (Symbol == null || double.IsNaN(Symbol.Bid))
        return 0;
    return Symbol.Bid;
    }
}

Mq4Double Ask
{
    get 
    {
    if (Symbol == null || double.IsNaN(Symbol.Ask))
        return 0;
    return Symbol.Ask;
    }
}


void Mq4Print(params object[] parameters)
{
    Print(string.Join(string.Empty, parameters));
}

//{
int ArrayResize(IMq4DoubleArray array, int new_size)
{
    array.Resize(new_size);
    return new_size;
}

int ArrayResize(Mq4DoubleTwoDimensionalArray array, int new_size)
{
    return 0;
}
//}

int ArrayResize(Mq4StringArray array, int new_size)
{
    array.Resize(new_size);
    return new_size;
}

int ArraySize(IMq4DoubleArray array)
{
    return array.Length;
}

int ArraySize(Mq4StringArray array)
{
    return array.Length;
}


private int _lastError;
Mq4Double GetLastError()
{
    return _lastError;
}

const string GlobalVariablesPath = "Software\\2calgo\\Global Variables\\";


Symbol GetSymbol(string symbolCode)
{
    if (symbolCode == "0" || string.IsNullOrEmpty(symbolCode))
    {
        return Symbol;
    }
    return MarketData.GetSymbol(symbolCode);
}

MarketSeries GetSeries(string symbol, int period)
{
    var timeFrame = PeriodToTimeFrame(period);
    var symbolObject = GetSymbol(symbol);

    if (symbolObject == Symbol && timeFrame == TimeFrame)
        return MarketSeries;

    return MarketData.GetSeries(symbolObject.Code, timeFrame);
}

private DataSeries ToAppliedPrice(string symbol, int timeframe, int constant)
{
    var series = GetSeries(symbol, timeframe);
    switch (constant)
    {
        case PRICE_OPEN:
            return series.Open;
        case PRICE_HIGH:
            return series.High;
        case PRICE_LOW:
            return series.Low;
        case PRICE_CLOSE:
            return series.Close;
        case PRICE_MEDIAN:
            return series.Median;       
        case PRICE_TYPICAL:
            return series.Typical;    
        case PRICE_WEIGHTED:
            return series.WeightedClose;
    }
    throw new NotImplementedException("Converter doesn't support working with this type of AppliedPrice");
}   
const string xArrow = "✖";

public static string GetArrowByCode(int code)
{
    switch (code) 
    {
        case 0:
            return string.Empty;
        case 32:
            return " ";
        case 33:
            return "✏";
        case 34:
            return "✂";
        case 35:
            return "✁";
        case 40:
            return "☎";
        case 41:
            return "✆";
        case 42:
            return "✉";
        case 54:
            return "⌛";
        case 55:
            return "⌨";
        case 62:
            return "✇";
        case 63:
            return "✍";
        case 65:
            return "✌";
        case 69:
            return "☜";
        case 70:
            return "☞";
        case 71:
            return "☝";
        case 72:
            return "☟";
        case 74:
            return "☺";
        case 76:
            return "☹";
        case 78:
            return "☠";
        case 79:
            return "⚐";
        case 81:
            return "✈";
        case 82:
            return "☼";
        case 84:
            return "❄";
        case 86:
            return "✞";
        case 88:
            return "✠";
        case 89:
            return "✡";
        case 90:
            return "☪";
        case 91:
            return "☯";
        case 92:
            return "ॐ";
        case 93:
            return "☸";
        case 94:
            return "♈";
        case 95:
            return "♉";
        case 96:
            return "♊";
        case 97:
            return "♋";
        case 98:
            return "♌";
        case 99:
            return "♍";
        case 100:
            return "♎";
        case 101:
            return "♏";
        case 102:
            return "♐";
        case 103:
            return "♑";
        case 104:
            return "♒";
        case 105:
            return "♓";
        case 106:
            return "&";
        case 107:
            return "&";
        case 108:
            return "●";
        case 109:
            return "❍";
        case 110:
            return "■";
        case 111:
        case 112:
            return "□";
        case 113:
            return "❑";
        case 114:
            return "❒";
        case 115:
        case 116:
            return "⧫";
        case 117:
        case 119:
            return "◆";
        case 118:
            return "❖";
        case 120:
            return "⌧";
        case 121:
            return "⍓";
        case 122:
            return "⌘";
        case 123:
            return "❀";
        case 124:
            return "✿";
        case 125:
            return "❝";
        case 126:
            return "❞";
        case 127:
            return "▯";
        case 128:
            return "⓪";
        case 129:
            return "①";
        case 130:
            return "②";
        case 131:
            return "③";
        case 132:
            return "④";
        case 133:
            return "⑤";
        case 134:
            return "⑥";
        case 135:
            return "⑦";
        case 136:
            return "⑧";
        case 137:
            return "⑨";
        case 138:
            return "⑩";
        case 139:
            return "⓿";
        case 140:
            return "❶";
        case 141:
            return "❷";
        case 142:
            return "❸";
        case 143:
            return "❹";
        case 144:
            return "❺";
        case 145:
            return "❻";
        case 146:
            return "❼";
        case 147:
            return "❽";
        case 148:
            return "❾";
        case 149:
            return "❿";
        case 158:
            return "·";
        case 159:
            return "•";
        case 160:
        case 166:
            return "▪";
        case 161:
            return "○";
        case 162:
        case 164:
            return "⭕";
        case 165:
            return "◎";
        case 167:
            return "✖";
        case 168:
            return "◻";
        case 170:
            return "✦";
        case 171:
            return "★";
        case 172:
            return "✶";
        case 173:
            return "✴";
        case 174:
            return "✹";
        case 175:
            return "✵";
        case 177:
            return "⌖";
        case 178:
            return "⟡";
        case 179:
            return "⌑";
        case 181:
            return "✪";
        case 182:
            return "✰";
        case 195:
        case 197:
        case 215:
        case 219:
        case 223:
        case 231:
            return "◀";
        case 196:
        case 198:
        case 224:
            return "▶";
        case 213:
            return "⌫";
        case 214:
            return "⌦";
        case 216:
            return "➢";
        case 220:
            return "➲";
        case 232:
            return "➔";
        case 233:
        case 199:
        case 200:
        case 217:
        case 221:
        case 225:
            return "◭";
        case 234:
        case 201:
        case 202:
        case 218:
        case 222:
        case 226:
            return "⧨";
        case 239:
            return "⇦";
        case 240:
            return "⇨";
        case 241:
            return "◭";
        case 242:
            return "⧨";
        case 243:
            return "⬄";
        case 244:
            return "⇳";
        case 245:
        case 227:
        case 235:
            return "↖";
        case 246:
        case 228:
        case 236:
            return "↗";
        case 247:
        case 229:
        case 237:
            return "↙";
        case 248:
        case 230:
        case 238:
            return "↘";
        case 249:
            return "▭";
        case 250:
            return "▫";
        case 251:
            return "✗";
        case 252:
            return "✓";
        case 253:
            return "☒";
        case 254:
            return "☑";
        default:
            return xArrow;
    }
}
class Mq4OutputDataSeries : IMq4DoubleArray
{
    public IndicatorDataSeries OutputDataSeries { get; private set; }
    private readonly IndicatorDataSeries _originalValues;
    private int _currentIndex;
    private int _shift;
    private double _emptyValue = EMPTY_VALUE;
    private readonly ChartObjects _chartObjects;
    private readonly int _style;
    private readonly int _bufferIndex;
    private readonly ConvertedRobot _indicator;
        
    public Mq4OutputDataSeries(
        ConvertedRobot indicator, 
        IndicatorDataSeries outputDataSeries, 
        ChartObjects chartObjects, 
        int style, 
        int bufferIndex,
        Func<IndicatorDataSeries> dataSeriesFactory,
        int lineWidth,
        Colors? color = null)
    {
        OutputDataSeries = outputDataSeries;
        _chartObjects = chartObjects;
        _style = style;
        _bufferIndex = bufferIndex;
        _indicator = indicator;
        Color = color;
        _originalValues = dataSeriesFactory();
        LineWidth = lineWidth;
    }

    public int LineWidth { get; private set; }
    public Colors? Color { get; private set; }

    public int Length
    {
        get 
        {
            return OutputDataSeries.Count;
        }
    }

    public void Resize(int newSize)
    {        
    }

    public void SetCurrentIndex(int index)
    {
        _currentIndex = index;
    }        
        
    public void SetShift(int shift)
    {
        _shift = shift;
    }
        
    public void SetEmptyValue(double emptyValue)
    {
        _emptyValue = emptyValue;
    }

    public Mq4Double this[int index]
    {
        get 
        { 
            var indexToGetFrom = _currentIndex - index + _shift;
            if (indexToGetFrom < 0 || indexToGetFrom > _currentIndex)
                    return 0;
            if (indexToGetFrom >= _originalValues.Count)
                return _emptyValue;

            return _originalValues[indexToGetFrom];
        }
        set 
        { 
            var indexToSet = _currentIndex - index + _shift;  
            if (indexToSet < 0)
                return;

            _originalValues[indexToSet] = value;

            var valueToSet = value;
            if (valueToSet == _emptyValue)
                valueToSet = double.NaN;

            if (indexToSet < 0)
                return;
                
            OutputDataSeries[indexToSet] = valueToSet; 

            switch (_style)
            {
                case DRAW_ARROW:
                    var arrowName = GetArrowName(indexToSet);
                    if (double.IsNaN(valueToSet))
                        _chartObjects.RemoveObject(arrowName);
                    else
                    {
                        var color = Color.HasValue ? Color.Value : Colors.Red;
                        _chartObjects.DrawText(arrowName , _indicator.ArrowByIndex[_bufferIndex], indexToSet, valueToSet, VerticalAlignment.Center, HorizontalAlignment.Center, color);
                    }
                    break;
                case DRAW_HISTOGRAM:
                    if (false)
                    {
                        var anotherLine = _indicator.AllBuffers.FirstOrDefault(b => b.LineWidth == LineWidth && b != this);
                        if (anotherLine != null)
                        {                
                            var name = GetNameOfHistogramLineOnChartWindow(indexToSet);
                            Colors color;
                            if (this[index] > anotherLine[index])
                                color = Color ?? Colors.Green;
                            else
                                color = anotherLine.Color ?? Colors.Green;
                            var lineWidth = LineWidth;
                            if (lineWidth != 1 && lineWidth < 5)
                                lineWidth = 5;

                            _chartObjects.DrawLine(name, indexToSet, this[index], indexToSet, anotherLine[index], color, lineWidth);
                        }
                    }
                    break;
            }
        }
    }
        
    private string GetNameOfHistogramLineOnChartWindow(int index)
    {
        return string.Format("Histogram on chart window {0} {1}", LineWidth, index);
    }

    private string GetArrowName(int index)
    {
        return string.Format("Arrow {0} {1}", GetHashCode(), index);
    }
}
int ArrayResize(Mq4OutputDataSeries array, int new_size)
{
    return array.Length;
}


public Dictionary<int, string> ArrowByIndex = new Dictionary<int, string>{ {0, xArrow},  {1, xArrow},  {2, xArrow},  {3, xArrow},  {4, xArrow},  {5, xArrow},  {6, xArrow},  {7, xArrow}};
    void SetIndexArrow(int index, int code) 
    {
        ArrowByIndex[index] = GetArrowByCode(code);
    }

private int _indicatorCounted;
int FILE_READ = 1;
int FILE_WRITE = 2;
//int FILE_BIN = 8;
int FILE_CSV = 8;

int SEEK_END = 2;

class FileInfo
{
    public int Mode { get; set; }
    public int Handle { get; set; }
    public char Separator { get; set; }
    public string FileName { get; set; }
    public List<string> PendingParts { get; set; }
    public StreamWriter StreamWriter { get; set; }
    public StreamReader StreamReader { get; set; }
}

private Dictionary<int, FileInfo> _openedFiles = new Dictionary<int, FileInfo>();
private int _handleCounter = 1000;
Mq4Double FileOpen(Mq4String filename, Mq4Double mode)
{
    //AccessRights = AccessRights.FileSystem
    return FileOpen(filename, mode, 59);
}

Mq4Double FileOpen(Mq4String filename, Mq4Double mode, Mq4Char separator)
{
    //AccessRights = AccessRights.FileSystem
    var fullFileName = Path.Combine(FolderPaths._2calgoDesktopFolder, filename);
    int handle = 0;
    try
    {
        var directoryPath = Path.GetDirectoryName(fullFileName);
        if (!Directory.Exists(directoryPath))
            Directory.CreateDirectory(directoryPath);

        var intMode = (int)mode;
        if ((intMode & FILE_WRITE) > 0)
        {
            var streamWriter = File.CreateText(fullFileName);
            handle = _handleCounter++;
            var fileInfo = new FileInfo 
            {
                Handle = handle,
                Mode = mode,
                FileName = fullFileName,
                StreamWriter = streamWriter,
                Separator = separator
            };
            _openedFiles.Add(handle, fileInfo);
        }
        else if ((intMode & FILE_READ) > 0)
        {
            var streamReader = new StreamReader(fullFileName);
            handle = _handleCounter++;
            var fileInfo = new FileInfo 
            {
                Handle = handle,
                Mode = mode,
                FileName = fullFileName,
                StreamReader = streamReader,
                Separator = separator
            };
            _openedFiles.Add(handle, fileInfo);
        }
    }
    catch (Exception e)
    {
        Print("Can not open file: " + e.ToString());
        
    }
    return handle;
}


Mq4String FileReadString(Mq4Double handle)
{
    //AccessRights = AccessRights.FileSystem
    try
    {
        FileInfo fileInfo;
        if (!_openedFiles.TryGetValue(handle, out fileInfo))
            return string.Empty;

        if (fileInfo.PendingParts == null || fileInfo.PendingParts.Count == 0)
            fileInfo.PendingParts = fileInfo.StreamReader.ReadLine().Split(fileInfo.Separator).ToList();
    
        if (fileInfo.PendingParts.Count == 0)
            return string.Empty;

        var result = fileInfo.PendingParts[0];
        fileInfo.PendingParts.RemoveAt(0);
        return result;
    }
    catch (Exception e)
    {
        Print("Can not read string from file: " + e.ToString());
        
        return string.Empty;
    }
}

void FileClose(Mq4Double handle) 
{
    //AccessRights = AccessRights.FileSystem
    try
    {
        FileInfo fileInfo;
        if (!_openedFiles.TryGetValue(handle, out fileInfo))
            return;

        _openedFiles.Remove(handle);
        if (fileInfo.StreamWriter != null)
            fileInfo.StreamWriter.Close();
        if (fileInfo.StreamReader != null)
            fileInfo.StreamReader.Close();
    }
    catch (Exception e)
    {
        Print("Can not close file: " + e.ToString());
        
    }
}

class FolderPaths
{
    public static string _2calgoAppDataFolder
    {
        get
        {
            var result = Path.Combine(SystemAppData, "2calgo");
            if (!Directory.Exists(result))
                Directory.CreateDirectory(result);
            return result;
        }
    }

    public static string _2calgoDesktopFolder
    {
        get
        {
            var result = Path.Combine(Desktop, "2calgo");
            if (!Directory.Exists(result))
                Directory.CreateDirectory(result);
            return result;
        }
    }

    static string SystemAppData
    {
        get 
        { 
            return Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); 
        }
    }

    static string Desktop
    {
        get 
        { 
            return Environment.GetFolderPath(Environment.SpecialFolder.Desktop); 
        }
    }
}
const int MODE_TRADES = 0;
const int MODE_HISTORY = 1;
const int SELECT_BY_POS = 0;
const int SELECT_BY_TICKET = 1;

T GetPropertyValue<T>(Func<Position, T> getFromPosition, Func<PendingOrder, T> getFromPendingOrder, Func<HistoricalTrade, T> getFromHistory)
{
    if (_currentOrder == null)
        return default(T);

    return GetPropertyValue<T>(_currentOrder, getFromPosition, getFromPendingOrder, getFromHistory);
}

T GetPropertyValue<T>(object obj, Func<Position, T> getFromPosition, Func<PendingOrder, T> getFromPendingOrder, Func<HistoricalTrade, T> getFromHistory)
{
    if (obj is Position)
        return getFromPosition((Position) obj);
    if (obj is PendingOrder)
        return getFromPendingOrder((PendingOrder) obj);

    return getFromHistory((HistoricalTrade) obj);

private Mq4Double GetTicket(object trade)
{
    return new Mq4Double(GetPropertyValue<int>(trade, _ => _.Id, _ => _.Id, _ => _.ClosingDealId));
}
Mq4Double OrderTicket()
{
    if (_currentOrder == null)
        return 0;

    return GetTicket(_currentOrder);
}
private int GetMagicNumber(string label)
{            
    int magicNumber;
    if (int.TryParse(label, out magicNumber))
        return magicNumber;

    return 0;
}

private int GetMagicNumber(object order)
{    
    var label = GetPropertyValue<string>(order, _ => _.Label, _ => _.Label, _ => _.Label);
    return GetMagicNumber(label);
}
Mq4Double OrderMagicNumber()
{
    if (_currentOrder == null)
        return 0;

    return GetMagicNumber(_currentOrder);
}


Mq4Double OrdersTotal()
{
    return Positions.Count + PendingOrders.Count;
}


Mq4Double OrdersHistoryTotal()
{
    return History.Count;
}
object _currentOrder;
bool OrderSelect(int index, int select, int pool = MODE_TRADES)
{
    _currentOrder = null;

    if (pool == MODE_TRADES)
    {
        var allOrders = Positions.OfType<object>()
                                .Concat(PendingOrders.OfType<object>())
                                .ToArray();

        switch (select)
        {
            case SELECT_BY_POS:    
                if (index < 0 || index >= allOrders.Length)
                    return false;

                _currentOrder = allOrders[index];
                return true;
            case SELECT_BY_TICKET:
                _currentOrder = GetOrderByTicket(index);
                return _currentOrder != null;
        }
    }    
    if (pool == MODE_HISTORY)
    {
        switch (select)
        {
            case SELECT_BY_POS:    
                if (index < 0 || index >= History.Count)
                    return false;

                _currentOrder = History[index];
                return true;
            case SELECT_BY_TICKET:
                _currentOrder = History.FindLast(index.ToString());
                return _currentOrder != null;
        }
    }

    return false;
}
double GetLots(object order)
{
    var volume = GetPropertyValue<long>(order, _ => _.Volume,  _ => _.Volume, _ => _.Volume);
    var symbolCode = GetPropertyValue<string>(order, _ => _.SymbolCode, _ => _.SymbolCode, _ => _.SymbolCode);
    var symbolObject = MarketData.GetSymbol(symbolCode);
    
    return symbolObject.ToLotsVolume(volume);
}

object GetOrderByTicket(int ticket)
{
    var allOrders = Positions.OfType<object>()
                            .Concat(PendingOrders.OfType<object>())
                            .ToArray();

    return allOrders.FirstOrDefault(_ => GetTicket(_) == ticket);
}
Mq4Double OrderLots()
{
    if (_currentOrder == null)
        return 0;

    return GetLots(_currentOrder);
}

Mq4Double OrderType()
{
    if (_currentOrder == null)
        return 0;

    var position = _currentOrder as Position;
    if (position != null)
    {
        return position.TradeType == TradeType.Buy ? OP_BUY : OP_SELL;
    }
    var pendingOrder = _currentOrder as PendingOrder;
    if (pendingOrder != null)
    {
        if (pendingOrder.OrderType == PendingOrderType.Limit)
            return pendingOrder.TradeType == TradeType.Buy ? OP_BUYLIMIT : OP_SELLLIMIT;
        return pendingOrder.TradeType == TradeType.Buy ? OP_BUYSTOP : OP_SELLSTOP;
    }

    var historicalTrade = (HistoricalTrade)_currentOrder;

    return historicalTrade.TradeType == TradeType.Buy ? OP_BUY : OP_SELL;
}

Mq4String OrderSymbol()
{
    return GetPropertyValue<string>(_ => _.SymbolCode, _ => _.SymbolCode, _ => _.SymbolCode);
}
double GetOpenPrice(object order)
{
    return GetPropertyValue<double>(order, _ => _.EntryPrice, _ => _.TargetPrice, _ => _.EntryPrice);
}
Mq4Double OrderOpenPrice()
{
    if (_currentOrder == null)
        return 0;

    return GetOpenPrice(_currentOrder);
}


private double GetStopLoss(object order)
{
    var nullableValue = GetPropertyValue<double?>(order, _ => _.StopLoss, _ => _.StopLoss, _ => 0);
    return nullableValue ?? 0;
}

private double GetTakeProfit(object order)
{
    var nullableValue = GetPropertyValue<double?>(order, _ => _.TakeProfit, _ => _.TakeProfit, _ => 0);
    return nullableValue ?? 0;
}

Mq4Double OrderOpenTime()
{
    var position = _currentOrder as Position;
    if (position != null)
        return Mq4TimeSeries.ToInteger(position.EntryTime);

    var historicalTrade = _currentOrder as HistoricalTrade;
    if (historicalTrade != null)
        return Mq4TimeSeries.ToInteger(historicalTrade.EntryTime);

    return 0;
}


Mq4Double AccountFreeMargin()
{
    return Account.FreeMargin;
}


Mq4Double AccountFreeMarginCheck(Mq4String symbol, Mq4Double cmd, Mq4Double volume)
{
    _lastError = ERR_NO_ERROR;
    var result = Account.FreeMargin - volume * MarketInfo(symbol, MODE_MARGINREQUIRED);
    if (result <= 0)
        _lastError = ERR_NOT_ENOUGH_MONEY;

    return result;
}
class ParametersKey
{
    private readonly object[] _parameters;
    
    public ParametersKey(params object[] parameters)
    {
        _parameters = parameters;        
    }
    
    public override bool Equals(object obj)
    {
        var other = (ParametersKey)obj;
        for (var i = 0; i < _parameters.Length; i++)
        {
            if (!_parameters[i].Equals(other._parameters[i]))
                return false;
        }
        return true;
    }
    
    public override int GetHashCode()
    {
        unchecked
        {
            var hashCode = 0;
            foreach (var parameter in _parameters)
            {
                hashCode = (hashCode*397) ^ parameter.GetHashCode();
            }
            return hashCode;
        }
    }
}

class Cache<TValue>
{
    private Dictionary<ParametersKey, TValue> _dictionary = new Dictionary<ParametersKey, TValue>();
    
    public bool TryGetValue(out TValue value, params object[] parameters)
    {
        var key = new ParametersKey(parameters);
        return _dictionary.TryGetValue(key, out value);
    }
    
    public void Add(TValue value, params object[] parameters)
    {
        var key = new ParametersKey(parameters);
        _dictionary.Add(key, value);
    }
}


        private static MovingAverageType ToMaType(int constant)
        {
            switch (constant)
            {
                case MODE_SMA:
                    return MovingAverageType.Simple;
                case MODE_EMA:
                    return MovingAverageType.Exponential;
                case MODE_LWMA:
                    return MovingAverageType.Weighted;
                default:
                  throw new ArgumentOutOfRangeException("Not supported moving average type");
            }
        }

//{
#region iRSI
        private Mq4Double iRSI(Mq4String symbol, Mq4Double timeframe, Mq4Double period, Mq4Double applied_price, Mq4Double shift)
        {
            var series = ToAppliedPrice(symbol, timeframe, applied_price);
      
            return CalculateRsi(series, period, shift);
        }       
                
        private Mq4Double iRSIOnArray(Mq4DoubleArray mq4Array, Mq4Double total, Mq4Double period, Mq4Double shift) 
        {
            var dataSeries = _mq4ArrayToDataSeriesConverterFactory.Create(mq4Array);
            return CalculateRsi(dataSeries, period, shift);
        }
        
        private double CalculateRsi(DataSeries dataSeries, int period, int shift)
        {     
            var indicator = Indicators.RelativeStrengthIndex(dataSeries, period);
            return indicator.Result[dataSeries.Count - 1 - shift];
        }

#endregion //iRSI    
        //}

//{

    Mq4Double iStochastic(Mq4String symbol, Mq4Double timeframe, Mq4Double kperiod, Mq4Double dperiod, Mq4Double slowing, Mq4Double method, Mq4Double price_field, Mq4Double mode, Mq4Double shift)
    {
        var maType = ToMaType(method);   
        var stochasticMode = method == 0 ? StochasticMode.LowHigh : StochasticMode.CloseClose;        
        var marketSeries = GetSeries(symbol, timeframe);
        var index = marketSeries.Close.Count - 1 - shift;

        var stochasticValues = CalculateStochastic(marketSeries, kperiod, dperiod, slowing, maType, stochasticMode, index);

        switch (mode)
        {
            case MODE_MAIN:
                return stochasticValues.K;
            case MODE_SIGNAL:
                return stochasticValues.D; 
        }

        return 0;
    }

    private struct StochasticParameters
    {
        public int KPeriods;
        public int DPeriods;
        public int KSlowing;
        public MovingAverageType MAType;
        public StochasticMode StochasticMode;
        public MarketSeries MarketSeries;

        public bool Equals(StochasticParameters other)
        {
            return KPeriods == other.KPeriods && DPeriods == other.DPeriods && KSlowing == other.KSlowing && MAType == other.MAType && StochasticMode == other.StochasticMode && Equals(MarketSeries, other.MarketSeries);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            return obj is StochasticParameters && Equals((StochasticParameters) obj);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                var hashCode = KPeriods;
                hashCode = (hashCode*397) ^ DPeriods;
                hashCode = (hashCode*397) ^ KSlowing;
                hashCode = (hashCode*397) ^ (int) MAType;
                hashCode = (hashCode*397) ^ (int) StochasticMode;
                hashCode = (hashCode*397) ^ (MarketSeries != null ? MarketSeries.GetHashCode() : 0);
                return hashCode;
            }
        }
    }

    private class StochasticValues_
    {
        public Mq4Double K { get; private set; }
        public Mq4Double D { get; private set; }

        public StochasticValues_(double k, double d)
        {
            K = k;
            D = d;
        }
    }

    private enum StochasticMode
    {
        LowHigh,
        CloseClose
    }

    private class StochasticIndicator_
    {
        private readonly StochasticParameters _parameters;
        private IndicatorDataSeries _fastK;
        private MovingAverage _slowK;
        private MovingAverage _averageOnSlowK;

        public StochasticIndicator_(
            StochasticParameters stochasticParameters, 
            IIndicatorsAccessor indicatorAccessor, 
            Func<IndicatorDataSeries> dataSeriesFactory)
        {
            _parameters = stochasticParameters;
            _fastK = dataSeriesFactory();
            _slowK = indicatorAccessor.MovingAverage(_fastK, _parameters.KSlowing, _parameters.MAType);
            _averageOnSlowK = indicatorAccessor.MovingAverage(_slowK.Result, _parameters.DPeriods, _parameters.MAType);
        }

        public StochasticValues_ Calculate(int index)
        {
            for (var i = index - _parameters.KSlowing * _parameters.DPeriods; i <= index; i++)
                _fastK[i] = GetFastKValue(i);    

            for (var i = Math.Max(0, index - _parameters.DPeriods); i <= index; i++)
                _slowK.Calculate(i + 1);
            var k = _slowK.Result[index];

            for (var i = Math.Max(0, index - _parameters.DPeriods); i <= index; i++)
                _averageOnSlowK.Calculate(i + 1);    
            var d = _averageOnSlowK.Result[index];

            return new StochasticValues_(k, d);
        }

        private double GetFastKValue(int index)
        {
            DataSeries low = _parameters.MarketSeries.Low;
            DataSeries high = _parameters.MarketSeries.High;
                
            if (_parameters.StochasticMode == StochasticMode.CloseClose)
            {
                low = _parameters.MarketSeries.Close;
                high = _parameters.MarketSeries.Close;
            }
            double minFromPeriod = GetMinFromPeriod(low, index, _parameters.KPeriods);
            double maxFromPeriod = GetMaxFromPeriod(high, index, _parameters.KPeriods);
            return (_parameters.MarketSeries.Close[index] - minFromPeriod) / (maxFromPeriod - minFromPeriod) * 100.0;
        }

        private static double GetMinFromPeriod(DataSeries dataSeries, int endIndex, int periods)
        {
            double num = dataSeries[endIndex];
            for (int index = endIndex; index > endIndex - periods; --index)
            {
                if (dataSeries[index] < num)
                    num = dataSeries[index];
            }
            return num;
        }

        private static double GetMaxFromPeriod(DataSeries dataSeries, int endIndex, int periods)
        {
            double num = dataSeries[endIndex];
            for (int index = endIndex; index > endIndex - periods; --index)
            {
                if (dataSeries[index] > num)
                    num = dataSeries[index];
            }
            return num;
        }
    }
    
    private Dictionary<StochasticParameters, StochasticIndicator_> _stochasticIndicators = new Dictionary<StochasticParameters, StochasticIndicator_>();

    private StochasticValues_ CalculateStochastic(MarketSeries marketSeries, int kPeriod, int dPeriod, int slowing, MovingAverageType maType, StochasticMode stochasticMode, int index)
    {
        var parameters = new StochasticParameters
        {
            KPeriods = kPeriod,
            DPeriods = dPeriod,
            KSlowing = slowing,
            MAType = maType,
            StochasticMode = stochasticMode,
            MarketSeries = marketSeries,
        };

        StochasticIndicator_ indicator;
        if (!_stochasticIndicators.TryGetValue(parameters, out indicator))
        {
            indicator = new StochasticIndicator_(parameters, Indicators, () => CreateDataSeries());
            _stochasticIndicators[parameters] = indicator;
        }

        return indicator.Calculate(index);
    }    
//}

//{
private Mq4Double iMomentumOnArray(Mq4DoubleArray mq4Array, Mq4Double total, Mq4Double period, Mq4Double shift) 
{
    var dataSeries = _mq4ArrayToDataSeriesConverterFactory.Create(mq4Array);

    return Indicators.MomentumOscillator(dataSeries, period).Result[dataSeries.Count - 1 - shift];
}

Mq4Double iMomentum(Mq4String symbol, Mq4Double timeframe, Mq4Double period, Mq4Double applied_price, Mq4Double shift)
{
    var dataSeries = ToAppliedPrice(symbol, timeframe, applied_price);

    return Indicators.MomentumOscillator(dataSeries, period).Result[dataSeries.Count - 1 - shift];
}
//}

class CachedStandardIndicators
    {
        private readonly IIndicatorsAccessor _indicatorsAccessor;

        public CachedStandardIndicators(IIndicatorsAccessor indicatorsAccessor)
        {
            _indicatorsAccessor = indicatorsAccessor;
        }

}
const bool True = true;
const bool False = false;
const bool TRUE = true;
const bool FALSE = false;                
Mq4Null NULL;
const int EMPTY = -1;
const double EMPTY_VALUE = 2147483647;
public const int WHOLE_ARRAY = 0;

const int MODE_SMA = 0; //Simple moving average
const int MODE_EMA = 1; //Exponential moving average,
const int MODE_SMMA = 2; //Smoothed moving average,
const int MODE_LWMA = 3; //Linear weighted moving average. 

const int PRICE_CLOSE = 0; //Close price. 
const int PRICE_OPEN = 1; //Open price. 
const int PRICE_HIGH = 2; //High price. 
const int PRICE_LOW = 3; //Low price. 
const int PRICE_MEDIAN = 4; //Median price, (high+low)/2. 
const int PRICE_TYPICAL = 5; //Typical price, (high+low+close)/3. 
const int PRICE_WEIGHTED = 6; //Weighted close price, (high+low+close+close)/4. 

const int DRAW_LINE = 0;
const int DRAW_SECTION = 1;
const int DRAW_HISTOGRAM = 2;
const int DRAW_ARROW = 3;
const int DRAW_ZIGZAG = 4;
const int DRAW_NONE = 12;

const int STYLE_SOLID = 0;
const int STYLE_DASH = 1;
const int STYLE_DOT = 2;
const int STYLE_DASHDOT = 3;
const int STYLE_DASHDOTDOT = 4;

const int MODE_OPEN = 0;
const int MODE_LOW = 1;
const int MODE_HIGH = 2;
const int MODE_CLOSE = 3;
const int MODE_VOLUME = 4;
const int MODE_TIME = 5;
const int MODE_BID = 9;
const int MODE_ASK = 10;
const int MODE_POINT = 11;
const int MODE_DIGITS = 12;
const int MODE_SPREAD = 13;
const int MODE_TRADEALLOWED = 22;
const int MODE_PROFITCALCMODE = 27;
const int MODE_MARGINCALCMODE = 28;
const int MODE_SWAPTYPE = 26;
const int MODE_TICKSIZE = 17;    
const int MODE_FREEZELEVEL = 33;
const int MODE_STOPLEVEL = 14;
const int MODE_LOTSIZE = 15;
const int MODE_TICKVALUE = 16;    
/*const int MODE_SWAPLONG = 18;
const int MODE_SWAPSHORT = 19;
const int MODE_STARTING = 20;
const int MODE_EXPIRATION = 21;    
*/
const int MODE_MINLOT = 23;
const int MODE_LOTSTEP = 24;
const int MODE_MAXLOT = 25;
/*const int MODE_MARGININIT = 29;
const int MODE_MARGINMAINTENANCE = 30;
const int MODE_MARGINHEDGED = 31;*/
const int MODE_MARGINREQUIRED = 32;

const int OBJ_VLINE = 0;
    const int OBJ_HLINE = 1;
    const int OBJ_TREND = 2;
    const int OBJ_FIBO = 10;

    /*const int OBJ_TRENDBYANGLE = 3;
    const int OBJ_REGRESSION = 4;
    const int OBJ_CHANNEL = 5;
    const int OBJ_STDDEVCHANNEL = 6;
    const int OBJ_GANNLINE = 7;
    const int OBJ_GANNFAN = 8;
    const int OBJ_GANNGRID = 9;
    const int OBJ_FIBOTIMES = 11;
    const int OBJ_FIBOFAN = 12;
    const int OBJ_FIBOARC = 13;
    const int OBJ_EXPANSION = 14;
    const int OBJ_FIBOCHANNEL = 15;*/
    const int OBJ_RECTANGLE = 16;
    /*const int OBJ_TRIANGLE = 17;
    const int OBJ_ELLIPSE = 18;
    const int OBJ_PITCHFORK = 19;
    const int OBJ_CYCLES = 20;*/
    const int OBJ_TEXT = 21;
    const int OBJ_ARROW = 22;
const int OBJ_LABEL = 23;
    
    const int OBJPROP_TIME1 = 0;
    const int OBJPROP_PRICE1 = 1;
    const int OBJPROP_TIME2 = 2;
    const int OBJPROP_PRICE2 = 3;
    const int OBJPROP_TIME3 = 4;
    const int OBJPROP_PRICE3 = 5;
    const int OBJPROP_COLOR = 6;
    const int OBJPROP_STYLE = 7;
    const int OBJPROP_WIDTH = 8;
    const int OBJPROP_BACK = 9;
    const int OBJPROP_RAY = 10;
    const int OBJPROP_ELLIPSE = 11;
    //const int OBJPROP_SCALE = 12;
    const int OBJPROP_ANGLE = 13;//angle for text rotation
    const int OBJPROP_ARROWCODE = 14;
    const int OBJPROP_TIMEFRAMES = 15;
    //const int OBJPROP_DEVIATION = 16;
    const int OBJPROP_FONTSIZE = 100;
    const int OBJPROP_CORNER = 101;
    const int OBJPROP_XDISTANCE = 102;
    const int OBJPROP_YDISTANCE = 103;
    const int OBJPROP_FIBOLEVELS = 200;
    const int OBJPROP_LEVELCOLOR = 201;
    const int OBJPROP_LEVELSTYLE = 202;
    const int OBJPROP_LEVELWIDTH = 203;
    const int OBJPROP_FIRSTLEVEL = 210;

    const int PERIOD_M1 = 1;
const int PERIOD_M5 = 5;
const int PERIOD_M15 = 15;
const int PERIOD_M30 = 30;
const int PERIOD_H1 = 60;
const int PERIOD_H4 = 240;
const int PERIOD_D1 = 1440;
const int PERIOD_W1 = 10080;
const int PERIOD_MN1 = 43200;

const int TIME_DATE = 1;
const int TIME_MINUTES = 2;
const int TIME_SECONDS = 4;

const int MODE_MAIN = 0;
const int MODE_BASE = 0;
const int MODE_PLUSDI = 1;
const int MODE_MINUSDI = 2;
const int MODE_SIGNAL = 1;

const int MODE_UPPER = 1;
const int MODE_LOWER = 2;

const int MODE_GATORLIPS = 3;
const int MODE_GATORJAW = 1;
const int MODE_GATORTEETH = 2;

const int CLR_NONE = 32768; 

const int White = 16777215;
const int Snow = 16448255;
const int MintCream = 16449525;
const int LavenderBlush = 16118015;
const int AliceBlue = 16775408;
const int Honeydew = 15794160;
const int Ivory = 15794175;
const int Seashell = 15660543;
const int WhiteSmoke = 16119285;
const int OldLace = 15136253;
const int MistyRose = 14804223;
const int Lavender = 16443110;
const int Linen = 15134970;
const int LightCyan = 16777184;
const int LightYellow = 14745599;
const int Cornsilk = 14481663;
const int PapayaWhip = 14020607;
const int AntiqueWhite = 14150650;
const int Beige = 14480885;
const int LemonChiffon = 13499135;
const int BlanchedAlmond = 13495295;
const int LightGoldenrod = 13826810;
const int Bisque = 12903679;
const int Pink = 13353215;
const int PeachPuff = 12180223;
const int Gainsboro = 14474460;
const int LightPink = 12695295;
const int Moccasin = 11920639;
const int NavajoWhite = 11394815;
const int Wheat = 11788021;
const int LightGray = 13882323;
const int PaleTurquoise = 15658671;
const int PaleGoldenrod = 11200750;
const int PowderBlue = 15130800;
const int Thistle = 14204888;
const int PaleGreen = 10025880;
const int LightBlue = 15128749;
const int LightSteelBlue = 14599344;
const int LightSkyBlue = 16436871;
const int Silver = 12632256;
const int Aquamarine = 13959039;
const int LightGreen = 9498256;
const int Khaki = 9234160;
const int Plum = 14524637;
const int LightSalmon = 8036607;
const int SkyBlue = 15453831;
const int LightCoral = 8421616;
const int Violet = 15631086;
const int Salmon = 7504122;
const int HotPink = 11823615;
const int BurlyWood = 8894686;
const int DarkSalmon = 8034025;
const int Tan = 9221330;
const int MediumSlateBlue = 15624315;
const int SandyBrown = 6333684;
const int DarkGray = 11119017;
const int CornflowerBlue = 15570276;
const int Coral = 5275647;
const int PaleVioletRed = 9662683;
const int MediumPurple = 14381203;
const int Orchid = 14053594;
const int RosyBrown = 9408444;
const int Tomato = 4678655;
const int DarkSeaGreen = 9419919;
const int Cyan = 16776960;
const int MediumAquamarine = 11193702;
const int GreenYellow = 3145645;
const int MediumOrchid = 13850042;
const int IndianRed = 6053069;
const int DarkKhaki = 7059389;
const int SlateBlue = 13458026;
const int RoyalBlue = 14772545;
const int Turquoise = 13688896;
const int DodgerBlue = 16748574;
const int MediumTurquoise = 13422920;
const int DeepPink = 9639167;
const int LightSlateGray = 10061943;
const int BlueViolet = 14822282;
const int Peru = 4163021;
const int SlateGray = 9470064;
const int Gray = 8421504;
const int Red = 255;
const int Magenta = 16711935;
const int Blue = 16711680;
const int DeepSkyBlue = 16760576;
const int Aqua = 16776960;
const int SpringGreen = 8388352;
const int Lime = 65280;
const int Chartreuse = 65407;
const int Yellow = 65535;
const int Gold = 55295;
const int Orange = 42495;
const int DarkOrange = 36095;
const int OrangeRed = 17919;
const int LimeGreen = 3329330;
const int YellowGreen = 3329434;
const int DarkOrchid = 13382297;
const int CadetBlue = 10526303;
const int LawnGreen = 64636;
const int MediumSpringGreen = 10156544;
const int Goldenrod = 2139610;
const int SteelBlue = 11829830;
const int Crimson = 3937500;
const int Chocolate = 1993170;
const int MediumSeaGreen = 7451452;
const int MediumVioletRed = 8721863;
const int FireBrick = 2237106;
const int DarkViolet = 13828244;
const int LightSeaGreen = 11186720;
const int DimGray = 6908265;
const int DarkTurquoise = 13749760;
const int Brown = 2763429;
const int MediumBlue = 13434880;
const int Sienna = 2970272;
const int DarkSlateBlue = 9125192;
const int DarkGoldenrod = 755384;
const int SeaGreen = 5737262;
const int OliveDrab = 2330219;
const int ForestGreen = 2263842;
const int SaddleBrown = 1262987;
const int DarkOliveGreen = 3107669;
const int DarkBlue = 9109504;
const int MidnightBlue = 7346457;
const int Indigo = 8519755;
const int Maroon = 128;
const int Purple = 8388736;
const int Navy = 8388608;
const int Teal = 8421376;
const int Green = 32768;
const int Olive = 32896;
const int DarkSlateGray = 5197615;
const int DarkGreen = 25600;
const int Fuchsia = 16711935;
const int Black = 0;  

const int SYMBOL_LEFTPRICE = 5;
const int SYMBOL_RIGHTPRICE = 6;

const int SYMBOL_ARROWUP = 241;
const int SYMBOL_ARROWDOWN = 242;
const int SYMBOL_STOPSIGN = 251;
/*
const int SYMBOL_THUMBSUP = 67;
const int SYMBOL_THUMBSDOWN = 68;    
const int SYMBOL_CHECKSIGN = 25;
*/

public const int MODE_ASCEND = 1;
public const int MODE_DESCEND = 2;

const int MODE_TENKANSEN = 1;
const int MODE_KIJUNSEN = 2;
const int MODE_SENKOUSPANA = 3;
const int MODE_SENKOUSPANB = 4;
const int MODE_CHINKOUSPAN = 5;
    const int OP_BUY = 0;
    const int OP_SELL = 1;
    const int OP_BUYLIMIT = 2;
    const int OP_SELLLIMIT = 3;
    const int OP_BUYSTOP = 4;
    const int OP_SELLSTOP = 5;
const int OBJ_PERIOD_M1 = 0x0001;
const int OBJ_PERIOD_M5 = 0x0002;
const int OBJ_PERIOD_M15 = 0x0004;
const int OBJ_PERIOD_M30 = 0x0008;
const int OBJ_PERIOD_H1 = 0x0010;
const int OBJ_PERIOD_H4 = 0x0020;
const int OBJ_PERIOD_D1 = 0x0040;
const int OBJ_PERIOD_W1 = 0x0080;
const int OBJ_PERIOD_MN1 = 0x0100;
const int OBJ_ALL_PERIODS = 0x01FF;

const int REASON_REMOVE = 1;
const int REASON_RECOMPILE = 2;
const int REASON_CHARTCHANGE = 3;
const int REASON_CHARTCLOSE = 4;
const int REASON_PARAMETERS = 5;
const int REASON_ACCOUNT = 6;
const int ERR_NO_ERROR = 0;
const int ERR_NO_RESULT = 1;
const int ERR_COMMON_ERROR = 2;
const int ERR_INVALID_TRADE_PARAMETERS = 3;
const int ERR_SERVER_BUSY = 4;
const int ERR_OLD_VERSION = 5;
const int ERR_NO_CONNECTION = 6;
const int ERR_NOT_ENOUGH_RIGHTS = 7;
const int ERR_TOO_FREQUENT_REQUESTS = 8;
const int ERR_MALFUNCTIONAL_TRADE = 9;
const int ERR_ACCOUNT_DISABLED = 64;
const int ERR_INVALID_ACCOUNT = 65;
const int ERR_TRADE_TIMEOUT = 128;
const int ERR_INVALID_PRICE = 129;
const int ERR_INVALID_STOPS = 130;
const int ERR_INVALID_TRADE_VOLUME = 131;
const int ERR_MARKET_CLOSED = 132;
const int ERR_TRADE_DISABLED = 133;
const int ERR_NOT_ENOUGH_MONEY = 134;
const int ERR_PRICE_CHANGED = 135;
const int ERR_OFF_QUOTES = 136;
const int ERR_BROKER_BUSY = 137;
const int ERR_REQUOTE = 138;
const int ERR_ORDER_LOCKED = 139;
const int ERR_LONG_POSITIONS_ONLY_ALLOWED = 140;
const int ERR_TOO_MANY_REQUESTS = 141;
const int ERR_TRADE_MODIFY_DENIED = 145;
const int ERR_TRADE_CONTEXT_BUSY = 146;
const int ERR_TRADE_EXPIRATION_DENIED = 147;
const int ERR_TRADE_TOO_MANY_ORDERS = 148;
const int ERR_TRADE_HEDGE_PROHIBITED = 149;
const int ERR_TRADE_PROHIBITED_BY_FIFO = 150;
const int ERR_NO_MQLERROR = 4000;
const int ERR_WRONG_FUNCTION_POINTER = 4001;
const int ERR_ARRAY_INDEX_OUT_OF_RANGE = 4002;
const int ERR_NO_MEMORY_FOR_CALL_STACK = 4003;
const int ERR_RECURSIVE_STACK_OVERFLOW = 4004;
const int ERR_NOT_ENOUGH_STACK_FOR_PARAM = 4005;
const int ERR_NO_MEMORY_FOR_PARAM_STRING = 4006;
const int ERR_NO_MEMORY_FOR_TEMP_STRING = 4007;
const int ERR_NOT_INITIALIZED_STRING = 4008;
const int ERR_NOT_INITIALIZED_ARRAYSTRING = 4009;
const int ERR_NO_MEMORY_FOR_ARRAYSTRING = 4010;
const int ERR_TOO_LONG_STRING = 4011;
const int ERR_REMAINDER_FROM_ZERO_DIVIDE = 4012;
const int ERR_ZERO_DIVIDE = 4013;
const int ERR_UNKNOWN_COMMAND = 4014;
const int ERR_WRONG_JUMP = 4015;
const int ERR_NOT_INITIALIZED_ARRAY = 4016;
const int ERR_DLL_CALLS_NOT_ALLOWED = 4017;
const int ERR_CANNOT_LOAD_LIBRARY = 4018;
const int ERR_CANNOT_CALL_FUNCTION = 4019;
const int ERR_EXTERNAL_CALLS_NOT_ALLOWED = 4020;
const int ERR_NO_MEMORY_FOR_RETURNED_STR = 4021;
const int ERR_SYSTEM_BUSY = 4022;
const int ERR_INVALID_FUNCTION_PARAMSCNT = 4050;
const int ERR_INVALID_FUNCTION_PARAMVALUE = 4051;
const int ERR_STRING_FUNCTION_INTERNAL = 4052;
const int ERR_SOME_ARRAY_ERROR = 4053;
const int ERR_INCORRECT_SERIESARRAY_USING = 4054;
const int ERR_CUSTOM_INDICATOR_ERROR = 4055;
const int ERR_INCOMPATIBLE_ARRAYS = 4056;
const int ERR_GLOBAL_VARIABLES_PROCESSING = 4057;
const int ERR_GLOBAL_VARIABLE_NOT_FOUND = 4058;
const int ERR_FUNC_NOT_ALLOWED_IN_TESTING = 4059;
const int ERR_FUNCTION_NOT_CONFIRMED = 4060;
const int ERR_SEND_MAIL_ERROR = 4061;
const int ERR_STRING_PARAMETER_EXPECTED = 4062;
const int ERR_INTEGER_PARAMETER_EXPECTED = 4063;
const int ERR_DOUBLE_PARAMETER_EXPECTED = 4064;
const int ERR_ARRAY_AS_PARAMETER_EXPECTED = 4065;
const int ERR_HISTORY_WILL_UPDATED = 4066;
const int ERR_TRADE_ERROR = 4067;
const int ERR_END_OF_FILE = 4099;
const int ERR_SOME_FILE_ERROR = 4100;
const int ERR_WRONG_FILE_NAME = 4101;
const int ERR_TOO_MANY_OPENED_FILES = 4102;
const int ERR_CANNOT_OPEN_FILE = 4103;
const int ERR_INCOMPATIBLE_FILEACCESS = 4104;
const int ERR_NO_ORDER_SELECTED = 4105;
const int ERR_UNKNOWN_SYMBOL = 4106;
const int ERR_INVALID_PRICE_PARAM = 4107;
const int ERR_INVALID_TICKET = 4108;
const int ERR_TRADE_NOT_ALLOWED = 4109;
const int ERR_LONGS_NOT_ALLOWED = 4110;
const int ERR_SHORTS_NOT_ALLOWED = 4111;
const int ERR_OBJECT_ALREADY_EXISTS = 4200;
const int ERR_UNKNOWN_OBJECT_PROPERTY = 4201;
const int ERR_OBJECT_DOES_NOT_EXIST = 4202;
const int ERR_UNKNOWN_OBJECT_TYPE = 4203;
const int ERR_NO_OBJECT_NAME = 4204;
const int ERR_OBJECT_COORDINATES_ERROR = 4205;
const int ERR_NO_SPECIFIED_SUBWINDOW = 4206;
const int ERR_SOME_OBJECT_ERROR = 4207;
class Mq4ChartObjects
{
    private readonly ChartObjects _algoChartObjects;
    private readonly TimeSeries _timeSeries;

    private readonly Dictionary<string, Mq4Object> _mq4ObjectByName = new Dictionary<string, Mq4Object>();
    private readonly List<string> _mq4ObjectNameByIndex = new List<string>();

    public Mq4ChartObjects(ChartObjects chartObjects, TimeSeries timeSeries)
    {
        _algoChartObjects = chartObjects;
        _timeSeries = timeSeries;
    }

public void Set(string name, int index, Mq4Double value)
    {
        if (!_mq4ObjectByName.ContainsKey(name))
            return;
        _mq4ObjectByName[name].Set(index, value);
        _mq4ObjectByName[name].Draw();
    }
public void SetText(string name, string text, int font_size, string font, int color)
    {
        if (!_mq4ObjectByName.ContainsKey(name))
            return;

Set(name, OBJPROP_COLOR, color);
    }

private T GetObject<T>(string name) where T : Mq4Object
    {
        Mq4Object mq4Object;
        if (!_mq4ObjectByName.TryGetValue(name, out mq4Object))
            return null;
        return mq4Object as T;
    }

}

abstract class Mq4Object : IDisposable
{   
    private readonly ChartObjects _chartObjects;

    protected Mq4Object(string name, int type, ChartObjects chartObjects)
    {
        Name = name;
        Type = type;
        _chartObjects = chartObjects;
    }
      
    public int Type { get; private set; }

    public string Name { get; private set; }

    protected DateTime Time1
    {
        get
        {
            int seconds = Get(OBJPROP_TIME1);
            return Mq4TimeSeries.ToDateTime(seconds);
        }
    }
            
    protected double Price1
    {
        get
        {
            return Get(OBJPROP_PRICE1);
        }
    }

    protected DateTime Time2
    {
        get
        {
            int seconds = Get(OBJPROP_TIME2);
            return Mq4TimeSeries.ToDateTime(seconds);
        }
    }
            
    protected double Price2
    {
        get
        {
            return Get(OBJPROP_PRICE2);
        }
    }

    protected Colors Color
    {
        get
        {                    
            int intColor = Get(OBJPROP_COLOR);
            if (intColor != CLR_NONE)
                return Mq4Colors.GetColorByInteger(intColor);

            return Colors.Yellow;      
        }
    }

    protected int Width
    {
        get
        {
            return Get(OBJPROP_WIDTH);
        }
    }

    protected int Style
    {
        get
        {
            return Get(OBJPROP_STYLE);
        }
    }

    public abstract void Draw();

    private readonly Dictionary<int, Mq4Double> _properties = new Dictionary<int, Mq4Double>
        {
            {OBJPROP_WIDTH, new Mq4Double(1)},
            {OBJPROP_COLOR, new Mq4Double(CLR_NONE)},
            {OBJPROP_RAY, new Mq4Double(1)},

            {OBJPROP_LEVELCOLOR, new Mq4Double(CLR_NONE)},
            {OBJPROP_LEVELSTYLE, new Mq4Double(0)},
            {OBJPROP_LEVELWIDTH, new Mq4Double(1)},
            {OBJPROP_FIBOLEVELS, new Mq4Double(9)},
            {OBJPROP_FIRSTLEVEL + 0, new Mq4Double(0)},
            {OBJPROP_FIRSTLEVEL + 1, new Mq4Double(0.236)},
            {OBJPROP_FIRSTLEVEL + 2, new Mq4Double(0.382)},
            {OBJPROP_FIRSTLEVEL + 3, new Mq4Double(0.5)},
            {OBJPROP_FIRSTLEVEL + 4, new Mq4Double(0.618)},
            {OBJPROP_FIRSTLEVEL + 5, new Mq4Double(1)},
            {OBJPROP_FIRSTLEVEL + 6, new Mq4Double(1.618)},
            {OBJPROP_FIRSTLEVEL + 7, new Mq4Double(2.618)},
            {OBJPROP_FIRSTLEVEL + 8, new Mq4Double(4.236)},
        };

    public virtual void Set(int index, Mq4Double value)
    {
        _properties[index] = value;
    }

    public Mq4Double Get(int index)
    {
        return _properties.ContainsKey(index) ? _properties[index] : new Mq4Double(0);
    }

    private readonly List<string> _addedAlgoChartObjects = new List<string>();

    protected void DrawText(string objectName, string text, int index, double yValue, VerticalAlignment verticalAlignment = VerticalAlignment.Center, HorizontalAlignment horizontalAlignment = HorizontalAlignment.Center, Colors? color = null)
    {
        _addedAlgoChartObjects.Add(objectName);
        _chartObjects.DrawText(objectName, text, index, yValue, verticalAlignment, horizontalAlignment, color);
    }

    protected void DrawText(string objectName, string text, StaticPosition position, Colors? color = null)
    {
        _addedAlgoChartObjects.Add(objectName);
        _chartObjects.DrawText(objectName, text, position, color);
    }

    protected void DrawLine(string objectName, int index1, double y1, int index2, double y2, Colors color, double thickness = 1.0, cAlgo.API.LineStyle style = cAlgo.API.LineStyle.Solid)
    {
        _addedAlgoChartObjects.Add(objectName);
        _chartObjects.DrawLine(objectName, index1, y1, index2, y2, color, thickness, style);
    }

    protected void DrawLine(string objectName, DateTime date1, double y1, DateTime date2, double y2, Colors color, double thickness = 1.0, cAlgo.API.LineStyle style = cAlgo.API.LineStyle.Solid)
    {
        _addedAlgoChartObjects.Add(objectName);
        _chartObjects.DrawLine(objectName, date1, y1, date2, y2, color, thickness, style);
    }

    protected void DrawVerticalLine(string objectName, DateTime date, Colors color, double thickness = 1.0, cAlgo.API.LineStyle style = cAlgo.API.LineStyle.Solid)
    {
        _addedAlgoChartObjects.Add(objectName);
        _chartObjects.DrawVerticalLine(objectName, date, color, thickness, style);
    }

    protected void DrawVerticalLine(string objectName, int index, Colors color, double thickness = 1.0, cAlgo.API.LineStyle style = cAlgo.API.LineStyle.Solid)
    {
        _addedAlgoChartObjects.Add(objectName);
        _chartObjects.DrawVerticalLine(objectName, index, color, thickness, style);
    }

    protected void DrawHorizontalLine(string objectName, double y, Colors color, double thickness = 1.0, cAlgo.API.LineStyle style = cAlgo.API.LineStyle.Solid)
    {
        _addedAlgoChartObjects.Add(objectName);
        _chartObjects.DrawHorizontalLine(objectName, y, color, thickness, style);
    }

    public void Dispose()
    {
        foreach (var name in _addedAlgoChartObjects)
        {
            _chartObjects.RemoveObject(name);
        }
    }
}

class Mq4Arrow : Mq4Object
    {
        private readonly TimeSeries _timeSeries;
        private int _index;

        public Mq4Arrow(string name, int type, ChartObjects chartObjects, TimeSeries timeSeries) 
            : base(name, type, chartObjects)
        {
            _timeSeries = timeSeries;
        }
            
        public override void Set(int index, Mq4Double value)
        {
            base.Set(index, value);
            switch (index)        
            { 
                case OBJPROP_TIME1:                               
                    _index = _timeSeries.GetIndexByTime(Time1);
                    break;
            }
        }

        private int ArrowCode
        {
            get
            {
                return Get(OBJPROP_ARROWCODE);
            }
        }

        public override void Draw()
        {
            string arrowString;
            HorizontalAlignment horizontalAlignment;
            switch (ArrowCode)
            {
                case SYMBOL_RIGHTPRICE:
                    horizontalAlignment = HorizontalAlignment.Right;
                    arrowString = Price1.ToString();
                    break;
                case SYMBOL_LEFTPRICE:
                    horizontalAlignment = HorizontalAlignment.Left;
                    arrowString = Price1.ToString();
                    break;
                default:
                    arrowString = ConvertedRobot.GetArrowByCode(ArrowCode);
                    horizontalAlignment = HorizontalAlignment.Center;
                    break;
            }                
            DrawText(Name, arrowString, _index, Price1, VerticalAlignment.Center, horizontalAlignment, Color);
        }
    }

Mq4Double OrderSend(Mq4String symbol, int cmd, Mq4Double volume, Mq4Double price, Mq4Double slippagePoints, Mq4Double stoploss, 
    Mq4Double takeprofit, Mq4String comment = null, Mq4Double? magic = null, int expiration = 0, int arrow_color = CLR_NONE)
{
    _lastError = ERR_NO_ERROR;
    if (magic == null)
        magic = 0;    
    var label = magic.Value.ToString();

    var symbolObject = GetSymbol(symbol);
    var volumeInUnits = symbolObject.ToUnitsVolume(volume);

    switch (cmd)
    {
        case OP_BUY:
        case OP_SELL:
            {
                var tradeType = cmd == OP_BUY ? TradeType.Buy : TradeType.Sell;
                var slippageInPrice = symbolObject.TickSize * slippagePoints;
                var slippageInPips = (int)Math.Round((double)slippageInPrice / symbolObject.PipSize);
                double? stopLossPips = null;
                if (stoploss != 0)
                    stopLossPips = tradeType == TradeType.Buy ? (symbolObject.Ask - stoploss) / symbolObject.PipSize : (stoploss - symbolObject.Bid) / symbolObject.PipSize;
                double? takeProfitPips = null;
                if (takeprofit != 0)
                    takeProfitPips = tradeType == TradeType.Buy ? (takeprofit - symbolObject.Ask) / symbolObject.PipSize : (symbolObject.Bid - takeprofit) / symbolObject.PipSize;

                var marketOrderResult = ExecuteMarketOrder(tradeType, symbolObject, volumeInUnits, label, stopLossPips, takeProfitPips, slippageInPips, comment);
                
                if (marketOrderResult.IsSuccessful)
                    return GetTicket(marketOrderResult.Position);
                else
                {
                    _lastError = ToMq4ErrorCode(marketOrderResult.Error.Value);
                    return -1;
                }
            }
        case OP_BUYLIMIT:
        case OP_SELLLIMIT:
        case OP_BUYSTOP:
        case OP_SELLSTOP:
            {
                var tradeType = cmd == OP_BUYLIMIT || cmd == OP_BUYSTOP ? TradeType.Buy : TradeType.Sell;

                double? stopLossPips = null;
                if (stoploss != 0)
                    stopLossPips = tradeType == TradeType.Buy ? (price - stoploss) / symbolObject.PipSize : (stoploss - price) / symbolObject.PipSize;
                double? takeProfitPips = null;
                if (takeprofit != 0)
                    takeProfitPips = tradeType == TradeType.Buy ? (takeprofit - price) / symbolObject.PipSize : (price - takeprofit) / symbolObject.PipSize;

                TradeResult placeOrderResult;
                if (cmd == OP_BUYLIMIT || cmd == OP_SELLLIMIT)
                    placeOrderResult = PlaceLimitOrder(tradeType, symbolObject, volumeInUnits, price, label, stopLossPips, takeProfitPips, expiration.ToNullableDateTime(), comment);
                else
                    placeOrderResult = PlaceStopOrder(tradeType, symbolObject, volumeInUnits, price, label, stopLossPips, takeProfitPips, expiration.ToNullableDateTime(), comment);

                if (placeOrderResult.IsSuccessful)
                    return GetTicket(placeOrderResult.PendingOrder);
                else
                {
                    _lastError = ToMq4ErrorCode(placeOrderResult.Error.Value);
                    return -1;
                }
            }
        default:
            throw new Exception("Not supported by converter");            
    }

    return 0;
}
Mq4Double OrderClose(int ticket, double lots, double price, int slippagePoints, int Color = CLR_NONE)
{
    _lastError = ERR_NO_ERROR;

    var position = GetOrderByTicket(ticket) as Position;
    if (position == null)
    {
        _lastError = ERR_INVALID_TICKET;
        return false;
    }
    var symbolObject = MarketData.GetSymbol(position.SymbolCode);
    
    var volumeInUnits = symbolObject.ToUnitsVolume(lots);    
    ClosePosition(position, volumeInUnits);    

    if (!LastResult.IsSuccessful)
        _lastError = ToMq4ErrorCode(LastResult.Error.Value);

    return LastResult.IsSuccessful;
}

}

    //Custom Indicators Place Holder

class Mq4DoubleComparer : IComparer<Mq4Double>
{
    public int Compare(Mq4Double x, Mq4Double y)
    {
        return x.CompareTo(y);
    }
}
class Mq4String
{
    private readonly string _value;
    
    public Mq4String(string value)
    {
        _value = value;
    }

    public static implicit operator Mq4String(string value)
    {
        return new Mq4String(value);
    }
    
    public static implicit operator Mq4String(int value)
    {
        return new Mq4String(value.ToString());
    }
        
    public static implicit operator Mq4String(Mq4Null mq4Null)
    {
        return new Mq4String(null);
    }
    
    public static implicit operator string(Mq4String mq4String)
    {
        if ((object)mq4String == null)
                return null;

        return mq4String._value;
    }
            
    public static implicit operator Mq4String(Mq4Double mq4Double)
    {
        return new Mq4String(mq4Double.ToString());
    }

    public static bool operator <(Mq4String x, Mq4String y)
    {
        return string.Compare(x._value, y._value) == -1;
    }
        
    public static bool operator >(Mq4String x, Mq4String y)
    {
        return string.Compare(x._value, y._value) == 1;
    }
    
    public static bool operator <(Mq4String x, string y)
    {
        return string.Compare(x._value, y) == -1;
    }
        
    public static bool operator >(Mq4String x, string y)
    {
        return string.Compare(x._value, y) == 1;
    }
    public static bool operator <=(Mq4String x, Mq4String y)
    {
        return string.Compare(x._value, y._value) <= 0;
    }
        
    public static bool operator >=(Mq4String x, Mq4String y)
    {
        return string.Compare(x._value, y._value) >= 0;
    }
    
    public static bool operator <=(Mq4String x, string y)
    {
        return string.Compare(x._value, y) <= 0;
    }
        
    public static bool operator >=(Mq4String x, string y)
    {
        return string.Compare(x._value, y) >= 0;
    }
            
    public static bool operator ==(Mq4String x, Mq4String y)
    {
        return string.Compare(x._value, y._value) == 0;
    }
            
    public static bool operator !=(Mq4String x, Mq4String y)
    {
        return string.Compare(x._value, y._value) != 0;
    }
                
    public static bool operator ==(Mq4String x, string y)
    {
        return string.Compare(x._value, y) == 0;
    }
            
    public static bool operator !=(Mq4String x, string y)
    {
        return string.Compare(x._value, y) != 0;
    }
        
    public override string ToString()
    {
        if ((object)this == null)
            return string.Empty;

        return _value.ToString();
    }
    
    public static readonly Mq4String Empty = new Mq4String(string.Empty);

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((Mq4String) obj);
    }

    protected bool Equals(Mq4String other)
    {
        return this == other;
    }

    public override int GetHashCode()
    {
        return (_value != null ? _value.GetHashCode() : 0);
    }
}
struct Mq4Char
{
    char _char;
            
    public Mq4Char(byte code)
    {
        _char = Encoding.Unicode.GetString(new byte[]{code, 0})[0];    
    }

    public Mq4Char(char @char)
    {
        _char = @char;
    }

    public static implicit operator char(Mq4Char mq4Char)
    {
        return mq4Char._char;
    }
    
    public static implicit operator Mq4Char(int code)
    {
        return new Mq4Char((byte)code);
    }
    
    public static implicit operator Mq4Char(string str)
    {
        if (string.IsNullOrEmpty(str) || str.Length == 0)
            return new Mq4Char(' ');
        return new Mq4Char(str[0]);
    }
}
struct Mq4Null
{
    public static implicit operator string(Mq4Null mq4Null)
    {
        return (string)null;
    }

    public static implicit operator int(Mq4Null mq4Null)
    {
        return 0;
    }
    
    public static implicit operator double(Mq4Null mq4Null)
    {
        return 0;
    }
}
static class Comparers
{
    public static IComparer<T> GetComparer<T>()
    {
        if (typeof(T) == typeof(Mq4Double))
            return (IComparer<T>)new Mq4DoubleComparer();

        return Comparer<T>.Default;
    }
}
    static class DataSeriesExtensions
    {
        public static int InvertIndex(this DataSeries dataSeries, int index)
        {
            return dataSeries.Count - 1 - index;
        }

        public static Mq4Double Last(this DataSeries dataSeries, int shift, DataSeries sourceDataSeries)
        {
            return dataSeries[sourceDataSeries.Count - 1 - shift];
        }
    }
    static class TimeSeriesExtensions
    {
        public static DateTime Last(this TimeSeries timeSeries, int index)
        {
            return timeSeries[timeSeries.InvertIndex(index)];
        }

        public static int InvertIndex(this TimeSeries timeSeries, int index)
        {
            return timeSeries.Count - 1 - index;
        }

        public static int GetIndexByTime(this TimeSeries timeSeries, DateTime time)
        {
            var index = timeSeries.Count - 1;
            for (var i = timeSeries.Count - 1; i >= 0; i--)
            {
                if (timeSeries[i] < time)
                {
                    index = i + 1;
                    break;
                }
            }   
            return index;
        }
    }
static class Mq4Colors
{
    public static Colors GetColorByInteger(int integer)
    {
        switch (integer)
        {
            case 16777215: return Colors.White; case 16448255: return Colors.Snow; case 16449525: return Colors.MintCream; case 16118015: return Colors.LavenderBlush; case 16775408: return Colors.AliceBlue; case 15794160: return Colors.Honeydew; case 15794175: return Colors.Ivory; case 16119285: return Colors.WhiteSmoke; case 15136253: return Colors.OldLace; case 14804223: return Colors.MistyRose; case 16443110: return Colors.Lavender; case 15134970: return Colors.Linen; case 16777184: return Colors.LightCyan; case 14745599: return Colors.LightYellow; case 14481663: return Colors.Cornsilk; case 14020607: return Colors.PapayaWhip; case 14150650: return Colors.AntiqueWhite; case 14480885: return Colors.Beige; case 13499135: return Colors.LemonChiffon; case 13495295: return Colors.BlanchedAlmond; case 12903679: return Colors.Bisque; case 13353215: return Colors.Pink; case 12180223: return Colors.PeachPuff; case 14474460: return Colors.Gainsboro; case 12695295: return Colors.LightPink; case 11920639: return Colors.Moccasin; case 11394815: return Colors.NavajoWhite; case 11788021: return Colors.Wheat; case 13882323: return Colors.LightGray; case 15658671: return Colors.PaleTurquoise; case 11200750: return Colors.PaleGoldenrod; case 15130800: return Colors.PowderBlue; case 14204888: return Colors.Thistle; case 10025880: return Colors.PaleGreen; case 15128749: return Colors.LightBlue; case 14599344: return Colors.LightSteelBlue; case 16436871: return Colors.LightSkyBlue; case 12632256: return Colors.Silver; case 13959039: return Colors.Aquamarine; case 9498256: return Colors.LightGreen; case 9234160: return Colors.Khaki; case 14524637: return Colors.Plum; case 8036607: return Colors.LightSalmon; case 15453831: return Colors.SkyBlue; case 8421616: return Colors.LightCoral; case 15631086: return Colors.Violet; case 7504122: return Colors.Salmon; case 11823615: return Colors.HotPink; case 8894686: return Colors.BurlyWood; case 8034025: return Colors.DarkSalmon; case 9221330: return Colors.Tan; case 15624315: return Colors.MediumSlateBlue; case 6333684: return Colors.SandyBrown; case 11119017: return Colors.DarkGray; case 15570276: return Colors.CornflowerBlue; case 5275647: return Colors.Coral; case 9662683: return Colors.PaleVioletRed; case 14381203: return Colors.MediumPurple; case 14053594: return Colors.Orchid; case 9408444: return Colors.RosyBrown; case 4678655: return Colors.Tomato; case 9419919: return Colors.DarkSeaGreen; case 11193702: return Colors.MediumAquamarine; case 3145645: return Colors.GreenYellow; case 13850042: return Colors.MediumOrchid; case 6053069: return Colors.IndianRed; case 7059389: return Colors.DarkKhaki; case 13458026: return Colors.SlateBlue; case 14772545: return Colors.RoyalBlue; case 13688896: return Colors.Turquoise; case 16748574: return Colors.DodgerBlue; case 13422920: return Colors.MediumTurquoise; case 9639167: return Colors.DeepPink; case 10061943: return Colors.LightSlateGray; case 14822282: return Colors.BlueViolet; case 4163021: return Colors.Peru; case 9470064: return Colors.SlateGray; case 8421504: return Colors.Gray; case 255: return Colors.Red; case 16711935: return Colors.Magenta; case 16711680: return Colors.Blue; case 16760576: return Colors.DeepSkyBlue; case 16776960: return Colors.Aqua; case 8388352: return Colors.SpringGreen; case 65280: return Colors.Lime; case 65407: return Colors.Chartreuse; case 65535: return Colors.Yellow; case 55295: return Colors.Gold; case 42495: return Colors.Orange; case 36095: return Colors.DarkOrange; case 17919: return Colors.OrangeRed; case 3329330: return Colors.LimeGreen; case 3329434: return Colors.YellowGreen; case 13382297: return Colors.DarkOrchid; case 10526303: return Colors.CadetBlue; case 64636: return Colors.LawnGreen; case 10156544: return Colors.MediumSpringGreen; case 2139610: return Colors.Goldenrod; case 11829830: return Colors.SteelBlue; case 3937500: return Colors.Crimson; case 1993170: return Colors.Chocolate; case 7451452: return Colors.MediumSeaGreen; case 8721863: return Colors.MediumVioletRed; case 13828244: return Colors.DarkViolet; case 11186720: return Colors.LightSeaGreen; case 6908265: return Colors.DimGray; case 13749760: return Colors.DarkTurquoise; case 2763429: return Colors.Brown; case 13434880: return Colors.MediumBlue; case 2970272: return Colors.Sienna; case 9125192: return Colors.DarkSlateBlue; case 755384: return Colors.DarkGoldenrod; case 5737262: return Colors.SeaGreen; case 2330219: return Colors.OliveDrab; case 2263842: return Colors.ForestGreen; case 1262987: return Colors.SaddleBrown; case 3107669: return Colors.DarkOliveGreen; case 9109504: return Colors.DarkBlue; case 7346457: return Colors.MidnightBlue; case 8519755: return Colors.Indigo; case 128: return Colors.Maroon; case 8388736: return Colors.Purple; case 8388608: return Colors.Navy; case 8421376: return Colors.Teal; case 32768: return Colors.Green; case 32896: return Colors.Olive; case 5197615: return Colors.DarkSlateGray; case 25600: return Colors.DarkGreen; 
            case 0:
            default:
                return Colors.Black;
        }
    }
}
static class EventExtensions
{
    public static void Raise<T1, T2>(this Action<T1, T2> action, T1 arg1, T2 arg2)
    {
        if (action != null)
            action(arg1, arg2);
    }
}    
static class Mq4LineStyles
{
    public static LineStyle ToLineStyle(int style)
    {
        switch (style)
        {
            case 1: 
            return LineStyle.Lines;
            case 2: 
            return LineStyle.Dots;
            case 3: 
            case 4: 
            return LineStyle.LinesDots;
            default:
            return LineStyle.Solid;
        }
    }
}
    class Mq4TimeSeries
    {
        private readonly TimeSeries _timeSeries;
        private static readonly DateTime StartDateTime = new DateTime(1970, 1, 1);

        public Mq4TimeSeries(TimeSeries timeSeries)
        { 
            _timeSeries = timeSeries;
        }

        public static int ToInteger(DateTime dateTime)
        {
          return (int)(dateTime - StartDateTime).TotalSeconds;
        }
            
        public static DateTime ToDateTime(int seconds)
        {
          return StartDateTime.AddSeconds(seconds);
        }
                
        public int this[int index]
        {
            get 
            { 
                if (index < 0 || index >= _timeSeries.Count)
                  return 0;
                  
                DateTime dateTime = _timeSeries[_timeSeries.Count - 1 - index];

                return ToInteger(dateTime); 
            }
        }
    }
static class ConvertExtensions
{
    public static double? ToNullableDouble(this double protection)
    {
        if (protection == 0)
            return null;
        return protection;
    }

    public static DateTime? ToNullableDateTime(this int time)
    {
        if (time == 0)
            return null;

        return Mq4TimeSeries.ToDateTime(time);
    }       

    public static long ToUnitsVolume(this Symbol symbol, double lots) 
    {        
        return symbol.NormalizeVolume(symbol.ToNotNormalizedUnitsVolume(lots));
    }

    public static double ToNotNormalizedUnitsVolume(this Symbol symbol, double lots) 
    {
        if (symbol.Code.Contains("XAU") || symbol.Code.Contains("XAG"))
            return 100 * lots;
            
        return 100000 * lots;
    }

    public static double ToLotsVolume(this Symbol symbol, long volume) 
    {
        if (symbol.Code.Contains("XAU") || symbol.Code.Contains("XAG"))
            return volume * 1.0 / 100;
            
        return volume * 1.0 / 100000;
    }
}
struct Mq4Double : IComparable, IComparable<Mq4Double>
    {
      private readonly double _value;

      public Mq4Double(double value)
      {
        _value = value;
      }
      
      public static implicit operator double(Mq4Double property)
      {
        return property._value;
      }
      
      public static implicit operator int(Mq4Double property)
      {
        return (int)property._value;
      }     

      public static implicit operator bool(Mq4Double property)
      {
        return (int)property._value != 0;
      }

      public static implicit operator Mq4Double(double value)
      {
        return new Mq4Double(value);
      }

      public static implicit operator Mq4Double(int value)
      {
        return new Mq4Double(value);
      }

      public static implicit operator Mq4Double(bool value)
      {
        return new Mq4Double(value ? 1 : 0);
      }

      public static implicit operator Mq4Double(Mq4Null value)
      {
        return new Mq4Double(0);
      }
      
      public static Mq4Double operator +(Mq4Double d1, Mq4Double d2) 
      {
        return new Mq4Double(d1._value + d2._value);
      }
      
      public static Mq4Double operator -(Mq4Double d1, Mq4Double d2) 
      {
        return new Mq4Double(d1._value - d2._value);
      }

      public static Mq4Double operator -(Mq4Double d) 
      {
        return new Mq4Double(-d._value);
      }
      
      public static Mq4Double operator +(Mq4Double d) 
      {
        return new Mq4Double(+d._value);
      }
                  
      public static Mq4Double operator *(Mq4Double d1, Mq4Double d2) 
      {
        return new Mq4Double(d1._value * d2._value);
      }
      
      public static Mq4Double operator /(Mq4Double d1, Mq4Double d2) 
      {
        return new Mq4Double(d1._value / d2._value);
      }
      
      public static bool operator ==(Mq4Double d1, Mq4Double d2) 
      {
        return d1._value == d2._value;
      }
            
      public static bool operator >(Mq4Double d1, Mq4Double d2) 
      {
        return d1._value > d2._value;
      } 
      
      public static bool operator >=(Mq4Double d1, Mq4Double d2) 
      {
        return d1._value >= d2._value;
      }
            
      public static bool operator <(Mq4Double d1, Mq4Double d2) 
      {
        return d1._value < d2._value;
      }
            
      public static bool operator <=(Mq4Double d1, Mq4Double d2) 
      {
        return d1._value <= d2._value;
      }
      
      public static bool operator !=(Mq4Double d1, Mq4Double d2) 
      {
        return d1._value != d2._value;
      }
          
      public override string ToString()
      {
        return _value.ToString();
      }

      public int CompareTo(object obj)
      {
          return _value.CompareTo(obj);
      }

      public int CompareTo(Mq4Double obj)
      {
          return _value.CompareTo(obj);
      }
}   
    class Mq4DoubleTwoDimensionalArray
    {
        private List<Mq4Double> _data = new List<Mq4Double>();
        private List<Mq4DoubleArray> _arrays = new List<Mq4DoubleArray>();
        private readonly Mq4Double _defaultValue;
        private readonly int _size2;
              
        public Mq4DoubleTwoDimensionalArray(int size2)
        {
            _defaultValue = 0;
            _size2 = size2;
        }

        public void Add(Mq4Double value)
        {
            _data.Add(value);
        }

        private void EnsureCountIsEnough(int index)
        {
            while (_arrays.Count <= index)
                _arrays.Add(new Mq4DoubleArray());
        }

        public void Initialize(Mq4Double value)
        {
            for (var i = 0; i < _data.Count; i++)
                _data[i] = value;
        }

        public int Range(int index)
        {
            if (index == 0)
                return _data.Count;
            return this[0].Length;
        }
                     
        public Mq4DoubleArray this[int index]
        {       
            get
            {
                if (index < 0)
                    return new Mq4DoubleArray();

                EnsureCountIsEnough(index);         

                return _arrays[index];
            }       
        }    

        public Mq4Double this[int index1, int index2]
        {       
            get
            {
                if (index1 < 0)
                    return 0;

                EnsureCountIsEnough(index1);         

                return _arrays[index1][index2];
            }    
            set
            {
                if (index1 < 0)
                    return;

                EnsureCountIsEnough(index1);         

                _arrays[index1][index2] = value;
            }   
        }    
    }
    class Mq4DoubleArray : IMq4DoubleArray, IEnumerable
    {
        private List<Mq4Double> _data = new List<Mq4Double>();
        private readonly Mq4Double _defaultValue;
              
        public Mq4DoubleArray(int size = 0)
        {
            _defaultValue = 0;
        }

        public IEnumerator GetEnumerator()
        {
            return _data.GetEnumerator();
        }

        private bool _isInverted;
        public bool IsInverted
        {
            get { return _isInverted; }
            set { _isInverted = value; }
        }

        public void Add(Mq4Double value)
        {
            _data.Add(value);
        }

        private void EnsureCountIsEnough(int index)
        {
            while (_data.Count <= index)
                _data.Add(_defaultValue);
        }

        public int Length 
        {
            get { return _data.Count; }
        }

        public void Resize(int newSize)
        { 
            while (newSize < _data.Count)
                _data.RemoveAt(_data.Count - 1);

            while (newSize > _data.Count)
                _data.Add(_defaultValue);
        }
                     
        public Mq4Double this[int index]
        {       
            get
            {
                if (index < 0)
                    return _defaultValue;    
            
                EnsureCountIsEnough(index);         

                return _data[index];
            }       
            set
            {
                if (index < 0)
                    return;
            
                EnsureCountIsEnough(index);
          
                _data[index] = value;
                Changed.Raise(index, value);
            }
        }
public event Action<int, Mq4Double> Changed;
    }
    class Mq4MarketDataSeries : IMq4DoubleArray
    {
        private DataSeries _dataSeries;

        public Mq4MarketDataSeries(DataSeries dataSeries)
        {
            _dataSeries = dataSeries;
        }

        public Mq4Double this[int index]
        {
            get { return _dataSeries.Last(index); }
            set { }
        }

        public int Length 
        {
            get { return _dataSeries.Count; }
        }

        public void Resize(int newSize)
        {        
        }
    }
    class Mq4StringArray : IEnumerable
    {
        private List<Mq4String> _data = new List<Mq4String>();
        private readonly Mq4String _defaultValue;
              
        public Mq4StringArray(int size = 0)
        {
            _defaultValue = "";
        }

        public IEnumerator GetEnumerator()
        {
            return _data.GetEnumerator();
        }

        private bool _isInverted;
        public bool IsInverted
        {
            get { return _isInverted; }
            set { _isInverted = value; }
        }

        public void Add(Mq4String value)
        {
            _data.Add(value);
        }

        private void EnsureCountIsEnough(int index)
        {
            while (_data.Count <= index)
                _data.Add(_defaultValue);
        }

        public int Length 
        {
            get { return _data.Count; }
        }

        public void Resize(int newSize)
        { 
            while (newSize < _data.Count)
                _data.RemoveAt(_data.Count - 1);

            while (newSize > _data.Count)
                _data.Add(_defaultValue);
        }
                     
        public Mq4String this[int index]
        {       
            get
            {
                if (index < 0)
                    return _defaultValue;    
            
                EnsureCountIsEnough(index);         
          
                return _data[index];
            }       
            set
            {
                if (index < 0)
                    return;
            
                EnsureCountIsEnough(index);
          
                _data[index] = value;
            }
        }    
    }
    interface IMq4DoubleArray
    {        
        Mq4Double this[int index] { get; set; }
        int Length { get; }
        void Resize(int newSize);
    }
    class Mq4ArrayToDataSeriesConverter
    {
        private readonly Mq4DoubleArray _mq4Array;
        private readonly IndicatorDataSeries _dataSeries;

        public Mq4ArrayToDataSeriesConverter(Mq4DoubleArray mq4Array, IndicatorDataSeries dataSeries)
        {
            _mq4Array = mq4Array;
            _dataSeries = dataSeries;
            _mq4Array.Changed += OnValueChanged;
            CopyAllValues();
        }

        private void CopyAllValues()
        {
            for (var i = 0; i < _mq4Array.Length; i++)
            {
                if (_mq4Array.IsInverted)
                    _dataSeries[_mq4Array.Length - i] = _mq4Array[i];
                else
                    _dataSeries[i] = _mq4Array[i];
            }
        }

        private void OnValueChanged(int index, Mq4Double value)
        {            
            int indexToSet;
            if (_mq4Array.IsInverted)
                indexToSet = _mq4Array.Length - index;
            else
                indexToSet = index;

            if (indexToSet < 0)
                return;

            _dataSeries[indexToSet] = value;
        }
    }
    class Mq4ArrayToDataSeriesConverterFactory
    {
        private readonly Dictionary<Mq4DoubleArray, IndicatorDataSeries> _cachedAdapters = new Dictionary<Mq4DoubleArray, IndicatorDataSeries>();
        private Func<IndicatorDataSeries> _dataSeriesFactory;

        public Mq4ArrayToDataSeriesConverterFactory(Func<IndicatorDataSeries> dataSeriesFactory)
        {
            _dataSeriesFactory = dataSeriesFactory;
        }

        public DataSeries Create(Mq4DoubleArray mq4Array)
        {
            IndicatorDataSeries dataSeries;

            if (_cachedAdapters.TryGetValue(mq4Array, out dataSeries))
                return dataSeries;

            dataSeries = _dataSeriesFactory();
            new Mq4ArrayToDataSeriesConverter(mq4Array, dataSeries);
            _cachedAdapters[mq4Array] = dataSeries;

            return dataSeries;
        }
    }

}