GLFX





//GLFX basic information:
//Optimalized for Metatrader 4, build 216
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008 Globus"

// Constants used in the Signals section

#define Buy                +1
#define Sell               -1
#define None                0

// Constant used in T2_SendTrade for ordersend.

#define Failed             -1

//************* User Variables ******************//

extern string     COM_TMT              = "#-# Trade Settings";
extern int        TMT_MaxCntTrades                = 1; //allow this amount of open trade at the same time
extern int        TMT_MaxInDirection              = 1; //allow this amount of open trade at the same direction
int CntBuyDirection; //system holds a count of long trades
int CntSellDirection;//system holds a count of short trades
int               TMT_LastOpenTime;                   //holds a open time of a last trade
extern int        TMT_TimeShiftOrder             =21600; //amount of seconds must pass to allow opening a new trade after a last open trade, active when TMT_MaxCntTrades>1
extern int        TMT_SignalsRepeat            = 3; //to open new trade, wait for confirmation repeated TMT_SignalsRepeat *times
extern bool       TMT_SignalsReset       = true; //if true, open only in case of a explicit consequence signals without interrupt
extern string     TMT_Currency           = "EURUSD"; //Currency pair to be traded
extern string     TMT_Period                = "M15";  //TimeFrame, use the labels from the MT4 buttons
extern int        TMT_Slippage        =  1; // acceptable slippage
extern int        TMT_TP                 = 90;  //Take Profit, it can move higher if EMT_ExitWithTS =true;
extern int        TMT_SL                 = 75;  //Stop Loss
extern bool       TMT_TPfromSL_1On        =true; //count TP from SL as TP=SL+TMT_ADDtoSLforTP
extern int        TMT_ADDtoSLforTP       =2; // when f.e.=2 then TP=SL+2
double TMT_LastOpenDirection[3]; //holds type of the last still open trade(Buy or Sell) and its open price[1] and order ticket[2]
double TMT_LastLostDirection[3];//holds type of the last trade (Buy or Sell) closed with lost and its open price[1] and order ticket[2]
extern bool       TMT_AlternateBuySell   =false; //if it is true than can not be opened a trade in the same direction like the last open trade

extern string     COM_MMT               = "#-# Money Management";
extern double     MMT_Lots                     = 1;        //Money management will override setting
extern double     MMT_MinLot                   = 0.01;	 //Set to be micro safe by default
extern double     MMT_MaxLot                   = 90.0;	 //Set to previous max value by default
extern bool       MMT_UseMManagement            = true; //Money management for lot sizing
extern double     MMT_MaxRisk                  = 0.005;     //Percentage of FreeMargin for trade
extern bool       MMT_DecreaseLots_1On       =false; //use decrease factor , when false then is automaticly set on 100% value
extern string     MMT_DecrLotsPerc           = "080050010";    //9 digit number, 3 digits per subsequent loss 080050010= 080% 050% 010%
int MMT_DecrFactor[3]={80,50,10}; //9 digit number, 3 digits per subsequent loss 080050010= 080% 050% 010%
extern bool       MMT_LimitLosses           = false; //if a certain amount of last closed trades ended in consequent losses and if there is a counter trend , move SL accordind to MMT_TS_SLFactor (leave open trade sooner)
extern int        MMT_ConseqLosses                         =1; //amount of consequent losses to use function limit losses , 0= use always
int MMT_TS_SLFactor[4]                       ={07,14,20,35}; //move SL to +7/14/20(with profit), as soon as it gets 20/30/35+pips profit. 
extern string     MMT_MoveSLwhenProfit = "07142035";// as MMT_TS_SLFactor, but available in extern variables
int MMT_TS_ProfitFactor[4]                   ={20,30,35,55}; // after 55 it will use 35 trailing stop
extern string     MMT_WhenProfitMoveSL = "20303555";// as MMT_TS_ProfitFactor, but available in extern variables
extern bool       MMT_Martingale_1On = true; //After each loss the bet should be increased so, that the win would recover all previous losses plus a small profit
extern bool       MMT_ContIfMGfail = false; //if martingale can not cover all lost continue with the maximal possible lot size
double MMT_MaxAccBalance; //reached max account balance


extern string     COM_CLS               = "#-# Confirmation Signals ";
bool       CLS_NearSR_2Lot_1On         = false;  //Will double lotsize if S&R lines near.
extern bool       CLS_CheckPA_2On               =true; //check profitability a new comming set and then change lot size, it works also if SMT_LookForNextSet=false
extern double     CLS_PA_Increasing           =30; //if a set is profitable, a lot size will increase max about ... %               
extern double     CLS_PA_Decreasing           =30; //if a set is not profitable, a lot size will decrease max about ... %
extern int        CLS_PA_History              =10; //check this amount last closed trades in history
extern bool       CLS_CheckLastTrade_4On       =false; //check if the last trade in the same direction was closed with profit or not 
extern double     CLS_DecrLotsIfLastTrade      =50; //if CLS_CheckLastTrade_4On is on and the last trade was closed with lost decrease a new open trade in the same direction about this amount %


extern string     COM_AOP               = "#-# Only for Auto Optimalization";
extern bool       AOP_Optimalization_1On = false; //Allow to find the best set from a prepared file saved in tester directory of the second terminal
extern int        AOP_OptEveryHours   = 7; //run auto optimalization every certain amount of hours
datetime          AOP_LastAutoOptim; //holds last time of auto optimalization
bool              AOP_OptimRunning=false; // is changing by system
extern int        AOP_ProveCyc_Start=1; //start to optimilizate with the first value
extern int        AOP_ProveCyc_Step=10; //step value when looking for the best set
extern int        AOP_ProveCyc_End=0; //finish, when the third value is reached, if 3-rd=0, then the value is founded in an end of "Optim-xxxxxx-xxx.csv" file
int AOP_SetCount=0;               //how many sets are within Optim file, PC finds alone
extern string     AOP_sorting_GP_PF_EP = "123";// set the priority for filtering-Sorting by Maximal profit,Maximal profit factor  or Maximal expected payoff
int AOP_GP_PF_EP[3] ={1,2,3}; // set the priority for filtering:first sorting by Maximal profit,then Maximal profit factor and finaly by Maximal expected payoff
int AOP_Gross_Profit   = 1; // set the priority for filtering-Sorting by Maximal profit
int AOP_Profit_Factor  = 2; //                               -Sorting by Maximal profit factor        
int AOP_Expected_Payoff= 3; //                               -Sorting by Maximal expected payoff
extern int        AOP_TestDays=3;//set the amount of days for optimization,but if SMT_ProveCurrentSet=true, depends on SMT_ProveHoursBack
extern int        AOP_MinTrCnt           = 2;    //Limitation for the minimum amount of trades within a testing area
extern int        AOP_MaxTrCnt           = 10;   //Limitation for maximal amount of trades within a testing area
bool              AOP_AllowNewTrades     =true; //if there is not a suitable set within auto-optimalization, no new trade will open - it is a system variable
extern double     AOP_MinPercSuitableSets=5; //in percents minimal number of suitables sets from all examined sets within results of optimilization 
extern bool       AOP_ModifyTPSL_2On=false; //with new a set modify TP and SL of all open trades
extern bool       AOP_TPSLpromptly=false;//when a new set is loaded then immediately run function AOP_ModifyTPSL_2On despite of trade enter conditions
extern bool       AOP_TPSLperi=true;//check periodically if there is a condition to run function AOP_ModifyTPSL_2On, trade conditions must be fulfilled
extern int        AOP_TPSLwait=420;//300=every 5 minutes check AOP_TPSLperi
datetime          AOP_TPSLnextRun; //holds time of next running of AOP_ModifyTPSL_2On
extern int        AOP_TPSLmaxChanges=1;//how many times it is allowed to change setting of TP and SL for buy or sell orders
int AOP_TPSLbuyCnt,AOP_TPSLsellCnt; //system holds number of changes, change within AOP_TPSLpromptly not counted

                                                      
extern string     COM_SMT               = "#-# Set Management";
extern bool       SMT_LookForNextSet         = false; //you will use this function when you are looking for the second set from results of the first optimalization
extern bool       SMT_CheckSetBeforeLoading  =false; //if system requieres to load a new set, prove first if it has a profitable history
extern bool       SMT_ProveCurrentSet        =false; //try selected set in history, valid only if testing, don't forget to fill variable FTS_NotTradeFrom2 
extern int        SMT_ProveHoursBack         =72; //76 = prove selected set 76 hours back in history
int               SMT_NextSet                  =0; //number of set readed from a file Set-symbol.csv
int               SMT_CurrentSet                  =0; //a nummber of a set taken from a optim file and currently active
extern int        SMT_CurrentPass               =0; //used within auto-optimalization, here is setted nummber of cycles
int               SMT_CntTrades              =0; //count of history orders
extern int        SMT_CntLosses               =2; //count of consequence losses to activate function  
int               SMT_LastLossTicket          =-1;  //system variable, hold last lossy ticket   
extern bool       SMT_AwayFromLosses        =false; //// if a trade is going agains trend set trailing stop
extern int        SMT_AFL_Range             =5;//change set only if within 5 last trades(=SMT_AFL_Range) is less then 2 (=SMT_AFL_Losses)
extern int        SMT_AFL_Losses            =2; //unprofit closed trades opened within Nr. of SMT_NextSet
extern bool       SMT_ResetTimeShiftOrder=false; //reset TimeShiftOrder and allow to open new trade immediately


extern string     COM_EMT              = "#-# Exit Management";
extern bool       EMT_DecreaseTPOn             =false; // allow to decrease Take Profit value if a counter trend is recognized
extern int        EMT_DecTPShiftBar               =19; //count this function within this amount last bars
extern int        EMT_DecTPShiftPeriod            =0; //0=current period, 2=period about 2 degree higher (f.e. from M15 to H1)
extern bool       EMT_ExitWithTS           = false; //Enable static trailing stops
extern int        EMT_TS                   = 5; //If EMT_TS is enabled, use this pip value for TS
extern int        EMT_MoveTPonTS                =1; //increase Trailing stop by this value in pips each time TS is adjusted. Allows good trades to rise higher
extern bool       EMT_ModifyTSOn               = true; //modify EMT_MoveTPonTS according to distance between TP and SL
extern int        EMT_DelayTS                  = 49; //pips to wait before activating trailing stop
extern int        EMT_BE_SL                    = 0;  //Pips in profit to enable a Break Even SL
extern int        EMT_BE_Profit                = 10; //If 0, this sets trade to BE. If a number, this sets the number of pips in profit to lock in
extern int        EMT_RecrossMax           =0;      //0 disables setting. Close a profit ticket in case of crossing open price x times
extern double     EMT_RecrossCoefGood           =0.9; //close order only if it reached again  max reached price decreased about EMT_RecrossCoefGood %
extern double     EMT_RecrossCoefBad           =0.9; //close order only if it reached again  max reached price decreased about EMT_RecrossCoefBad %
double EMT_bcRecross[1][7]; //holds a couple of last trade with parameters ticket Nr.,recross count,last recrossed bar,max reached price
int EMT_minStop;                                          //Pulled from broker in init(), minimal TS value


extern string     COM_EGF               = "#-# Time Conditional Exit";
extern int        EGF_OnlyProfit_Hours   = 0;       //Setting of 0 disables, 24 = 24 hours -guarantee to exit with a profit
extern int        EGF_ForceHours         = 0;       //Setting of 0 disables, 48 = 48 hours -force to exit
extern bool       EGF_ForceCloseAgainSwap=true; //force to close a trade only if swap is negative
extern int        EGF_OnlyProfit_TS        = 5;	//Trailing stop in pips to use during Grace Exit: should be small
extern bool       EGF_CloseBeforeRollOver=true; //close all opened trade before roll-over, start to close according to times EGF_TimeDayEnd and EGF_TimeBeforeEnd
extern bool       EGF_CloseOnlyOnFriday=true; //close all opened trade before weekend, start to close according to times EGF_TimeDayEnd and EGF_TimeBeforeEnd
extern bool       EGF_KeepWhenSwapOK=true; //if swap is good in a open trade directions and the trade is lossy, keep it unclosed during weekend
extern double     EGF_TimeBeforeEnd = 5.30; //try to close trades this amount hour and minutes before EGF_TimeDayEnd and wait when a trade is in a profit
extern double     EGF_TimeDayEnd = 21.50; //close trades definitely at EGF_TimeDayEnd, excepting is when EGF_KeepWhenSwapOK=true and EGF_CloseOnlyOnFriday=true
extern double     EGF_TimeFridayEnd=22.50; //close trades definitely on Friday at EGF_TimeFridayEnd, excepting is when EGF_KeepWhenSwapOK=true
extern int        EGF_WaitOnProfitInPips=3; //0=disable; when net profit in pips is reached then close this order

double SwapLong,SwapShort; //keep global swaps to save CPU cycles

extern string     COM_EXT                  = "#-# Exceptional trades"; 
//this settins are superior to undermentioned signals, so there is no influence of Entry Signals or Filters
//it is allowed to open more trades then TMT_MaxCntTrades
//this settins should care about trades in unusual situations
extern bool       EXT_ExceptionalTradeOnly=false; //open only exceptional trades
extern bool       EXT_CheckTempTrend = true; //check temporary trend, if it appears, close contra trade orders if SL is close
extern int        EXT_TC_SetSize   = 14; //remember last amount of ticks, amount = EXT_TC_SetSize
extern int        EXT_TC_Relevant  = 11; //if this number from amount of last ticks is in one direction than temporary trend is located
extern int        EXT_TC_PipsToClose  = 3; //if between current price and SL is diference <=EXT_TC_PipsToClose then sooner closing is allowed 
double EXT_TC_LastTick; //remember a last tick
int EXT_TC_Direction; //shows a direction of a discovered temporary trend
double EXT_TC_Store[]; //holds last ticks
extern bool       EXT_OpenDeniedTimeIfSwapOK=true; //open a trade within denied time (according to filter FTE_Time_2On) if swap in a requested direction is positive
bool EXT_IsOpenedTradeIfSwapOK=false; //a sign if a trade is open from the function OpenIfSwapOK


extern string     COM_SGE                  = "#-# Signals and Filters Enabled";
int SGE_signalsRequired;     // calculated on init (a count of signals)
            //These settings turn on/off different signals.Editing these settings is not necessary or recommended
            //  when GLFX is being optimized. New strategies require changes to the signals that are executed.
extern bool       SGE_Envelope_1On           = true; // Envelope signal
extern bool       SGE_SMAD_2On           = true; // Simple Moving Average Difference 
extern bool       SGE_OSMA_3On           = true; // OSMA Cross
extern bool       SGE_MA_Diverg_4On           = true; // Divergence Trading Signal
extern bool       SGE_RSI_low_5On           = false; //RSI is rising, then Buy ; RSI is decreasing, then Sell 
extern bool       SGE_RSI_high_6On           = false; // if RSI<SGS_RSI_High then buy ; if RSI>SGS_RSI_Low then sell, but it needs confirmation of 3 consequence bars
extern bool       SGE_Envelope_HF_7On           = false; // Envelope Filter on a higher timeframe about 2 degree
extern bool       SGE_SMA_HF_8On           = false; // SMA Difference on a higher timeframe about 2 degree 
                           //FILTERS : Enabling these settings reduces the number of trades.
extern bool       FTE_ATR_1On           = true;  //Envelope Filter 
extern bool       FTE_Time_2On           = true;  //only trade during permitted hours
extern bool       FTE_MA_BuyTrend_3On           = false;  //if BUY Signal, check buy trend 
extern bool       FTE_MA_SellTrend_4On           = false; //if SELL Signal, check sell trend
extern bool       FTE_FolMainTrend_5On           = false; //follow main trend 
extern bool       FTE_LocMainTrend_6On           = true; //locate main trend and allow to trade only in its  direction
extern bool       FTE_TemporaryTrend_7On         = true; //find a temporary trend and block to trade agains it
extern bool       FTE_WaitForPeaks_8On           =true;//wait for a next peak and do not enter trades immediately

extern string     COM_SGS1                  = "#-# SGE_Envelope_1On - settings";
extern double     SGS_EnvPerc                  = 0.013;   //Percent deviation from the main line 
extern int        SGS_EnvPer                   = 2;       //ma_period-Averaging period for calculation of the main line 

extern string     COM_SGS2                  = "#-# SGE_SMAD_2On - settings";
extern int        SGS_SMAPer                   = 9; //Averaging period for calculation simple moving average
extern int        SGS_SMA2Bars                 = 7; //Index of the value taken from the indicator buffer (shift relative to the current bar the given amount of periods ago)

extern string     COM_SGS3                  = "#-# SGE_OSMA_3On - settings";
extern int        SGS_OSMAFast                 = 8; //Number of periods for fast moving average calculation
extern int        SGS_OSMASlow                 = 21;//Number of periods for slow moving average calculation
extern double     SGS_OSMASignal               = 7; //Number of periods for signal moving average calculation

extern string     COM_SGS4                  = "#-# SGE_MA_Diverg_4On - settings";
extern int        SGS_Fast_Per              = 4; 
int        SGS_Fast_Price               = PRICE_OPEN;
extern int        SGS_Slow_Per              = 12;
int        SGS_Slow_Price               = PRICE_OPEN;
extern double     SGS_DVmin                = 1; //only needs 1 decimal at most
extern double     SGS_DVmax                = 7; //only needs 1 decimal at most

extern string     COM_SGS5_6                  = "SGE_RSI_low_5On & SGE_RSI_high_6On - settings";
extern int        SGS_RSI_High                 = 70; //max value to confirm buy signal,but in case of condition RSI1>RSI2>RSI3
extern int        SGS_RSI_Low                  = 30; //min value to confirm sell signal,but in case of condition RSI1<RSI2<RSI3
extern int        SGS_RSI_Per                  = 2; //Number of periods for calculation
double SGS_RSI1, SGS_RSI2, SGS_RSI3;   //3 globals saves 6 indicator calls.
int    SGS_RSIBar, SGS_ES4_SRBar;
double SGS_ES4_SR[4]; 

extern string     COM_SGS7                  = "#-# SGE_Envelope_HF_7On - settings";
extern double     SGS_PHEnvPerc                  = 0.016;   //Percent deviation from the main line
extern int        SGS_PHPerEnv                   = 4;       //ma_period-Averaging period for calculation of the main line

extern string     COM_SGS8                  = "#-# SGE_SMA_HF_8On - settings";
extern int        SGS_PHSMAPer                   = 4; //Averaging period for calculation simple moving average
extern int        SGS_PHSMA2Bars                 = 3; //Index of the value taken from the indicator buffer (shift relative to the current bar the given amount of periods ago)


extern string     C0M_FTS1                  = "#-# FTE_ATR_1On - settings";
extern int        FTS_ATR                    = 1;    //Short term period for consolidation
extern double     FTS_minATR                         = 0.0008; //Minimum value to allow trades (f.e. from 0 to 0.5)

extern string        C0M_FTS2               = "#-# FTE_Time_2On - settings";
extern double        FTS_WeekAt1                   = 0;    //Defaults will trader 24 hours Mon-Thu
extern double        FTS_WeekTo1                   = 24;   
extern double        FTS_WeekAt2                   = 24;
extern double        FTS_WeekTo2                   = 24;
extern double        FTS_SunAt                     = 0;    //Sunday trading is disabled
extern double        FTS_SunTo                     = 0;
extern double        FTS_FriAt                     = 0;    //Friday trading ends early
extern double        FTS_FriTo                     = 13.50; // at Friday trade to 13:50 hour/minutes
extern double        FTS_MonAt                     = 4;    //Monday without Japanese Open
extern double        FTS_MonTo                     = 24;
extern datetime      FTS_NotTradeFrom1             =D'2008.02.10 00:00'; //do not open new order within selected time zone ; does not depend on setting FTE_Time_2On
extern datetime      FTS_NotTradeTo1               =D'2008.02.10 00:00'; //it is very useful during the second optimalization; does not depend on setting FTE_Time_2On
extern datetime      FTS_NotTradeFrom2             =D'2034.02.11 00:00'; //the second time filter, also useful within optimalization; does not depend on setting FTE_Time_2On
extern datetime      FTS_NotTradeTo2               =D'2034.02.11 00:00'; // does not depend on setting FTE_Time_2On

extern string     C0M_FTS3_4                = "#-# FTE_MA_BuyTrend_3On & FTE_MA_SellTrend_4On - settings";
extern int        FTS_TrendPer              = 25;
extern int        FTS_TrendShift            = 4;
extern double     FTS_TrendStr              = 17;  //Difference in pips between price and MA.

