//+--------------------------------------------------------------------------------------------+ //| SRS EA.mq4 | //| Copyright © 2014, isaackoay | //| Programming by Serega Lykov, http://mtexperts.narod.ru/ | //+--------------------------------------------------------------------------------------------+ // mod001 - release the EA // mod002 - add options TradeSingleOrder, MoveToBE, STOCH_MaxBarsAfterRSI, STOCH_OnlyFirstCrossing and RSI_CheckRetrace // mod003 - rework to trade one symbol and one timeframe; modify option MoveToBE to the 4-steps // - add option DinamicSL // mod004 - replace indicator "PZ_SupportResistance" by "ZigZag"; add options DinamicSL_MinimumPips and DinamicSL_MaximumPips // - modify option UseMM // mod005 - modify option UseMM (now it based on the possible loss of order) #property copyright "Copyright © 2014, isaackoay" #property link "" //---- constant values ------------------------------------------------------------------------+ #define FolderName_Expert "SRS" #define FolderName_Screenshots "Screenshots" #define FolderName_Logs "Logs" #define FileName_OrdersHistory "OrdersHistory" #define ScreenshotSizeX 1024 #define ScreenshotSizeY 768 #define ScreenshotStartBar -1 #define ScreenshotChartScale -1 #define ScreenshotChartMode -1 #define ExpertName "SRS" #define SubjectOpen "New Trade Information" #define SubjectClose "New Trade Information" #define SubjectDelete "New Trade Information" #define NumRiskMultipliers 10 #define NumRiskValues 11 #define IndicatorFileName_ZZ "ZigZag" enum ENUM_TIMEFRAMES_MY { Current = 0, M1 = 1, M5 = 5, M15 = 15, M30 = 30, H1 = 60, H4 = 240, D1 = 1440, W1 = 10080, MN1 = 43200 }; //---- external parameters --------------------------------------------------------------------+ //---- parameters of trade -----------------------------------------------------------------+ extern string _____Trade_Options____ ="----------------------------------------------"; extern bool AutoDetectSymbolAppendix = true; // true = auto-detect appendix at symbols (for example, you set name of symbol "EURUSD" and the EA modify it to "EURUSDxxx", where xxx - it is appendix in names of symbols) extern bool TradeSingleOrder = true; // true = ignore new opening signal if still exist previous order from signal of any pair/timeframe; false = the EA can add orders of others opening signals and close order at the opposite opening signal (work as version "mod001") extern bool MoveSLToBE_Use = true; // true = use option MoveSLToBE; false = does not use option MoveSLToBE extern double MoveSLToBE_1_ProfitPercents = 25; // (amount percents from TakeProfit) profit when move level stop-loss to the new price; 0 = without move stop-loss to BE (option is disabled) extern double MoveSLToBE_1_OffsetRate = -0.5; // (multiplier for distance of stop-loss) offset of new level stop-loss from opening price of order; negative_value = offset to side of loss, positive_value = offset to side of profit extern double MoveSLToBE_2_ProfitPercents = 50; // (amount percents from TakeProfit) profit when move level stop-loss to the new price; 0 = without move stop-loss to BE (option is disabled) extern double MoveSLToBE_2_OffsetRate = 0; // (multiplier for distance of stop-loss) offset of new level stop-loss from opening price of order; negative_value = offset to side of loss, positive_value = offset to side of profit extern double MoveSLToBE_3_ProfitPercents = 70; // (amount percents from TakeProfit) profit when move level stop-loss to the new price; 0 = without move stop-loss to BE (option is disabled) extern double MoveSLToBE_3_OffsetRate = 0.6; // (multiplier for distance of stop-loss) offset of new level stop-loss from opening price of order; negative_value = offset to side of loss, positive_value = offset to side of profit extern double MoveSLToBE_4_ProfitPercents = 85; // (amount percents from TakeProfit) profit when move level stop-loss to the new price; 0 = without move stop-loss to BE (option is disabled) extern double MoveSLToBE_4_OffsetRate = 1.2; // (multiplier for distance of stop-loss) offset of new level stop-loss from opening price of order; negative_value = offset to side of loss, positive_value = offset to side of profit extern double Lots = 0.1; // size of lots (use in the mode UseMM = false) extern bool UseMM = false; // enable/disable auto-calculation for size of lots: false = constant size of lots (value of parameter "Lots"); true = calculate by percent from Balance and stop-loss (parameter "RiskPercents") extern double RiskPercents = 2; // percent from Balance that will loss at closing order by stop-loss (use in the mode UseMM = true) extern bool MultipleRiskAfterLoss = true; // true = multiple RiskPercents after order with loss; false = does not multiple RiskPercents after order with lots extern double RiskMultiplier_01 = 2.25; // multiplier for RiskPercents after first order with loss (use in the mode UseMM = true and MultipleRiskAfterLoss = true) extern double RiskMultiplier_02 = 3.00; // multiplier for RiskPercents after second order with loss (use in the mode UseMM = true and MultipleRiskAfterLoss = true) extern double RiskMultiplier_03 = 4.00; // multiplier for RiskPercents after third order with loss (use in the mode UseMM = true and MultipleRiskAfterLoss = true) extern double RiskMultiplier_04 = 5.00; // multiplier for RiskPercents after forth order with loss (use in the mode UseMM = true and MultipleRiskAfterLoss = true) extern double RiskMultiplier_05 = 5.50; // multiplier for RiskPercents after fifth order with loss (use in the mode UseMM = true and MultipleRiskAfterLoss = true) extern double RiskMultiplier_06 = 7.75; // multiplier for RiskPercents after 6th order with loss (use in the mode UseMM = true and MultipleRiskAfterLoss = true) extern double RiskMultiplier_07 = 3.00; // multiplier for RiskPercents after 7th order with loss (use in the mode UseMM = true and MultipleRiskAfterLoss = true) extern double RiskMultiplier_08 = 4.00; // multiplier for RiskPercents after 8th order with loss (use in the mode UseMM = true and MultipleRiskAfterLoss = true) extern double RiskMultiplier_09 = 5.00; // multiplier for RiskPercents after 9th order with loss (use in the mode UseMM = true and MultipleRiskAfterLoss = true) extern double RiskMultiplier_10 = 5.50; // multiplier for RiskPercents after 10th order with loss (use in the mode UseMM = true and MultipleRiskAfterLoss = true) extern double MaxLots = 1000; // maximum size of lots for one order that possible to trade for EA extern string Symbol_Name = ""; // name of symbol; empty_string = use symbol of chart extern ENUM_TIMEFRAMES_MY TimeFrame = 0; // timeframe where check trading signal extern int DinamicSL_Levels = 4; // amount nearest levels sup/res; 0 = without dinamic stop-loss (the EA use parameter StopLoss) extern int DinamicSL_IndexOfLevel = 3; // index of nearest level sup/res that use as stop-loss extern double DinamicSL_OffsetPips = 5; // (amount pips) offset of level stop-loss from level res/sup extern double DinamicSL_MinimumPips = 0; // (amount pips) minimum distance to level stop-loss when possible to open order; 0 = wihout limit extern double DinamicSL_MaximumPips = 0; // (amount pips) maximum distance to level stop-loss when possible to open order; 0 = wihout limit extern double StopLoss = 30; // {use this parameter only in the mode DinamicSL_Levels = 0} (amount pips) positive_value = stop-loss as amount pips (for example, 80 = stop-loss at -80 pips); 0 = without stop-loss extern double TakeProfit = -2; // (amount pips) positive_value = take profit as amount pips; 0 = without take profit; negative_value = multiplier for stop-loss (for examples: 80 = take profit at +80 pips; -2 = take profit at distance SL*2 pips) //---- parameters of MA --------------------------------------------------------------------+ extern string _______MA_____________ = "---------------------------------------------"; extern int MA_Period = 150; // the period of MA extern int MA_Method = 0; // (0-3) the method of MA: 0 = Simple, 1 = Exponential, 2 = Smoothed, 3 = Weighted extern int MA_Price = 0; // (0-6) the price for MA: 0 = Close, 1 = Open, 2 = High, 3 = Low, 4 = Median, 5 = Typical, 6 = Weighted //---- parameters of RSI -------------------------------------------------------------------+ extern string _______RSI____________ = "---------------------------------------------"; extern bool RSI_CheckRetrace = true; // true = detect zone oversold/overbought only after retrace RSI to the level 50; false = without this limit extern double RSI_UpperLevel = 80; // upper level; the EA autocalculate opposite level by formula RSI_LowerLevel = 100 - RSI_UpperLevel extern int RSI_Period = 3; // the period of RSI extern int RSI_Price = 0; // (0-6) the price for RSI: 0 = Close, 1 = Open, 2 = High, 3 = Low, 4 = Median, 5 = Typical, 6 = Weighted //---- parameters of Stochastic ------------------------------------------------------------+ extern string _____Stochastic_______ = "---------------------------------------------"; extern int STOCH_MaxBarsAfterRSI = 10; // amount bars after entrance RSI inside zone oversold/overbought where must occur crossing of Stochastic; 0 = without limit extern bool STOCH_OnlyFirstCrossing = true; // true = trade only at the first crossing of Stochastic after zone oversold/overbought of RSI; false = without this limit extern double STOCH_UpperLevel = 70; // upper level; the EA autocalculate opposite level by formula STOCH_LowerLevel = 100 - STOCH_UpperLevel extern int STOCH_Kperiod = 6; // %K line period extern int STOCH_Dperiod = 3; // %D line period extern int STOCH_Slowing = 3; // slowing value extern int STOCH_Method = 0; // (0-3) MA method. Possible values: 0 = Simple, 1 = Exponential, 2 = Smoothed, 3 = Weighted extern int STOCH_PriceField = 0; // (0-1) price field parameter. Can be one of this values: 0 = Low/High or 1 = Close/Close //---- parameters of ZigZag ----------------------------------------------------------------+ extern string ______ZigZag____________ = "---------------------------------------------"; extern int ZZ_Depth = 12; // parameter for indicator "ZigZag" extern int ZZ_Deviation = 5; // parameter for indicator "ZigZag" extern int ZZ_Backstep = 3; // parameter for indicator "ZigZag" //---- others parameters -------------------------------------------------------------------+ extern string _____Others___________ ="----------------------------------------------"; extern int Slippage = 3; // (amount pips) maximum price slippage at open and close orders extern int MagicNumber = 20140714; // "magic number" for orders of EA extern string ExpertComment = "SRS EA"; // comment for orders of EA extern color ColorBuy = clrBlue; // color arrows of Buy-orders extern color ColorSell = clrRed; // color arrows of Sell-orders extern bool SendEmail = false; // enable/disable send e-mail at open/close orders by EA extern bool SoundAlert = false; // enable/disable play sound-file at open/close orders by EA extern string SoundFileAtOpen = "alert.wav"; // name of sound-file that will play at open order; empty string ("") = don't play sound-file at this is event extern string SoundFileAtClose = "alert.wav"; // name of sound-file that will play at close order; empty string ("") = don't play sound-file at this is event static string SoundFileAtDelete = "alert.wav"; // name of sound-file that will played at delete order; empty string ("") = don't play sound-file at this is event static string SoundFileAtModify = ""; // name of sound-file that will played at modify order; empty string ("") = don't play sound-file at this is event extern bool CreateScreenshots = false; // enable/disable create screenshots at open, modify and close any order extern bool ShowInformation = true; // enable/disable show the information on chart extern bool WriteLog = true; // enable/disable write to log-files about errors and trades static bool WriteDebugLog = false; // enable/disable write debug informations to log-files static bool WriteToSeparateLogFile = false; // true = write log informations to separate log-files; false = write log informations to public log-files //----- global variables ----------------------------------------------------------------------+ static bool first_run = true; static int lots_digits; static double maxlots; static double minlots; static double lotstep; static string symbol; static string path_screenshots; static string path_logs; static string current_log_file_name; static datetime bartime_logs; static int fhandle_logs=-1; static datetime bartime_newbar; static bool is_testing; static string account_currency; static bool play_sound_at_open; static bool play_sound_at_close; static bool play_sound_at_delete; static bool play_sound_at_modify; static string str_comment_header; static double RSI_LowerLevel; static double STOCH_LowerLevel; static bool detect_start_of_rsi; static int digits; static int symbol_digits; static int pips_digits; static int correction; static int slippage; static double point; static double symbol_point; static datetime bartime; static double main_tp; static double main_be_1_profit; static double main_be_2_profit; static double main_be_3_profit; static double main_be_4_profit; static double main_be_1_offset; static double main_be_2_offset; static double main_be_3_offset; static double main_be_4_offset; static string str_comment; static bool S_Enable; static double RiskMultiplier[NumRiskMultipliers]; static double risk_percent [NumRiskValues]; static string str_tf; //---------------------------------------------------------------------------------------------+ //---- init -----------------------------------------------------------------------------------+ //---------------------------------------------------------------------------------------------+ int init() { if(WriteDebugLog) WriteLog = true; is_testing = IsTesting(); account_currency = AccountCurrency(); symbol = Symbol(); if(StringLen(ExpertComment) > 20) ExpertComment = StringSubstr(ExpertComment,0,20); if(WriteLog) { if(WriteToSeparateLogFile) { path_logs = StringConcatenate(FolderName_Expert,"\\",StringSubstr(symbol,0,6),"\\",DoubleToStr(MagicNumber,0),"\\",FolderName_Logs,"\\"); datetime cur_bartime_d1 = iTime(NULL,PERIOD_D1,0); if(is_testing) int mode = FILE_CSV|FILE_WRITE; else mode = FILE_CSV|FILE_READ|FILE_WRITE; current_log_file_name = StringConcatenate(path_logs,TimeToStr(cur_bartime_d1,TIME_DATE),".log"); fhandle_logs = FileOpen(current_log_file_name,mode,';'); if(fhandle_logs <= 0) { Print("WriteLog: Cannot open file ",current_log_file_name); return(0); } FileSeek(fhandle_logs,0,SEEK_END); } bartime_logs = cur_bartime_d1; } maxlots = MarketInfo(symbol,MODE_MAXLOT); minlots = MarketInfo(symbol,MODE_MINLOT); lotstep = MarketInfo(symbol,MODE_LOTSTEP); if(lotstep == 0.01) lots_digits = 2; else if(lotstep == 0.1) lots_digits = 1; else if(lotstep == 1) lots_digits = 0; else if(lotstep == 0.001) lots_digits = 3; else lots_digits = 4; Lots = NormalizeDouble(Lots,lots_digits); if(Lots < minlots) Lots = minlots; else if(Lots > maxlots) Lots = maxlots; risk_percent[0] = RiskPercents / 100.0; if(MultipleRiskAfterLoss) { RiskMultiplier[0] = RiskMultiplier_01; RiskMultiplier[1] = RiskMultiplier_02; RiskMultiplier[2] = RiskMultiplier_03; RiskMultiplier[3] = RiskMultiplier_04; RiskMultiplier[4] = RiskMultiplier_05; RiskMultiplier[5] = RiskMultiplier_06; RiskMultiplier[6] = RiskMultiplier_07; RiskMultiplier[7] = RiskMultiplier_08; RiskMultiplier[8] = RiskMultiplier_09; RiskMultiplier[9] = RiskMultiplier_10; for(int i=1; i= 100.0) MoveSLToBE_1_ProfitPercents = 0.0; if(MoveSLToBE_2_ProfitPercents >= 100.0) MoveSLToBE_2_ProfitPercents = 0.0; if(MoveSLToBE_3_ProfitPercents >= 100.0) MoveSLToBE_3_ProfitPercents = 0.0; if(MoveSLToBE_4_ProfitPercents >= 100.0) MoveSLToBE_4_ProfitPercents = 0.0; } if(StringLen(Symbol_Name) == 0) Symbol_Name = symbol; else if(AutoDetectSymbolAppendix) Symbol_Name = GetSymbolName(Symbol_Name); S_Enable = true; if(is_testing) if(Symbol_Name != symbol) S_Enable = false; symbol_point = MarketInfo(Symbol_Name,MODE_POINT); symbol_digits = MarketInfo(Symbol_Name,MODE_DIGITS); if(symbol_digits == 0) { point = 1.0; digits = 0; } else { if(symbol_digits < 2) { point = 0.1; digits = 1; } else { if(symbol_digits < 4) { point = 0.01; digits = 2; } else { point = 0.0001; digits = 4; } } } if(StringFind(Symbol_Name,"XAU") >= 0 || StringFind(Symbol_Name,"GOLD") >= 0) { point = 0.1; digits = 1; } else { if(StringFind(Symbol_Name,"XAG") >= 0 || StringFind(Symbol_Name,"SILVER") >= 0) { point = 0.01; digits = 2; } } pips_digits = symbol_digits - digits; correction = MathPow(10,pips_digits); slippage = Slippage * correction; DinamicSL_MinimumPips = NormalizeDouble(DinamicSL_MinimumPips,pips_digits); DinamicSL_MaximumPips = NormalizeDouble(DinamicSL_MaximumPips,pips_digits); main_tp = NormalizeDouble(TakeProfit * point,symbol_digits); if(DinamicSL_Levels > 0) { if(DinamicSL_IndexOfLevel <= 0 || DinamicSL_IndexOfLevel > DinamicSL_Levels) DinamicSL_Levels = 0; else DinamicSL_IndexOfLevel--; } RSI_LowerLevel = 100.0 - RSI_UpperLevel; STOCH_LowerLevel = 100.0 - STOCH_UpperLevel; detect_start_of_rsi = STOCH_OnlyFirstCrossing || STOCH_MaxBarsAfterRSI > 0; if(UseMM) UseMM = RiskPercents > 0.0 && (DinamicSL_Levels > 0 || StopLoss > 0.0); str_comment_header = ""; if(ShowInformation) { if(S_Enable) str_comment_header = StringConcatenate(Symbol_Name," ",TimeFrameToStr(TimeFrame)); else if(StringLen(str_comment_header) <= 0) str_comment_header = "there is no"; str_comment_header = StringConcatenate("Signals for trade:\n",str_comment_header,"\n----------\n"); } if(ShowInformation) str_comment = ""; if(WriteDebugLog) { WriteFileLogs(fhandle_logs,"Active signals:"); if(S_Enable) WriteFileLogs(fhandle_logs,StringConcatenate(Symbol_Name," ",TimeFrameToStr(TimeFrame))); } bartime = 0; if(CreateScreenshots) path_screenshots=StringConcatenate(FolderName_Expert,"\\",StringSubstr(symbol,0,6),"\\",DoubleToStr(MagicNumber,0),"\\",FolderName_Screenshots,"\\"); play_sound_at_open = SoundAlert && (StringLen(SoundFileAtOpen) > 0); play_sound_at_close = SoundAlert && (StringLen(SoundFileAtClose) > 0); play_sound_at_delete = SoundAlert && (StringLen(SoundFileAtDelete) > 0); play_sound_at_modify = SoundAlert && (StringLen(SoundFileAtModify) > 0); if(first_run) { bartime_newbar = Time[0]; first_run = false; } if(WriteLog) WriteFileLogs(fhandle_logs,"----------------------- Initialization finished -----------------------"); return(0); } //---------------------------------------------------------------------------------------------+ //---- deinit ---------------------------------------------------------------------------------+ //---------------------------------------------------------------------------------------------+ int deinit() { if(ShowInformation) Comment(""); if(WriteLog) { WriteFileLogs(fhandle_logs,"************************** Deinitialization **************************"); WriteFileLogs(fhandle_logs,StringConcatenate("Uninitialize Reason = ",GetUninitializeReason())); } if(WriteLog) { if(fhandle_logs > 0) { FileClose(fhandle_logs); fhandle_logs = -1; } } if(WriteLog) Print("----------------------- Deinitialization finished -----------------------"); return(0); } //---------------------------------------------------------------------------------------------+ //---- start ----------------------------------------------------------------------------------+ //---------------------------------------------------------------------------------------------+ int start() { if(WriteLog) { if(WriteToSeparateLogFile) { datetime cur_bartime_d1 = iTime(NULL,PERIOD_D1,0); if(bartime_logs != cur_bartime_d1) { if(fhandle_logs > 0) { FileFlush(fhandle_logs); int file_size = FileSize(fhandle_logs); FileClose(fhandle_logs); if(file_size == 0) FileDelete(current_log_file_name); } if(is_testing) int mode = FILE_CSV|FILE_WRITE; else mode = FILE_CSV|FILE_READ|FILE_WRITE; current_log_file_name = StringConcatenate(path_logs,TimeToStr(cur_bartime_d1,TIME_DATE),".log"); fhandle_logs = FileOpen(current_log_file_name,mode,';'); if(fhandle_logs <= 0) { Print("WriteLog: Cannot open file ",current_log_file_name); return(0); } FileSeek(fhandle_logs,0,SEEK_END); bartime_logs = cur_bartime_d1; } } if(WriteDebugLog) WriteFileLogs(fhandle_logs,StringConcatenate("-------- New Tick at ",TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS)," ------------------------------")); } datetime cur_bartime = Time[0]; if(WriteDebugLog) { if(bartime_newbar != cur_bartime) { WriteFileLogs(fhandle_logs,StringConcatenate("-------- New Bar at ",TimeToStr(cur_bartime,TIME_DATE|TIME_MINUTES|TIME_SECONDS)," ------------------------------")); bartime_newbar = cur_bartime; } } SetOrderLevelsMC(MagicNumber); WatchOrderLevelsMC(MagicNumber); if(MoveSLToBE_Use) { if(MoveSLToBE_1_ProfitPercents > 0.0) WatchMoveSLToBEMC(MoveSLToBE_1_ProfitPercents,MoveSLToBE_1_OffsetRate,MagicNumber); if(MoveSLToBE_2_ProfitPercents > 0.0) WatchMoveSLToBEMC(MoveSLToBE_2_ProfitPercents,MoveSLToBE_2_OffsetRate,MagicNumber); if(MoveSLToBE_3_ProfitPercents > 0.0) WatchMoveSLToBEMC(MoveSLToBE_3_ProfitPercents,MoveSLToBE_3_OffsetRate,MagicNumber); if(MoveSLToBE_4_ProfitPercents > 0.0) WatchMoveSLToBEMC(MoveSLToBE_4_ProfitPercents,MoveSLToBE_4_OffsetRate,MagicNumber); } if(S_Enable) { datetime curr_bartime = iTime(Symbol_Name,TimeFrame,0); if(bartime != curr_bartime) { bartime = curr_bartime; double close = NormalizeDouble(iClose(Symbol_Name,TimeFrame,1),symbol_digits); if(close == 0.0) bartime--; else { double ma = NormalizeDouble(iMA(Symbol_Name,TimeFrame,MA_Period,0,MA_Method,MA_Price,1),symbol_digits); int ma_trend = 0; if(close > ma) ma_trend++; else if(close < ma) ma_trend--; int rsi_trend = 0; for(int n=1; n= 50.0) { is_retrace = true; break; } } if(!is_retrace) continue; } rsi_trend++; if(detect_start_of_rsi) { for(m=n+1; m RSI_LowerLevel) { int rsi_barshift = m - 1; break; } } } break; } if(n_rsi >= RSI_UpperLevel) { if(RSI_CheckRetrace) { is_retrace = false; is_outside_zone = false; for(m=n+1; m= RSI_UpperLevel) continue; is_outside_zone = true; } if(m_rsi >= RSI_UpperLevel) break; if(m_rsi <= 50.0) { is_retrace = true; break; } } if(!is_retrace) continue; } rsi_trend--; if(detect_start_of_rsi) { for(m=n+1; m curr_stoch_signal) { stoch_trend++; stoch_is_crossing = prev_stoch_main <= prev_stoch_signal; } else { if(curr_stoch_main < curr_stoch_signal) { stoch_trend--; stoch_is_crossing = prev_stoch_main >= prev_stoch_signal; } } if(stoch_is_crossing) double stoch_value_of_crossing = GetValueOfCrossing(prev_stoch_main,curr_stoch_main,prev_stoch_signal,curr_stoch_signal); int signal_to_open = 0; if(stoch_is_crossing) { if(stoch_trend > 0) if(ma_trend > 0) if(rsi_trend > 0) signal_to_open++; if(stoch_trend < 0) if(ma_trend < 0) if(rsi_trend < 0) signal_to_open--; } if(ShowInformation) string str_trade_signal = StringConcatenate("Signal = ",TrendToStr(signal_to_open)); if(signal_to_open != 0) { if(signal_to_open > 0) { if(stoch_value_of_crossing > STOCH_LowerLevel) { if(ShowInformation) str_trade_signal = StringConcatenate(str_trade_signal," [ignore signal because crossing of Stoch occur above STOCH_LowerLevel]"); signal_to_open = 0; } } else { if(stoch_value_of_crossing < STOCH_UpperLevel) { if(ShowInformation) str_trade_signal = StringConcatenate(str_trade_signal," [ignore signal because crossing of Stoch occur below STOCH_UpperLevel]"); signal_to_open = 0; } } } if(signal_to_open != 0) { if(STOCH_MaxBarsAfterRSI > 0) { if(rsi_barshift > STOCH_MaxBarsAfterRSI) { if(ShowInformation) str_trade_signal = StringConcatenate(str_trade_signal,StringConcatenate(" [ignore signal by limit STOCH_MaxBarsAfterRSI (crossing at the ",DoubleToStr(rsi_barshift,0)," bar)]")); signal_to_open = 0; } } } if(signal_to_open != 0) { if(STOCH_OnlyFirstCrossing) { if(signal_to_open > 0) { for(n=2; n<=rsi_barshift; n++) { double n_curr_stoch_main = iStochastic(NULL,TimeFrame,STOCH_Kperiod,STOCH_Dperiod,STOCH_Slowing,STOCH_Method,STOCH_PriceField,MODE_MAIN, n); double n_curr_stoch_signal = iStochastic(NULL,TimeFrame,STOCH_Kperiod,STOCH_Dperiod,STOCH_Slowing,STOCH_Method,STOCH_PriceField,MODE_SIGNAL,n); double n_prev_stoch_main = iStochastic(NULL,TimeFrame,STOCH_Kperiod,STOCH_Dperiod,STOCH_Slowing,STOCH_Method,STOCH_PriceField,MODE_MAIN, n+1); double n_prev_stoch_signal = iStochastic(NULL,TimeFrame,STOCH_Kperiod,STOCH_Dperiod,STOCH_Slowing,STOCH_Method,STOCH_PriceField,MODE_SIGNAL,n+1); if(n_curr_stoch_main > n_curr_stoch_signal && n_prev_stoch_main <= n_prev_stoch_signal) { if(ShowInformation) str_trade_signal = StringConcatenate(str_trade_signal," [ignore signal by limit STOCH_OnlyFirstCrossing]"); signal_to_open = 0; break; } } } else { for(n=2; n<=rsi_barshift; n++) { n_curr_stoch_main = iStochastic(NULL,TimeFrame,STOCH_Kperiod,STOCH_Dperiod,STOCH_Slowing,STOCH_Method,STOCH_PriceField,MODE_MAIN, n); n_curr_stoch_signal = iStochastic(NULL,TimeFrame,STOCH_Kperiod,STOCH_Dperiod,STOCH_Slowing,STOCH_Method,STOCH_PriceField,MODE_SIGNAL,n); n_prev_stoch_main = iStochastic(NULL,TimeFrame,STOCH_Kperiod,STOCH_Dperiod,STOCH_Slowing,STOCH_Method,STOCH_PriceField,MODE_MAIN, n+1); n_prev_stoch_signal = iStochastic(NULL,TimeFrame,STOCH_Kperiod,STOCH_Dperiod,STOCH_Slowing,STOCH_Method,STOCH_PriceField,MODE_SIGNAL,n+1); if(n_curr_stoch_main < n_curr_stoch_signal && n_prev_stoch_main >= n_prev_stoch_signal) { if(ShowInformation) str_trade_signal = StringConcatenate(str_trade_signal," [ignore signal by limit STOCH_OnlyFirstCrossing]"); signal_to_open = 0; break; } } } } } if(signal_to_open != 0) { if(TradeSingleOrder) { if(IsOrder(MagicNumber)) { if(ShowInformation) str_trade_signal = StringConcatenate(str_trade_signal," [ignore signal because exist order]"); signal_to_open = 0; } } } if(signal_to_open != 0) { if(signal_to_open > 0) int order_type = OP_BUY; else order_type = OP_SELL; if(HaveOrders(order_type,MagicNumber,Symbol_Name) != 0) { if(ShowInformation) str_trade_signal = StringConcatenate(str_trade_signal," [ignore signal because exist ",OrderTypeToStr(order_type),"-order]"); signal_to_open = 0; } } if(signal_to_open != 0) { if(NumTradesAfterTimeMC(curr_bartime,order_type,MagicNumber,Symbol_Name,true,true) != 0) { signal_to_open = 0; if(ShowInformation) str_trade_signal = StringConcatenate(str_trade_signal," [ignore signal because already was ",OrderTypeToStr(order_type),"-order at current bar]"); } } if(signal_to_open != 0) { bool to_open = true; if(signal_to_open > 0) { double sl_pips = GetSL(OP_BUY); if(DinamicSL_MinimumPips > 0.0) if(sl_pips < DinamicSL_MinimumPips) to_open = false; if(DinamicSL_MaximumPips > 0.0) if(sl_pips > DinamicSL_MaximumPips) to_open = false; if(to_open) { if(CloseOrders(OP_SELL,MagicNumber,slippage,Symbol_Name) < 0) bartime--; else if(OpenOrderMC(Symbol_Name,OP_BUY,MagicNumber,StringConcatenate(DoubleToStr(sl_pips,pips_digits)," ",ExpertComment),GetLots(sl_pips,MagicNumber),slippage) < 0) bartime--; } else if(ShowInformation) str_trade_signal = StringConcatenate(str_trade_signal," [ignore signal by limit for distance to s/l (SL = ",DoubleToStr(sl_pips,pips_digits)," pips)]"); } else { sl_pips = GetSL(OP_SELL); if(DinamicSL_MinimumPips > 0.0) if(sl_pips < DinamicSL_MinimumPips) to_open = false; if(DinamicSL_MaximumPips > 0.0) if(sl_pips > DinamicSL_MaximumPips) to_open = false; if(to_open) { if(CloseOrders(OP_BUY,MagicNumber,slippage,Symbol_Name) < 0) bartime--; else if(OpenOrderMC(Symbol_Name,OP_SELL,MagicNumber,StringConcatenate(DoubleToStr(sl_pips,pips_digits)," ",ExpertComment),GetLots(sl_pips,MagicNumber),slippage) < 0) bartime--; } else if(ShowInformation) str_trade_signal = StringConcatenate(str_trade_signal," [ignore signal by limit for distance to s/l (SL = ",DoubleToStr(sl_pips,pips_digits)," pips)]"); } } if(ShowInformation) { if(!stoch_is_crossing) string str_stoch = ""; else str_stoch = StringConcatenate(" crossing at = ",DoubleToStr(stoch_value_of_crossing,5)); str_comment = StringConcatenate("MA = ",TrendToStr(ma_trend),"\n", "RSI = ",TrendToStr(rsi_trend),"\n", "STOCH = ",TrendToStr(stoch_trend),str_stoch,"\n", str_trade_signal,"\n" ); } } } } if(ShowInformation) Comment(str_comment_header,str_comment); return(0); Print("---- Programming by Serega Lykov, http://mtexperts.narod.ru/ ----"); } //---------------------------------------------------------------------------------------------+ //---- ErrorDescription -----------------------------------------------------------------------+ //---------------------------------------------------------------------------------------------+ string ErrorDescription(int error_code) { switch(error_code) { case 0: case 1: string error_string="no error"; break; case 2: error_string="common error"; break; case 3: error_string="invalid trade parameters"; break; case 4: error_string="trade server is busy"; break; case 5: error_string="old version of the client terminal"; break; case 6: error_string="no connection with trade server"; break; case 7: error_string="not enough rights"; break; case 8: error_string="too frequent requests"; break; case 9: error_string="malfunctional trade operation (never returned error)"; break; case 64: error_string="account disabled"; break; case 65: error_string="invalid account"; break; case 128: error_string="trade timeout"; break; case 129: error_string="invalid price"; break; case 130: error_string="invalid stops"; break; case 131: error_string="invalid trade volume"; break; case 132: error_string="market is closed"; break; case 133: error_string="trade is disabled"; break; case 134: error_string="not enough money"; break; case 135: error_string="price changed"; break; case 136: error_string="off quotes"; break; case 137: error_string="broker is busy (never returned error)"; break; case 138: error_string="requote"; break; case 139: error_string="order is locked"; break; case 140: error_string="long positions only allowed"; break; case 141: error_string="too many requests"; break; case 145: error_string="modification denied because order too close to market"; break; case 146: error_string="trade context is busy"; break; case 147: error_string="expirations are denied by broker"; break; case 148: error_string="amount of open and pending orders has reached the limit"; break; case 149: error_string="hedging is prohibited"; break; case 150: error_string="prohibited by FIFO rules"; break; case 4000: error_string="no error (never generated code)"; break; case 4001: error_string="wrong function pointer"; break; case 4002: error_string="array index is out of range"; break; case 4003: error_string="no memory for function call stack"; break; case 4004: error_string="recursive stack overflow"; break; case 4005: error_string="not enough stack for parameter"; break; case 4006: error_string="no memory for parameter string"; break; case 4007: error_string="no memory for temp string"; break; case 4008: error_string="not initialized string"; break; case 4009: error_string="not initialized string in array"; break; case 4010: error_string="no memory for array\' string"; break; case 4011: error_string="too long string"; break; case 4012: error_string="remainder from zero divide"; break; case 4013: error_string="zero divide"; break; case 4014: error_string="unknown command"; break; case 4015: error_string="wrong jump (never generated error)"; break; case 4016: error_string="not initialized array"; break; case 4017: error_string="dll calls are not allowed"; break; case 4018: error_string="cannot load library"; break; case 4019: error_string="cannot call function"; break; case 4020: error_string="expert function calls are not allowed"; break; case 4021: error_string="not enough memory for temp string returned from function"; break; case 4022: error_string="system is busy (never generated error)"; break; case 4050: error_string="invalid function parameters count"; break; case 4051: error_string="invalid function parameter value"; break; case 4052: error_string="string function internal error"; break; case 4053: error_string="some array error"; break; case 4054: error_string="incorrect series array using"; break; case 4055: error_string="custom indicator error"; break; case 4056: error_string="arrays are incompatible"; break; case 4057: error_string="global variables processing error"; break; case 4058: error_string="global variable not found"; break; case 4059: error_string="function is not allowed in testing mode"; break; case 4060: error_string="function is not confirmed"; break; case 4061: error_string="send mail error"; break; case 4062: error_string="string parameter expected"; break; case 4063: error_string="integer parameter expected"; break; case 4064: error_string="double parameter expected"; break; case 4065: error_string="array as parameter expected"; break; case 4066: error_string="requested history data in update state"; break; case 4099: error_string="end of file"; break; case 4100: error_string="some file error"; break; case 4101: error_string="wrong file name"; break; case 4102: error_string="too many opened files"; break; case 4103: error_string="cannot open file"; break; case 4104: error_string="incompatible access to a file"; break; case 4105: error_string="no order selected"; break; case 4106: error_string="unknown symbol"; break; case 4107: error_string="invalid price parameter for trade function"; break; case 4108: error_string="invalid ticket"; break; case 4109: error_string="trade is not allowed in the expert properties"; break; case 4110: error_string="longs are not allowed in the expert properties"; break; case 4111: error_string="shorts are not allowed in the expert properties"; break; case 4200: error_string="object is already exist"; break; case 4201: error_string="unknown object property"; break; case 4202: error_string="object is not exist"; break; case 4203: error_string="unknown object type"; break; case 4204: error_string="no object name"; break; case 4205: error_string="object coordinates error"; break; case 4206: error_string="no specified subwindow"; break; default: error_string="unknown error"; } return(error_string); } //---------------------------------------------------------------------------------------------+ //---- GetUninitializeReason ------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ string GetUninitializeReason() { switch(UninitializeReason()) { case 0: string reason = "Script finished its execution independently."; break; case REASON_REMOVE: reason = "Programm removed from chart."; break; case REASON_RECOMPILE: reason = "Programm recompiled."; break; case REASON_CHARTCHANGE: reason = "Symbol or timeframe changed on the chart."; break; case REASON_CHARTCLOSE: reason = "Chart closed."; break; case REASON_PARAMETERS: reason = "Inputs parameters was changed by user."; break; case REASON_ACCOUNT: reason = "Other account activated."; break; default: reason = "Unknown."; break; } return(reason); } //---------------------------------------------------------------------------------------------+ //---- OrderTypeToStr -------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ string OrderTypeToStr(int order_type) { switch(order_type) { case OP_BUY: string result = "Buy"; break; case OP_SELL: result = "Sell"; break; case OP_BUYLIMIT: result = "BuyLimit"; break; case OP_SELLLIMIT: result = "SellLimit"; break; case OP_BUYSTOP: result = "BuyStop"; break; case OP_SELLSTOP: result = "SellStop"; break; default: result = "Unknown"; break; } return(result); } //---------------------------------------------------------------------------------------------+ //---- TimeFrameToStr -------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ string TimeFrameToStr(int period) { switch(period) { case 0: string str_timeframe = TimeFrameToStr(Period()); break; case 1: str_timeframe = "M1"; break; case 5: str_timeframe = "M5"; break; case 15: str_timeframe = "M15"; break; case 30: str_timeframe = "M30"; break; case 60: str_timeframe = "H1"; break; case 240: str_timeframe = "H4"; break; case 1440: str_timeframe = "D1"; break; case 10080: str_timeframe = "W1"; break; case 43200: str_timeframe = "MN"; break; default: str_timeframe = StringConcatenate("M",DoubleToStr(period,0)); } return(str_timeframe); } //---------------------------------------------------------------------------------------------+ //---- TrendToStr -----------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ string TrendToStr(int trend) { if(trend > 0) return("Buy"); if(trend < 0) return("Sell"); return("None"); } //---------------------------------------------------------------------------------------------+ //---- BoolToStr ------------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ string BoolToStr(bool bool_value) { if(!bool_value) return("false"); return("true"); } //---------------------------------------------------------------------------------------------+ //---- WatchOrderLevelsMC ---------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ void WatchOrderLevelsMC(int magic_number) { int total = OrdersTotal() - 1; for(int i=total; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate("WatchOrderLevelsMC: OrderSelect() error = ",ErrorDescription(GetLastError()))); continue; } if(OrderMagicNumber() != magic_number) continue; int order_type = OrderType(); if(order_type > OP_SELL) continue; string order_symbol = OrderSymbol(); if(order_symbol != Symbol_Name) continue; double order_sl = NormalizeDouble((-1.0) * StringToDouble(OrderComment())*point,symbol_digits); if(TakeProfit < 0.0) double order_tp = NormalizeDouble(TakeProfit * order_sl,symbol_digits); else order_tp = main_tp; double order_close_price = NormalizeDouble(OrderClosePrice(),symbol_digits); double order_open_price = NormalizeDouble(OrderOpenPrice(), symbol_digits); if(order_type == OP_BUY) double profit = NormalizeDouble(order_close_price - order_open_price,symbol_digits); else profit = NormalizeDouble(order_open_price - order_close_price,symbol_digits); if(order_sl < 0.0) { if(profit <= order_sl) { if(WriteDebugLog) WriteFileLogs(fhandle_logs,"WatchOrderLevelsMC: closing by level s/l."); if(order_type == OP_BUY) color order_color = ColorBuy; else order_color = ColorSell; OrderCloseEx(OrderTicket(),OrderLots(),order_close_price,slippage,order_color,"WatchOrderLevelsMC"); continue; } } if(order_tp > 0.0) { if(profit >= order_tp) { if(WriteDebugLog) WriteFileLogs(fhandle_logs,"WatchOrderLevelsMC: closing by level t/p."); if(order_type == OP_BUY) order_color = ColorBuy; else order_color = ColorSell; OrderCloseEx(OrderTicket(),OrderLots(),order_close_price,slippage,order_color,"WatchOrderLevelsMC"); } } } } //---------------------------------------------------------------------------------------------+ //---- SetOrderLevelsMC -----------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ void SetOrderLevelsMC(int magic_number) { int total = OrdersTotal() - 1; for(int i=total; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate("SetOrderLevelsMC: OrderSelect() error = ",ErrorDescription(GetLastError()))); continue; } if(OrderMagicNumber() != magic_number) continue; string order_symbol = OrderSymbol(); if(order_symbol != Symbol_Name) continue; double order_stop_loss = NormalizeDouble(OrderStopLoss(), symbol_digits); double order_take_profit = NormalizeDouble(OrderTakeProfit(),symbol_digits); if(order_stop_loss != 0.0 && order_take_profit != 0.0) continue; double order_sl = NormalizeDouble((-1.0) * StringToDouble(OrderComment())*point,symbol_digits); if(TakeProfit < 0.0) double order_tp = NormalizeDouble(TakeProfit * order_sl,symbol_digits); else order_tp = main_tp; double stoplevel = NormalizeDouble(MarketInfo(order_symbol,MODE_STOPLEVEL)*symbol_point,symbol_digits); int order_type = OrderType(); double order_close_price = NormalizeDouble(OrderClosePrice(),symbol_digits); double order_open_price = NormalizeDouble(OrderOpenPrice(), symbol_digits); if(order_type > OP_SELL) { if(NormalizeDouble(MathAbs(order_open_price - order_close_price),symbol_digits) <= stoplevel) continue; } bool to_modify_sl = false; if(order_stop_loss == 0.0) { if(order_sl < 0.0) { if((order_type % 2) == OP_BUY) { double stoploss = NormalizeDouble(order_open_price + order_sl,symbol_digits); if(order_type == OP_BUY) { if(NormalizeDouble(order_close_price - stoploss,symbol_digits) > stoplevel) to_modify_sl = true; else stoploss = order_stop_loss; } else to_modify_sl = true; } else { stoploss = NormalizeDouble(order_open_price - order_sl,symbol_digits); if(order_type == OP_SELL) { if(NormalizeDouble(stoploss - order_close_price,symbol_digits) > stoplevel) to_modify_sl = true; else stoploss = order_stop_loss; } else to_modify_sl = true; } } else stoploss = order_stop_loss; } else stoploss = order_stop_loss; bool to_modify_tp = false; if(order_take_profit == 0.0) { if(order_tp > 0.0) { if((order_type % 2) == OP_BUY) { double takeprofit = NormalizeDouble(order_open_price + order_tp,symbol_digits); if(order_type == OP_BUY) { if(NormalizeDouble(takeprofit - order_close_price,symbol_digits) > stoplevel) to_modify_tp = true; else takeprofit = order_take_profit; } else to_modify_tp = true; } else { takeprofit = NormalizeDouble(order_open_price - order_tp,symbol_digits); if(order_type == OP_SELL) { if(NormalizeDouble(order_close_price - takeprofit,symbol_digits) > stoplevel) to_modify_tp = true; else takeprofit = order_take_profit; } else to_modify_tp = true; } } else takeprofit = order_take_profit; } else takeprofit = order_take_profit; if(to_modify_sl || to_modify_tp) { if((order_type % 2) == OP_BUY) color order_color = ColorBuy; else order_color = ColorSell; OrderModifyEx(OrderTicket(),order_open_price,stoploss,takeprofit,0,order_color,"SetOrderLevelsMC"); } } } //---------------------------------------------------------------------------------------------+ //---- OrderModifyEx --------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ bool OrderModifyEx(int order_ticket, double new_open_price, double new_stop_loss, double new_take_profit, datetime new_expiration = -1, color order_color = CLR_NONE, string parent_fun_name = "") { #define number_attempts_modify 3 #define number_attempts_modify_select 3 #define number_attempts_modify_wait 30 if(StringLen(parent_fun_name) > 0) parent_fun_name = StringConcatenate(parent_fun_name," -> "); int err_129 = 0; int err_130 = 0; int err_137 = 0; int err_138 = 0; int err_145 = 0; while(true) { if(!is_testing) { if(!IsExpertEnabled()) { bool error = false; break; } } RefreshRates(); int counter_attempts_select = 0; while(counter_attempts_select < number_attempts_modify_select) { if(OrderSelect(order_ticket,SELECT_BY_TICKET)) break; if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate(parent_fun_name,"OrderModifyEx: OrderSelect() error = ",ErrorDescription(GetLastError()))); Sleep(1000); counter_attempts_select++; } if(counter_attempts_select >= number_attempts_modify_select) { error = false; break; } if(OrderCloseTime() != 0) { error = true; break; } string order_symbol = OrderSymbol(); int order_type = OrderType(); int order_digits = MarketInfo(order_symbol,MODE_DIGITS); new_open_price = NormalizeDouble(new_open_price, order_digits); new_stop_loss = NormalizeDouble(new_stop_loss, order_digits); new_take_profit = NormalizeDouble(new_take_profit,order_digits); double order_open_price = NormalizeDouble(OrderOpenPrice(), order_digits); double order_close_price = NormalizeDouble(OrderClosePrice(),order_digits); double order_stop_loss = NormalizeDouble(OrderStopLoss(), order_digits); double order_take_profit = NormalizeDouble(OrderTakeProfit(),order_digits); datetime order_expiration = OrderExpiration(); double stoplevel = NormalizeDouble(MarketInfo(order_symbol,MODE_STOPLEVEL)*MarketInfo(order_symbol,MODE_POINT),order_digits); bool to_modify = false; if(order_type > OP_SELL) { if(new_open_price < 0.0 || new_open_price == order_open_price) { double modify_open_price = order_open_price; if(NormalizeDouble(MathAbs(modify_open_price - order_close_price),order_digits) < stoplevel) { error = false; break; } } else { modify_open_price = new_open_price; to_modify = true; bool to_modify2 = true; switch(order_type) { case OP_BUYLIMIT: case OP_SELLSTOP: if(NormalizeDouble(order_close_price - modify_open_price,order_digits) < stoplevel) to_modify2 = false; break; case OP_BUYSTOP: case OP_SELLLIMIT: if(NormalizeDouble(modify_open_price - order_close_price,order_digits) < stoplevel) to_modify2 = false; break; } if(!to_modify2) { error = false; break; } } if(new_expiration < 0 || new_expiration == order_expiration) double modify_expiration = order_expiration; else { modify_expiration = new_expiration; to_modify = true; } double second_price = modify_open_price; } else { modify_open_price = order_open_price; modify_expiration = order_expiration; second_price = order_close_price; } if(new_stop_loss < 0 || new_stop_loss == order_stop_loss) double modify_stop_loss = order_stop_loss; else { modify_stop_loss = new_stop_loss; to_modify = true; } if(new_take_profit < 0 || new_take_profit == order_take_profit) double modify_take_profit = order_take_profit; else { modify_take_profit = new_take_profit; to_modify = true; } if(!to_modify) { error = true; break; } if((order_type % 2) == OP_BUY) { if(modify_stop_loss != 0.0 && NormalizeDouble(second_price - modify_stop_loss,order_digits) < stoplevel) { error = false; break; } if(modify_take_profit != 0.0 && NormalizeDouble(modify_take_profit - second_price,order_digits) < stoplevel) { error = false; break; } } else { if(modify_stop_loss != 0.0 && NormalizeDouble(modify_stop_loss - second_price,order_digits) < stoplevel) { error = false; break; } if(modify_take_profit != 0.0 && NormalizeDouble(second_price - modify_take_profit,order_digits) < stoplevel) { error = false; break; } } if(!is_testing) { for(int i=0; i= number_attempts_modify_wait) continue; } GetLastError(); error = OrderModify(order_ticket,modify_open_price,modify_stop_loss,modify_take_profit,modify_expiration,order_color); if(!error) { int err = GetLastError(); if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate(parent_fun_name,"OrderModifyEx(",OrderTypeToStr(order_type),",",DoubleToStr(order_ticket,0),") error = ",ErrorDescription(err))); bool cont = false; switch(err) { case 0: Sleep(10000); cont = true; break; case 6: Sleep(10000); if(IsConnected()) cont = true; break; case 128: Sleep(70000); cont = true; break; case 129: Sleep(6000); err_129++; if(err_129 <= number_attempts_modify) cont = true; break; case 130: Sleep(6000); err_130++; if(err_130 <= number_attempts_modify) cont = true; break; case 134: Sleep(6000); cont = true; break; case 135: cont = true; break; case 136: Sleep(6000); cont = true; break; case 137: Sleep(20000); err_137++; if(err_137 <= number_attempts_modify) cont = true; break; case 138: err_138++; if(err_138 <= number_attempts_modify) cont = true; break; case 142: Sleep(70000); cont = true; break; case 143: Sleep(70000); cont = true; break; case 145: //Sleep(20000); //err_145++; //if(err_145 <= number_attempts_modify) cont = true; break; case 146: while(IsTradeContextBusy()) Sleep(1000); cont = true; break; case 147: new_expiration = 0; cont = true; break; case 4000: Sleep(10000); cont = true; break; } if(!cont) break; } else { if(CreateScreenshots) CreateScreenshot(); if(play_sound_at_modify) PlaySound(SoundFileAtModify); if(WriteLog && WriteToSeparateLogFile) { counter_attempts_select = 0; while(counter_attempts_select < number_attempts_modify_select) { if(OrderSelect(OrderTicket(),SELECT_BY_TICKET)) { string order_print = StringConcatenate("modify #",DoubleToStr(OrderTicket(),0)," ", StringSubstr(OrderSymbol(),0,6)," ",OrderTypeToStr(OrderType())," ", DoubleToStr(OrderLots(),lots_digits), " OP = ",DoubleToStr(OrderOpenPrice(),order_digits), " OT = ",TimeToStr(OrderOpenTime(),TIME_DATE|TIME_MINUTES|TIME_SECONDS), " SL = ",DoubleToStr(OrderStopLoss(),order_digits), " TP = ",DoubleToStr(OrderTakeProfit(),order_digits), ", [",DoubleToStr(OrderMagicNumber(),0),"] \"",OrderComment(),"\"" ); WriteFileLogs(fhandle_logs,order_print); break; } if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate("OrderModifyEx: OrderSelect() error = ",ErrorDescription(GetLastError()))); Sleep(1000); counter_attempts_select++; } } break; } } return(error); } //---------------------------------------------------------------------------------------------+ //---- OrderDeleteEx --------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ bool OrderDeleteEx(int order_ticket, color order_color = CLR_NONE, string parent_fun_name = "") { #define number_attempts_delete 3 #define number_attempts_delete_select 3 if(StringLen(parent_fun_name) > 0) parent_fun_name = StringConcatenate(parent_fun_name," -> "); int err_129 = 0; int err_130 = 0; int err_137 = 0; int err_138 = 0; while(true) { if(!is_testing) { if(!IsExpertEnabled()) { bool error = false; break; } } RefreshRates(); int counter_attempts_select = 0; while(counter_attempts_select < number_attempts_delete_select) { if(OrderSelect(order_ticket,SELECT_BY_TICKET)) break; if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate(parent_fun_name,"OrderDeleteEx: OrderSelect() error = ",ErrorDescription(GetLastError()))); Sleep(1000); counter_attempts_select++; } if(counter_attempts_select >= number_attempts_delete_select) { error = false; break; } if(OrderCloseTime() != 0) { error = true; break; } if(!is_testing) while(IsTradeContextBusy()) Sleep(1000); int order_type = OrderType(); GetLastError(); if(order_type <= OP_SELL) error = OrderClose(order_ticket,OrderLots(),OrderClosePrice(),Slippage,order_color); else error = OrderDelete(order_ticket,order_color); if(!error) { int err = GetLastError(); if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate(parent_fun_name,"OrderDeleteEx(",OrderTypeToStr(order_type),",",DoubleToStr(order_ticket,0),") error = ",ErrorDescription(err))); bool cont = false; switch(err) { case 0: Sleep(10000); cont = true; break; case 6: Sleep(10000); if(IsConnected()) cont = true; break; case 128: Sleep(70000); cont = true; break; case 129: Sleep(6000); err_129++; if(err_129 <= number_attempts_delete) cont = true; break; case 130: Sleep(6000); err_130++; if(err_130 <= number_attempts_delete) cont = true; break; case 134: Sleep(6000); cont = true; break; case 135: cont = true; break; case 136: Sleep(6000); cont = true; break; case 137: Sleep(20000); err_137++; if(err_137 <= number_attempts_delete) cont = true; break; case 138: err_138++; if(err_138 <= number_attempts_delete) cont = true; break; case 142: Sleep(70000); cont = true; break; case 143: Sleep(70000); cont = true; break; case 145: //Sleep(20000); //cont = true; break; case 146: while(IsTradeContextBusy()) Sleep(1000); cont = true; break; case 4000: Sleep(10000); cont = true; break; } if(!cont) break; } else { if(CreateScreenshots) CreateScreenshot(); if(SendEmail) SendMail(SubjectDelete,StringConcatenate(ExpertName," EA Trade Information\nCurrency Pair: ",StringSubstr(OrderSymbol(),0,6),"\nTime: ",TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS),"\nOrder Type: ",OrderTypeToStr(order_type),"\nEvent: Order Deleted","\n\nCurrent Balance: ",DoubleToStr(AccountBalance(),2)," ",account_currency,"\nCurrent Equity: ",DoubleToStr(AccountEquity(),2)," ",account_currency)); if(play_sound_at_delete) PlaySound(SoundFileAtDelete); if(WriteLog && WriteToSeparateLogFile) { counter_attempts_select = 0; while(counter_attempts_select < number_attempts_delete_select) { if(OrderSelect(OrderTicket(),SELECT_BY_TICKET)) { int order_digits = MarketInfo(OrderSymbol(),MODE_DIGITS); string order_print = StringConcatenate("delete #",DoubleToStr(OrderTicket(),0)," ", StringSubstr(OrderSymbol(),0,6)," ",OrderTypeToStr(OrderType())," ", DoubleToStr(OrderLots(),lots_digits), " CT = ",TimeToStr(OrderCloseTime(),TIME_DATE|TIME_MINUTES|TIME_SECONDS)," ", " OP = ",DoubleToStr(OrderOpenPrice(),order_digits), " OT = ",TimeToStr(OrderOpenTime(),TIME_DATE|TIME_MINUTES|TIME_SECONDS), " SL = ",DoubleToStr(OrderStopLoss(),order_digits), " TP = ",DoubleToStr(OrderTakeProfit(),order_digits), " ET = ",TimeToStr(OrderExpiration(),TIME_DATE|TIME_MINUTES|TIME_SECONDS), ", [",DoubleToStr(OrderMagicNumber(),0),"] \"",OrderComment(),"\"" ); WriteFileLogs(fhandle_logs,order_print); break; } if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate("OrderDeleteEx: OrderSelect() error = ",ErrorDescription(GetLastError()))); Sleep(1000); counter_attempts_select++; } } break; } } return(error); } //---------------------------------------------------------------------------------------------+ //---- OrderCloseEx ---------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ bool OrderCloseEx(int order_ticket, double order_lots, double order_close_price, int order_slippage, color order_color = CLR_NONE, string parent_fun_name = "") { #define number_attempts_close 3 #define number_attempts_close_select 3 #define number_attempts_close_wait 30 if(StringLen(parent_fun_name) > 0) parent_fun_name = StringConcatenate(parent_fun_name," -> "); int err_129 = 0; int err_130 = 0; int err_137 = 0; int err_138 = 0; while(true) { if(!is_testing) { if(!IsExpertEnabled()) { bool error = false; break; } } RefreshRates(); int counter_attempts_select = 0; while(counter_attempts_select < number_attempts_close_select) { if(OrderSelect(order_ticket,SELECT_BY_TICKET)) { int order_digits = MarketInfo(OrderSymbol(),MODE_DIGITS); break; } if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate(parent_fun_name,"OrderCloseEx: OrderSelect() error = ",ErrorDescription(GetLastError()))); Sleep(1000); counter_attempts_select++; } if(counter_attempts_select >= number_attempts_close_select) { error = false; break; } if(OrderCloseTime() != 0) { error = true; break; } int order_type = OrderType(); if(!is_testing) { for(int i=0; i= number_attempts_close_wait) continue; } RefreshRates(); GetLastError(); order_close_price = NormalizeDouble(OrderClosePrice(),order_digits); error = OrderClose(order_ticket,order_lots,order_close_price,order_slippage,order_color); if(!error) { int err = GetLastError(); if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate(parent_fun_name,"OrderCloseEx(",OrderTypeToStr(order_type),",",DoubleToStr(order_ticket,0),") error = ",ErrorDescription(err))); bool cont = false; switch(err) { case 0: Sleep(10000); if(OrderSelect(order_ticket,SELECT_BY_TICKET)) if(OrderCloseTime() == 0) cont = true; break; case 6: Sleep(10000); if(IsConnected()) cont = true; break; case 128: Sleep(70000); if(OrderSelect(order_ticket,SELECT_BY_TICKET)) if(OrderCloseTime() == 0) cont = true; break; case 129: Sleep(6000); err_129++; if(err_129 <= number_attempts_close) cont = true; break; case 130: Sleep(6000); err_130++; if(err_130 <= number_attempts_close) cont = true; break; case 135: cont = true; break; case 136: Sleep(6000); cont = true; break; case 137: Sleep(20000); err_137++; if(err_137 <= number_attempts_close) cont = true; break; case 138: err_138++; if(err_138 <= number_attempts_close) cont = true; break; case 142: Sleep(70000); if(OrderSelect(order_ticket,SELECT_BY_TICKET)) if(OrderCloseTime() == 0) cont = true; break; case 143: Sleep(70000); if(OrderSelect(order_ticket,SELECT_BY_TICKET)) if(OrderCloseTime() == 0) cont = true; break; case 145: //Sleep(20000); //cont = true; break; case 146: while(IsTradeContextBusy()) Sleep(1000); cont = true; break; case 4000: Sleep(10000); if(OrderSelect(order_ticket,SELECT_BY_TICKET)) if(OrderCloseTime() == 0) cont = true; break; } if(!cont) break; } else { if(CreateScreenshots) CreateScreenshot(); if(OrderSelect(order_ticket,SELECT_BY_TICKET)) order_close_price = OrderClosePrice(); if(SendEmail) SendMail(SubjectClose,StringConcatenate(ExpertName," EA Trade Information\nCurrency Pair: ",StringSubstr(OrderSymbol(),0,6),"\nTime: ",TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS),"\nOrder Type: ",OrderTypeToStr(order_type),"\nPrice: ",DoubleToStr(order_close_price,order_digits),"\nLot size: ",DoubleToStr(order_lots,lots_digits),"\nEvent: Trade Closed","\n\nCurrent Balance: ",DoubleToStr(AccountBalance(),2)," ",account_currency,"\nCurrent Equity: ",DoubleToStr(AccountEquity(),2)," ",account_currency)); if(play_sound_at_close) PlaySound(SoundFileAtClose); if(WriteLog && WriteToSeparateLogFile) { counter_attempts_select = 0; while(counter_attempts_select < number_attempts_close_select) { if(OrderSelect(order_ticket,SELECT_BY_TICKET)) { string order_print = StringConcatenate("close #",DoubleToStr(OrderTicket(),0)," ", StringSubstr(OrderSymbol(),0,6)," ",OrderTypeToStr(OrderType())," ", DoubleToStr(OrderLots(),lots_digits), " CP = ",DoubleToStr(OrderClosePrice(),order_digits), " CT = ",TimeToStr(OrderCloseTime(),TIME_DATE|TIME_MINUTES|TIME_SECONDS)," ", " OP = ",DoubleToStr(OrderOpenPrice(),order_digits), " OT = ",TimeToStr(OrderOpenTime(),TIME_DATE|TIME_MINUTES|TIME_SECONDS), " SL = ",DoubleToStr(OrderStopLoss(),order_digits), " TP = ",DoubleToStr(OrderTakeProfit(),order_digits), ", [",DoubleToStr(OrderMagicNumber(),0),"] \"",OrderComment(),"\"" ); WriteFileLogs(fhandle_logs,order_print); WriteFileLogs(fhandle_logs,StringConcatenate("order profit = ",DoubleToStr(OrderProfit() + OrderSwap() + OrderCommission(),2)," ",account_currency)); break; } if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate("OrderCloseEx: OrderSelect() error = ",ErrorDescription(GetLastError()))); Sleep(1000); counter_attempts_select++; } } break; } } return(error); } //---------------------------------------------------------------------------------------------+ //---- OrderSendEx ----------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ int OrderSendEx(string order_symbol, int order_type, double order_lots, double order_open_price, int order_slippage, double order_stop_loss, double order_take_profit, string order_comment = "", int order_magic_number = 0, datetime order_expiration = 0, color order_color = CLR_NONE, string parent_fun_name = "") { #define number_attempts_send 3 #define number_attempts_send_select 3 if(StringLen(parent_fun_name) > 0) parent_fun_name = StringConcatenate(parent_fun_name," -> "); int err_129 = 0; int err_130 = 0; int err_137 = 0; int err_138 = 0; int err_4107 = 0; if(order_symbol == "" || order_symbol == "0") order_symbol = symbol; int order_digits = MarketInfo(order_symbol,MODE_DIGITS); order_open_price = NormalizeDouble(order_open_price,order_digits); order_stop_loss = NormalizeDouble(order_stop_loss,order_digits); order_take_profit = NormalizeDouble(order_take_profit,order_digits); while(true) { if(!is_testing) { if(!IsExpertEnabled()) { int ticket = -1; break; } } RefreshRates(); double ask = NormalizeDouble(MarketInfo(order_symbol,MODE_ASK),order_digits); double bid = NormalizeDouble(MarketInfo(order_symbol,MODE_BID),order_digits); double stoplevel = NormalizeDouble(MarketInfo(order_symbol,MODE_STOPLEVEL)*MarketInfo(order_symbol,MODE_POINT),order_digits); if(order_type > OP_SELL) { if(order_open_price <= 0.0) { ticket = -1; break; } if((order_type % 2) == OP_BUY) double current_price = ask; else current_price = bid; switch(order_type) { case OP_BUYLIMIT: case OP_SELLSTOP: double distance = NormalizeDouble(current_price - order_open_price,order_digits); break; case OP_BUYSTOP: case OP_SELLLIMIT: distance = NormalizeDouble(order_open_price - current_price,order_digits); break; } if(distance < stoplevel) { if(WriteLog) { if(distance < 0) WriteFileLogs(fhandle_logs,StringConcatenate(parent_fun_name,"OrderSendEx: The position of open price order does not correspond to type of the order.")); else WriteFileLogs(fhandle_logs,StringConcatenate(parent_fun_name,"OrderSendEx: It is impossible to open the order (the open price is near to the current price).")); } ticket = -1; break; } if(order_slippage < 0) order_slippage = 0; } else { if(order_type == OP_BUY) { if(order_open_price <= 0.0) order_open_price = ask; } else { if(order_open_price <= 0.0) order_open_price = bid; } if(order_slippage < 0) order_slippage = Slippage; } if(order_stop_loss != 0) { if((order_type % 2) == OP_BUY) distance = NormalizeDouble(order_open_price - order_stop_loss,order_digits); else distance = NormalizeDouble(order_stop_loss - order_open_price,order_digits); if(distance < stoplevel) { if(WriteLog) { if(distance < 0) WriteFileLogs(fhandle_logs,StringConcatenate(parent_fun_name,"OrderSendEx: The position of stop-loss price order does not correspond to type of the order.")); else WriteFileLogs(fhandle_logs,StringConcatenate(parent_fun_name,"OrderSendEx: It is impossible to open the order (stop-loss is near to the open price).")); } ticket = -1; break; } } if(order_take_profit != 0) { if((order_type % 2) == OP_BUY) distance = NormalizeDouble(order_take_profit - order_open_price,order_digits); else distance = NormalizeDouble(order_open_price - order_take_profit,order_digits); if(distance < stoplevel) { if(WriteLog) { if(distance < 0) WriteFileLogs(fhandle_logs,StringConcatenate(parent_fun_name,"OrderSendEx: The position of take-profit price order does not correspond to type of the order.")); else WriteFileLogs(fhandle_logs,StringConcatenate(parent_fun_name,"OrderSendEx: It is impossible to open the order (take-profit is near to the open price).")); } ticket = -1; break; } } if(!is_testing) while(IsTradeContextBusy()) Sleep(1000); GetLastError(); ticket = OrderSend(order_symbol,order_type,order_lots,order_open_price,order_slippage,order_stop_loss,order_take_profit,order_comment,order_magic_number,order_expiration,order_color); if(ticket < 0) { int err = GetLastError(); if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate(parent_fun_name,"OrderSendEx: OrderSend(",OrderTypeToStr(order_type),") ",ErrorDescription(err))); bool cont = false; switch(err) { case 0: Sleep(10000); break; case 6: //Sleep(10000); //if(IsConnected()) cont = true; break; case 128: Sleep(70000); break; case 129: Sleep(6000); err_129++; if(err_129 <= number_attempts_send) cont = true; break; case 130: Sleep(6000); err_130++; if(err_130 <= number_attempts_send) cont = true; break; case 134: Sleep(6000); break; case 135: cont = true; break; case 136: Sleep(6000); cont = true; break; case 137: Sleep(20000); err_137++; if(err_137 <= number_attempts_send) cont = true; break; case 138: err_138++; if(err_138 <= number_attempts_send) cont = true; break; case 140: if((order_type % 2) == OP_BUY) cont = true; break; case 142: Sleep(70000); break; case 143: Sleep(70000); break; case 146: while(IsTradeContextBusy()) Sleep(1000); cont = true; break; case 147: order_expiration = 0; cont = true; break; case 4000: Sleep(10000); break; case 4107: err_4107++; if(err_4107 <= number_attempts_send) cont = true; break; case 4110: if((order_type % 2) == OP_SELL) cont = true; break; case 4111: if((order_type % 2) == OP_BUY) cont = true; break; } if(!cont) break; } else { if(CreateScreenshots) CreateScreenshot(); if(OrderSelect(ticket,SELECT_BY_TICKET)) order_open_price = OrderOpenPrice(); if(SendEmail) SendMail(SubjectOpen,StringConcatenate(ExpertName," EA Trade Information\nCurrency Pair: ",StringSubstr(order_symbol,0,6),"\nTime: ",TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS),"\nOrder Type: ",OrderTypeToStr(order_type),"\nPrice: ",DoubleToStr(order_open_price,order_digits),"\nLot size: ",DoubleToStr(order_lots,lots_digits),"\nEvent: Trade Opened","\n\nCurrent Balance: ",DoubleToStr(AccountBalance(),2)," ",account_currency,"\nCurrent Equity: ",DoubleToStr(AccountEquity(),2)," ",account_currency)); if(play_sound_at_open) PlaySound(SoundFileAtOpen); if(WriteLog && WriteToSeparateLogFile) { int counter_attempts_select = 0; while(counter_attempts_select < number_attempts_send_select) { if(OrderSelect(ticket,SELECT_BY_TICKET)) { string order_print = StringConcatenate("open #",DoubleToStr(OrderTicket(),0)," ", StringSubstr(OrderSymbol(),0,6)," ",OrderTypeToStr(OrderType())," ", DoubleToStr(OrderLots(),lots_digits), " OP = ",DoubleToStr(OrderOpenPrice(),order_digits), " OT = ",TimeToStr(OrderOpenTime(),TIME_DATE|TIME_MINUTES|TIME_SECONDS), " SL = ",DoubleToStr(OrderStopLoss(),order_digits), " TP = ",DoubleToStr(OrderTakeProfit(),order_digits), ", [",DoubleToStr(OrderMagicNumber(),0),"] \"",OrderComment(),"\"" ); WriteFileLogs(fhandle_logs,order_print); break; } if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate("OrderSendEx: OrderSelect() error = ",ErrorDescription(GetLastError()))); Sleep(1000); counter_attempts_select++; } } break; } } return(ticket); } //---------------------------------------------------------------------------------------------+ //---- CloseOrders ----------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ int CloseOrders(int cmd, int magic_number, int loc_slippage, string order_symbol = "", datetime before_time = 0, string comment_signature = "", string comment_signature_except = "") { bool check_comment = StringLen(comment_signature) > 0; bool check_comment_except = StringLen(comment_signature_except) > 0; if(StringLen(order_symbol) <= 0) order_symbol = symbol; int order_digits = MarketInfo(order_symbol,MODE_DIGITS); int num_errors = 0; int num_orders = 0; int total = OrdersTotal() - 1; for(int i=total; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate("CloseOrders: OrderSelect() error = ",ErrorDescription(GetLastError()))); continue; } if(OrderMagicNumber() != magic_number) continue; if(OrderSymbol() != order_symbol) continue; if(before_time != 0) if(OrderOpenTime() >= before_time) continue; int order_type = OrderType(); if(cmd == -4) { if((order_type % 2) != OP_BUY) continue; } else { if(cmd == -5) { if((order_type % 2) != OP_SELL) continue; } else { if(cmd == -3) { if(order_type <= OP_SELL) continue; } else { if(cmd == -2) { if(order_type > OP_SELL) continue; } else { if(cmd >= OP_BUY) { if(order_type != cmd) continue; } } } } } if(check_comment) if(StringFind(OrderComment(),comment_signature) < 0) continue; if(check_comment_except) if(StringFind(OrderComment(),comment_signature_except) >= 0) continue; if(order_type <= OP_SELL) { if(order_type == OP_BUY) color order_color = ColorBuy; else order_color = ColorSell; bool error = OrderCloseEx(OrderTicket(),OrderLots(),NormalizeDouble(OrderClosePrice(),order_digits),loc_slippage,order_color,"CloseOrders"); } else error = OrderDeleteEx(OrderTicket()); if(!error) num_errors--; else num_orders++; } if(num_errors != 0) return(num_errors); return(num_orders); } //---------------------------------------------------------------------------------------------+ //---- OpenOrderMC ----------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ int OpenOrderMC(string order_symbol, int order_type, int magic_number, string order_comment, double order_lots, int loc_slippage, double open_price = 0.0) { if(order_type > OP_SELL && open_price <= 0.0) return(-1); int order_direction = order_type % 2; if(order_lots < minlots) order_lots = minlots; else if(order_lots > maxlots) order_lots = maxlots; if(AccountFreeMarginCheck(order_symbol,order_direction,order_lots) <= 0 || GetLastError() == 134) { if(WriteLog) WriteFileLogs(fhandle_logs,"OpenOrderMC: you don\'t have free margin."); return(-1); } if(order_direction == OP_BUY) color order_color = ColorBuy; else order_color = ColorSell; RefreshRates(); int order_digits = MarketInfo(order_symbol,MODE_DIGITS); double order_point = MarketInfo(order_symbol,MODE_POINT); double stoplevel = NormalizeDouble(MarketInfo(order_symbol,MODE_STOPLEVEL)*order_point,order_digits); double ask = NormalizeDouble(MarketInfo(order_symbol,MODE_ASK),order_digits); double bid = NormalizeDouble(MarketInfo(order_symbol,MODE_BID),order_digits); switch(order_type) { case OP_BUY: open_price = ask; break; case OP_SELL: open_price = bid; break; case OP_BUYLIMIT: if(open_price >= ask) { open_price = ask; order_type = OP_BUY; } else { if(NormalizeDouble(ask - open_price,order_digits) < stoplevel) { if(WriteLog) WriteFileLogs(fhandle_logs,"OpenOrderMC: can not place pending order because current price is near to opening price."); return(-2); } } break; case OP_SELLLIMIT: if(open_price <= bid) { open_price = bid; order_type = OP_SELL; } else { if(NormalizeDouble(open_price - bid,order_digits) < stoplevel) { if(WriteLog) WriteFileLogs(fhandle_logs,"OpenOrderMC: can not place pending order because current price is near to opening price."); return(-2); } } break; case OP_BUYSTOP: if(open_price <= ask) { open_price = ask; order_type = OP_BUY; } else { if(NormalizeDouble(open_price - ask,order_digits) < stoplevel) { if(WriteLog) WriteFileLogs(fhandle_logs,"OpenOrderMC: can not place pending order because current price is near to opening price."); return(-2); } } break; case OP_SELLSTOP: if(open_price >= bid) { open_price = bid; order_type = OP_SELL; } else { if(NormalizeDouble(bid - open_price,order_digits) < stoplevel) { if(WriteLog) WriteFileLogs(fhandle_logs,"OpenOrderMC: can not place pending order because current price is near to opening price."); return(-2); } } break; default: return(-1); break; } int ticket = OrderSendEx(order_symbol,order_type,order_lots,open_price,loc_slippage,0.0,0.0,order_comment,magic_number,0,order_color,"OpenOrderMC"); return(ticket); } //---------------------------------------------------------------------------------------------+ //---- CreateScreenshot -----------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ bool CreateScreenshot() { RefreshRates(); datetime cur_time = TimeCurrent(); string file_name = StringConcatenate(path_screenshots,"Screenshot_",IntegerToStr(TimeYear(cur_time),4),"_",IntegerToStr(TimeMonth(cur_time),2),"_",IntegerToStr(TimeDay(cur_time),2)," ",IntegerToStr(TimeHour(cur_time),2),"_",IntegerToStr(TimeMinute(cur_time),2),"_",IntegerToStr(TimeSeconds(cur_time),2),".gif"); bool error = WindowScreenShot(file_name,ScreenshotSizeX,ScreenshotSizeY,ScreenshotStartBar,ScreenshotChartScale,ScreenshotChartMode); if(!error) { if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate("CreateScreenshot: WindowScreenShot() error = ",ErrorDescription(GetLastError()))); } return(error); } //---------------------------------------------------------------------------------------------+ //---- IntegerToStr ---------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ string IntegerToStr(int integer_number, int minimum_chars, string add_char="0") { string result = DoubleToStr(integer_number,0); for(int i=minimum_chars-StringLen(result); i>0; i--) result = StringConcatenate(add_char,result); return(result); } //---------------------------------------------------------------------------------------------+ //---- WriteFileLogs --------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ bool WriteFileLogs(int fhandle, string message) { if(!WriteToSeparateLogFile) Print(message); else { RefreshRates(); int num_chars = FileWrite(fhandle,StringConcatenate(TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS)," : ",message)); if(num_chars < 0) { Print("WriteFileLogs: FileWrite(",fhandle,") error = ",ErrorDescription(GetLastError())); Print("WriteFileLogs: ",StringConcatenate(TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS)," : ",message)); return(false); } } return(true); } //---------------------------------------------------------------------------------------------+ //---- NumTradesAfterTimeMC -------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ int NumTradesAfterTimeMC(datetime after_time, int order_direction, int magic_number, string order_symbol, bool check_opened = true, bool check_closed = true, string comment_signature = "") { bool check_comment = StringLen(comment_signature) > 0; int num_orders = 0; if(check_opened) { int total = OrdersTotal() - 1; for(int i=total; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate("NumTradesAfterTimeMC_1: OrderSelect() error = ",ErrorDescription(GetLastError()))); continue; } if(OrderMagicNumber() != magic_number) continue; if(OrderSymbol() != order_symbol) continue; if(OrderOpenTime() < after_time) break; if(order_direction >= 0) if((OrderType() % 2) != order_direction) continue; if(check_comment) if(StringFind(OrderComment(),comment_signature) < 0) continue; num_orders++; } } if(check_closed) { total = OrdersHistoryTotal() - 1; for(i=total; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) { if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate("NumTradesAfterTimeMC_2: OrderSelect() error = ",ErrorDescription(GetLastError()))); continue; } if(OrderMagicNumber() != magic_number) continue; if(OrderSymbol() != order_symbol) continue; if(OrderCloseTime() < after_time) break; if(order_direction >= 0) if((OrderType() % 2) != order_direction) continue; if(StringFind(OrderComment(),"to #",0) >= 0) continue; if(check_comment) if(StringFind(OrderComment(),comment_signature) < 0) continue; num_orders++; } } return(num_orders); } //---------------------------------------------------------------------------------------------+ //---- GetLots --------------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ double GetLots(double sl_pips, int magic_number) { if(!UseMM || sl_pips <= 0.0) double lots = Lots; else { int num_orders_with_loss = 0; if(MultipleRiskAfterLoss) { int total = OrdersHistoryTotal() - 1; for(int i=total; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) { if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate("GetLots: OrderSelect() error = ",ErrorDescription(GetLastError()))); continue; } if(OrderMagicNumber() != magic_number) continue; if(OrderSymbol() != Symbol_Name) continue; if(OrderType() == OP_BUY) double order_profit = NormalizeDouble(OrderClosePrice() - OrderOpenPrice(),symbol_digits); else order_profit = NormalizeDouble(OrderOpenPrice() - OrderClosePrice(),symbol_digits); if(order_profit > 0.0) break; if(order_profit == 0.0) continue; num_orders_with_loss++; } if(num_orders_with_loss >= NumRiskValues) num_orders_with_loss = num_orders_with_loss % NumRiskValues; } if(WriteDebugLog) WriteFileLogs(fhandle_logs,StringConcatenate("risk_percent = ",DoubleToStr(risk_percent[num_orders_with_loss],8))); double sl_points = NormalizeDouble(sl_pips * correction,0); double risk_money = AccountBalance() * risk_percent[num_orders_with_loss]; lots = NormalizeDouble(risk_money / (MarketInfo(Symbol_Name,MODE_TICKVALUE) * sl_points),lots_digits); } if(lots > MaxLots) lots = MaxLots; if(lots < minlots) lots = minlots; else if(lots > maxlots) lots = maxlots; return(lots); } //---------------------------------------------------------------------------------------------+ //---- HaveOrders -----------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ int HaveOrders(int cmd, int magic_number, string order_symbol = "", string comment_signature_except = "") { bool check_comment = StringLen(comment_signature_except) > 0; if(StringLen(order_symbol) <= 0) order_symbol = symbol; int num_orders = 0; int total = OrdersTotal() - 1; for(int i=total; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate("HaveOrdersMC: OrderSelect() error = ",ErrorDescription(GetLastError()))); continue; } if(OrderMagicNumber() != magic_number) continue; if(OrderSymbol() != order_symbol) continue; int order_type = OrderType(); if(cmd == -4) { if((order_type % 2) != OP_BUY) continue; } else { if(cmd == -5) { if((order_type % 2) != OP_SELL) continue; } else { if(cmd == -3) { if(order_type <= OP_SELL) continue; } else { if(cmd == -2) { if(order_type > OP_SELL) continue; } else { if(cmd >= OP_BUY) { if(order_type != cmd) continue; } } } } } if(check_comment) if(StringFind(OrderComment(),comment_signature_except) >= 0) continue; num_orders++; } return(num_orders); } //---------------------------------------------------------------------------------------------+ //---- GetSymbolName --------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ string GetSymbolName(string name_of_currency_pair) { name_of_currency_pair = StringTrimLeft(StringTrimRight(name_of_currency_pair)); if(StringLen(name_of_currency_pair) <= 0) string symbol_name = symbol; else { int symbol_length = StringLen(symbol); if(symbol_length <= 6) string symbol_appendix = ""; symbol_appendix = StringSubstr(symbol,6,0); if(StringLen(name_of_currency_pair) < symbol_length) symbol_name = StringConcatenate(name_of_currency_pair,symbol_appendix); else symbol_name = StringSubstr(name_of_currency_pair,0,symbol_length); for(int i=0; i<6; i++) { int char_i = StringGetChar(symbol_name,i); if(char_i <= 'Z') continue; char_i -= 32; symbol_name = StringSetChar(symbol_name,i,char_i); } } return(symbol_name); } //---------------------------------------------------------------------------------------------+ //---- GetValueOfCrossing ---------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ double GetValueOfCrossing(double y11, double y12, double y21, double y22) { #define x 100000.0 double a1 = (y12 - y11) / x; double b1 = y11; double a2 = (y22 - y21) / x; double b2 = y21; double value_of_crossing = a1 * ((b2 - b1) / (a1 - a2)) + b1; return(value_of_crossing); } //---------------------------------------------------------------------------------------------+ //---- IsOrder --------------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ bool IsOrder(int magic_number) { bool result = false; int total = OrdersTotal() - 1; for(int i=total; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate("IsOrder: OrderSelect() error = ",ErrorDescription(GetLastError()))); continue; } if(OrderMagicNumber() != magic_number) continue; result = true; break; } return(result); } //---------------------------------------------------------------------------------------------+ //---- WatchMoveSLToBEMC ------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ void WatchMoveSLToBEMC(double be_profit_percents, double be_offset_rate, int magic_number) { int total = OrdersTotal() - 1; for(int i=total; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(WriteLog) WriteFileLogs(fhandle_logs,StringConcatenate("WatchMoveSLToBEMC: OrderSelect() error = ",ErrorDescription(GetLastError()))); continue; } if(OrderMagicNumber() != magic_number) continue; int order_type = OrderType(); if(order_type > OP_SELL) continue; string order_symbol = OrderSymbol(); if(order_symbol != Symbol_Name) continue; double order_sl = NormalizeDouble((-1.0) * StringToDouble(OrderComment())*point,symbol_digits); if(TakeProfit < 0.0) double order_tp = NormalizeDouble(TakeProfit * order_sl,symbol_digits); else order_tp = main_tp; if(order_tp <= 0.0 || order_sl >= 0.0) continue; double be_profit = NormalizeDouble(be_profit_percents / 100.0 * order_tp,symbol_digits); double be_offset = NormalizeDouble((-1.0) * be_offset_rate * order_sl,symbol_digits); double order_stop_loss = NormalizeDouble(OrderStopLoss(), symbol_digits); double order_open_price = NormalizeDouble(OrderOpenPrice(), symbol_digits); double order_close_price = NormalizeDouble(OrderClosePrice(),symbol_digits); if(order_type == OP_BUY) { double new_stop_loss = NormalizeDouble(order_open_price + be_offset,symbol_digits); if(order_stop_loss >= new_stop_loss) continue; double order_profit = NormalizeDouble(order_close_price - order_open_price,symbol_digits); } else { new_stop_loss = NormalizeDouble(order_open_price - be_offset,symbol_digits); if(order_stop_loss != 0.0 && order_stop_loss <= new_stop_loss) continue; order_profit = NormalizeDouble(order_open_price - order_close_price,symbol_digits); } if(order_profit < be_profit) continue; double stoplevel = NormalizeDouble(MarketInfo(order_symbol,MODE_STOPLEVEL)*symbol_point,symbol_digits); if(order_profit < stoplevel) { if(WriteDebugLog) WriteFileLogs(fhandle_logs,StringConcatenate("WatchMoveSLToBEMC: ticket ",DoubleToStr(OrderTicket(),0)," - it is impossible to move, the level stop-loss is near to the close price.")); continue; } if(order_type == OP_BUY) color order_color = ColorBuy; else order_color = ColorSell; OrderModifyEx(OrderTicket(),order_open_price,new_stop_loss,NormalizeDouble(OrderTakeProfit(),symbol_digits),0,order_color,"WatchMoveSLToBE"); } } //---------------------------------------------------------------------------------------------+ //---- GetSL ----------------------------------------------------------------------------------+ //-------------------------------- programming by Serega Lykov, http://mtexperts.narod.ru/ ----+ //---------------------------------------------------------------------------------------------+ double GetSL(int direction) { if(DinamicSL_Levels <= 0) double result = StopLoss; else { result = 0.0; double last_levels[]; if(ArraySize(last_levels) != DinamicSL_Levels) ArrayResize(last_levels,DinamicSL_Levels); int num_levels = 0; if(direction == OP_BUY) { double open_price = NormalizeDouble(MarketInfo(Symbol_Name,MODE_ASK),symbol_digits); for(int i=0; i= DinamicSL_Levels) break; } } ArraySort(last_levels,DinamicSL_Levels,0,MODE_DESCEND); result = NormalizeDouble((open_price - last_levels[DinamicSL_IndexOfLevel])/point + DinamicSL_OffsetPips,pips_digits); } else { open_price = NormalizeDouble(MarketInfo(Symbol_Name,MODE_BID),symbol_digits); for(i=0; i open_price) { last_levels[num_levels] = i_zigzag; num_levels++; if(num_levels >= DinamicSL_Levels) break; } } ArraySort(last_levels,DinamicSL_Levels,0,MODE_ASCEND); result = NormalizeDouble((last_levels[DinamicSL_IndexOfLevel] - open_price)/point + DinamicSL_OffsetPips,pips_digits); } } //for(k=0; k