extern string     C0M_FTS5                = "#-# FTE_FolMainTrend_5On - settings";
extern int        FTS_HorizDist              = 270; // amount bars checked in history to locate a trend 
double            FTS_SR_MaxPoint0,FTS_SR_MinPoint0,FTS_SR_MaxPoint1,FTS_SR_MinPoint1,FTS_SR_MaxPoint2,FTS_SR_MinPoint2;
int               FTS_SR_MaxPos0,FTS_SR_MinPos0,FTS_SR_MaxPos1,FTS_SR_MinPos1,FTS_SR_MaxPos2,FTS_SR_MinPos2,FTS_SR_barsCount;

extern string     C0M_FTS6                = "#-# FTE_LocMainTrend_6On - settings";
extern int        FTS_Distance = 8; // specify how many bars in history this filter calculates
extern int        FTS_TimePerShift = 2; // counts within period times higher (if current period is M15 and FTS_TimePerShift=2, then H1)
extern double     FTS_MaxDiff = 140; // difference in pips in total sum of bars
extern double     FTS_MinSlope=0.3; // slope between the first and the last calculated bar
double FTS_Slope,FTS_Difference,FTS_Bar1,FTS_Bar3;
int FTS_LastBarCnt;

extern string     C0M_FTS8                = "#-# FTE_WaitForPeaks_8On - settings";
extern int        FTS_BarsBack=3; //count of bars where to find max and min price
extern int        FTS_BarsForward=2; //count of bars where the peak is valid
datetime FTS_TimeLimitLong; //system variable, controls a time limitation of the peak
datetime FTS_TimeLimitShort;//system variable, controls a time limitation of the peak
extern double FTS_PeakPerc=0.4; //wait for a peak in a certain distance from actual price given with difference between max and min price 
double FTS_PeakLong; //system variable,holds price of the peak for long trades
double FTS_PeakShort; //system variable,holds price of the peak for short trades
int FTS_PeaksBars; //holds count of bars in the current chart to save CPU


extern string     COM_RCS             = "#-# Record Settings";
extern bool       RCS_WriteLog                 = true; //display and write log event
extern bool       RCS_WriteDebug               = false; //display and write system informations
extern bool       RCS_SaveInFile               =false; //archive all logs into a file
int RCS_LogFilter[9]={0,0,1,1,1,1,1,1,1}; //filter messages what all should be written on printscreen or into a log file,1=true,0=false
//0.signals,1.filters,2.money management,3.open trade,4.all about sets,5.closeing ticket,6.changing strategy,7.all about auto-optimalization,8.common settings 
extern string     RCS_FilterLog = "001111111"; //as RCS_LogFilter, but available in extern variables
int RCS_DebugFilter[9]={0,0,1,1,1,1,1,1,1}; //filter messages what all should be written on printscreen or into a log file,1=true,0=false
extern string     RCS_FilterDebug = "001111111"; // //as RCS_DebugFilter, but available in extern variables
extern string     RCS_EAComment                = "080726"; //attached as trade comment 
extern string     RCS_NameEA     = "GLFX";        // EA's name, under this name a tester looks for this EA
double RCS_LogFileSize=1000000; //The Log file will be devided into files with a given size


extern string     COM_GBV            = "#-# Global Variables";
#define    GBV_MagicNumSet1     080726 //must be unique
int    GBV_maxMagic         =  0; //Set size of magic numbers used
bool   GBV_GreenLight     =  true; //allow or forbid trading, controled by system
int    GBV_LogHandle        = -1; //number of log file
int    GBV_BuySignalCount; //system counts how many buy signals were fulfilled
int    GBV_SellSignalCount;//system counts how many sell signals were fulfilled
double GBV_currentTime; //One global variable saves thousands of CPU cycles.
extern bool       GBV_HideTestIndicators=true; //sets a flag hiding indicators called by the EA


#import  "shell32.dll"           //Connect a dll (provided with Windows)             
  int ShellExecuteA(int hwnd,string Operation,string File,string Parameters,string Directory,int ShowCmd); 
#import
//#include <stderror.mqh>
//#include <stdlib.mqh> 

//----------------------  INIT  --------------------

void init()
  { //Startup Functions, only called once.
    string filename, FileLine,message;
    int cnt,handle,fsize,number;
    double CurrTime;
    double DecrTime;
     
//****************** start -settings for auto-optimalization **************************
    if(SMT_ProveCurrentSet)AOP_TestDays = MathCeil(SMT_ProveHoursBack/24); //set the amount of days for optimization according SMT_ProveHoursBack
    filename="\\optimalization\\tester\\files\\LastOptim.csv";
    handle=FileOpen(filename,FILE_CSV|FILE_READ,';');
    if(handle!=-1) 
      {
        FileClose(handle);
        FileDelete(filename); 
      }  
    if(AOP_Optimalization_1On) //prepare a variable AOP_ProveCyc for autooptimalization
      {     
        filename=StringConcatenate("Optim-",TMT_Currency,"-",TMT_Period,".csv");
        handle=FileOpen(filename,FILE_READ,';'); 
        if(handle==-1)
         {
            message=StringConcatenate("AOP_Optimalization_1On: File ",filename,"does not exist! Tester can not be run!");
            Alert(message);  
            if(RCS_WriteLog) L2_WriteLog(8,message);
            GBV_GreenLight=false;
         }   
        else   
         {
            if(FileSize(handle)>3000) FileSeek(handle,FileSize(handle)-3000,SEEK_SET);
            while(FileIsLineEnding(handle)==false) FileLine=FileReadString(handle);
            while(FileIsEnding(handle)==false)
               {
                  number=StrToInteger(FileReadString(handle)); 
                  while(FileIsLineEnding(handle)==false) FileLine=FileReadString(handle);
                  if(number!=0) AOP_SetCount=number;
               }  
            if(AOP_ProveCyc_End==0) AOP_ProveCyc_End=AOP_SetCount;//if a value is not scritly given, set it according to lengh of a file
            FileClose(handle);  
         }                                                 
      }
    if(AOP_ModifyTPSL_2On && !AOP_TPSLpromptly && !AOP_TPSLperi) Alert("AOP_ModifyTPSL_2On: Can not modify TP or SL, check AOP_TPSLpromptly or AOP_TPSLperi on !"); 
    if(AOP_Optimalization_1On && !IsOptimization() ) AOP_AllowNewTrades=false; //first find a new set and then allow to trade
    
//****************** end -settings for auto-optimalization **************************

    if(SMT_ProveCurrentSet && !AOP_Optimalization_1On && (IsTesting() || IsOptimization()) ) //try selected set in history, valid only if testing
      { //Fill time until you want to prove the set into a variable FTS_NotTradeFrom2 !!
          FTS_NotTradeTo2=D'2035.02.10 00:00'; //selected time must be higher then current time
          FTS_NotTradeTo1=SetTimeFrom(SMT_ProveHoursBack,FTS_NotTradeFrom2);
          FTS_NotTradeFrom1=0;     
      } 


    if(AOP_Optimalization_1On && SMT_LookForNextSet && !IsOptimization())
      {
         message="AOP_Optimalization_1On : Optimalization can not run with a function LookForNextSet when optimalization is not running! System is switching off LookForNextSet !";
         Alert(message);  
         if(RCS_WriteLog) L2_WriteLog(8,message);
         SMT_LookForNextSet=false;
      }
         
    if (SMT_LookForNextSet)
      { 
        filename=StringConcatenate("Sets-",TMT_Currency,"-",TMT_Period,".csv");
        handle=FileOpen(filename,FILE_READ,';'); 
        if(handle==-1)
         {
            message=StringConcatenate("SMT_LookForNextSet: File ",filename,"does not exist! Looking for a set can not start!");
            Alert(message);  
            if(RCS_WriteLog) L2_WriteLog(8,message);
            GBV_GreenLight=false;
         }   
        else   
         {
            FileClose(handle);  
            MM_VarFromFile();            
         }                                                 
       }
      
    if((Symbol() != TMT_Currency) && (Symbol() != TMT_Currency+"m"))
      {
        message=StringConcatenate("TMT_Currency: These settings are designed for ",TMT_Currency," only! Change chart or update TMT_Currency");
        Alert(message);  
        if(RCS_WriteLog) L2_WriteLog(8,message);
        GBV_GreenLight=false;
      }

    if(MMT_MaxLot >MarketInfo(Symbol(),MODE_MAXLOT)) MMT_MaxLot=MarketInfo(Symbol(),MODE_MAXLOT);
    if(MMT_MinLot <MarketInfo(Symbol(),MODE_MINLOT)) MMT_MinLot=MarketInfo(Symbol(),MODE_MINLOT);

    int PerArrayNr[]={1,5,15,30,60,240,1440,10080,43200};
    string PerArrayStr[]={"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
    int PosPer=ArrayBsearch(PerArrayNr,Period(),WHOLE_ARRAY,0,MODE_ASCEND);
    if(PerArrayStr[PosPer]!=TMT_Period) 
      {
        message=StringConcatenate("TMT_Period: These settings are designed for ",TMT_Period," only! Change chart or update TMT_Period");
        Alert(message);  
        if(RCS_WriteLog) L2_WriteLog(8,message);
        GBV_GreenLight=false;
      }   


    //Initial Settings:


    //TODO starting balance for complex money management.
    SGE_signalsRequired=SGE_Envelope_1On+SGE_SMAD_2On+SGE_OSMA_3On+SGE_MA_Diverg_4On+SGE_RSI_low_5On+SGE_RSI_high_6On+SGE_Envelope_HF_7On+SGE_SMA_HF_8On;

    EMT_minStop=MarketInfo(Symbol(),MODE_STOPLEVEL);
    if(EMT_BE_SL<EMT_BE_Profit+EMT_minStop) 
      EMT_BE_Profit=EMT_BE_SL-EMT_minStop;
      
    if(FTS_WeekAt1>FTS_WeekTo1) { Alert("FTS_WeekAt1>FTS_WeekTo1"); GBV_GreenLight = false; }
    if(FTS_WeekAt2>FTS_WeekTo2) { Alert("FTS_WeekAt2>FTS_WeekTo2"); GBV_GreenLight = false; }
    if(FTS_WeekTo1>FTS_WeekAt2) { Alert("FTS_WeekTo1>=FTS_WeekAt2"); GBV_GreenLight = false; }
    if(FTS_SunAt>FTS_SunTo) { Alert("FTS_SunAt>FTS_SunTo"); GBV_GreenLight = false; }
    if(FTS_FriAt>FTS_FriTo) { Alert("FTS_FriAt>FTS_FriTo"); GBV_GreenLight = false; }
    if(FTS_MonAt>FTS_MonTo) { Alert("FTS_MonAt>FTS_MonTo"); GBV_GreenLight = false; }
    
    if(GBV_HideTestIndicators) HideTestIndicators(true);
    else HideTestIndicators(false);
    
    ArrayResize(EXT_TC_Store,EXT_TC_SetSize);
    
    // gain arrays from strings obtained from extern variables  
    TextIntoArray (RCS_FilterLog,"RCS_FilterLog",RCS_LogFilter,1);
    TextIntoArray (RCS_FilterDebug,"RCS_FilterDebug",RCS_DebugFilter,1);   
    TextIntoArray (MMT_MoveSLwhenProfit,"MMT_MoveSLwhenProfit",MMT_TS_SLFactor,2);
    TextIntoArray (MMT_WhenProfitMoveSL,"MMT_WhenProfitMoveSL",MMT_TS_ProfitFactor,2);    
    TextIntoArray (MMT_DecrLotsPerc,"MMT_DecrLotsPerc",MMT_DecrFactor,3);
    TextIntoArray (AOP_sorting_GP_PF_EP,"AOP_sorting_GP_PF_EP",AOP_GP_PF_EP,1);
     
   AOP_Gross_Profit   = AOP_GP_PF_EP[0]; // set the priority for filtering-Sorting by Maximal profit
   AOP_Profit_Factor  = AOP_GP_PF_EP[1]; //                               -Sorting by Maximal profit factor        
   AOP_Expected_Payoff= AOP_GP_PF_EP[2]; //                               -Sorting by Maximal expected payoff
         
    
    if(AOP_Gross_Profit+AOP_Profit_Factor+AOP_Expected_Payoff !=6) 
      {
         message="AOP_sorting_GP_PF_EP: Bad input values! Type 1, 2 and 3 in a sequence which you want to start filtering and together sum = 6";
         Alert(message);  
         if(RCS_WriteLog) L2_WriteLog(8,message);
         Alert("AOP_Optimalization_1On is not allowed !");
         AOP_Optimalization_1On=false;
      }   


    if(MMT_DecreaseLots_1On)
      {
         if(MMT_DecrFactor[0]<MMT_DecrFactor[1] || MMT_DecrFactor[1]<MMT_DecrFactor[2])
            {
               message="MMT_DecrLotsPerc : Usually values should be sorted from max to min !";
               Alert(message);  
               if(RCS_WriteLog) L2_WriteLog(2,message);
            }
      }
    
    //if(!MMT_DecreaseLots_1On) for(cnt=0;cnt<3;cnt++) MMT_DecrFactor[cnt]=100; //same chance for all trade, use it specially with auto-optimalization
   
    if(TMT_TPfromSL_1On) TMT_TP=TMT_SL+TMT_ADDtoSLforTP; //count with different TP then in startup

    SwapLong=MarketInfo(TMT_Currency,MODE_SWAPLONG);
    SwapShort=MarketInfo(TMT_Currency,MODE_SWAPSHORT);
  
    if(EGF_CloseBeforeRollOver && EGF_WaitOnProfitInPips<0)
      {
         message="CloseBeforeRollOver :EGF_WaitOnProfitInPips must be equal or higher then 0! EGF_WaitOnProfitInPips is set to 0!";
         Alert(message);  
         if(RCS_WriteLog) L2_WriteLog(8,message);
         EGF_WaitOnProfitInPips=0;
      }               
         
    if(EGF_CloseBeforeRollOver && FTE_Time_2On) //close all opened trade before roll-over, start to close according to times EGF_TimeDayEnd and EGF_TimeBeforeEnd
      {
         if(EGF_CloseOnlyOnFriday) //check if all variables make sense together
            {
               if(EGF_TimeFridayEnd<FTS_FriTo)
                  {
                     message="EGF_CloseBeforeRollOver: Because EGF_CloseBeforeRollOver and EGF_TimeFridayEnd<FTS_FriTo, trades will be opened and closed immediately !";
                     if(EGF_KeepWhenSwapOK) message=message+" A condition is that swap is negative.";
                     Alert(message);  
                     if(RCS_WriteLog) L2_WriteLog(8,message);
                  }
               if(EGF_TimeFridayEnd+EGF_TimeBeforeEnd<FTS_FriTo)     
                  {
                     message="EGF_CloseBeforeRollOver: Because EGF_CloseBeforeRollOver and EGF_TimeFridayEnd+EGF_TimeBeforeEnd<FTS_FriTo, trades will be opened and closed when a little profit is reached!";
                     if(EGF_KeepWhenSwapOK) message=message+" A condition is that swap is negative.";
                     Alert(message);  
                     if(RCS_WriteLog) L2_WriteLog(8,message);
                  }
            }
         else
            {
               if(EGF_TimeDayEnd<FTS_WeekTo2)
                  {
                     message="EGF_CloseBeforeRollOver: Because EGF_CloseBeforeRollOver and EGF_TimeDayEnd<FTS_WeekTo2, trades will be opened and closed immediately !";
                     if(EGF_KeepWhenSwapOK) message=message+" A condition is that swap is negative.";
                     Alert(message);  
                     if(RCS_WriteLog) L2_WriteLog(8,message);
                  }
               if(EGF_TimeDayEnd+EGF_TimeBeforeEnd<FTS_WeekTo2)     
                  {
                     message="EGF_CloseBeforeRollOver: Because EGF_CloseBeforeRollOver and EGF_TimeDayEnd+EGF_TimeBeforeEnd<FTS_WeekTo2, trades will be opened and closed when a little profit is reached!";
                     if(EGF_KeepWhenSwapOK) message=message+" A condition is that swap is negative.";
                     Alert(message);  
                     if(RCS_WriteLog) L2_WriteLog(8,message);
                  }
            }
      }      // end of close all opened trade before roll-over ...

    if(CLS_CheckLastTrade_4On && !MMT_UseMManagement)
      {
         message="CLS_CheckLastTrade_4On can not be used because MMT_UseMManagement is off!";
         Alert(message);  
         if(RCS_WriteLog) L2_WriteLog(8,message);
      }
      
      
            
   
                          
   if(MMT_Martingale_1On && MMT_DecreaseLots_1On)
      {
         message="MMT_Martingale_1On: MMT_Martingale_1On & MMT_DecreaseLots_1On are on. Be carefull to keep working these two functions together.";
         Alert(message); 
         if(RCS_WriteLog) L2_WriteLog(8,message);
      } 
   MMT_MaxAccBalance=AccountBalance();        
    
}

//---- DEINITIACION
int deinit()
  {
   HideTestIndicators(false);
   if(AOP_Optimalization_1On && IsOptimization()) 
     {
        int handle=FileOpen("LastOptim.csv",FILE_CSV|FILE_WRITE,';');
        FileWrite(handle,SMT_CurrentPass,TimeToStr(FTS_NotTradeFrom2,TIME_DATE|TIME_MINUTES|TIME_SECONDS),TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS));
        FileClose(handle);
     }   


   return(0);
  }  

//----------------------  START  --------------------

void start()
  {
    if(GBV_GreenLight == false) return(0);
    GBV_currentTime=TimeHour(TimeCurrent())+TimeMinute(TimeCurrent())*0.01;    //one global variable saves thousands of CPU cycles
    
    L1_OpenLogFile(RCS_NameEA);
    int ordercount;
    CntBuyDirection=0;
    CntSellDirection=0;
 
//********* beginning of a area for auto optimalization *******    
    if(AOP_Optimalization_1On && !IsOptimization() && AOP_OptimRunning) //provide careing a results of a optimalization to the terminal
      {
         while(IsTesting() && A_CheckStatus()==false) Sleep(10000); // wait 1 sec and be near to reality and allow to use auto-optimalization in tester mode  
         if(A_CheckStatus()==true) 
            {
               if(AutoOptResult(AOP_TestDays,RCS_NameEA,AOP_Gross_Profit,AOP_Profit_Factor,AOP_Expected_Payoff))
                  {
                     MM_VarFromFile(); // set new variables according to voted SMT_CurrentPass 
                     AOP_AllowNewTrades=true;
                  } 
               else 
                  {
                     if(RCS_WriteLog) L2_WriteLog(7,"AOP_Optimalization_1On: Something was bad within a sorting of results from optimalization !");                     
                     AOP_AllowNewTrades=false;
                  }    
               AOP_OptimRunning=false;
               string filename="\\optimalization\\tester\\files\\LastOptim.csv";
               int handle=FileOpen(filename,FILE_CSV|FILE_READ,';');
               if(handle!=-1) 
                {
                  FileClose(handle);
                  FileDelete(filename);  
                }   
               AOP_LastAutoOptim=TimeCurrent();                                
             }     
       }           

    if(AOP_Optimalization_1On && !IsOptimization() && !AOP_OptimRunning) //check if time is ready for looking for a new suitable set
         if(TimeCurrent()>AOP_OptEveryHours*3600+AOP_LastAutoOptim) //run optimalization
            {
               int CheckIfExist=FileOpen("\\optimalization\\tester\\files\\LastOptim.csv",FILE_CSV|FILE_READ,';');
               if(CheckIfExist==-1)//check if optimilization doesn't run under an other EA
                  {
                    if(RCS_WriteLog) L2_WriteLog(7,"AOP_Optimalization_1On: Ready to run optimalization");
                    if(AutoOptStart(AOP_TestDays,RCS_NameEA))AOP_OptimRunning=true; //run optimalization from a tester with a script               
                    else if(RCS_WriteLog) L2_WriteLog(7,"Attempt to optimalize system currupted");
                  } 
               else FileClose(CheckIfExist); //system is ready for optimilization but there is an other EA, for which tester is makeing optimilization  
            }
            
    if(AOP_TPSLnextRun<TimeCurrent() && AOP_ModifyTPSL_2On && AOP_TPSLperi) AOP_ModifyTPSL_2OnFunction(); // modify TP and SL at a given time      
        
//********* end of a area for auto optimalization *******                  
  
    
    if(EXT_CheckTempTrend || FTE_TemporaryTrend_7On) TickContainer(); //check a temporary trend
    
    if (SMT_LookForNextSet && !IsOptimization())
      if (MM_CheckLosses()) MM_VarFromFile(); //use new set if there are more consequence losses then varible "SMT_CntLosses"

    if( ArrayRange(EMT_bcRecross,0) < TMT_MaxCntTrades) ArrayResize(EMT_bcRecross,TMT_MaxCntTrades); //must be checked because TMT_MaxCntTrades should change by a new set

    //*************** Detect open trades *********************//
    for (int cticket = 0; cticket < OrdersTotal(); cticket++) 
      {
       if (OrderSelect(cticket, SELECT_BY_POS) == false)
         continue;

       if (OrderSymbol() != Symbol())
         continue;

       if (OrderMagicNumber() >= GBV_MagicNumSet1 && OrderMagicNumber() <= GBV_MagicNumSet1 + GBV_maxMagic)
         {
           if(OrderOpenTime()>TMT_LastOpenDirection[1]) //holds type of the last open trade 
            {
               TMT_LastOpenDirection[1]=OrderOpenTime();
               TMT_LastOpenDirection[2]=OrderTicket();
               if(OrderType()==OP_BUY) TMT_LastOpenDirection[0]=Buy;
               if(OrderType()==OP_SELL) TMT_LastOpenDirection[0]=Sell; 
            }                 
               
           X1_ManageExit(OrderTicket());
           ordercount++;
           if(OrderType()==OP_BUY) CntBuyDirection++; //count how many long trades are opened
           if(OrderType()==OP_SELL) CntSellDirection++;  //count how many short trades are opened     
         }
      }


    if (TimeCurrent()>FTS_NotTradeFrom1 && TimeCurrent()<FTS_NotTradeTo1) return(0); //do not open new order within selected time zone
    if (TimeCurrent()>FTS_NotTradeFrom2 && TimeCurrent()<FTS_NotTradeTo2) return(0); //the second time filter


    if ( ordercount < TMT_MaxCntTrades && AOP_AllowNewTrades) //check if it is allowed to open new trades
      {
         if(ordercount==0) A1_OpenTrade_If_Signal();
         else if(TMT_LastOpenTime+TMT_TimeShiftOrder<TimeCurrent() && ordercount>0 && !EXT_ExceptionalTradeOnly) A1_OpenTrade_If_Signal();
      } 
      
    if(ordercount==0) EXT_IsOpenedTradeIfSwapOK=false;   
    if(EXT_OpenDeniedTimeIfSwapOK && EGF_CloseBeforeRollOver && ordercount < TMT_MaxCntTrades ) OpenIfSwapOK();

    if(RCS_SaveInFile) FileFlush(GBV_LogHandle);
    
  } //End Start() 



//********************* Check for New Trade *******************//

void A1_OpenTrade_If_Signal()
  { 
    bool enableBuy= true;
    bool enableSell=true;    
    int TradeDirect=A2_Check_If_Signal(TMT_SignalsRepeat,GBV_BuySignalCount,GBV_SellSignalCount);   
     // If the GBV_BuySignalCount or GBV_SellSignalCount exceeds the TMT_SignalsRepeat required
     // then the Buy order or Sell order will be submitted.
     
    if(TradeDirect==0) return; //no signals to open a trade
    if (FTE_WaitForPeaks_8On) 
      {
         FTS_ControlPeaks(TradeDirect);
         Z_F8_BlockTradingFilter8(enableBuy,enableSell);
      }    
    
    if(TradeDirect==1 && CntBuyDirection<TMT_MaxInDirection)
      {
        if(!enableBuy) return;
        if(TMT_AlternateBuySell && TMT_LastOpenDirection[0]==Buy)
         {
            if(RCS_WriteDebug) L3_WriteDebug(3,"TMT_AlternateBuySell: Can not open long trade because the last order was Buy !");         
            return; 
         }   
        if( A1_1_OrderNewBuy(MM_OptimizeLotSize(Buy)*A1_3_EntryConfirmation(OP_BUY)) != Failed)
         {
          GBV_BuySignalCount=0;
         } 
      }
    else if(TradeDirect==-1 && CntSellDirection<TMT_MaxInDirection)
      {
        if(!enableSell) return;
        if(TMT_AlternateBuySell && TMT_LastOpenDirection[0]==Sell)
         {
            if(RCS_WriteDebug) L3_WriteDebug(3,"TMT_AlternateBuySell: Can not open short trade because the last order was Sell !");         
            return; 
         }   
        if( A1_2_OrderNewSell(MM_OptimizeLotSize(Sell)*A1_3_EntryConfirmation(OP_SELL)) != Failed)
         {
          GBV_SellSignalCount=0;
         } 
      }
  }





int A2_Check_If_Signal(int ConsSignal,int& BuySigCnt,int& SellSigCnt)
  { //Check singals and conditions to enter new trade
    int  signalCount;
    bool enableBuy= true;
    bool enableSell=true;

//EntryFilters enable or disable trading, while EntrySignals generate "buy" or "sell"
//EntryFilter should return "false" if trading is still enabled.    
    if (FTE_ATR_1On) //Changed filters to quit ASAP.
      if (Z_F1_BlockTradingFilter1()) return(0);

    if (FTE_Time_2On)
      if (Z_F2_BlockTradingFilter2()) return(0);

    if (FTE_MA_BuyTrend_3On)
      if (Z_F3_BlockTradingFilter3()) { enableBuy=false; BuySigCnt=0; }

    if (FTE_MA_SellTrend_4On)
      if (Z_F4_BlockTradingFilter4()) { enableSell=false; SellSigCnt=0; }

    if (FTE_FolMainTrend_5On)
      if (Z_F5_BlockTradingFilter5(enableBuy,enableSell)) return(0);
 
    if (FTE_LocMainTrend_6On)
      if (Z_F6_BlockTradingFilter6(enableBuy,enableSell)) return(0);      

    if (FTE_TemporaryTrend_7On)
      if (Z_F7_BlockTradingFilter7(enableBuy,enableSell)) return(0);

    if (FTE_WaitForPeaks_8On) Z_F8_BlockTradingFilter8(enableBuy,enableSell);      

    //Check all the EntrySignals for Buy=1 or Sell=-1 values. See constants at top of file.

    if (SGE_Envelope_1On)
      {
        signalCount += Z_S1_EntrySignal1();    
        if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_Envelope_1On: Signal sum: "+signalCount);
      }
    if (SGE_SMAD_2On)
      {
        signalCount += Z_S2_EntrySignal2();    
        if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_SMAD_2On: Signal sum: "+signalCount);
      }
    if (SGE_OSMA_3On)
      {
        signalCount += Z_S3_EntrySignal3();    
        if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_OSMA_3On: Signal sum: "+signalCount);
      }
    if (SGE_MA_Diverg_4On)
      {
        signalCount += Z_S4_EntrySignal4();    
        if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_MA_Diverg_4On: Signal sum: "+signalCount);
      }
    if (SGE_RSI_low_5On)
      {
        signalCount += Z_S5_EntrySignal5();    
        if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_RSI_low_5On: Signal sum: "+signalCount);
      }
    if (SGE_RSI_high_6On)
      {
        signalCount += Z_S6_EntrySignal6();    
        if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_RSI_high_6On: Signal sum: "+signalCount);
      }
    if (SGE_Envelope_HF_7On)
      {
        signalCount += Z_S7_EntrySignal7();    
        if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_Envelope_HF_7On: Signal sum: "+signalCount);
      }
    if (SGE_SMA_HF_8On)
      {
        signalCount += Z_S8_EntrySignal8();    
        if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_SMA_HF_8On: Signal sum: "+signalCount);
      }      
    // Counting up the number of buy or sell signals that happen consecutively.  
    if(enableBuy)
      if(signalCount >= SGE_signalsRequired) 
        { //Check for Buy
          BuySigCnt++;
          SellSigCnt=0; 
        }   
    if(enableSell)
      if(signalCount <= (-1)*SGE_signalsRequired)
        {
          BuySigCnt=0;
          SellSigCnt++;
        }
    if(TMT_SignalsReset)
       if(  (signalCount <= (-1)*SGE_signalsRequired) && (signalCount >= SGE_signalsRequired))
         {//If neither buy nor sell signal is received
           BuySigCnt =0;
           SellSigCnt=0;
         }
    if(RCS_WriteLog) L2_WriteLog(0,"TMT_SignalsReset: signal#:"+signalCount+" ConsSignal:" +ConsSignal+" BuySigCnt:" +BuySigCnt+" SellSigCnt:"+ SellSigCnt);
     
     // If the BuySigCnt or SellSigCnt exceeds the ConsSignal required
     // then the Buy order or Sell order shoul be entered
    if(ConsSignal <= BuySigCnt)return(1); // possibility to open buy order
    else if(ConsSignal <= SellSigCnt)return(-1);// possibility to open sell order
    return(0); //no possibility
  }

 
int A1_1_OrderNewBuy(double lots)  //Trade TP+SL Signals
  { 
    int ticket=T2_SendTrade(TMT_TP, TMT_SL, lots, OP_BUY);
    return(ticket);
  }

int A1_2_OrderNewSell(double lots)   //Trade TP+SL Signals
  { 
    int ticket=T2_SendTrade(TMT_TP, TMT_SL, lots, OP_SELL);
    return(ticket);    
  }

double A1_3_EntryConfirmation(int direction)
{ //Gann Style Support and Resist Lines.
   if(!CLS_NearSR_2Lot_1On) return (1.0);
   double value=1;
   if(SGS_ES4_SRBar>iBars(Symbol(),PERIOD_H4))
   {
      SGS_ES4_SRBar=iBars(Symbol(),PERIOD_H4);
      SGS_ES4_SR[4]=iHigh(Symbol(),PERIOD_H4,1);
      SGS_ES4_SR[0]=iLow(Symbol(),PERIOD_H4,1);
      if(SGS_ES4_SR[4]-SGS_ES4_SR[0]<(TMT_TP+TMT_SL)*Point)
      {
         SGS_ES4_SR[4]=iHigh(Symbol(),PERIOD_D1,1);
         SGS_ES4_SR[0]=iLow(Symbol(),PERIOD_D1,1);
      }
      SGS_ES4_SR[3]=(SGS_ES4_SR[0]+SGS_ES4_SR[4])*0.75;
      SGS_ES4_SR[2]=(SGS_ES4_SR[0]+SGS_ES4_SR[4])*0.5;
      SGS_ES4_SR[1]=(SGS_ES4_SR[0]+SGS_ES4_SR[4])*0.25;
   }
   int next=ArrayBsearch(SGS_ES4_SR,Bid);
   if(direction==OP_SELL) 
   {
      if(Bid+TMT_SL*Point>SGS_ES4_SR[next]) value=2;
   }
   if(direction==OP_BUY) 
   {
      if(next !=0)//safe array
      { 
         if(Bid-TMT_SL*Point<SGS_ES4_SR[next-1]) value=2; 
      }
      else value=1;
   }
   return (value);  
}

bool A1_4_IsTradePossible()
  {
    if(IsTradeAllowed() || !IsTradeContextBusy()) return(true);
    else return(false);
  }  

/*double EntryConfirmation2()
{ //TODO Speed Angle Check
return(1.0);
}
*/

/*double EntryConfirmation3()
{ //TODO 4-7 Rule
return(1.0);
}
*/

//********************* Money Management *****************//

double MM_OptimizeLotSize(int direction)
  {
    double lots         =MMT_Lots;
    int    orders       =OrdersHistoryTotal();
    int    i            =orders-1;
    int    trades       =0;
    double    wins         =0;
    double    losses       =0;
    double lotStep=MarketInfo(Symbol(),MODE_LOTSTEP);    
    double changeLot;
    int    ticket;
    bool FirstLost=false;
    
    if(MMT_UseMManagement) lots=(AccountFreeMargin()*MMT_MaxRisk)/(MarketInfo(Symbol(),MODE_TICKVALUE)*TMT_SL);
    else lots=MMT_Lots;
    
    if(CLS_CheckPA_2On)
      {
       MM_CheckSet(SMT_CurrentSet,CLS_PA_History,ticket,wins,losses);
       if(wins+losses!=0) //no history for this set
         { 
           if(wins>losses) changeLot=(wins/(wins+losses))*(CLS_PA_Increasing/100);
           else            changeLot=((-1)*losses/(wins+losses))*(CLS_PA_Decreasing/100);
           if(RCS_WriteDebug) L3_WriteDebug(2,StringConcatenate("CLS_CheckPA_2On: wins : ",wins," losses : ",losses," changeLot : ",changeLot," CLS_PA_Increasing : ",CLS_PA_Increasing," CLS_PA_Decreasing : ",CLS_PA_Decreasing));
           wins=0;
           losses=0;
           if(RCS_WriteLog) L2_WriteLog(2,"CLS_CheckPA_2On: Changing basic lots size about "+changeLot);
           lots=lots+changeLot*lots;
         }  
     
      }
    
    while (i > 0 || (!FirstLost && trades<3))
      {
            if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)
              {
                if(RCS_WriteLog) L2_WriteLog(2,"MMT_DecrLotsPerc: Decrease factor noticed error in history!");
                break;
              }
            if(OrderSymbol()==Symbol() && OrderType()<=OP_SELL)
              {
                if(OrderProfit()<0 && trades<3) losses++;
                if(OrderProfit()>0 && trades<3) wins++;
                trades++;   
                if(OrderProfit()<0 && TMT_LastLostDirection[1]<=OrderCloseTime())
                  {
                     TMT_LastLostDirection[1]=OrderCloseTime(); //holds the last lossy trade
                     TMT_LastLostDirection[2]=OrderTicket();
                     if(OrderType()==OP_BUY) TMT_LastLostDirection[0]=Buy;
                     else TMT_LastLostDirection[0]=Sell;
                     FirstLost=true;
                     if(RCS_WriteDebug) L3_WriteDebug(2,"TMT_LastLostDirection: Last lossy trade : ticket Nr."+OrderTicket()) ;                     
                  }   
              }
            i--;
      }

    if(CLS_CheckLastTrade_4On)
      {
         if(TMT_LastLostDirection[0]==direction)
           {
             lots=lots*( (100-CLS_DecrLotsIfLastTrade)/100); //if CLS_CheckLastTrade_4On is on and the last trade was closed with lost decrease a new open trade in the same direction about this amount %
             if(RCS_WriteLog) L2_WriteLog(2,"CLS_CheckLastTrade_4On: Basic lots were decreased about "+CLS_DecrLotsIfLastTrade+"%");
           }  
         else if(RCS_WriteDebug) L3_WriteDebug(2,"CLS_CheckLastTrade_4On: No need to decrease basic lot!");
      }   
   
    if(MMT_Martingale_1On)
      {
         if(MMT_MaxAccBalance>AccountBalance())
            {
               changeLot=(MMT_MaxAccBalance-AccountBalance())/((TMT_TP-MarketInfo(Symbol(),MODE_SPREAD)) *MarketInfo(Symbol(),MODE_TICKVALUE));
               if(changeLot>lots)
                  {
                     if(RCS_WriteDebug) L3_WriteDebug(2,"MMT_Martingale_1On: Because AccountBalance was recently higher, lots will be increase from "+lots+" to "+changeLot);
                     lots=changeLot;                  
                  }
            }      
      }

    changeLot=AccountFreeMargin()/MarketInfo(Symbol(),MODE_MARGINREQUIRED);
    if(lots>changeLot && MMT_ContIfMGfail) 
      {
         if(RCS_WriteDebug) L3_WriteDebug(2,"MMT_Martingale_1On: Not possible to cover all lost. Neccesary lot value is "+lots+", but the account allows to use only "+changeLot);
         lots=changeLot;
      }

    if(MMT_DecreaseLots_1On) 
      {
         if(RCS_WriteDebug) L3_WriteDebug(2,"MMT_DecrLotsPerc: Decrease Factors "+MMT_DecrFactor[0]+" "+MMT_DecrFactor[1]+" "+MMT_DecrFactor[2]) ;
         if (losses==1)lots=lots*MMT_DecrFactor[0]*0.01;   
         if (losses==2)lots=lots*MMT_DecrFactor[1]*0.01;   
         if (losses>=3)lots=lots*MMT_DecrFactor[2]*0.01;   
         if(RCS_WriteDebug) L3_WriteDebug(2,"MMT_DecrLotsPerc: wins: "+wins+" losses: "+losses+"  lots: "+lots);
      }
      
    
    if(MMT_MaxAccBalance<AccountBalance()) MMT_MaxAccBalance=AccountBalance();  
    if(lots<MMT_MinLot) { lots=MMT_MinLot; if(RCS_WriteLog) L2_WriteLog(2,"MMT_DecrLotsPerc: lots switched to min "+lots); }
    if(lots>MMT_MaxLot) { lots=MMT_MaxLot; if(RCS_WriteLog) L2_WriteLog(2,"MMT_DecrLotsPerc: lots switched to max "+lots); }

    lots /=lotStep;
    lots  = MathFloor(lots);
    lots *= lotStep;

    return(lots);
  }

int T2_SendTrade(int TP, int SL, double lot, int order, int incMagic = 0)  //Execute Trades
  { 
    double price;
    color  arrow;
    int    ticket;

    string tradecomment= StringConcatenate(RCS_EAComment," GX ",incMagic,"#",SMT_CurrentSet);
    RefreshRates();

    if (order %2==OP_BUY)
      { //if number is even
        price =  Ask;
        arrow =  Navy;
      }

    if (order %2==OP_SELL)
      { //if number is odd
        price =  Bid;
        SL    = -SL;
        TP    = -TP;
        arrow =  Magenta;
      }
      
    if(!A1_4_IsTradePossible()) return(Failed);
    if(AccountFreeMarginCheck(Symbol(),order,lot)<0)
      {
        if(RCS_WriteLog) L2_WriteLog(3,"AccountFreeMarginCheck - not enough money to open a new trade");
        GBV_GreenLight=false;
      }    
    else ticket = OrderSend( Symbol(),
                        order,
                        lot,
                        price,
                        TMT_Slippage,
                        price-SL*Point,
                        price+TP*Point,
                        tradecomment,
                        GBV_MagicNumSet1 + incMagic,
                        0, 
                        arrow );

    if (ticket != Failed)
      {
        if(RCS_WriteLog) L2_WriteLog(3,"New trade-Ticket Nr."+ticket+" "+Symbol()+" order:"+order+" lot:"+lot+" price:"+price+" SL:"+(price-SL*Point)+" TP:"+(price+TP*Point));
        TMT_LastOpenTime=TimeCurrent();
        return (ticket); //TODO use ticket number somehow
      } 
    else
      {
        int error=GetLastError();
        if(RCS_WriteLog) L2_WriteLog(3,"New trade-Error:"+error+" "+Symbol()+" order:"+order+" lot:"+lot+" price:"+price+" SL:"+(price-SL*Point)+" TP:"+(price+TP*Point));
        return (Failed); 
      }
  }


bool MM_VarFromFile()  
{
   int ticket  =0;
   double wins    =0;
   double losses  =0;
   int range=SMT_AFL_Range;
   int pass,newpass=-1;
   string variable,file,message;
   int futureset,fsize;
   double pointer;

   if(SMT_CheckSetBeforeLoading && !IsOptimization() && SMT_CurrentSet!=0)
      {
        if(!MM_CheckSet(SMT_NextSet,range,ticket,wins,losses))
         {
          if(RCS_WriteLog) L2_WriteLog(4,"SMT_CheckSetBeforeLoading: Set "+SMT_NextSet+" denied!. Stay with a old set!");
          //MMT_ConseqLosses=2;
        //  SMT_CntLosses=2;          
          return(false);
         } 
      }
   if (IsOptimization() || AOP_Optimalization_1On) file=StringConcatenate("Optim-",TMT_Currency,"-",TMT_Period,".csv");
   else file=StringConcatenate("Sets-",TMT_Currency,"-",TMT_Period,".csv");
   int handle=FileOpen(file,FILE_CSV|FILE_READ,';');

   if (handle<1) 
      {
        int error=GetLastError();
        if(RCS_WriteLog) L2_WriteLog(4,"AOP_Optimalization_1On: Error:"+error+" File "+file+" does not exist !");
        return(false);
      } 
   
   if (IsOptimization() || AOP_Optimalization_1On)
      {
         futureset=SMT_CurrentPass;
         fsize=FileSize(handle);
         pointer=((fsize*SMT_CurrentPass)/AOP_SetCount)-5000; //for quicker running set a starting point near to SMT_CurrentPass
         if(pointer>0) 
          {
             FileSeek(handle,pointer,SEEK_SET);
             while(FileIsLineEnding(handle)==false) variable=FileReadString(handle);
          }
          
      }  
   else futureset=SMT_NextSet;
         
   while(FileIsEnding(handle)==false && pass<=futureset && newpass==-1)
      {
        pass=StrToInteger(FileReadString(handle));
        if (futureset==0) futureset=pass;
        
        while(FileIsLineEnding(handle)==false && FileIsEnding(handle)==false) 
         {
           variable=FileReadString(handle);
           if (pass==futureset) 
            {
              MM_FindVar(variable);
              SMT_CurrentSet=pass;
            }  
         }
        if (pass==futureset) 
         {
           variable=FileReadString(handle);
           if (FileIsEnding(handle)==false) newpass=StrToInteger(variable);
           else 
            {
                   FileSeek(handle,0,SEEK_SET);
                   newpass=StrToInteger(FileReadString(handle));
            }  
         }
      }
   SMT_NextSet=newpass;
   message=StringConcatenate("AOP_Optimalization_1On: Set was changed. A current set is ",SMT_CurrentSet,".");
   if(!AOP_Optimalization_1On) message=StringConcatenate(message," A next set will be ",SMT_NextSet);
   if(RCS_WriteLog) L2_WriteLog(4,message);
   FileClose(handle);
   if(AOP_ModifyTPSL_2On && AOP_TPSLpromptly) 
      {
         AOP_TPSLbuyCnt=0;
         AOP_TPSLsellCnt=0;
         AOP_ModifyTPSL_2OnFunction();
      }   
   AOP_TPSLbuyCnt=0;
   AOP_TPSLsellCnt=0;
   if(SMT_ResetTimeShiftOrder) TMT_LastOpenTime=0; //allow to open new trade immediately if max count of trades is less than limit
   if(TMT_TPfromSL_1On) TMT_TP=TMT_SL+TMT_ADDtoSLforTP; //count with different TP then in startup
 
   return(true);
}

bool MM_FindVar(string variable)
{
  int pos=StringFind(variable,"=",0);
  if (pos==-1) return(false);
  string var=StringSubstr(variable,0,pos);
  string value=StringSubstr(variable,pos+1,StringLen(variable)-1);
  double val=StrToDouble(value);
  //Print (variable," var : ",var," val : ",val);
/*  if(SMT_CurrentSet==10) 
   {
      int handle=FileOpen("zk.csv",FILE_CSV|FILE_READ|FILE_WRITE,';');
      FileSeek(handle,0,SEEK_END);
      FileWrite(handle,variable," var : ",var," val : ",val);
      FileClose(handle);
   }   */

  //if(var=="TMT_MaxCntTrades")        TMT_MaxCntTrades=val;
  //if(var=="TMT_TimeShiftOrder")      TMT_TimeShiftOrder=val;
  //if(var=="TMT_SignalsRepeat")       TMT_SignalsRepeat=val;
  //if(var=="TMT_SignalsReset")  TMT_SignalsReset=val;
  if(var=="TMT_Currency")            TMT_Currency=val;
  if(var=="TMT_Period")             TMT_Period=val;
  //if(var=="TMT_Slippage")      TMT_Slippage=val;
  if(var=="TMT_TP")                    TMT_TP=val;
  if(var=="TMT_SL")                    TMT_SL=val;
  if(var=="TMT_TPfromSL_1On")          TMT_TPfromSL_1On=val;
  if(var=="TMT_ADDtoSLforTP")          TMT_ADDtoSLforTP=val;  
  //if(var=="MMT_Lots")                MMT_Lots=val;
  //if(var=="MMT_MinLot")              MMT_MinLot=val;
  //if(var=="MMT_MaxLot")              MMT_MaxLot=val;
  //if(var=="MMT_UseMManagement")      MMT_UseMManagement=val;
  //if(var=="MMT_MaxRisk")             MMT_MaxRisk=val;
  //if(var=="MMT_LimitLosses")     MMT_LimitLosses=val;
  //if(var=="MMT_ConseqLosses")        MMT_ConseqLosses=val;
  //if(var=="MMT_MoveSLwhenProfit")    MMT_MoveSLwhenProfit=val;  
  //if(var=="MMT_WhenProfitMoveSL")    MMT_WhenProfitMoveSL=val; 

  //if(var=="CLS_NearSR_2Lot_1On")    CLS_NearSR_2Lot_1On=val;
  //if(var=="CLS_CheckPA_2On")         CLS_CheckPA_2On=val;
  //if(var=="CLS_PA_Increasing")       CLS_PA_Increasing=val;
  //if(var=="CLS_PA_Decreasing")       CLS_PA_Decreasing=val;
  //if(var=="CLS_PA_History")          CLS_PA_History=val;
  //if(var=="MMT_DecreaseLots_1On")   MMT_DecreaseLots_1On=val;
  //if(var=="MMT_DecrLotsPerc")      MMT_DecrLotsPerc=val;
  //if(var=="AOP_Optimalization_1On")  AOP_Optimalization_1On=val;
  //if(var=="AOP_OptEveryHours")       AOP_OptEveryHours=val;
  //if(var=="AOP_Gross_Profit")        AOP_Gross_Profit=val;
  //if(var=="AOP_Profit_Factor")       AOP_Profit_Factor=val;
  //if(var=="AOP_Expected_Payoff")     AOP_Expected_Payoff=val;
  //if(var=="AOP_TestDays")             AOP_TestDays=val;
  //if(var=="AOP_MinTrCnt")            AOP_MinTrCnt=val;
  //if(var=="AOP_MaxTrCnt")            AOP_MaxTrCnt=val;
  //if(var=="AOP_MinPercSuitableSets") AOP_MinPercSuitableSets=val;
  //if(var=="AOP_ModifyTPSL_2On")      AOP_ModifyTPSL_2On=val;
  //if(var=="AOP_TPSLpromptly")        AOP_TPSLpromptly=val;
  //if(var=="AOP_TPSLperi")            AOP_TPSLperi=val;
  //if(var=="AOP_TPSLwait")            AOP_TPSLwait=val;

  //if(var=="AOP_TPSLmaxChanges")      AOP_TPSLmaxChanges=val;
  //if(var=="SMT_LookForNextSet")      SMT_LookForNextSet=val;
  //if(var=="SMT_CheckSetBeforeLoading") SMT_CheckSetBeforeLoading=val;
  //if(var=="SMT_ProveCurrentSet")     SMT_ProveCurrentSet=val;
  //if(var=="SMT_ProveHoursBack")      SMT_ProveHoursBack=val;
  //if(var=="SMT_CntLosses")           SMT_CntLosses=val;

  //if(var=="SMT_AwayFromLosses")      SMT_AwayFromLosses=val;
  //if(var=="SMT_AFL_Range")           SMT_AFL_Range=val;
  //if(var=="SMT_AFL_Losses")          SMT_AFL_Losses=val;

  //if(var=="EMT_DecreaseTPOn")        EMT_DecreaseTPOn=val;
  if(var=="EMT_DecTPShiftBar")         EMT_DecTPShiftBar=val;
  if(var=="EMT_DecTPShiftPeriod")      EMT_DecTPShiftPeriod=val;
  //if(var=="EMT_ExitWithTS")      EMT_ExitWithTS=val;
  if(var=="EMT_TS")              EMT_TS=val;
  if(var=="EMT_MoveTPonTS")            EMT_MoveTPonTS=val;
  //if(var=="EMT_ModifyTSOn")       EMT_ModifyTSOn=val;
  if(var=="EMT_DelayTS")               EMT_DelayTS=val;
  if(var=="EMT_BE_SL")                 EMT_BE_SL=val;
  if(var=="EMT_BE_Profit")             EMT_BE_Profit=val;
  //if(var=="EMT_RecrossMax")          EMT_RecrossMax=val;
  if(var=="EMT_RecrossCoefGood")       EMT_RecrossCoefGood=val;
  if(var=="EMT_RecrossCoefBad")        EMT_RecrossCoefBad=val;

  //if(var=="EGF_OnlyProfit_Hours")          EGF_OnlyProfit_Hours=val;
  //if(var=="EGF_ForceHours")          EGF_ForceHours=val;
  //if(var=="EGF_OnlyProfit_TS")             EGF_OnlyProfit_TS=val;

  //if(var=="EXT_CheckTempTrend")      EXT_CheckTempTrend=val;

  if(var=="EXT_TC_SetSize")            EXT_TC_SetSize=val;
  if(var=="EXT_TC_Relevant")           EXT_TC_Relevant=val;
  if(var=="EXT_TC_PipsToClose")        EXT_TC_PipsToClose=val;
  
  if(var=="SGE_Envelope_1On")          SGE_Envelope_1On=val;
  if(var=="SGE_SMAD_2On")              SGE_SMAD_2On=val;
  if(var=="SGE_OSMA_3On")              SGE_OSMA_3On=val;
  if(var=="SGE_MA_Diverg_4On")         SGE_MA_Diverg_4On=val;
  if(var=="SGE_RSI_low_5On")           SGE_RSI_low_5On=val;
  if(var=="SGE_RSI_high_6On")          SGE_RSI_high_6On=val;
  if(var=="SGE_Envelope_HF_7On")       SGE_Envelope_HF_7On=val;
  if(var=="SGE_SMA_HF_8On")            SGE_SMA_HF_8On=val;

  if(var=="FTE_ATR_1On")               FTE_ATR_1On=val;
  if(var=="FTE_Time_2On")              FTE_Time_2On=val;
  if(var=="FTE_MA_BuyTrend_3On")       FTE_MA_BuyTrend_3On=val;
  if(var=="FTE_MA_SellTrend_4On")      FTE_MA_SellTrend_4On=val;
  if(var=="FTE_FolMainTrend_5On")      FTE_FolMainTrend_5On=val;
  if(var=="FTE_LocMainTrend_6On")      FTE_LocMainTrend_6On=val;
  if(var=="FTE_TemporaryTrend_7On")    FTE_TemporaryTrend_7On=val;

  if(var=="SGS_EnvPerc")               SGS_EnvPerc=val;
  if(var=="SGS_EnvPer")                SGS_EnvPer=val;

  if(var=="SGS_SMAPer")                SGS_SMAPer=val;
  if(var=="SGS_SMA2Bars")              SGS_SMA2Bars=val;

  if(var=="SGS_OSMAFast")              SGS_OSMAFast=val;
  if(var=="SGS_OSMASlow")              SGS_OSMASlow=val;
  if(var=="SGS_OSMASignal")            SGS_OSMASignal=val;

  if(var=="SGS_Fast_Per")              SGS_Fast_Per=val;
  if(var=="SGS_Fast_Price")            SGS_Fast_Price=val;
  if(var=="SGS_Slow_Per")              SGS_Slow_Per=val;
  if(var=="SGS_Slow_Price")            SGS_Slow_Price=val;
  if(var=="SGS_DVmin")             SGS_DVmin=val;
  if(var=="SGS_DVmax")             SGS_DVmax=val;

  if(var=="SGS_RSI_High")              SGS_RSI_High=val;
  if(var=="SGS_RSI_Low")               SGS_RSI_Low=val;
  if(var=="SGS_RSI_Per")               SGS_RSI_Per=val;

  if(var=="SGS_PHEnvPerc")             SGS_PHEnvPerc=val;
  if(var=="SGS_PHPerEnv")              SGS_PHPerEnv=val;

  if(var=="SGS_PHSMAPer")              SGS_PHSMAPer=val;
  if(var=="SGS_PHSMA2Bars")            SGS_PHSMA2Bars=val;

  if(var=="FTS_ATR")              FTS_ATR=val;
  if(var=="FTS_minATR")                FTS_minATR=val;

  if(var=="FTS_WeekAt1")                FTS_WeekAt1=val;
  if(var=="FTS_WeekTo1")                FTS_WeekTo1=val;
  if(var=="FTS_WeekAt2")                FTS_WeekAt2=val;
  if(var=="FTS_WeekTo2")                FTS_WeekTo2=val;
  if(var=="FTS_SunAt")                 FTS_SunAt=val;
  if(var=="FTS_SunTo")                 FTS_SunTo=val;
  if(var=="FTS_FriAt")                 FTS_FriAt=val;
  if(var=="FTS_FriTo")                 FTS_FriTo=val;
  if(var=="FTS_MonAt")                 FTS_MonAt=val;
  if(var=="FTS_MonTo")                 FTS_MonTo=val;
  //if(var=="FTS_NotTradeFrom1")       FTS_NotTradeFrom1=val;
  //if(var=="FTS_NotTradeTo1")         FTS_NotTradeTo1=val;
  //if(var=="FTS_NotTradeFrom2")       FTS_NotTradeFrom2=val;
  //if(var=="FTS_NotTradeTo2")         FTS_NotTradeTo2=val;

  if(var=="FTS_TrendPer")              FTS_TrendPer=val;
  if(var=="FTS_TrendShift")            FTS_TrendShift=val;
  if(var=="FTS_TrendStr")              FTS_TrendStr=val;

  if(var=="FTS_HorizDist")             FTS_HorizDist=val;

  if(var=="FTS_Distance")              FTS_Distance=val;
  if(var=="FTS_TimePerShift")          FTS_TimePerShift=val;
  if(var=="FTS_MaxDiff")               FTS_MaxDiff=val;
  if(var=="FTS_MinSlope")              FTS_MinSlope=val;

  //if(var=="RCS_WriteLog")            RCS_WriteLog=val;
  //if(var=="RCS_WriteDebug")          RCS_WriteDebug=val;
  //if(var=="RCS_SaveInFile")          RCS_SaveInFile=val;
  //if(var=="RCS_FilterLog")           RCS_FilterLog=val;  
  //if(var=="RCS_FilterDebug")         RCS_FilterDebug=val;  
  //if(var=="RCS_EAComment")           RCS_EAComment=val;
  //if(var=="RCS_NameEA")              RCS_NameEA=val;

  return(true);
}

bool MM_CheckLosses()
{
  int ticket=0;
  int count=OrdersHistoryTotal();
  if(RCS_WriteDebug) L3_WriteDebug(6,StringConcatenate("Checking looses- count : ",count," SMT_CntTrades : ",SMT_CntTrades," SMT_CntLosses : ",SMT_CntLosses));
  if (count==SMT_CntTrades) return(false);
  SMT_CntTrades=count;
  if (!M2_MM_LastTrade(SMT_CntLosses,ticket)) return(false);
  return(true);
}  
 
 
 
  
//**********  Exit Strategies & Trailing Stops **********************************//
void X1_ManageExit(int ticket)
{ //Contains all of the exit strategies and trade management routines. Listed in priority.
    RefreshRates();
    if(AOP_Optimalization_1On && TimeCurrent()>FTS_NotTradeFrom2 && IsOptimization()) 
      { // during a testing not to trade on future data that ware not really known before
        if(OrderType()==OP_SELL) OrderClose(ticket,OrderLots(),Ask,TMT_Slippage,Red);
        else                     OrderClose(ticket,OrderLots(),Bid,TMT_Slippage,Red);
        if(RCS_WriteDebug) L3_WriteDebug(5,"AOP_Optimalization_1On: Ticket "+ticket+" was closed because of a reality simulation of the optimalization!");            
        return;
      }  
    bool enableBuy=true,enableSell=true;
    
    if(EXT_CheckTempTrend && EXT_TC_SetSize>=EXT_TC_Relevant && EXT_TC_Direction!=0) //close sooner if a temporary counter trend is recognized
     {  
       if(EXT_TC_Direction==Buy && OrderType()==OP_SELL && OrderStopLoss()-Ask<=EXT_TC_PipsToClose*Point) 
           if(A1_4_IsTradePossible()) 
            {
              if(RCS_WriteLog) L2_WriteLog(5,StringConcatenate("EXT_CheckTempTrend: Ticket Nr.",ticket," will be closed sooner because of a temporary counter trend and close SL."));
              OrderClose(ticket,OrderLots(),Ask,TMT_Slippage,Red);
            }  
       if(EXT_TC_Direction==Sell && OrderType()==OP_BUY && Bid-OrderStopLoss()<=EXT_TC_PipsToClose*Point)
           if(A1_4_IsTradePossible()) 
            {
              if(RCS_WriteLog) L2_WriteLog(5,StringConcatenate("Ticket Nr.",ticket," will be closed sooner because of a temporary counter trend and close SL."));
              OrderClose(ticket,OrderLots(),Bid,TMT_Slippage,Red);
            }  
     }
     
    EMT_minStop=MarketInfo(Symbol(),MODE_STOPLEVEL); //updated every tick in case of news SL movement
    if(EGF_OnlyProfit_Hours !=0 || EGF_ForceHours !=0)
      { 
         if(X1_ForceClose_or_GraceModify(ticket)) return;
      }   
  
    if(EGF_CloseBeforeRollOver) 
      {
         if(CloseBeforeWeekend (ticket)) return;
      }   
   
    if(EMT_RecrossMax>0) //check recross functions
      {
         int poolPos=EX_RecrossCheck(int ticket);
         if(poolPos!=-1) 
            {
                if( EX_RecrossExit(ticket,poolPos) ) 
                    {
                       if(RCS_WriteLog) L2_WriteLog(5,"EMT_RecrossMax: Ticket : "+ticket+" was closed because of a function Recross Exit.") ;
                       return;
                    }  
            }                
      }
    
  
  if(EMT_BE_SL>0)
  {  //    BreakEven SL @target
    if(EMT_BE_SL<EMT_BE_Profit+EMT_minStop) EMT_BE_Profit=EMT_BE_SL-EMT_minStop; //keeps trade safe all of the time
    if (OrderType() == OP_BUY && Bid-OrderOpenPrice()>=Point*EMT_BE_SL && OrderStopLoss()-Point*EMT_BE_Profit<OrderOpenPrice() && Bid-OrderOpenPrice()-EMT_BE_Profit*Point>=EMT_minStop*Point)
        X9_ModifySL(OrderOpenPrice()+EMT_BE_Profit*Point,ticket); 
    if (OrderType() == OP_SELL && OrderOpenPrice()-Ask>=Point*EMT_BE_SL+MarketInfo(Symbol(),MODE_SPREAD)*Point && OrderStopLoss()+Point*EMT_BE_Profit+MarketInfo(Symbol(),MODE_SPREAD)*Point>OrderOpenPrice() && OrderOpenPrice()+EMT_BE_Profit*Point+MarketInfo(Symbol(),MODE_SPREAD)*Point-Ask>=EMT_minStop*Point)
        X9_ModifySL(OrderOpenPrice()-EMT_BE_Profit*Point-MarketInfo(Symbol(),MODE_SPREAD)*Point,ticket); 
  }

  if(MMT_LimitLosses && OrderProfit()>0) EX_LimitLosses(ticket);//if a certain amount of last closed trades ended in consequent losses and if there is a counter trend , move SL accordind to MMT_TS_SLFactor (leave open trade sooner)

  if(SMT_AwayFromLosses) // if a trade is going agains trend set trailing stop
    {
      enableBuy=true;
      enableSell=true;
      Z_F5_BlockTradingFilter5(enableBuy,enableSell);   //locate main trend and trade in its direction only 
      if (OrderType()==OP_BUY && enableBuy==false) X9_ModifyTrailingStop(ticket,EMT_TS,0);
      if (OrderType()==OP_SELL && enableSell==false) X9_ModifyTrailingStop(ticket,EMT_TS,0);   
      if(RCS_WriteLog && (enableBuy==false || enableSell==false)) L2_WriteLog(6,"SMT_AwayFromLosses - Open ticket : "+ticket+" goes again main trend ! Trailing stop was setted. ") ;
    }       

              
  if (EMT_ExitWithTS) 
  {
    X9_ModifyTrailingStop(ticket,EMT_TS,EMT_DelayTS);
  }
}


bool X1_ForceClose_or_GraceModify(int ticket)   //force to exit after a certain amount of time
  {  
    int    PerForce = EGF_ForceHours*3600;
    int    PerGrace = EGF_OnlyProfit_Hours*3600;
    double newSL       =0;
    if (PerForce!=0)
      {
      if((OrderOpenTime() + PerForce) < Time[0])
         {
         if(OrderType() == OP_BUY)  
            {
               if(EGF_ForceCloseAgainSwap && SwapLong>0) return(false);
               else OrderClose(OrderTicket(),OrderLots(),Bid,TMT_Slippage,Red); 
            }  
         if(OrderType() == OP_SELL) 
            {
               if(EGF_ForceCloseAgainSwap && SwapShort>0) return(false);
               OrderClose(OrderTicket(),OrderLots(),Ask,TMT_Slippage,Red);
            }   
         if(RCS_WriteLog) L2_WriteLog(5,"Force to close - ticket:"+ticket+" - too long is opened this trade !");
         return(true);
         }
      }

    if(PerGrace!=0)
      {
        if(OrderOpenTime() + PerGrace < Time[0])
          {
            X9_ModifyTrailingStop(ticket, EGF_OnlyProfit_TS, EGF_OnlyProfit_TS);  // EGF_OnlyProfit_TS=minimal 0 profit on TS with PerGrace
            if(RCS_WriteDebug) L3_WriteDebug(5,"Close when profit - ticket:"+ticket+" guarantees minimal profit !");            
          }
      }
    return(false);  
   }

void X9_ModifyTrailingStop(int ticket, int tsvalue, int delayts)
  {
   
    if(EMT_DecreaseTPOn) EX_DecrTPifCountTrend(ticket);       
    double slvalue;
    if(tsvalue>=EMT_minStop) //check minimal value allowed by broker
      {        
        if(EMT_ModifyTSOn) 
        { 
          if(OrderProfit()>0)tsvalue=MathAbs(MathFloor(((OrderTakeProfit()-OrderStopLoss())/Point)*0.5));
          if(tsvalue<EMT_minStop)tsvalue=EMT_minStop;
        }
      } 
    else 
      { //Set safe value
        tsvalue=EMT_minStop;
      }
      
    if(RCS_WriteDebug) L3_WriteDebug(5,"EXIT function: TS ticket:"+ticket+" tsvalue:"+tsvalue+" delayts:"+delayts);

    if      (OrderType() == OP_BUY)
      {
        slvalue=NormalizeDouble(Bid-(Point*tsvalue),Digits);
        if (OrderStopLoss()<slvalue && OrderOpenPrice()+Point*delayts<Bid)//&& OrderOpenPrice()+Point*delayts<Bid-tsvalue*Point
        {
          if(!X9_ModifySL(slvalue,ticket))
          {
            L4_WriteError();
            L3_WriteDebug(5,"Buy order-ERROR OrderSL:" +OrderStopLoss()+ " slvalue:"+ slvalue);
          }
        }
      } 
    else if (OrderType() == OP_SELL)
      {
        slvalue=NormalizeDouble(Ask+(Point*tsvalue),Digits);
        if (OrderStopLoss()>slvalue && OrderOpenPrice()-Point*delayts>Ask)// && OrderOpenPrice()-Point*delayts>Ask+tsvalue*Point
        {
          if(!X9_ModifySL(slvalue,ticket))
          {
            L4_WriteError();
            L3_WriteDebug(5,"EXIT function: Sell order-ERROR OrderSL:" +OrderStopLoss()+ " slvalue:"+ slvalue);
          }
        }
      }
  }

bool X9_ModifySL(double sl, int ticket)
  {
    double MoveTP;
    if(EMT_MoveTPonTS !=0)
    {
      if (OrderType() == OP_SELL) 
      {
        MoveTP=EMT_MoveTPonTS*(-1)*Point;
        if(NormalizeDouble(sl-Ask,Digits)<EMT_minStop*Point)return(true); 
        if(Ask-OrderTakeProfit()+MoveTP<EMT_minStop*Point) 
          MoveTP=-(EMT_minStop*Point+Ask-OrderTakeProfit()); //Set the new distance to minimum safe point, -OTP() cancels OTP() // repared error 4051
      }
      else 
      {
        MoveTP=EMT_MoveTPonTS*Point;
        if(NormalizeDouble(Bid-sl,Digits)<EMT_minStop*Point) return(true); 
        if(OrderTakeProfit()-Bid+MoveTP<EMT_minStop*Point) 
          MoveTP=EMT_minStop*Point-Bid+OrderTakeProfit();  //Set the new distance to minimum safe point, -OTP() cancels OTP()
      }
    }
    
    if(RCS_WriteDebug) L3_WriteDebug(6,"MODIFY Ticket:"+ticket+" OpenPrice:"+OrderOpenPrice()+" SL:"+sl+" TP:"+(OrderTakeProfit()+MoveTP*Point));

    sl=NormalizeDouble(sl,Digits);
    MoveTP=NormalizeDouble(MoveTP,Digits);
    
    if(MMT_LimitLosses && M2_MM_LastTrade(MMT_ConseqLosses,ticket)) MoveTP=0; 
  
    if(sl==NormalizeDouble(OrderStopLoss(),Digits)) return(true); 

    if(!A1_4_IsTradePossible()) return(false); //check if trade is allowed 
    if(OrderModify ( ticket, OrderOpenPrice(), sl,
                      OrderTakeProfit()+MoveTP,   
                      0, DarkOrchid) ==(-1)) 
        return(false);
    else return(true);
  }

bool M2_MM_LastTrade(int ConsLos,int& ticket)
  {
    int    orders       =OrdersHistoryTotal();
    int    i            =orders-1;
    int    trades       =0;
    int    wins         =0;
    int    losses       =0;
    int    LossyTicket;
        
    if (ConsLos==0) return(true); //to use it always
    if (ConsLos<1) ConsLos=1;
        while (trades<ConsLos && i > 0)
          {
            if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)
              {
                if(RCS_WriteLog) L2_WriteLog(2,"Check last trade: Error in history!");
                break;
              }
            if(OrderSymbol()==Symbol() && OrderType()<=OP_SELL)
              {
                if(OrderProfit()<=0) 
                  {
                    losses++;    
                    if (SMT_LookForNextSet && OrderTicket()<=SMT_LastLossTicket&& ticket==0) return(false);
                    LossyTicket=OrderTicket(); 
                  }  
                if(OrderProfit()>0) wins++;
                trades++;
              }
            i--;
          }

     OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES); //it needs to be after Lasttrade function
     if (losses>=ConsLos)
       {
         if (SMT_LookForNextSet && ticket==0)
            if(LossyTicket-SMT_LastLossTicket>=ConsLos) SMT_LastLossTicket=LossyTicket;   
            else return(false);               
         return(true);
       }  
     else return(false);

  }


bool MM_CheckSet(int futureset,int range,int& ticket,double& wins,double& losses) //allow to check, if next set was profitable in the past in a range of 5 (=SMT_AFL_Range)closed trades
  {
    int    orders       =OrdersHistoryTotal();
    int    i            =orders-1;
    int    trades       =0;
    int set,pos;
        
    if (range<1) return(true); //to use it always
        while (trades<range && i > 0)
          {
            if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)
              {
                if(RCS_WriteLog) L2_WriteLog(4,"SMT_CheckSetBeforeLoading: Error in history!");
                break;
              }
            if(OrderSymbol()==Symbol() && OrderType()<=OP_SELL)
              {
                pos=StringFind(OrderComment(),"#",0);
                set=StrToInteger(StringSubstr(OrderComment(),pos+1,0));
                if(RCS_WriteDebug) L3_WriteDebug(4,StringConcatenate("SMT_CheckSetBeforeLoading: Ticket : ",OrderTicket()," set : ",set," futureset : ",futureset," losses : ",losses));
                if(set==futureset)
                  {
                    if(OrderProfit()<=0) losses++;
                    if(OrderProfit()>0) wins++;                  
                  }  
                trades++;
              }
            i--;
          }
     OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES); //it needs to be after MM_CheckSet function
     if(RCS_WriteDebug) L3_WriteDebug(4,StringConcatenate("SMT_CheckSetBeforeLoading: losses : ",losses," SMT_AFL_Losses : ",SMT_AFL_Losses));
     if (losses>=SMT_AFL_Losses)return(false);
     else return(true);
  }

  
//********************** SIGNALS *********************//
int Z_S1_EntrySignal1()
  { //Envelope Filter
    int Signal=None;

    double HighEnvelope1 = iEnvelopes(NULL,0,SGS_EnvPer,MODE_SMA,0,PRICE_CLOSE,SGS_EnvPerc,MODE_UPPER,0);
    double LowEnvelope1  = iEnvelopes(NULL,0,SGS_EnvPer,MODE_SMA,0,PRICE_CLOSE,SGS_EnvPerc,MODE_LOWER,0);
    double CloseBar1     = iClose(NULL,0,0);

    if(CloseBar1 > HighEnvelope1) {Signal=Sell;}
    if(CloseBar1 < LowEnvelope1)  {Signal=Buy; }

    if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_Envelope_1On: Signal "+Signal+" HighEnv:"+HighEnvelope1+" LowEnv:"+LowEnvelope1+" Close:"+CloseBar1);

    return (Signal);
  }

int Z_S2_EntrySignal2()
  { //SMA Difference
    int Signal=None;

    double SMA1=iMA(NULL,0,SGS_SMAPer,0,MODE_SMA,PRICE_CLOSE,0);
    double SMA2=iMA(NULL,0,SGS_SMAPer,0,MODE_SMA,PRICE_CLOSE,SGS_SMA2Bars);

    if (SMA2>SMA1 ) Signal=Buy;
    else            Signal=Sell;

    if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_SMAD_2On: Signal "+Signal+" SMA Diff:"+(SMA2-SMA1)+" SMA2:"+SMA2+" SMA1:"+SMA1);

    return (Signal);
  }


int Z_S3_EntrySignal3()
  { //OSMA Cross
    int Signal=None;

    double OsMABar2=iOsMA(NULL,0,SGS_OSMAFast,SGS_OSMASlow,SGS_OSMASignal,PRICE_CLOSE,1);
    double OsMABar1=iOsMA(NULL,0,SGS_OSMAFast,SGS_OSMASlow,SGS_OSMASignal,PRICE_CLOSE,0);

    if (OsMABar2>OsMABar1) Signal=Buy;
    else                   Signal=Sell;

    if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_OSMA_3On: Signal "+Signal+" OsMA Diff:"+(OsMABar2-OsMABar1)+" OsMABar2:"+OsMABar2+" OsMABar1:"+OsMABar1);

    return (Signal);
  }

int Z_S4_EntrySignal4()
  { //Divergence Trading Signal
    int Signal;  
    double diverge = ZZ_F1_Divergence(SGS_Fast_Per, SGS_Slow_Per, SGS_Fast_Price, SGS_Slow_Price,0);
    if(diverge >= SGS_DVmin && diverge <= SGS_DVmax) Signal=Buy;
    else if(diverge <= (SGS_DVmin*(-1)) && diverge >= (SGS_DVmax*(-1))) Signal=Sell;
    if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_MA_Diverg_4On: Signal "+Signal+" diverge:"+diverge+" SGS_DVmin:"+SGS_DVmin+" SGS_DVmax:"+SGS_DVmax);
    return (Signal);  
  }

int Z_S5_EntrySignal5()
  { 
   int value=0;
   if(SGS_RSIBar<Bars)
   {  //This should be based on bars, reduces check to once every bar.
      SGS_RSIBar=Bars;
      SGS_RSI3=SGS_RSI2; //This reduces computation to 1/3
      SGS_RSI2=SGS_RSI1;
   }
   SGS_RSI1 = iRSI(NULL, Period(), SGS_RSI_Per, PRICE_CLOSE, 0);
   if (SGS_RSI1 < SGS_RSI_High)      //Save CPU cycles with quick filters
    { if(SGS_RSI2 < SGS_RSI1 && SGS_RSI3 < SGS_RSI2) value=Buy; } 
   else if (SGS_RSI1 > SGS_RSI_Low)  //only one set needs to be checked, and not always.  
      if(SGS_RSI2 > SGS_RSI1 && SGS_RSI3 > SGS_RSI2) value=Sell;
   if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_RSI_low_5On: Signal "+value+" SGS_RSI1:"+SGS_RSI1+" SGS_RSI2:"+SGS_RSI2+" SGS_RSI3:"+SGS_RSI3);
   return(value);
  }

int Z_S6_EntrySignal6()
  { 
   int value=0;
   double w_RSI = iRSI(NULL, Period(), SGS_RSI_Per, PRICE_CLOSE, 0);
   if (w_RSI < SGS_RSI_High)      
      value=Buy;
   else if (w_RSI > SGS_RSI_Low)   
      value=Sell;
   if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_RSI_high_6On: Signal "+value+" w_RSI:"+w_RSI);
   return(value);
  }

int Z_S7_EntrySignal7()
  { //Envelope Filter on a higher timeframe about 2 degree
    int Signal=None;

    double HighEnvelope0 = iEnvelopes(NULL,MovePeriodHigher(2),SGS_PHPerEnv,MODE_SMA,0,PRICE_CLOSE,SGS_PHEnvPerc,MODE_UPPER,0);
    double LowEnvelope0  = iEnvelopes(NULL,MovePeriodHigher(2),SGS_PHPerEnv,MODE_SMA,0,PRICE_CLOSE,SGS_PHEnvPerc,MODE_LOWER,0);
    double CloseBar0     = iClose(NULL,0,0);

    if(CloseBar0 > HighEnvelope0) {Signal=Sell;}
    if(CloseBar0 < LowEnvelope0)  {Signal=Buy; }

    if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_Envelope_HF_7On: Signal "+Signal+" HighEnv:"+HighEnvelope0+" LowEnv:"+LowEnvelope0+" Close:"+CloseBar0);

    return (Signal);
  }

int Z_S8_EntrySignal8()
  { //SMA Difference on a higher timeframe about 2 degree
    int Signal=None;

    double SMA1=iMA(NULL,MovePeriodHigher(2),SGS_PHSMAPer,0,MODE_SMA,PRICE_CLOSE,0);
    double SMA2=iMA(NULL,MovePeriodHigher(2),SGS_PHSMAPer,0,MODE_SMA,PRICE_CLOSE,SGS_PHSMA2Bars);

    if (SMA2>SMA1 ) Signal=Buy;
    else            Signal=Sell;

    if(RCS_WriteDebug) L3_WriteDebug(0,"SGE_SMA_HF_8On: Signal "+Signal+" SMA Diff:"+(SMA2-SMA1)+" SMA2:"+SMA2+" SMA1:"+SMA1);

    return (Signal);
  }

  
bool Z_F1_BlockTradingFilter1()
{   
  bool BlockTrade=false;  //trade by default
  double dAtrShort = iATR(NULL, 0, FTS_ATR, 0);
  if(dAtrShort<FTS_minATR)
   {
      BlockTrade=true;
      if(RCS_WriteDebug && BlockTrade) L3_WriteDebug(1,"FTE_ATR_1On: Trading is blocked");
   }
  return (BlockTrade); 
}

bool Z_F2_BlockTradingFilter2()   
  { //Time Expiry
    bool BlockTrade=true;  //only trade during permitted hours
    
      if(TimeDayOfWeek(Time[0])==0)  //Sunday
        {
          if(GBV_currentTime>=FTS_SunAt && GBV_currentTime<FTS_SunTo) 
            {
               BlockTrade=false;
               if(RCS_WriteDebug) L3_WriteDebug(1,"FTE_Time_2On: Trading within Sunday is allowed:"+GBV_currentTime);
            }   
        }
      else if(TimeDayOfWeek(Time[0])==5)  //Friday
        {
          if(GBV_currentTime>=FTS_FriAt && GBV_currentTime<FTS_FriTo) 
            {
               BlockTrade=false;
               if(RCS_WriteDebug) L3_WriteDebug(1,"FTE_Time_2On: Trading within Friday is allowed:"+GBV_currentTime);
            }   
        }
      else if(TimeDayOfWeek(Time[0])==1)  //Monday
        {
          if(GBV_currentTime>=FTS_MonAt && GBV_currentTime<FTS_MonTo) 
            {
               BlockTrade=false;
               if(RCS_WriteDebug) L3_WriteDebug(1,"FTE_Time_2On: Trading within Monday is allowed:"+GBV_currentTime);
            }   
        }
      else if((GBV_currentTime>=FTS_WeekAt1 && GBV_currentTime<FTS_WeekTo1) ||
      (GBV_currentTime>=FTS_WeekAt2 && GBV_currentTime<FTS_WeekTo2)) BlockTrade=false;

    if(RCS_WriteDebug && BlockTrade) L3_WriteDebug(1,"FTE_Time_2On: Trading is blocked:"+GBV_currentTime);
    return (BlockTrade);
  }
  
bool Z_F3_BlockTradingFilter3()   //if BUY Signal, check buy trend. True = quit.
  {
    bool BlockTrade=true; //if true trading is disallowed
  
    double TrendB=iMA(NULL,0,FTS_TrendPer,FTS_TrendShift,MODE_LWMA,PRICE_MEDIAN,0)-High[1];

    if(FTS_TrendStr*Point<TrendB)
      {
        BlockTrade=false;
        if(RCS_WriteDebug) L3_WriteDebug(1,"FTE_MA_BuyTrend_3On: TrendMA:"+TrendB+" Buy="+BlockTrade+" Buy Allowed");
      }
    else
      { 
        if(RCS_WriteDebug) L3_WriteDebug(1,"FTE_MA_BuyTrend_3On: TrendMA:"+TrendB+" Buy="+BlockTrade+" Buy DisAllowed");
      }

    return(BlockTrade);
  }
  
bool Z_F4_BlockTradingFilter4()
  {
    //if SELL Signal, check sell trend
    //Currently assuming that rising and falling trends have similar properties.
    bool BlockTrade=true;
    
    double TrendS=Low[1]-iMA(NULL,0,FTS_TrendPer,FTS_TrendShift,MODE_LWMA,PRICE_MEDIAN,0);
    
    if(FTS_TrendStr*Point<TrendS) 
      {
        BlockTrade=false;
        if(RCS_WriteDebug) L3_WriteDebug(1,"FTE_MA_SellTrend_4On: TrendMA:"+TrendS+" Sell="+BlockTrade+" Sell Allowed");
      }
    else
      {
        if(RCS_WriteDebug) L3_WriteDebug(1,"FTE_MA_SellTrend_4On: TrendMA:"+TrendS+" Sell="+BlockTrade+" Sell DisAllowed");
      }

    return(BlockTrade);
  }

bool Z_F5_BlockTradingFilter5(bool& enableBuy,bool& enableSell)   //locate main trend and trade in its direction only
  { 
    double lengh;
    if (FTS_SR_barsCount<iBars(NULL,0) || FTS_SR_barsCount==0) //count only when a new bar appears
      {
        double FTS_SR_high[];
        double FTS_SR_low[];
        ArrayCopySeries(FTS_SR_high,MODE_HIGH,NULL,0);
        ArrayCopySeries(FTS_SR_low,MODE_LOW,NULL,0);        
        FTS_SR_MaxPos0=ArrayMaximum(FTS_SR_high,FTS_HorizDist,0);
        FTS_SR_MinPos0=ArrayMinimum(FTS_SR_low,FTS_HorizDist,0);
        FTS_SR_MaxPoint0=FTS_SR_high[FTS_SR_MaxPos0];
        FTS_SR_MinPoint0=FTS_SR_low[FTS_SR_MinPos0];
        FTS_SR_MaxPos1=ArrayMaximum(FTS_SR_high,MathRound(FTS_HorizDist/2),0);
        FTS_SR_MinPos1=ArrayMinimum(FTS_SR_low,MathRound(FTS_HorizDist/2),0);        
        FTS_SR_MaxPos2=ArrayMaximum(FTS_SR_high,FTS_HorizDist,MathRound(FTS_HorizDist/2)+1);
        FTS_SR_MinPos2=ArrayMinimum(FTS_SR_low,FTS_HorizDist,MathRound(FTS_HorizDist/2)+1);
        FTS_SR_MaxPoint1=FTS_SR_high[FTS_SR_MaxPos1];
        FTS_SR_MinPoint1=FTS_SR_low[FTS_SR_MinPos1];
        FTS_SR_MaxPoint2=FTS_SR_high[FTS_SR_MaxPos2];
        FTS_SR_MinPoint2=FTS_SR_low[FTS_SR_MinPos2];
        
        FTS_SR_barsCount=iBars(NULL,0);                        
        
      }

    if (FTS_SR_MaxPos0<FTS_SR_MinPos0) // check buy condition
      {
         lengh=Bid-FTS_SR_MinPoint0;
         if (TMT_SL*Point<lengh) 
           {
            if(!(FTS_SR_MaxPoint1>FTS_SR_MaxPoint2 && FTS_SR_MinPoint1>FTS_SR_MinPoint2)) 
               {
                if(RCS_WriteDebug) L3_WriteDebug(1,"FTE_FolMainTrend_5On: main trend : Block buy trade.");
                enableBuy=false;
               }
            else if(RCS_WriteDebug) L3_WriteDebug(1,"FTE_FolMainTrend_5On: main trend : Follow long trend.");              
           } 
               
      } 
    if (FTS_SR_MaxPos0>FTS_SR_MinPos0) // check sell condition
      {
         lengh=FTS_SR_MaxPoint0-Bid;
         if(TMT_SL*Point<lengh) 
           {
            if(!(FTS_SR_MaxPoint1<FTS_SR_MaxPoint2 && FTS_SR_MinPoint1<FTS_SR_MinPoint2))
               {
                if(RCS_WriteDebug) L3_WriteDebug(1,"FTE_FolMainTrend_5On: main trend : Block sell trade.");
                enableSell=false;
               } 
            else if(RCS_WriteDebug) L3_WriteDebug(1,"FTE_FolMainTrend_5On: main trend : Follow short trend."); 
           } 
         
      } 

    return (false);  //do not block trading
  }


bool Z_F6_BlockTradingFilter6(bool& enableBuy,bool& enableSell)//locate main trend and allow to trade only in its  direction  
  { 

 if (FTS_LastBarCnt<iBars(NULL,MovePeriodHigher(FTS_TimePerShift))) //count only when a new bar appears
  {
    FTS_Bar1=iClose(NULL,MovePeriodHigher(FTS_TimePerShift),1);
    FTS_Bar3=iClose(NULL,MovePeriodHigher(FTS_TimePerShift),FTS_Distance);
    double averPrice,bar2;
   
    FTS_Difference=0;
    for(int cnt=FTS_Distance;cnt>0;cnt--)
      {
         averPrice=cnt*MathAbs(FTS_Bar3-FTS_Bar1)/FTS_Distance;
         if(FTS_Bar3-FTS_Bar1>=0) bar2=FTS_Bar1+averPrice;
         else bar2=FTS_Bar1-averPrice;
         FTS_Difference+=MathAbs( iClose(NULL,MovePeriodHigher(FTS_TimePerShift),cnt)-bar2);  
      }
     FTS_Difference/=Point;
     FTS_Slope=MathAbs( (FTS_Bar1-FTS_Bar3)/(Point*FTS_Distance) );
     FTS_LastBarCnt=iBars(NULL,0);
   }     
     if(FTS_Slope<FTS_MinSlope || FTS_MaxDiff<FTS_Difference) return(false);//do not block trading
     if(FTS_Bar3>FTS_Bar1) 
      {
         enableBuy=false;
         if(RCS_WriteDebug) L3_WriteDebug(1,"FTE_LocMainTrend_6On-main trend : Block long trades.");
      }   

     else 
      {
         enableSell=false;
         if(RCS_WriteDebug) L3_WriteDebug(1,"FTE_LocMainTrend_6On-main trend : Block short trades.");
      }   
         
     return (false);//do not block trading
  }

bool Z_F7_BlockTradingFilter7(bool& enableBuy,bool& enableSell)  //find a temporary trend and block to trade agains it  
  { 
    if(EXT_TC_Direction==Buy) 
      {
         enableSell=false;
         if(RCS_WriteDebug) L3_WriteDebug(1,"FTE_TemporaryTrend_7On-temporary trend : Block short trades.");
      }   
         
    if(EXT_TC_Direction==Sell) 
      {
         enableBuy=false;
         if(RCS_WriteDebug) L3_WriteDebug(1,"FTE_TemporaryTrend_7On-temporary trend : Block long trades.");
      }   
         
  }  
  
bool FTS_ControlPeaks(int TradeDirect)  //wait for peaks
  { 
     if(FTS_PeaksBars==Bars) return(false);
     else FTS_PeaksBars=Bars;
     double maxhigh,minlow,scale;
          
     if(FTS_PeakLong==0 || FTS_PeakShort==0) 
      {
         maxhigh=High[iHighest(NULL,0,MODE_HIGH,FTS_BarsBack,0)];
         minlow=Low[iLowest(NULL,0,MODE_LOW,FTS_BarsBack,0)]; 
         scale=NormalizeDouble((maxhigh-minlow)*FTS_PeakPerc,4);
      } 
     else return(false);     

     if(FTS_PeakLong==0 && TradeDirect==1) 
      {
         FTS_PeakLong=Bid-scale;
         FTS_TimeLimitLong=TimeCurrent()+Period()*FTS_BarsForward*60;
      }           
     if(FTS_PeakShort==0 && TradeDirect==-1) 
      {
         FTS_PeakShort=Bid+scale;
         FTS_TimeLimitShort=TimeCurrent()+Period()*FTS_BarsForward*60;
      }           
     //Print("bid ",Bid," maxhigh ",maxhigh," minlow ",minlow," FTS_PeakLong ",FTS_PeakLong," FTS_PeakShort ",FTS_PeakShort," TradeDirect ",TradeDirect);
     return(true);    
             
  }    

bool Z_F8_BlockTradingFilter8(bool& enableBuy,bool& enableSell)  //wait for peaks FTE_WaitForPeaks_8On
  { 
     if(FTS_PeakLong<Bid && FTS_PeakLong!=0) 
      {
         enableBuy=false;
         if(RCS_WriteDebug) L3_WriteDebug(1,StringConcatenate("FTE_WaitForPeaks-still waiting for the peak, shift  ",Bid-FTS_PeakLong," needed : Block long trades."));
      }   
         
     if(FTS_PeakShort>Bid && FTS_PeakShort!=0) 
      {
         enableSell=false;
         if(RCS_WriteDebug) L3_WriteDebug(1,StringConcatenate("FTE_WaitForPeaks-still waiting for the peak, shift  ",FTS_PeakShort-Bid," needed : Block short trades."));
      }  
     if(FTS_TimeLimitLong<TimeCurrent()) FTS_PeakLong=0;
     if(FTS_TimeLimitShort<TimeCurrent()) FTS_PeakShort=0;
      
  }   
  
    
//********************** Signal Functions ******************//
double ZZ_F1_Divergence(int F_Per, int S_Per, int F_Price, int S_Price, int mypos)
  {
    double maF2 = iMA(Symbol(), 0, F_Per, 0, MODE_SMA, F_Price, mypos);
    double maS2 = iMA(Symbol(), 0, S_Per, 0, MODE_SMA, S_Price, mypos);

    return((maF2-maS2)/Point);
  }

//*********************** LOGGING **************************//
void L1_OpenLogFile(string strName)
  {
    if (!RCS_WriteLog && !RCS_WriteDebug || !RCS_SaveInFile)return;
    bool newfile=false;

    if(GBV_LogHandle <= 0) newfile=true;
    if(GBV_LogHandle > 0)
      {
         if(FileSize(GBV_LogHandle)>RCS_LogFileSize)newfile=true; //a file is divided into parts 
      }   
    if(!newfile)return;  //no need to open a new file, than return     
    if(GBV_LogHandle!=-1) FileClose(GBV_LogHandle);          
    string strMonthPad = "" ;
    if (Month() < 10) strMonthPad = "0";
    string strDayPad   = "" ;
    if (Day() < 10) strDayPad   = "0";
    string strFilename = StringConcatenate(strName, "_", Year(),
                                           strMonthPad, Month(),
                                           strDayPad,     Day(), "_log.txt");

    GBV_LogHandle =FileOpen(strFilename, FILE_CSV | FILE_READ | FILE_WRITE); //Pick a new file name and open it. 
  }



void L2_WriteLog(int rank,string msg)
  {
    if (!RCS_WriteLog) return;
    if(RCS_LogFilter[rank]==0) return;    
    Print(msg); 
    if(!RCS_SaveInFile) return;       
    if (GBV_LogHandle <= 0)   return;
    msg = TimeToStr(TimeCurrent(), TIME_DATE | TIME_MINUTES | TIME_SECONDS) + " " + msg;
    FileWrite(GBV_LogHandle, msg);
  }

void L3_WriteDebug(int rank,string msg)  //Signal Debugging, rarely called
  {
    if (!RCS_WriteDebug) return;
    if(RCS_DebugFilter[rank]==0) return;   
    Print(msg);     
    if(!RCS_SaveInFile) return;    
    if (GBV_LogHandle <= 0) return;
    msg = TimeToStr(TimeCurrent(), TIME_DATE | TIME_MINUTES | TIME_SECONDS) + " " + msg;
    FileWrite(GBV_LogHandle, msg);
  }

void L4_WriteError()
  {
    if (!RCS_WriteLog) return;
    string msg="Error:"+ GetLastError()+" OrderType:"+OrderType()+" Ticket:"+OrderTicket();    
    Print(msg);   
    if(!RCS_SaveInFile) return;          
    if (GBV_LogHandle <= 0)   return;
    msg = TimeToStr(TimeCurrent(), TIME_DATE | TIME_MINUTES | TIME_SECONDS) + " " + msg;
    FileWrite(GBV_LogHandle, msg);
  }


int MovePeriodHigher(int shift)
   {
      int CurrPer=Period();
      int PerArray[]={1,5,15,30,60,240,1440,10080,43200}; //array with periods in minutes
      int PosPer=ArrayBsearch(PerArray,CurrPer,WHOLE_ARRAY,0,MODE_ASCEND);
      if(PosPer+shift>7) return(43200);
      else return(PerArray[PosPer+shift]);            
   }   

bool DecreaseTP(int ticket,double orderTP)
   {
      if(!A1_4_IsTradePossible()) return(false); //check if trade is allowed 
      if(orderTP==OrderTakeProfit()) return(false);
      if(OrderType()==OP_SELL)
         {
            if(MathAbs(Ask-orderTP)<EMT_minStop*Point || orderTP<OrderTakeProfit()) return(false);
         }   
      if(OrderType()==OP_BUY)
         {
            if(MathAbs(Bid-orderTP)<EMT_minStop*Point || orderTP>OrderTakeProfit()) return(false);
         }   
      if(RCS_WriteLog) L2_WriteLog(6,StringConcatenate("Decrease TP by Ticket Nr.",ticket," ,Current TP : ",OrderTakeProfit()," ,Next TP : ",orderTP)) ;
      if(OrderModify ( ticket, OrderOpenPrice(), OrderStopLoss(),
                      orderTP, 0, Purple) ==(-1)) return(false);
                     else return(true);

   }

int TickContainer()
   {
      if(EXT_TC_Relevant<=EXT_TC_SetSize/2)return(0); //no result
      int cntRelevant;
      EXT_TC_Direction=0;
      for (int cnt=EXT_TC_SetSize-2;cnt>-1;cnt--)
         {
           EXT_TC_Store[cnt+1]=EXT_TC_Store[cnt];
           if(EXT_TC_Store[cnt+1]==1) cntRelevant++;
         }
      if(Bid>EXT_TC_LastTick)
         {
            cntRelevant++;
            EXT_TC_Store[0]=1;
         }
      else  EXT_TC_Store[0]=0;     
      EXT_TC_LastTick=Bid;    
      if(cntRelevant>=EXT_TC_Relevant) EXT_TC_Direction=1;   //a temporary trend is going up
      else if(cntRelevant<=EXT_TC_SetSize-EXT_TC_Relevant) EXT_TC_Direction=-1;  //a temporary trend is going down 
      return(EXT_TC_Direction); //no results   
   }

 
bool EX_LimitLosses(int ticket) // if there is a counter trend leave a open trade sooner
   {
       bool enableBuy=true,enableSell=true;
       Z_F6_BlockTradingFilter6(enableBuy,enableSell);
       if(  (ticket==OP_BUY && enableBuy==true) || (ticket==OP_SELL && enableSell==true) ) return (false); 
       if (!M2_MM_LastTrade(MMT_ConseqLosses,ticket)) return (false); // active only if there were a certain amount of losses
       for(int cnt=ArraySize(MMT_TS_ProfitFactor)-1;cnt>=0;cnt--)
          {
             if (OrderType()==OP_BUY && Bid-OrderOpenPrice()>=MMT_TS_ProfitFactor[cnt]*Point)
                {
                   if (cnt==ArraySize(MMT_TS_ProfitFactor)-1) // enable trailing stop
                      {
                          X9_ModifyTrailingStop(ticket,EMT_TS,MMT_TS_ProfitFactor[cnt]);
                          break;
                      }      
                   if (OrderStopLoss()-OrderOpenPrice()<MMT_TS_SLFactor[cnt]*Point) //move stoploss
                      {
                          X9_ModifySL(OrderOpenPrice()+MMT_TS_SLFactor[cnt]*Point,ticket);
                          break;
                      }     
                 } 
             if (OrderType()==OP_SELL && OrderOpenPrice()-Ask>=MMT_TS_ProfitFactor[cnt]*Point)
                 {
                   if (cnt==ArraySize(MMT_TS_ProfitFactor)-1) // enable trailing stop
                      {
                          X9_ModifyTrailingStop(ticket,EMT_TS,MMT_TS_ProfitFactor[cnt]);
                          break;
                      }      
                   if (OrderOpenPrice()-OrderStopLoss()<MMT_TS_SLFactor[cnt]*Point) //move stoploss
                      {
                          X9_ModifySL(OrderOpenPrice()-MMT_TS_SLFactor[cnt]*Point,ticket);
                          break;
                      }     
                  } 
                        
            } 
        if(RCS_WriteLog) L2_WriteLog(6,"MMT_LimitLosses-Descrease TS : ProfitFactor "+MMT_TS_ProfitFactor[cnt]+" SLFactor "+MMT_TS_SLFactor[cnt]) ;
   }// ******** end of a function limit losses 


bool EX_DecrTPifCountTrend(int ticket)
   {
          bool enableBuy=true,enableSell=true;
          Z_F6_BlockTradingFilter6(enableBuy,enableSell); 
          
          if(OrderType()==OP_BUY && enableBuy==false)//&& FTS_Difference>FTS_MaxDiff
            {
               double FTS_SR_high[],FTS_SR_Max;
               ArrayCopySeries(FTS_SR_high,MODE_HIGH,NULL,MovePeriodHigher(EMT_DecTPShiftPeriod));
               FTS_SR_Max=FTS_SR_high[ArrayMaximum(FTS_SR_high,EMT_DecTPShiftBar,0)];  
               if(FTS_SR_Max-Bid>TMT_SL*Point && OrderTakeProfit()>FTS_SR_Max)// && OrderOpenPrice()+TMT_TP*Point<FTS_SR_Max 
                  {
                     if(DecreaseTP(ticket,FTS_SR_Max)) 
                        {
                           if(RCS_WriteLog) L2_WriteLog(4,StringConcatenate("EMT_DecreaseTPOn: Ticket Nr. ",ticket," has new TP=",FTS_SR_Max," because of a counter trend danger."));
                           return(true);
                        }  
                  }
             }
             
          if(OrderType()==OP_SELL && enableSell==false)
            {
               double FTS_SR_low[],FTS_SR_Min;
               ArrayCopySeries(FTS_SR_low,MODE_LOW,NULL,MovePeriodHigher(EMT_DecTPShiftPeriod));
               FTS_SR_Min=FTS_SR_low[ArrayMinimum(FTS_SR_low,EMT_DecTPShiftBar,0)];  
               if(Bid-FTS_SR_Min>TMT_SL*Point && OrderTakeProfit()<FTS_SR_Min+MarketInfo(Symbol(),MODE_SPREAD)*Point)// && OrderOpenPrice()-TMT_TP*Point>FTS_SR_Min
                  {
                     if(DecreaseTP(ticket,FTS_SR_Min-MarketInfo(Symbol(),MODE_SPREAD)*Point))
                        {
                           if(RCS_WriteLog) L2_WriteLog(4,StringConcatenate("EMT_DecreaseTPOn: Ticket Nr. ",ticket," has new TP=",FTS_SR_Min-MarketInfo(Symbol(),MODE_SPREAD)*Point," because of a counter trend danger."));
                           return(true);
                        }  

                  }
             } 
   }
   

int EX_RecrossCheck(int ticket)
   {
     int index,cnt,cnt2;
     ArraySort(EMT_bcRecross,WHOLE_ARRAY,0,MODE_DESCEND);
     for(cnt=0;cnt<ArrayRange(EMT_bcRecross,0);cnt++)
      {
         if(EMT_bcRecross[cnt][0] == 0) continue;
         if(ticket!=EMT_bcRecross[cnt][0] && OrderSelect(EMT_bcRecross[cnt][0], SELECT_BY_TICKET,MODE_TRADES)==false) continue;
         if(OrderCloseTime() != 0) 
            {
              if(RCS_WriteDebug) L3_WriteDebug(5,"EX_RecrossCheck: Erase ticket : "+EMT_bcRecross[cnt][0]+" from recrosses pool.");              
              for(cnt2=0;cnt2<ArrayDimension(EMT_bcRecross);cnt2++) EMT_bcRecross[cnt][cnt2]=0;
            }   

         if(EMT_bcRecross[cnt][0] ==ticket)
            {
               OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES); //it needs to be after Lasttrade function                  
               if(OrderType()==OP_BUY &&  EMT_bcRecross[cnt][2]<Bid) EMT_bcRecross[cnt][2]=Bid;    
               if(OrderType()==OP_SELL && EMT_bcRecross[cnt][2]>Ask) EMT_bcRecross[cnt][2]=Ask;
               if(OrderType()==OP_BUY &&  EMT_bcRecross[cnt][5]>Bid) 
                  {
                     EMT_bcRecross[cnt][5]=Bid;
                     EMT_bcRecross[cnt][3]=EX_CountRecross(ticket,(EMT_bcRecross[index][5]-OrderOpenPrice())/ 2+OrderOpenPrice());  
                  }     
               if(OrderType()==OP_SELL && EMT_bcRecross[cnt][5]<Ask) 
                  {
                     EMT_bcRecross[cnt][5]=Ask;
                     EMT_bcRecross[cnt][3]=EX_CountRecross(ticket,OrderOpenPrice()-(OrderOpenPrice()-EMT_bcRecross[index][5])/ 2);
                  }
               return(cnt);      
            }   
       }      
      OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES); //it needs to be after previous orderselect  
      if(RCS_WriteDebug) L3_WriteDebug(5,"EX_RecrossCheck : Ticket : "+ticket+" was not founded recrosses pool.");
      
      for(index=0;index<ArrayRange(EMT_bcRecross,0);index++) if(EMT_bcRecross[index][0]==0) break;
      if(EMT_bcRecross[index][0] !=0)
         {
            if(RCS_WriteDebug) L3_WriteDebug(5,"EX_RecrossCheck : Error -no place in array");
            return(-1);
         }  
          
      EMT_bcRecross[index][0]=ticket; //holds Nr.of a ticket
      EMT_bcRecross[index][1]=1;       //holds count of recross throught a a upper S/R price
      EMT_bcRecross[index][2]=OrderOpenPrice();    //holds max reached price of the ticket
      EMT_bcRecross[index][3]=Bars;       //holds last sum of bars when upper S/R was recrossed 
      EMT_bcRecross[index][4]=1;       //holds count of recross throught a lower S/R price      
      EMT_bcRecross[index][5]=OrderOpenPrice();    //holds min reached price of the ticket
      EMT_bcRecross[index][6]=Bars;       //holds last sum of bars when lower S/R was recrossed 

      return(index);
    }  


bool EX_RecrossExit(int ticket,int poolPos)
   {
      double price,requiredPrice,comparePrice,replacedOP;
      bool crossingCheck=false;
      int cntRecross;
      if (OrderType() == OP_BUY)   
         {
            price=Bid;
            comparePrice=(EMT_bcRecross[poolPos][2]-EMT_bcRecross[poolPos][5])/2+EMT_bcRecross[poolPos][5];
            if(comparePrice<OrderOpenPrice()) //
               {
                  cntRecross=EMT_bcRecross[poolPos][4];
                  requiredPrice=( EMT_bcRecross[poolPos][2]-comparePrice)*EMT_RecrossCoefBad + comparePrice;
               }   
            else 
               {
                  cntRecross=EMT_bcRecross[poolPos][1];
                  requiredPrice=( EMT_bcRecross[poolPos][2]-comparePrice)*EMT_RecrossCoefGood + comparePrice;
               }   
            if(requiredPrice>=price && EMT_bcRecross[poolPos][4]>EMT_bcRecross[poolPos][1]) crossingCheck=true;
         }   
      if (OrderType() == OP_SELL) 
         {
            price=Ask;
            comparePrice=EMT_bcRecross[poolPos][5]-(EMT_bcRecross[poolPos][2]-EMT_bcRecross[poolPos][5])/2;
            if(comparePrice>OrderOpenPrice()) 
               {
                  cntRecross=EMT_bcRecross[poolPos][4];
                  requiredPrice=comparePrice-( comparePrice-EMT_bcRecross[poolPos][2] )*EMT_RecrossCoefBad;
               }                    
            else 
               {  cntRecross=EMT_bcRecross[poolPos][1];
                  requiredPrice=comparePrice-( comparePrice-EMT_bcRecross[poolPos][2] )*EMT_RecrossCoefGood;
               }   
            if(requiredPrice<=price  && EMT_bcRecross[poolPos][4]>EMT_bcRecross[poolPos][1]) crossingCheck=true;
         }

     if ( cntRecross>=EMT_RecrossMax && crossingCheck)
          {
           if(A1_4_IsTradePossible())
               {
                  for(int cnt2=0;cnt2<7;cnt2++) if(RCS_WriteDebug) L3_WriteDebug(6,StringConcatenate("EMT_RecrossMax-ticket : ",ticket," position : ",cnt2," value : ",EMT_bcRecross[poolPos][cnt2]));
                  if(OrderClose(ticket,OrderLots(),price,TMT_Slippage,Red)) return(true);
                  else L4_WriteError();
               }   
         }   
         
        if(Bars>EMT_bcRecross[poolPos][3]) //Bar hasn't been counted yet
         { 
            
            if(OrderType()==OP_BUY) replacedOP=NormalizeDouble((EMT_bcRecross[poolPos][2]-OrderOpenPrice())/ 2+OrderOpenPrice(),Digits );    
            else                    replacedOP=NormalizeDouble(OrderOpenPrice()-(OrderOpenPrice()-EMT_bcRecross[poolPos][2])/ 2,Digits );
            if( replacedOP == NormalizeDouble(price,Digits) )
                {
                  EMT_bcRecross[poolPos][1]++;
                  EMT_bcRecross[poolPos][3]=Bars;
                }  
          }  
          
        if(Bars>EMT_bcRecross[poolPos][6]) //Bar hasn't been counted yet
          { 
            
            if(OrderType()==OP_BUY) replacedOP=NormalizeDouble((OrderOpenPrice()-EMT_bcRecross[poolPos][5])/2 +EMT_bcRecross[poolPos][5],Digits );    
            else                    replacedOP=NormalizeDouble(EMT_bcRecross[poolPos][5]-(EMT_bcRecross[poolPos][5]-OrderOpenPrice())/ 2,Digits );
            if( replacedOP == NormalizeDouble(price,Digits) )
                {
                  EMT_bcRecross[poolPos][4]++;
                  EMT_bcRecross[poolPos][6]=Bars;
                }  
           }  
        
      return(false);
    }

int EX_CountRecross(int ticket,double price)
   {
       double FTS_SR_high[],FTS_SR_low[];
       double spread=MarketInfo(Symbol(),MODE_SPREAD)*Point;
       int recross;
       ArrayCopySeries(FTS_SR_high,MODE_HIGH,NULL,0);
       ArrayCopySeries(FTS_SR_low,MODE_LOW,NULL,0); 
       int timeBack=Bars-iBarShift(NULL,0,OrderOpenTime(),false);
       
       for(int cnt=0;cnt<=timeBack;cnt++)
         {
           if(OrderType()==OP_BUY && price>=FTS_SR_low[cnt] && price<=FTS_SR_high[cnt]) recross++;
           if(OrderType()==OP_SELL && price>=FTS_SR_low[cnt]+spread && price<=FTS_SR_high[cnt]+spread) recross++;           
         }
       return(recross);    
    }   

// ************** PART FOR A AUTO-OPTIMALIZATION - START ********************************
bool A_CheckStatus() //check if a optimalization on the second tester is done
   {
      string FileReportLocation;
      string FileReport="FileReport_"+Symbol()+".htm";                   //Tester report file name
      int fsize1,fsize2;
      
      if(!AOP_Optimalization_1On) return(false);
      int handle=FileOpen("\\optimalization\\tester\\files\\LastOptim.csv",FILE_CSV|FILE_READ,';');
      if(handle==Failed)
         {
           FileReportLocation="\\optimalization\\"+FileReport;   // Path into the tester directory   
           handle=FileOpen(FileReportLocation,FILE_CSV|FILE_READ,';');
           if (handle==-1) return(false);
           if(RCS_WriteLog) L2_WriteLog(7,"A_CheckStatus : No results were founded ! Probably no history data are loaded !");
           FileClose(handle);  
           return(true); //the file exists but it should not be so
         }   
      int pass=FileReadNumber(handle);
      FileClose(handle);
      if(pass>=AOP_ProveCyc_End-2*AOP_ProveCyc_Step) Sleep(10000);
      else 
         {
           return(false);
         }  
      FileReportLocation="\\optimalization\\"+FileReport;   // Path into the tester directory   
      handle=FileOpen(FileReportLocation,FILE_CSV|FILE_READ,';');
      if (handle==-1) return(false);
    
      if(RCS_WriteDebug) L3_WriteDebug(7,"A_CheckStatus : File "+FileReport+" is prepared !");
      fsize1=FileSize(handle);
      FileClose(handle);  
      
      Sleep(1000); 
      handle=FileOpen(FileReportLocation,FILE_CSV|FILE_READ,';');
      fsize2=FileSize(handle);  
      if (fsize1!=fsize2) 
         {
           FileClose(handle);        
           return(false); 
         }
      FileClose(handle); 
      if(RCS_WriteLog) L2_WriteLog(7,"A_CheckStatus : Ready to filter results of a optimalization !");

      return(true);
   }   

bool AutoOptStart(int AOP_TestDays,string RCS_NameEA)
  {
   
   string PuthTester;
   if(IsTesting())PuthTester=TerminalPath()+"\\tester\\files\\optimalization";   // Path of a executable tester file to the tester directory   
   else PuthTester=TerminalPath()+"\\experts\\files\\optimalization";   // Path of a executable tester file to the experts directory   
   
   string FileReport      = "FileReport_"+Symbol()+".htm";                   //Tester report file name
   datetime DayStart      = TimeLocal()-86400*AOP_TestDays;                        //Calculation of the starting date
   string DateStart       = TimeToStr(DayStart,TIME_DATE);                    //Optimization starting date
   string DateStop        = TimeToStr(TimeLocal()+86400,TIME_DATE);                 //Optimization ending date
   int    start,handle,cnt;
   string FileLine,FileReportLocation,FileLoc; 
   string ArrayOpttim[21]; 

   FileLoc="\\optimalization\\tester\\history\\"+Symbol()+Period()+"_0.fxt";
   handle=FileOpen(FileLoc,FILE_CSV|FILE_WRITE,';');     //Open a file to write
   if(handle!=-1) 
      {
         FileClose(handle); 
         FileDelete(FileLoc); //delete a generated file with bars from a history center , something like a tester's option Test Recalculate
         while(GetLastError()==4100) 
            {
               Sleep(1000);
               FileDelete(FileLoc); //probably the file is open, so try it again  
            }          
         if(RCS_WriteDebug) L3_WriteDebug(7,"AutoOptStart : File "+FileLoc+" was deleted !");
      }
   

//------------------------------parameters of the ini file are written in the string array----------------
   ArrayOpttim[0] = ";start strategy tester";                  //Prepare the ini file for optimization
   ArrayOpttim[1] = "ExpertsEnable=false";                        //Enable/Disable Expert Advisors
   ArrayOpttim[2] = "TestExpert="+RCS_NameEA;                        //Name of the EA file
   ArrayOpttim[3] = "TestExpertParameters=setGLFXforAutoOpt.set";   //Name of the file containing parameters
   ArrayOpttim[4] = "TestSymbol="+Symbol();                       //Symbol
   ArrayOpttim[5] = "TestPeriod="+Period();                       //Timeframe
   ArrayOpttim[6] = "TestModel="+0;                               //Modeling mode
   ArrayOpttim[7] = "TestRecalculate=true";                      //Recalculate
   ArrayOpttim[8] = "TestOptimization=true";                      //Optimization
   ArrayOpttim[9] = "TestDateEnable=true";                        //Use date
   ArrayOpttim[10]= "TestFromDate="+DateStart;                    //From
   ArrayOpttim[11]= "TestToDate="+DateStop;                       //To
   ArrayOpttim[12]= "TestReport="+FileReport;                     //Report file name
   ArrayOpttim[13]= "TestReplaceReport=true";                     //Rewrite the report file
   ArrayOpttim[14]= "TestShutdownTerminal=true";                  //Shut down the terminal upon completion
   
   handle=FileOpen("\\optimalization\\InitOptTester.ini",FILE_CSV|FILE_WRITE,';');     //Open a file to write
   for(cnt=0; cnt<15; cnt++) FileWrite(handle,ArrayOpttim[cnt]); //15=arraysize(ArrayOptim)
   FileClose(handle); 
   if(RCS_WriteDebug) L3_WriteDebug(7,"AutoOptStart : File InitOptTester.ini is prepared !");

//------------------------------parameters of the set file are written in the string array----------------
 
      string SfileName=StringConcatenate("Start-",TMT_Currency,"-",TMT_Period,".set");
      int Sfile=FileOpen(SfileName,FILE_READ,';');   
      int Tfile=FileOpen("\\optimalization\\tester\\setGLFXforAutoOpt.set",FILE_WRITE,';');  
      while(FileIsEnding(Sfile)==false)
        {                               //Cycle, until the file ends
          FileLine=FileReadString(Sfile); 
          if(FileLine!="") FileWrite(Tfile,FileLine);
        }
      FileClose(Sfile);                                                //Close the file
      FileClose(Tfile);                                                //Close the file
  

//---- enf of setting of time shift for optimalization

//changing basic set of variables with these values to be sure that a optimalization can run correctly
   ArrayOpttim[0] = "AOP_Optimalization_1On=1";               
   ArrayOpttim[1] = "SMT_ProveCurrentSet=1";                        
   ArrayOpttim[2] = "SMT_ProveHoursBack="+DoubleToStr(SMT_ProveHoursBack,0);                        
   ArrayOpttim[3] = "SMT_CurrentPass=0";          
   ArrayOpttim[4] = "SMT_CurrentPass,F=1";                       
   ArrayOpttim[5] = "SMT_CurrentPass,1="+DoubleToStr(AOP_ProveCyc_Start,0);                       
   ArrayOpttim[6] = "SMT_CurrentPass,2="+DoubleToStr(AOP_ProveCyc_Step,0);                              
   ArrayOpttim[7] = "SMT_CurrentPass,3="+DoubleToStr(AOP_ProveCyc_End,0);                     
   ArrayOpttim[8] = "FTS_NotTradeFrom1=0";                     
   ArrayOpttim[9] = "FTS_NotTradeTo1="+DoubleToStr(SetTimeFrom(SMT_ProveHoursBack,TimeCurrent()),0);                        
   ArrayOpttim[10]= "FTS_NotTradeFrom2="+DoubleToStr(TimeCurrent(),0);                    
   ArrayOpttim[11]= "FTS_NotTradeTo2=2054678400"; //set a date in far future ,f.e.'2035.02.10 00:00';                      
   ArrayOpttim[12]= "SMT_LookForNextSet=1";   
   ArrayOpttim[13]= "CLS_CheckPA_2On=0";
   ArrayOpttim[14]= "AOP_ModifyTPSL_2On=0";
   ArrayOpttim[15]= "RCS_WriteLog=0";
   ArrayOpttim[16]= "RCS_WriteDebug=0";
   ArrayOpttim[17]= "EXT_OpenDeniedTimeIfSwapOK=0"; //do not open trades according to swap
   ArrayOpttim[18]= "FTE_Time_2On=0"; //do not block trades according to time 
   ArrayOpttim[19]= "MMT_Martingale_1On=0"; //After each loss the bet should be increased so, that the win would recover all previous losses plus a small profit

//------------------------------- Write data into the set file           --------------------------                 
   handle=FileOpen("\\optimalization\\tester\\setGLFXforAutoOpt.set",FILE_CSV|FILE_WRITE|FILE_READ,';');     //Open a file to write
   FileSeek(handle,0,SEEK_END);
   for(cnt=0; cnt<20; cnt++) FileWrite(handle,ArrayOpttim[cnt]); //20=arraysize(ArrayOptim)
   FileClose(handle);  
   if(RCS_WriteDebug) L3_WriteDebug(7,"AutoOptStart : File setGLFXforAutoOpt.set is prepared !");                                           

//---------------------------------- Start Tester -------------------------
   if(IsTesting())FileReportLocation="\\optimalization\\"+FileReport;   // Path to the terminal into tester directory   
   else FileReportLocation="\\optimalization\\"+FileReport;   // Path to the terminal into experts directory  
   handle=FileOpen(FileReportLocation,FILE_CSV|FILE_READ,';');
   if(handle!=-1) 
      {
        FileClose(handle);
        FileDelete(FileReportLocation);  //Delete this file for sure that there is no colision in next optimalization 
      }   
   start   = ShellExecuteA(0,"Open","terminal.exe","InitOptTester.ini",PuthTester,7);
   if( start<0)
      {
        if(RCS_WriteLog) L2_WriteLog(7,"Failed starting Tester");
        return(false);
      } 
   if(RCS_WriteDebug) L3_WriteDebug(7,"AutoOptStart : Tester has started correctly with value :"+start);   
   return(true); 

 }  //Function AutoOptStart ends. 
 
 
bool AutoOptResult(int AOP_TestDays,string RCS_NameEA,int AOP_Gross_Profit,int AOP_Profit_Factor,int AOP_Expected_Payoff)
  {
   if(RCS_WriteDebug) L3_WriteDebug(7,"AutoOptResult : Starting AutoOptResult");   
   string PuthTester,PuthTerminal,FileReportLocation;
   if(IsTesting())PuthTester=TerminalPath()+"\\tester\\files\\optimalization";   // Path of a executable tester file to the tester directory   
   else PuthTester=TerminalPath()+"\\experts\\files\\optimalization";   // Path of a executable tester file to the experts directory   

   if(IsTesting())PuthTerminal=TerminalPath()+"\\tester\\files";   // Path to the terminal into tester directory   
   else PuthTerminal=TerminalPath()+"\\experts\\files";   // Path to the terminal into experts directory   

   string FileOptim       = "InitOptTester.ini";                                   //Name of the ini file for the tester
   datetime DayStart      = TimeLocal()-86400*AOP_TestDays;                        //Calculation of the starting date
   string DateStart       = TimeToStr(DayStart,TIME_DATE);                    //Optimization starting date
   string DateStop        = TimeToStr(TimeLocal()+86400,TIME_DATE);                 //Optimization ending date
   string FileReport      = "FileReport_"+Symbol()+".htm";                   //Tester report file name
   int    StepRes         = 21;                                               //The amount of lines for sorting
//-------------------------------other mediatory variables------------------------
   int    start,file=-1,Pptk,i;
   int    P1,P1k;
   int    ClStep,ClStepRazm,GrProf,GrProfRazm,TotTrad,TotTradRazm,ProfFact,ProfFactRazm,ExpPay,ExpPayRazm;
   int    text,index,kol,NumberStr,NumStr,CopyAr;
   int    GrosPr,PrCycle,Dubl;
   int    ResizeArayNew;
   double TotalTradesTransit,GrossProfitTransit,ExpectedPayoffTran;
   double PrFactDouble,PercSuitSets;
   double Prior1, Prior2, Prior3, transit, transit1;
   double Sort, SortTrans;
   string FileLine; 
   string CycleStep,GrossProfit,TotalTrades,ProfitFactor,ExpectedPayoff;
   string Perem1; 
   string select;
   bool   nodubl;
//----------------------------------- preparations of arrays -------------------------
   string ArrayOpttim[15]; 
   string ArrayStrg[10]; 
   double ArrayData[10][9]; 
   double ArrayTrans[10][9];

//------------------------ open a report file into the tester directory -------
   FileReportLocation="\\optimalization\\"+FileReport;   // Path to the terminal into tester directory   
   while (file<0)
      {
         if(RCS_WriteDebug) L3_WriteDebug(7,"AutoOptResult : Try to open "+FileReport);   
         file=FileOpen(FileReportLocation,FILE_READ,0x7F);                   //open the report file
      }      
//---------------- Read from file into the array ----------------------------------
    while(FileIsEnding(file)==false)
      {                               //Cycle, until the file ends
          FileLine=FileReadString(file);                            //Read a string from the report file
          index=StringFind(FileLine, "title", 20);                  //Find the necessary string and set the reference point there
          if(index>0)
           {
             ArrayResize(ArrayStrg,NumStr+1);                       //Increase the array in size
             ArrayStrg[NumStr]=FileLine;                            //Record the strings from the file in the array
             NumStr++;
           }  
      }
    FileClose(file);                                                //Close the file
    ArrayResize(ArrayData,NumStr);                                  //Set the array size by the amount of data read from the file
    PercSuitSets= (NumStr-1)*100 /((AOP_ProveCyc_End-AOP_ProveCyc_Start)/AOP_ProveCyc_Step);
    if(RCS_WriteLog) L2_WriteLog(7,StringConcatenate("There were founded ",PercSuitSets,"% profit sets from all of sets which were examined within optimalization."));
    if(AOP_MinPercSuitableSets > PercSuitSets)
      {
         if(RCS_WriteLog) L2_WriteLog(7,StringConcatenate("Because ",AOP_MinPercSuitableSets,"% is minimum, no set is choosen !"));
         return(false);
      }           
    
    for(text=0;text<NumStr;text++)
     {
        select=ArrayStrg[text]; 
//-------------------------------------------------------------------------; ">
//                    Then the necessary values are selected in the array:       
        //---------------------Reporting text processing (These are apples and oranges -----------------------------
        ClStep=StringFind(select, "; \">",20)+4;                                       //Position Pass 
        ClStepRazm=StringFind(select, "</td>",ClStep);                                 //Find the end of position
        CycleStep = StringSubstr(select, ClStep, ClStepRazm-ClStep);                   //Read the value
        //---------------- Position Profit  -------------------------------
        GrProf=StringFind(select, "<td class=mspt>",ClStepRazm);                       //Find the beginning of the position
        GrProfRazm=StringFind(select, "</td>",GrProf);                                 //Find the end of position
        GrossProfit = StringSubstr(select, GrProf+15,GrProfRazm-(GrProf+15));          //Read value
         //-------------Position Total Trades -----------------------------
        TotTrad=StringFind(select, "<td>",GrProfRazm);                                 //Find the beginning of position
        TotTradRazm=StringFind(select, "</td>",TotTrad);                               //Find the end of position
        TotalTrades = StringSubstr(select, TotTrad+4,TotTradRazm-(TotTrad+4));         //Read the value
        //-------------Position Profitability--------------------------------
        ProfFact=StringFind(select, "<td class=mspt>",TotTradRazm);                    //Find the beginning of position
        ProfFactRazm=StringFind(select, "</td>",ProfFact);                             //Find the end of position
        ProfitFactor = StringSubstr(select, ProfFact+15,ProfFactRazm-(ProfFact+15));     //Read the value
       //-------------Position Expected Payoff ---------------------------------
        ExpPay=StringFind(select, "<td class=mspt>",ProfFactRazm);                     //Find the beginning of position
        ExpPayRazm=StringFind(select, "</td>",ExpPay);                                 //Find the dn of position
        ExpectedPayoff = StringSubstr(select, ExpPay+15,ExpPayRazm-(ExpPay+15));         //Read the value
        //------------------------------------------------------------------
        //-------------Variables' positions starting with the second one---------------------
        P1=StringFind(select,"SMT_CurrentPass",20);                                                //Find the beginning of position
        P1k=StringFind(select, ";",P1);                                                //Find the end of position
        Perem1 = StringSubstr(select,P1+StringLen("SMT_CurrentPass")+1,P1k-(P1+1+StringLen("SMT_CurrentPass"))); //Read the Variable

//-----------------------Transform into number format----------------------------
       TotalTradesTransit=NormalizeDouble(StrToDouble(TotalTrades),0);
       GrossProfitTransit=NormalizeDouble(StrToDouble(GrossProfit),0);
       ExpectedPayoffTran=NormalizeDouble(StrToDouble(ExpectedPayoff),2);
       nodubl=true;
       if(RCS_WriteDebug) L3_WriteDebug(7,"AutoOptResult :Nr."+text+" Pass : "+CycleStep+" TotalTradesTransit : "+TotalTradesTransit+" GrossProfitTransit : "+GrossProfitTransit+" ExpectedPayoffTran : "+ExpectedPayoffTran); 
       
       if(AOP_MinTrCnt <= TotalTradesTransit && AOP_MaxTrCnt >= TotalTradesTransit)
        {                    //Filter by the amount of trades
          PrFactDouble = NormalizeDouble(StrToDouble(ProfitFactor),2);
          if(PrFactDouble==0){PrFactDouble=1000;}                                       //Replace 0 in the AOP_Profit_Factor for proper analysis
//-------------- Filter data having identical values -------------------       
           for(Dubl=0;Dubl<=text;Dubl++)
            {                                               //Start the loop searching for identical values
               if(GrossProfitTransit == ArrayData[Dubl][1])
                  {                            //check whether the results for maximal profit coincide
                     if(TotalTradesTransit == ArrayData[Dubl][2])
                        {                         //check whether the results for the amount of trades coincide
                           if(PrFactDouble == ArrayData[Dubl][3])
                              {                            //check whether the results for Profit Factor coincide
                                 if(ExpectedPayoffTran == ArrayData[Dubl][4])
                                    {                   //check whether the results for expected payoff coincide
                                       //nodubl=false;        // If everything coincides, flag it as coincided
                                    }   
                              }
                         }
                   }
            }                        
           
            
//---------------- Write the filtered data in the array ----------------------
           if(nodubl)
            {
              ArrayData[ResizeArayNew][1]=GrossProfitTransit;                                
              ArrayData[ResizeArayNew][2]=TotalTradesTransit;
              ArrayData[ResizeArayNew][3]=PrFactDouble;
              ArrayData[ResizeArayNew][4]=ExpectedPayoffTran;
              ArrayData[ResizeArayNew][5]=StrToDouble(Perem1);
              ResizeArayNew++;
            } 
        }
     }   
    //||||||||||||||||||||||||||||||| write variables into a intermediate file ||||||||||||||||||||||||||||||||||||                 
   int FileTst;
   int trs1,trs2,trs3,trs6;
   double trs4,trs5;
   if(RCS_WriteDebug) L3_WriteDebug(7,"AutoOptResult : Going to write results into a file ResultFilter1.csv");   
   FileTst=FileOpen("ResultFilter1.csv",FILE_CSV|FILE_WRITE,0x7F);           //open a file according to notes
   FileWrite(FileTst,"GrossProfit ; TotalTrades ; ProfitFactor ; ExpectedPayoff ;"+"SMT_CurrentPass"); 
   if(FileTst>0){
      for(i=0; i<ResizeArayNew; i++){
           trs2 = ArrayData[i][1];             
           trs3 = ArrayData[i][2];
           trs4 = ArrayData[i][3];             
           trs5 = ArrayData[i][4]; 
           trs6 = ArrayData[i][5];                       

          FileWrite(FileTst,trs2+";"+trs3+";"+trs4+";"+trs5+";"+trs6);                                  
      } 
      FileClose(FileTst);                                          //Close the file
   }
   else{
        if(RCS_WriteLog) L2_WriteLog(7,StringConcatenate("Not possible to write variables into a ResultFilter1 file. Error Nr. ",GetLastError()));
        return(false);
   }
//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

   if(RCS_WriteDebug) L3_WriteDebug(7,"AutoOptResult : Going to write results into a file ResultFilter2.csv");   
   FileTst=FileOpen("ResultFilter2.csv",FILE_CSV|FILE_WRITE,0x7F);                      
 
//------------------------------Analyzer---------------------------------------- 
// Analyzing principle is the sequential checking of maximal values according to the predefined filtering priority 
   if(ResizeArayNew<=0) 
      {
         if(RCS_WriteLog) L2_WriteLog(7,"AutoOptResult: Because no set passed through filters, no set is choosen !");
         return(false);
      }   
   ArrayResize(ArrayTrans, ResizeArayNew-1);
   for(int PrioStep=1;PrioStep<4;PrioStep++){
   FileWrite(FileTst,"GrossProfit ; TotalTrades ; ProfitFactor ; ExpectedPayoff ;"+"SMT_CurrentPass"); 
       for(PrCycle=0;PrCycle<ResizeArayNew;PrCycle++){
           Sort     = ArrayData[PrCycle][0];
           Prior1   = ArrayData[PrCycle][1];             
           transit  = ArrayData[PrCycle][2];
           Prior2   = ArrayData[PrCycle][3];             
           Prior3   = ArrayData[PrCycle][4];             
           transit1 = ArrayData[PrCycle][5];
           
           if(PrioStep==1){
              //Prepare for the 1st sorting
              if(AOP_Gross_Profit   ==1){SortTrans=Prior1;}
              if(AOP_Profit_Factor  ==1){SortTrans=Prior2;}
              if(AOP_Expected_Payoff==1){SortTrans=Prior3;}
           }
           if(PrioStep==2){
              //Restore
              if(AOP_Gross_Profit   ==1){Prior1=Sort;}
              if(AOP_Profit_Factor  ==1){Prior2=Sort;}
              if(AOP_Expected_Payoff==1){Prior3=Sort;} 
              //Prepare for the 2nd sorting
              if(AOP_Gross_Profit   ==2){SortTrans=Prior1;}
              if(AOP_Profit_Factor  ==2){SortTrans=Prior2;}
              if(AOP_Expected_Payoff==2){SortTrans=Prior3;}
           }
           if(PrioStep==3){
              //Restore
              if(AOP_Gross_Profit   ==2){Prior1=Sort;}
              if(AOP_Profit_Factor  ==2){Prior2=Sort;}
              if(AOP_Expected_Payoff==2){Prior3=Sort;} 
              //Prepare for the 3rd sorting
              if(AOP_Gross_Profit   ==3){SortTrans=Prior1;}
              if(AOP_Profit_Factor  ==3){SortTrans=Prior2;}
              if(AOP_Expected_Payoff==3){SortTrans=Prior3;}
           }          
           ArrayTrans[PrCycle][0] = SortTrans;
           ArrayTrans[PrCycle][1] = Prior1;
           ArrayTrans[PrCycle][2] = transit;
           ArrayTrans[PrCycle][3] = Prior2;
           ArrayTrans[PrCycle][4] = Prior3;
           ArrayTrans[PrCycle][5] = transit1;
       }
       ArraySort(ArrayTrans,WHOLE_ARRAY,0,MODE_DESCEND);               //Sort the array       
       ArrayResize(ArrayTrans,StepRes);                            //Cut off the unnecessary things
       for(CopyAr=0;CopyAr<StepRes;CopyAr++){
           ArrayData[CopyAr][0]=ArrayTrans[CopyAr][0];
           ArrayData[CopyAr][1]=ArrayTrans[CopyAr][1];
           ArrayData[CopyAr][2]=ArrayTrans[CopyAr][2];
           ArrayData[CopyAr][3]=ArrayTrans[CopyAr][3];
           ArrayData[CopyAr][4]=ArrayTrans[CopyAr][4];             
           ArrayData[CopyAr][5]=ArrayTrans[CopyAr][5];             //"SMT_CurrentPass"    Variable 1
      }
//|||||||||||||||||||||||||||||||    ||||||||||||||||||||||||||||||||||||                 
   
   if(FileTst>0){
      for(i=0; i<StepRes; i++){
          trs2 = ArrayData[i][1];             
          trs3 = ArrayData[i][2];
          trs4 = ArrayData[i][3];             
          trs5 = ArrayData[i][4];             
          trs6 = ArrayData[i][5];
          FileWrite(FileTst,trs2+";"+trs3+";"+trs4+";"+trs5+";"+trs6);     //write a variable into a file
   }} 
   else{
        if(RCS_WriteLog) L2_WriteLog(7,StringConcatenate("AutoOptResult: Not possible to write variables into ResultFilter2 file. Error Nr. ",GetLastError()));
        return(false);
   }
//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

       StepRes=StepRes/2;
   } 
    FileClose(FileTst);                                          //close the intermediate file with variables
     
       //Write the obtained results in variables
       double Peremen1 = ArrayTrans[0][5];                         
       if(Peremen1>0)
         {
           SMT_CurrentPass=Peremen1; 
           if(RCS_WriteLog) L2_WriteLog(7,StringConcatenate("AutoOptResult: The set Nr."," ",Peremen1," was choosen. Going to set it!"));
         }  
       else 
         {
           if(RCS_WriteLog) L2_WriteLog(7,"AutoOptResult: Optimalization is finished but the best Pass was not found !");
           return(false);
         }  
   if(RCS_WriteDebug) L3_WriteDebug(7,"AutoOptResult : Function is finished!");   
   return(true);    
 }  //Function ends. That's all, automated optimization is complete 
             
// ************** PART FOR A AUTO-OPTIMALIZATION - END ********************************

 
bool AOP_ModifyTPSL_2OnFunction()
   {
      int BuySigCnt=1,SellSigCnt=1;
      double orderSL,orderTP;
      double newSL,newTP,difference;
      int wait;
      string message;
      bool sellCnt=false,buyCnt=false;
      
      if(AOP_TPSLperi) AOP_TPSLnextRun=TimeCurrent()+AOP_TPSLwait; //run always after a certain amount of time
      if(!AOP_AllowNewTrades)
         {
            if(RCS_WriteDebug) L3_WriteDebug(6,"AOP_ModifyTPSL_2On : not change TP or SL, because a current set is not marked as profitable !");  
            return(false); 
         }   
      if(AOP_TPSLbuyCnt>=AOP_TPSLmaxChanges && AOP_TPSLsellCnt>=AOP_TPSLmaxChanges) return(false);
      if(RCS_WriteDebug) L3_WriteDebug(6,"Start AOP_ModifyTPSL_2On Function !");
      if(AOP_TPSLperi) 
         {
            BuySigCnt=0;
            SellSigCnt=0;
            if(A2_Check_If_Signal(1,BuySigCnt,SellSigCnt)==0 && !AOP_TPSLpromptly)
               {
                 if(RCS_WriteDebug) L3_WriteDebug(6,"AOP_ModifyTPSL_2On : No condition for opening a trade, so no modifying possible !");  
                 return(false);
               }  
         }   
      RefreshRates();
      for (int cnt = 0; cnt < OrdersTotal(); cnt++) 
        {
           if (OrderSelect(cnt, SELECT_BY_POS) == false) continue;
           if (OrderSymbol() != Symbol()) continue;
           if (OrderMagicNumber() >= GBV_MagicNumSet1 && OrderMagicNumber() <= GBV_MagicNumSet1 + GBV_maxMagic)
            {
              newSL=0;
              newTP=0; 
              wait=0;   
              message="Ticket Nr."+DoubleToStr(OrderTicket(),0);  
              if(RCS_WriteDebug) L3_WriteDebug(6,"AOP_ModifyTPSL_2On : "+message+" is examided if it is suitable to change TP or SL");  
              message=message+" was modified";  
              if(AOP_Optimalization_1On && AOP_LastAutoOptim<=OrderOpenTime() ) continue; //not change ticket within the set where it was opened                       
              if(OrderType()==OP_SELL && SellSigCnt>0 && AOP_TPSLsellCnt<AOP_TPSLmaxChanges) 
               {
                  orderSL=Ask+TMT_SL*Point;
                  if(OrderStopLoss()>orderSL) newSL=orderSL;
                  orderTP=Ask-TMT_TP*Point;
                  if(OrderTakeProfit()<orderTP) newTP=orderTP;
               }   
                  
              if(OrderType()==OP_BUY && BuySigCnt>0 && AOP_TPSLbuyCnt<AOP_TPSLmaxChanges) 
               {
                  orderSL=Bid-TMT_SL*Point;
                  if(OrderStopLoss()<orderSL) newSL=orderSL;
                  orderTP=Bid+TMT_TP*Point;
                  if(OrderTakeProfit()>orderTP) newTP=orderTP;
               }
              if(newSL!=0 || newTP!=0)
               {
                  if(newSL==0)newSL=OrderStopLoss();
                  else 
                     {
                        difference=MathAbs((OrderStopLoss()-newSL)/Point);
                        message=message+", SL was decreased about "+DoubleToStr(difference,0)+" points";
                     }   
                  if(newTP==0)newTP=OrderTakeProfit();
                  else 
                     {
                        difference=MathAbs((OrderTakeProfit()-newTP)/Point);
                        message=message+", TP was decreased about "+DoubleToStr(difference,0)+" points";
                     } 
                  while(wait>10 && !IsTradeAllowed()) 
                     {
                        Sleep(1000);
                        wait++;
                     } 
                  if(!A1_4_IsTradePossible())  //check if trade is allowed 
                     {
                        message="Modifying is not allowed !";
                        if(RCS_WriteLog) L2_WriteLog(6,message);
                        continue;
                     }   
                  if(OrderModify (OrderTicket(),OrderOpenPrice(), newSL,newTP,0, BlueViolet)==-1)
                     {
                        if(RCS_WriteLog) L2_WriteLog(6,"Modify error !");
                     }    
                  else 
                     {
                        if(OrderType()==OP_BUY) 
                           {
                              buyCnt=true;
                              message=message+", "+DoubleToStr(AOP_TPSLbuyCnt+1,0)+". change";
                           }  
                        else 
                           {
                              sellCnt=true;
                              message=message+", "+DoubleToStr(AOP_TPSLsellCnt+1,0)+". change";
                           }   
                        if(RCS_WriteLog) L2_WriteLog(6,message);                        
                     } 
               }   
            }
         } 
      if(buyCnt) AOP_TPSLbuyCnt++;
      if(sellCnt) AOP_TPSLsellCnt++;      
 
   }//end of AOP_ModifyTPSL_2OnFunction()
 
 
bool TextIntoArray (string textVar, string nameVar,int& variable[],int lenght)
   {
      string parametr,message;
      double val;
      if(StringLen(textVar)!=lenght*ArraySize(variable))
         {
            message=nameVar+" has wrong initial settings given by user! It uses predefined values.";
            Alert(message);
            if(RCS_WriteLog) L2_WriteLog(8,message);  
            return(false);
         } 
      for (int cnt=0;cnt<ArraySize(variable);cnt++)
         {
            parametr=StringSubstr(textVar,0,lenght);
            val=StrToDouble(parametr);
            variable[cnt]=val;
            textVar=StringSubstr(textVar,lenght,StringLen(textVar));
         }   
      return(true);
    }         

bool CloseBeforeWeekend (int ticket)
   {
      double price,TimeEnd;
      
      if(DayOfWeek()!=5) TimeEnd=EGF_TimeDayEnd;
      else TimeEnd=EGF_TimeFridayEnd;
      
      if(DayOfWeek()!=5 && EGF_CloseOnlyOnFriday) return(false); //is friday
      if(GBV_currentTime<TimeEnd-EGF_TimeBeforeEnd) return(false); //wait to active this function
      if(OrderType()==OP_BUY && OrderProfit()+OrderSwap()<0 && EGF_KeepWhenSwapOK && SwapLong>0) return(false);
      if(OrderType()==OP_SELL && OrderProfit()+OrderSwap()<0 && EGF_KeepWhenSwapOK && SwapShort>0) return(false);
      if(OrderType()==OP_BUY && GBV_currentTime>TimeEnd) price=Bid;
      if(OrderType()==OP_SELL && GBV_currentTime>TimeEnd) price=Ask;       
      
      if(OrderType()==OP_BUY && OrderProfit()+OrderSwap()>0) 
         {
            if(price==0 && EGF_WaitOnProfitInPips!=0)
               {
                  if(Bid-OrderOpenPrice()<EGF_WaitOnProfitInPips*Point) 
                     {
                        if(RCS_WriteDebug) L3_WriteDebug(5,"EGF_CloseBeforeRollOver : Ticket Nr."+ticket+" does not have expected profit.");  
                        return(false);
                     }   
               }   
            price=Bid;
         }   
      if(OrderType()==OP_SELL && OrderProfit()+OrderSwap()>0) 
         {
            if(price==0 && EGF_WaitOnProfitInPips!=0)
               {
                  if(OrderOpenPrice()-Ask<EGF_WaitOnProfitInPips*Point)
                     {
                        if(RCS_WriteDebug) L3_WriteDebug(5,"EGF_CloseBeforeRollOver : Ticket Nr."+ticket+" does not have expected profit.");  
                        return(false);
                     }   
               }   
            price=Ask; 
         }   
      
      if(price==0) return(false);
      if(!A1_4_IsTradePossible()) return(false); //check if trade is allowed 
      if(OrderClose(ticket,OrderLots(),price,TMT_Slippage,Red)!=-1)
         {
           if(RCS_WriteLog) L2_WriteLog(5,"EGF_CloseBeforeRollOver: Ticket Nr."+ticket+ "was closed because of a function CloseBeforeWeekend. SwapLong :"+SwapLong+" SwapShort : "+SwapShort);  
           if(EXT_OpenDeniedTimeIfSwapOK && FTE_Time_2On && Z_F2_BlockTradingFilter2()) EXT_IsOpenedTradeIfSwapOK=false;
           return(true);
         }
      else  if(RCS_WriteLog) L2_WriteLog(5,"EGF_CloseBeforeRollOver: Ticket Nr."+ticket+ " : closing error within function CloseBeforeWeekend"); 
      return(false);
      
   }

int SetTimeFrom (int SMT_ProveHoursBack,int NotFrom2) //gain time from which time it should trade {1.par = hours back, 2.par. counted from time}
   { 
      int cnt=SMT_ProveHoursBack;
      datetime NotTo1;
      datetime CurrTime=NotFrom2;
      NotTo1=NotFrom2;
          while(cnt>0)
            {
               CurrTime-=3600;               
               if(TimeDayOfWeek(CurrTime)==0 || TimeDayOfWeek(CurrTime)==6) continue; //saturday and sunday not counted
               NotTo1-=3600;
               cnt--;
            }  
      return(NotTo1);       
   } 
   
bool OpenIfSwapOK ()
   {
      if( FTE_Time_2On && !Z_F2_BlockTradingFilter2() ) return(false); //open only in restricted area
      if(EXT_IsOpenedTradeIfSwapOK) return(false);
      if(EGF_CloseOnlyOnFriday && DayOfWeek()!=5) return(false);
      bool TimeFilter=FTE_Time_2On;
      FTE_Time_2On=false;
      int TradeDirect=A2_Check_If_Signal(TMT_SignalsRepeat,GBV_BuySignalCount,GBV_SellSignalCount);
      FTE_Time_2On=TimeFilter;
            
      double TimeEnd;
      if(DayOfWeek()!=5) TimeEnd=EGF_TimeDayEnd;
      else TimeEnd=EGF_TimeFridayEnd;
            
      if(TradeDirect==1 && SwapLong>0 && GBV_currentTime<TimeEnd) //open when swap is in the direction of a future trade
        {
                if( A1_1_OrderNewBuy(MM_OptimizeLotSize(Buy)*A1_3_EntryConfirmation(OP_BUY)) != Failed)
                  {
                     if(RCS_WriteLog) L2_WriteLog(3,"Function EXT_OpenDeniedTimeIfSwapOK was opened a long trade !");
                     GBV_BuySignalCount   =0;
                     EXT_IsOpenedTradeIfSwapOK=true;
                  } 
        }
      else if(TradeDirect==-1 && SwapShort>0 && GBV_currentTime<TimeEnd)
        {
                if( A1_2_OrderNewSell(MM_OptimizeLotSize(Sell)*A1_3_EntryConfirmation(OP_SELL)) != Failed)
                  {
                     if(RCS_WriteLog) L2_WriteLog(3,"Function EXT_OpenDeniedTimeIfSwapOK was opened a short trade !");                     
                     GBV_SellSignalCount  =0;
                     EXT_IsOpenedTradeIfSwapOK=true;
                  } 
        }
        
   } //end of OpenIfSwapOK ()




//End Of File





Sample





Analysis



Market Information Used:

Series array that contains the highest prices of each bar
Series array that contains the lowest prices of each bar
Series array that contains open time of each bar
Series array that contains close prices for each bar


Indicator Curves created:


Indicators Used:

Envelopes indicator
Moving average indicator
Moving Average of Oscillator
Relative strength index
Indicator of the average true range


Custom Indicators Used:
shell32

Order Management characteristics:
Checks for the total of open orders
Checks for the total of closed orders
It Closes Orders by itself

Other Features:

Uses files from the file system

It issuies visual alerts to the screen
It reads information from a file
It writes information to file