//+------------------------------------------------------------------+ //| trade_lib.mqh | //| komposter | //| mailto:komposterius@mail.ru | //+------------------------------------------------------------------+ #include #include static string comment = ""; extern int Slippage = 10; extern color OrderBuyColor = Yellow; extern color OrderSellColor = DarkGreen; ///////////////////////////////////////////////////////////////////////////////// /**/ void _start_trade_lib ( string _Symbol, int TimeFrame ) ///////////////////////////////////////////////////////////////////////////////// // создаёт коммент к ордеру типа "ExpertName ( Symbol, TimeFrame )", если он (коммент) не задаётся вручную // если эксперт работает по одному инструменту/ТФ нужно вызвать ф-цию из init(), // если по нескольким, то из start() ///////////////////////////////////////////////////////////////////////////////// { comment = ExpertName + "(" + _Symbol + ", " + TimeFrame_str ( TimeFrame ) + ")"; } ///////////////////////////////////////////////////////////////////////////////// /**/ bool _IsExpertOrder ( int _MagicNumber ) ///////////////////////////////////////////////////////////////////////////////// // Проверка наличия позиций/ордеров, открытых экспертом + вывод информации. // Если таковые есть, возвращает true, если нет - возвращает false ///////////////////////////////////////////////////////////////////////////////// { // Print( "_IsExpertOrder ( ", _MagicNumber, " ) - loaded..." ); for ( int z = 0; z < OrdersTotal(); z ++ ) { if ( OrderSelect( z, SELECT_BY_POS ) == false ) { break; } if ( OrderMagicNumber() == _MagicNumber ) { int ordertype = OrderType(); int orderticket = OrderTicket(); string ordersymbol = OrderSymbol(); string ProfitLoss = DoubleToStr( OrderProfit() + OrderSwap() + OrderCommission(), 2 ); int digits = MarketInfo( ordersymbol, MODE_DIGITS ); string openprice_str = DoubleToStr( OrderOpenPrice(), digits ); string bid_str = DoubleToStr( MarketInfo( ordersymbol, MODE_BID ), digits ); string ask_str = DoubleToStr( MarketInfo( ordersymbol, MODE_ASK ), digits ); string _OrderType_str = _OrderType_str ( ordertype ); if ( ordertype <= OP_SELL ) { _info ( 1, ordersymbol + " - есть позиция, открытая этим экспертом:" ); _info ( 2, "№ " + orderticket + " - " + _OrderType_str + ", Profit/Loss = " + ProfitLoss ); _info ( 3, "" ); _info ( 4, "" ); } else { string tmp_str = ", Bid = " + bid_str; if ( ordertype == OP_BUYLIMIT || ordertype == OP_BUYSTOP ) { tmp_str = ", Ask = " + ask_str; } _info ( 1, ordersymbol + " - есть ордер, установленный этим экспертом:" ); _info ( 2, "№ " + orderticket + " - " + _OrderType_str ); _info ( 3, "Open Price = " + openprice_str + tmp_str ); _info ( 4, "" ); } // Print( "_IsExpertOrder ( ", _MagicNumber, " ) - return(true);" ); return(true); } } //Print( "_IsExpertOrder ( ", _MagicNumber, " ) - return(false);" ); return(false); } ///////////////////////////////////////////////////////////////////////////////// /**/ int _OrderSend ( string _Symbol, int _OrderType, double _Volume, double _OpenPrice, int _Slippage = 5, double _StopLoss = 0, double _TakeProfit = 0, string _Comment = "", int _MagicNumber = 0, datetime _Expiration = 0, color _Color = CLR_NONE ) ///////////////////////////////////////////////////////////////////////////////// // Стандартная ф-ция OrderSend + проверка значений + вывод информации. // При успешном выполнении возвращает OrderTicket, при ошибке установки возвращает "-1", при ошибке проверки возвращает "-2" ///////////////////////////////////////////////////////////////////////////////// { // Print( "_OrderSend( ", _Symbol, ", ", _OrderType, ", ", _Volume, ", ", _OpenPrice, ", ", _Slippage, ", ", _StopLoss, ", ", _TakeProfit, ", ", _Comment, ", ", _MagicNumber, ", ", _Expiration, ", ", _Color, " ) - loaded..." ); int digits = MarketInfo( _Symbol, MODE_DIGITS ); // - Первоначальные проверки и нормализация if ( _OrderType == OP_BUY ) { _OpenPrice = MarketInfo( _Symbol, MODE_ASK ); } if ( _OrderType == OP_SELL ) { _OpenPrice = MarketInfo( _Symbol, MODE_BID ); } _Volume = NormalizeDouble( _Volume, 1 ); _OpenPrice = NormalizeDouble( _OpenPrice, digits ); _StopLoss = NormalizeDouble( _StopLoss, digits ); _TakeProfit = NormalizeDouble( _TakeProfit, digits ); // - вывод информации string _OrderType_str = _OrderType_str ( _OrderType ); string str_tmp = "Устанавливаем " + _OrderType_str + "-ордер"; string str_tmp2 = "Установлен успешно..."; if ( _OrderType <= OP_SELL ) { str_tmp = "Открываем позицию " + _OrderType_str; str_tmp2 = "Открыта успешно..."; } _info ( 1, str_tmp + ", " + DoubleToStr( _Volume, 1) + " lot(s)..." ); _info ( 2, "Open Price = " + DoubleToStr( _OpenPrice, digits ) ); _info ( 3, "Stop Loss = " + DoubleToStr( _StopLoss, digits ) ); _info ( 4, "Take Profit = " + DoubleToStr( _TakeProfit, digits ) ); // - Проверки // Print( "_OrderCheck( ", _Symbol, ", ", _OrderType, ", ", _Volume, ", ", _OpenPrice, ", ", _StopLoss, ", ", _TakeProfit, ", ", _Expiration, " ) - loading..." ); if ( _OrderCheck( _Symbol, _OrderType, _Volume, _OpenPrice, _StopLoss, _TakeProfit, _Expiration ) != 1 ) { // Print( "_OrderSend( ", _Symbol, ", ", _OrderType, ", ", _Volume, ", ", _OpenPrice, ", ", _Slippage, ", ", _StopLoss, ", ", _TakeProfit, ", ", _Comment, ", ", _MagicNumber, ", ", _Expiration, ", ", _Color, " ) - return(-2);" ); return(-2); } if ( _Color <= 0 ) { _Color = OrderSellColor; if ( _OrderType == OP_BUY || _OrderType == OP_BUYLIMIT || _OrderType == OP_BUYSTOP ) { _Color = OrderBuyColor; } } if ( _Comment == "" ) _Comment = comment; // - 2-хкратная попытка открыть позицию/установить ордер for ( int x = 0; x < 2; x ++ ) { // - если со времени последней торговой операции прошло меньше 10 сек, ждём while ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) < 30 ) { _info ( 4, "Пауза между торговыми операциями. Осталось " + DoubleToStr( 30 - ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) ), 0 ) + " сек.", 0, 0 ); Sleep(1000); } if ( !IsTradeAllowed() ) { Sleep(3000); if ( !IsTradeAllowed() ) { _info ( 4, "IsTradeAllowed = false!!!", 1 ); return(0); } } int ordersend = OrderSend ( _Symbol, _OrderType, _Volume, _OpenPrice, _Slippage, _StopLoss, _TakeProfit, _Comment, _MagicNumber, _Expiration, _Color ); GlobalVariableSet ( "LastTradeTime", LocalTime() ); if ( ordersend > 0 ) { // - если всё хорошо, выводим информацию и выходим _info ( 4, str_tmp2 ); OrderSelect( ordersend, SELECT_BY_TICKET, MODE_TRADES ); OrderPrint(); // Print( "_OrderSend( ", _Symbol, ", ", _OrderType, ", ", _Volume, ", ", _OpenPrice, ", ", _Slippage, ", ", _StopLoss, ", ", _TakeProfit, ", ", _Comment, ", ", _MagicNumber, ", ", _Expiration, ", ", _Color, " ) - return(", ordersend, ");" ); // создания описаний к стрелочкам string arrow_description = _Comment + "\nId " + _MagicNumber; string end_name; switch ( _OrderType ) { case OP_BUY: end_name = " buy"; break; case OP_SELL: end_name = " sell"; break; case OP_BUYLIMIT: end_name = " buy limit"; break; case OP_SELLLIMIT: end_name = " sell limit"; break; case OP_BUYSTOP: end_name = " buy stop"; break; case OP_SELLSTOP: end_name = " sell stop"; break; } string open_name = "#" + ordersend + end_name; string sl_name = "#" + ordersend + " sl"; string tp_name = "#" + ordersend + " tp"; ObjectSetText( open_name, arrow_description, 10 ); ObjectSetText( sl_name, arrow_description, 10 ); ObjectSetText( tp_name, arrow_description, 10 ); return(ordersend); } // - если нет, выводим информацию, отдаём на отработку код ошибки и ждём 10 сек перед следующей попыткой int error_code = GetLastError(); _info ( 1, "Ошибка при установке ордера!!!", 1 ); Processing_Error ( error_code ); Sleep(10000); } // - если не удалось установить ордер/открыть позицию с 2-х попыток - выходим //Print( "_OrderSend( ", _Symbol, ", ", _OrderType, ", ", _Volume, ", ", _OpenPrice, ", ", _Slippage, ", ", _StopLoss, ", ", _TakeProfit, ", ", _Comment, ", ", _MagicNumber, ", ", _Expiration, ", ", _Color, " ) - return(-1);" ); return(-1); } ///////////////////////////////////////////////////////////////////////////////// /**/ int _OrderModify ( int _OrderTicket, double New_OpenPrice, double New_StopLoss, double New_TakeProfit, datetime New_Expiration, color _Color = CLR_NONE ) ///////////////////////////////////////////////////////////////////////////////// // Стандартная ф-ция OrderModify + проверки + вывод информации. // При успешном выполнении возвращает "1", при ошибке возвращает "-1", при ошибке выбора ордера возвращает "-2", при ошибке проверки возвращает "-3" ///////////////////////////////////////////////////////////////////////////////// { // Print( "_OrderModify ( ", _OrderTicket, ", ", New_OpenPrice, ", ", New_StopLoss, ", ", New_TakeProfit, ", ", New_Expiration, ", ", _Color, " ) - loaded..." ); if ( OrderSelect( _OrderTicket, SELECT_BY_TICKET ) == false ) { // Print( "_OrderModify ( ", _OrderTicket, ", ", New_OpenPrice, ", ", New_StopLoss, ", ", New_TakeProfit, ", ", New_Expiration, ", ", _Color, " ) - return(-2);" ); return(-2); } string _Symbol = OrderSymbol(); int _OrderType = OrderType(); int digits = MarketInfo( _Symbol, MODE_DIGITS ); if ( New_OpenPrice <= 0 ) { New_OpenPrice = OrderOpenPrice(); } if ( New_StopLoss <= 0 ) { New_StopLoss = OrderStopLoss(); } if ( New_TakeProfit <= 0 ) { New_TakeProfit = OrderTakeProfit(); } if ( New_Expiration <= 0 ) { New_Expiration = OrderExpiration(); } if ( _OrderType == OP_BUY || _OrderType == OP_SELL ) { New_OpenPrice = OrderOpenPrice(); New_Expiration = 0; } double _Volume = NormalizeDouble( OrderLots(), 1 ); New_OpenPrice = NormalizeDouble( New_OpenPrice, digits ); New_StopLoss = NormalizeDouble( New_StopLoss, digits ); New_TakeProfit = NormalizeDouble( New_TakeProfit, digits ); string str_tmp = "Модифицируем ордер № "; string str_tmp2 = "Модифицирован успешно..."; string _OrderType_str = _OrderType_str ( _OrderType ); if ( _OrderType <= OP_SELL ) { str_tmp = "Модифицируем позицию № "; str_tmp2 = "Модифицирована успешно..."; } _info ( 1, str_tmp + _OrderTicket + ", " + _OrderType_str + "..." ); _info ( 2, "New Open Price = " + DoubleToStr( New_OpenPrice, digits ) ); _info ( 3, "New Stop Loss = " + DoubleToStr( New_StopLoss, digits ) ); _info ( 4, "New Take Profit = " + DoubleToStr( New_TakeProfit, digits ) ); // Print( "_OrderCheck( ", _Symbol, ", ", _OrderType, ", ", _Volume, ", ", New_OpenPrice, ", ", New_StopLoss, ", ", New_TakeProfit, ", ", New_Expiration, " ) - loading..." ); if ( _OrderCheck( _Symbol, _OrderType, _Volume, New_OpenPrice, New_StopLoss, New_TakeProfit, New_Expiration ) != 1 ) { // Print( "_OrderModify ( ", _OrderTicket, ", ", New_OpenPrice, ", ", New_StopLoss, ", ", New_TakeProfit, ", ", New_Expiration, ", ", _Color, " ) - return(-3);" ); return(-3); } if ( _Color <= 0 ) { _Color = OrderSellColor; if ( _OrderType == OP_BUY || _OrderType == OP_BUYLIMIT || _OrderType == OP_BUYSTOP ) { _Color = OrderBuyColor; } } for ( int x = 0; x < 2; x ++ ) { while ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) < 30 ) { _info ( 4, "Пауза между торговыми операциями. Осталось " + DoubleToStr( 30 - ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) ), 0 ) + " сек.", 0, 0 ); Sleep(1000); } if ( OrderSelect( _OrderTicket, SELECT_BY_TICKET ) == false ) { // Print( "_OrderModify ( ", _OrderTicket, ", ", New_OpenPrice, ", ", New_StopLoss, ", ", New_TakeProfit, ", ", New_Expiration, ", ", _Color, " ) - return(-2);" ); return(-2); } if ( !IsTradeAllowed() ) { Sleep(3000); if ( !IsTradeAllowed() ) { _info ( 4, "IsTradeAllowed = false!!!", 1 ); return(0); } } int ordermodify = OrderModify( _OrderTicket, New_OpenPrice, New_StopLoss, New_TakeProfit, New_Expiration, _Color ); GlobalVariableSet ( "LastTradeTime", LocalTime() ); if ( ordermodify > 0 ) { _info ( 4, str_tmp2 ); // Print( "_OrderModify ( ", _OrderTicket, ", ", New_OpenPrice, ", ", New_StopLoss, ", ", New_TakeProfit, ", ", New_Expiration, ", ", _Color, " ) - return(1);" ); return(1); } int error_code = GetLastError(); _info ( 1, "Ошибка при модификации ордера!!!", 1 ); Processing_Error ( error_code ); Sleep(10000); } //Print( "_OrderModify ( ", _OrderTicket, ", ", New_OpenPrice, ", ", New_StopLoss, ", ", New_TakeProfit, ", ", New_Expiration, ", ", _Color, " ) - return(-1);" ); return(-1); } ///////////////////////////////////////////////////////////////////////////////// /**/ int _OrderClose ( int _OrderTicket, double _Volume, int _Slippage = 5, color _Color = CLR_NONE ) ///////////////////////////////////////////////////////////////////////////////// // Стандартная ф-ция OrderClose + вывод информации. // При успешном выполнении возвращает "1", при ошибке возвращает "-1", при ошибке № ордера возвращает "-2" ///////////////////////////////////////////////////////////////////////////////// { // Print( "_OrderClose ( ", _OrderTicket, ", ", _Slippage, " ) - loaded..." ); if ( OrderSelect( _OrderTicket, SELECT_BY_TICKET ) == false ) { // Print( "_OrderClose ( ", _OrderTicket, ", ", _Slippage, " ) - return(-2);" ); return(-2); } int _OrderType = OrderType(); string ordersymbol = OrderSymbol(); if ( _Volume < 0.1 || _Volume > OrderLots() ) { _Volume = OrderLots(); } _Volume = NormalizeDouble( _Volume, 1 ); string _OrderType_str = _OrderType_str ( _OrderType ); int digits = MarketInfo( ordersymbol, MODE_DIGITS ); if ( _OrderType > OP_SELL ) { return(-1); } if ( _Slippage < 0 ) { _Slippage = 0; } double _ClosePrice = NormalizeDouble( MarketInfo ( ordersymbol, MODE_ASK ), digits ); if ( _OrderType == OP_BUY ) { _ClosePrice = NormalizeDouble( MarketInfo ( ordersymbol, MODE_BID ), digits ); } if ( _Color <= 0 ) { _Color = OrderSellColor; if ( _OrderType == OP_BUY || _OrderType == OP_BUYLIMIT || _OrderType == OP_BUYSTOP ) { _Color = OrderBuyColor; } } _info ( 1, "Закрываем позицию № " + _OrderTicket + ", " + _OrderType_str + "..." ); _info ( 2, "Сlose Price = " + DoubleToStr( _ClosePrice, digits ) ); _info ( 3, "" ); _info ( 4, "" ); for ( int x = 0; x < 2; x ++ ) { while ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) < 30 ) { _info ( 4, "Пауза между торговыми операциями. Осталось " + DoubleToStr( 30 - ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) ), 0 ) + " сек.", 0, 0 ); Sleep(1000); } if ( OrderSelect( _OrderTicket, SELECT_BY_TICKET ) == false ) { // Print( "_OrderClose ( ", _OrderTicket, ", ", _Slippage, " ) - return(-2);" ); return(-2); } if ( !IsTradeAllowed() ) { Sleep(3000); if ( !IsTradeAllowed() ) { _info ( 4, "IsTradeAllowed = false!!!", 1 ); return(0); } } int orderclose = OrderClose( _OrderTicket, _Volume, _ClosePrice, _Slippage, _Color ); GlobalVariableSet ( "LastTradeTime", LocalTime() ); if ( orderclose > 0 ) { _info ( 3, "Закрыта успешно..." ); // Print( "_OrderClose ( ", _OrderTicket, ", ", _Slippage, " ) - return(1);" ); return(1); } int error_code = GetLastError(); _info ( 1, "Ошибка при закрытии позиции!!!", 1 ); Processing_Error ( error_code ); Sleep(10000); } //Print( "_OrderClose ( ", _OrderTicket, ", ", _Slippage, " ) - return(-1);" ); return(-1); } ///////////////////////////////////////////////////////////////////////////////// /**/ int _OrderDelete ( int _OrderTicket ) ///////////////////////////////////////////////////////////////////////////////// // Стандартная ф-ция OrderDelete + вывод информации. // При успешном выполнении возвращает "1", при ошибке удаления возвращает "-1", при ошибке № ордера, возвращает "-2" ///////////////////////////////////////////////////////////////////////////////// { // Print( "_OrderDelete ( ", _OrderTicket, " ) - loaded..." ); if ( OrderSelect( _OrderTicket, SELECT_BY_TICKET ) == false ) { // Print( "_OrderDelete ( ", _OrderTicket, " ) - return(-2);" ); return(-2); } int _OrderType = OrderType(); if ( _OrderType <= OP_SELL ) { return(-1); } string _OrderType_str = _OrderType_str ( _OrderType ); _info ( 1, "Удаляем ордер № " + _OrderTicket + ", " + _OrderType_str + "..." ); _info ( 2, "" ); _info ( 3, "" ); _info ( 4, "" ); for ( int x = 0; x < 2; x ++ ) { while ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) < 30 ) { _info ( 4, "Пауза между торговыми операциями. Осталось " + DoubleToStr( 30 - ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) ), 0 ) + " сек.", 0, 0 ); Sleep(1000); } if ( OrderSelect( _OrderTicket, SELECT_BY_TICKET ) == false ) { // Print( "_OrderDelete ( ", _OrderTicket, " ) - return(-2);" ); return(-2); } if ( !IsTradeAllowed() ) { Sleep(3000); if ( !IsTradeAllowed() ) { _info ( 4, "IsTradeAllowed = false!!!", 1 ); return(0); } } int orderdelete = OrderDelete( _OrderTicket ); GlobalVariableSet ( "LastTradeTime", LocalTime() ); if ( orderdelete > 0 ) { _info ( 2, "Удалён успешно..." ); // Print( "_OrderDelete ( ", _OrderTicket, " ) - return(1);" ); return(1); } int error_code = GetLastError(); _info ( 1, "Ошибка при удалении ордера!!!", 1 ); Processing_Error ( error_code ); Sleep(10000); } //Print( "_OrderDelete ( ", _OrderTicket, " ) - return(-1);" ); return(-1); } ///////////////////////////////////////////////////////////////////////////////// /**/ int _TrailingStop ( int _OrderTicket, int TrailingStop, color _Color = CLR_NONE ) ///////////////////////////////////////////////////////////////////////////////// // TrailingStop + вывод информации // При успешном смещёнии возвращает "1", при отстутствии необходимости двигать - "0", при ошибке "-1", при ошибке № ордера, возвращает "-2" ///////////////////////////////////////////////////////////////////////////////// { // Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - loaded..." ); if ( TrailingStop <= 0 ) { // Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - return(0);" ); return(0); } if ( OrderSelect( _OrderTicket, SELECT_BY_TICKET ) == false ) { // Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - return(-2);" ); return(-2); } string _Symbol = OrderSymbol(); int _OrderType = OrderType(); double point = MarketInfo ( _Symbol, MODE_POINT ); int digits = MarketInfo( _Symbol, MODE_DIGITS ); double bid = NormalizeDouble( MarketInfo ( _Symbol, MODE_BID ), digits ); double ask = NormalizeDouble( MarketInfo ( _Symbol, MODE_ASK ), digits ); double spread = MarketInfo ( _Symbol, MODE_SPREAD ) * point; double orderopenprice = NormalizeDouble ( OrderOpenPrice(), digits ); double orderstoploss = NormalizeDouble ( OrderStopLoss(), digits ); double ordertakeprofit = NormalizeDouble ( OrderTakeProfit(), digits ); datetime orderexpiration = OrderExpiration(); double NewStopLoss; string _OrderType_str = _OrderType_str ( _OrderType ); if ( _Color <= 0 ) { _Color = OrderSellColor; if ( _OrderType == OP_BUY || _OrderType == OP_BUYLIMIT || _OrderType == OP_BUYSTOP ) { _Color = OrderBuyColor; } } if ( _OrderType == OP_BUY ) { NewStopLoss = NormalizeDouble( bid - TrailingStop * point, digits ); if ( ( bid - orderopenprice ) > 0 ) { if ( orderstoploss <= 0 || NewStopLoss - orderstoploss > spread )//TrailingStop < ( bid - orderstoploss ) / point ) { _info ( 1, "Trailing Stop (" + TrailingStop + " points) для позиции № " + _OrderTicket + ", " + _OrderType_str + "..." ); _info ( 2, "Old Stop Loss = " + DoubleToStr( orderstoploss, digits ) ); _info ( 3, "New Stop Loss = " + DoubleToStr( NewStopLoss, digits ) ); _info ( 4, "" ); for ( int x = 0; x < 1; x ++ ) { while ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) < 30 ) { _info ( 4, "Пауза между торговыми операциями. Осталось " + DoubleToStr( 30 - ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) ), 0 ) + " сек.", 0, 0 ); Sleep(1000); } if ( OrderSelect( _OrderTicket, SELECT_BY_TICKET ) == false ) { // Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - return(-2);" ); return(-2); } if ( !IsTradeAllowed() ) { Sleep(3000); if ( !IsTradeAllowed() ) { _info ( 4, "IsTradeAllowed = false!!!", 1 ); return(0); } } int ordermodify = OrderModify( _OrderTicket, orderopenprice, NewStopLoss, ordertakeprofit, orderexpiration, _Color ); GlobalVariableSet ( "LastTradeTime", LocalTime() ); if ( ordermodify > 0 ) { _info ( 4, "Успешно..." ); // Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - return(1);" ); return(1); } int error_code = GetLastError(); _info ( 1, "Ошибка Trailing Stop!!!", 1 ); Processing_Error ( error_code ); Sleep(10000); } // Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - return(-1);" ); return(-1); } } } if ( _OrderType == OP_SELL ) { NewStopLoss = NormalizeDouble( ask + TrailingStop * point, digits ); if ( ( orderopenprice - ask ) > 0 ) { if ( orderstoploss <= 0 || orderstoploss - NewStopLoss > spread )//TrailingStop > ( ask + orderstoploss ) / point ) { _info ( 1, "Trailing Stop (" + TrailingStop + " points) для позиции № " + _OrderTicket + ", " + _OrderType_str + "..." ); _info ( 2, "Old Stop Loss = " + DoubleToStr( orderstoploss, digits ) ); _info ( 3, "New Stop Loss = " + DoubleToStr( NewStopLoss, digits ) ); _info ( 4, "" ); for ( x = 0; x < 1; x ++ ) { while ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) < 30 ) { _info ( 4, "Пауза между торговыми операциями. Осталось " + DoubleToStr( 30 - ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) ), 0 ) + " сек.", 0, 0 ); Sleep(1000); } if ( OrderSelect( _OrderTicket, SELECT_BY_TICKET ) == false ) { // Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - return(-2);" ); return(-2); } if ( !IsTradeAllowed() ) { Sleep(3000); if ( !IsTradeAllowed() ) { _info ( 4, "IsTradeAllowed = false!!!", 1 ); return(0); } } ordermodify = OrderModify( _OrderTicket, orderopenprice, NewStopLoss, ordertakeprofit, orderexpiration, _Color ); GlobalVariableSet ( "LastTradeTime", LocalTime() ); if ( ordermodify > 0 ) { _info ( 4, "Успешно..." ); // Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - return(1);" ); return(1); } error_code = GetLastError(); _info ( 1, "Ошибка Trailing Stop!!!", 1 ); Processing_Error ( error_code ); Sleep(10000); } // Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - return(-1);" ); return(-1); } } } //Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - return(0);" ); return(0); } ///////////////////////////////////////////////////////////////////////////////// /**/ int _BreakEven ( int _OrderTicket, int BreakEven_After, color _Color = CLR_NONE ) ///////////////////////////////////////////////////////////////////////////////// // Автостоп в безубыток + вывод информации // При успешном смещёнии возвращает "1", при отстутствии необходимости - "0", при ошибке "-1", при ошибке № ордера, возвращает "-2" ///////////////////////////////////////////////////////////////////////////////// { // Print( "_BreakEven ( ", _OrderTicket, ", ", BreakEven_After, " ) - loaded..." ); if ( BreakEven_After <= 0 ) { // Print( "_BreakEven ( ", _OrderTicket, ", ", BreakEven_After, " ) - return(0);" ); return(0); } if ( OrderSelect( _OrderTicket, SELECT_BY_TICKET ) == false ) { // Print( "_BreakEven ( ", _OrderTicket, ", ", BreakEven_After, " ) - return(-2);" ); return(-2); } string _Symbol = OrderSymbol(); int _OrderType = OrderType(); double point = MarketInfo ( _Symbol, MODE_POINT ); int digits = MarketInfo( _Symbol, MODE_DIGITS ); double bid = NormalizeDouble( MarketInfo ( _Symbol, MODE_BID ), digits ); double ask = NormalizeDouble( MarketInfo ( _Symbol, MODE_ASK ), digits ); double orderopenprice = NormalizeDouble ( OrderOpenPrice(), digits ); double orderstoploss = NormalizeDouble ( OrderStopLoss(), digits ); double ordertakeprofit = NormalizeDouble ( OrderTakeProfit(), digits ); datetime orderexpiration = OrderExpiration(); double NewStopLoss; string _OrderType_str = _OrderType_str ( _OrderType ); if ( _Color <= 0 ) { _Color = OrderSellColor; if ( _OrderType == OP_BUY || _OrderType == OP_BUYLIMIT || _OrderType == OP_BUYSTOP ) { _Color = OrderBuyColor; } } if ( _OrderType == OP_BUY ) { NewStopLoss = bid - BreakEven_After * point; _Color = GlobalVariableGet( "OrderBuyColor" ); if ( ( bid - orderopenprice ) >= ( BreakEven_After * point ) ) { if ( orderstoploss <= 0 || orderstoploss < NewStopLoss ) { _info ( 1, "Break Even для позиции № " + _OrderTicket + ", " + _OrderType_str + "..." ); _info ( 2, "New Stop Loss = " + DoubleToStr( NewStopLoss, digits ) ); _info ( 3, "" ); _info ( 4, "" ); for ( int x = 0; x < 1; x ++ ) { if ( OrderSelect( _OrderTicket, SELECT_BY_TICKET ) == false ) { // Print( "_BreakEven ( ", _OrderTicket, ", ", BreakEven_After, " ) - return(-2);" ); return(-2); } while ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) < 30 ) { _info ( 4, "Пауза между торговыми операциями. Осталось " + DoubleToStr( 30 - ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) ), 0 ) + " сек.", 0, 0 ); Sleep(1000); } if ( !IsTradeAllowed() ) { Sleep(3000); if ( !IsTradeAllowed() ) { _info ( 4, "IsTradeAllowed = false!!!", 1 ); return(0); } } int ordermodify = OrderModify( _OrderTicket, orderopenprice, NewStopLoss, ordertakeprofit, orderexpiration, _Color ); GlobalVariableSet ( "LastTradeTime", LocalTime() ); if ( ordermodify > 0 ) { _info ( 3, "Успешно..." ); // Print( "_BreakEven ( ", _OrderTicket, ", ", BreakEven_After, " ) - return(1);" ); return(1); } int error_code = GetLastError(); _info ( 1, "Ошибка BreakEven!!!", 1 ); Processing_Error ( error_code ); Sleep(10000); } // Print( "_BreakEven ( ", _OrderTicket, ", ", BreakEven_After, " ) - return(-1);" ); return(-1); } } } if ( _OrderType == OP_SELL ) { NewStopLoss = ask + BreakEven_After * point; if ( ( orderopenprice - ask ) >= ( BreakEven_After * point ) ) { if ( orderstoploss <= 0 || orderstoploss > NewStopLoss ) { _info ( 1, "Break Even для позиции № " + _OrderTicket + ", " + _OrderType_str + "..." ); _info ( 2, "New Stop Loss = " + DoubleToStr( NewStopLoss, digits ) ); _info ( 3, "" ); _info ( 4, "" ); for ( x = 0; x < 1; x ++ ) { if ( OrderSelect( _OrderTicket, SELECT_BY_TICKET ) == false ) { // Print( "_BreakEven ( ", _OrderTicket, ", ", BreakEven_After, " ) - return(-2);" ); return(-2); } while ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) < 30 ) { _info ( 4, "Пауза между торговыми операциями. Осталось " + DoubleToStr( 30 - ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) ), 0 ) + " сек.", 0, 0 ); Sleep(1000); } if ( !IsTradeAllowed() ) { Sleep(3000); if ( !IsTradeAllowed() ) { _info ( 4, "IsTradeAllowed = false!!!", 1 ); return(0); } } ordermodify = OrderModify( _OrderTicket, orderopenprice, NewStopLoss, ordertakeprofit, orderexpiration, _Color ); GlobalVariableSet ( "LastTradeTime", LocalTime() ); if ( ordermodify > 0 ) { _info ( 3, "Успешно..." ); // Print( "_BreakEven ( ", _OrderTicket, ", ", BreakEven_After, " ) - return(1);" ); return(1); } error_code = GetLastError(); _info ( 1, "Ошибка BreakEven!!!", 1 ); Processing_Error ( error_code ); Sleep(10000); } // Print( "_BreakEven ( ", _OrderTicket, ", ", BreakEven_After, " ) - return(-1);" ); return(-1); } } } //Print( "_BreakEven ( ", _OrderTicket, ", ", BreakEven_After, " ) - return(0);" ); return(0); } ///////////////////////////////////////////////////////////////////////////////// /**/ int _OrderCheck ( string _Symbol, int _OrderType, double _Volume, double _OpenPrice, double _StopLoss, double _TakeProfit, datetime _Expiration ) ///////////////////////////////////////////////////////////////////////////////// // проверяет растояния OP,SL,TP, объём и время истечения для ф-ций _OrderSend и _OrderModify. // При успешной проверке возвращает "1", при ошибке возвращает "-1" ///////////////////////////////////////////////////////////////////////////////// { //Print( "_OrderCheck( ", _Symbol, ", ", _OrderType, ", ", _Volume, ", ", _OpenPrice, ", ", _StopLoss, ", ", _TakeProfit, ", ", _Expiration, " ) - loaded..." ); int return_tmp; int digits = MarketInfo( _Symbol, MODE_DIGITS ); double ask = NormalizeDouble( MarketInfo( _Symbol, MODE_ASK ), digits ); double bid = NormalizeDouble( MarketInfo( _Symbol, MODE_BID ), digits ); double point = MarketInfo( _Symbol, MODE_POINT ); int stoplevel = MarketInfo( _Symbol, MODE_STOPLEVEL ); string ask_str = DoubleToStr( ask, digits ); string bid_str = DoubleToStr( bid, digits ); string _OpenPrice_str = DoubleToStr( _OpenPrice, digits ); string _StopLoss_str = DoubleToStr( _StopLoss, digits ); string _TakeProfit_str = DoubleToStr( _TakeProfit, digits ); string _Expiration_str = TimeToStr( _Expiration ); // _OrderType должен быть от 0 до 5 if ( _OrderType < 0 || _OrderType > 5 ) { _info ( 1, "Invalid OrderType ( " + _OrderType + " )!!!", 1 ); return_tmp = -1; } if ( _OrderType == OP_BUY || _OrderType == OP_BUYLIMIT || _OrderType == OP_BUYSTOP ) { // - OP_BUY if ( _OrderType == OP_BUY ) { // - - время истечения - должно быть 0 if ( _Expiration != 0 ) { _info ( 4, "Expiration Time = " + _Expiration_str + " - Для маркет-ордера нельзя установить время истечения!!!", 1 ); return_tmp = -1; } } // - OP_BUYLIMIT ордер if ( _OrderType == OP_BUYLIMIT ) { if ( ask - _OpenPrice < stoplevel * point ) { // - - цена открытия - должна быть ниже Ask if ( ask - _OpenPrice < 0 ) { _info ( 2, "Open Price = " + _OpenPrice_str + " - Неправильно (выше цены - " + ask_str + ")!!!", 1 ); } // - - минимальный отступ - stoplevel else { _info ( 2, "Open Price = " + _OpenPrice_str + " - слишком близко к рынку (" + ask_str + ")!!!", 1 ); } return_tmp = -1; } // - - время истечения (если есть) - должно быть > текущего серверного времени if ( _Expiration > 0 && _Expiration <= CurTime() ) { _info ( 4, "Expiration Time = " + _Expiration_str + " - Время истечения нельзя установить в прошлом!!!", 1 ); return_tmp = -1; } } // - OP_BUYSTOP ордер if ( _OrderType == OP_BUYSTOP ) { // - - цена открытия - должна быть выше Ask if ( _OpenPrice - ask < stoplevel * point ) { if ( _OpenPrice - ask < 0 ) { _info ( 2, "Open Price = " + _OpenPrice_str + " - Неправильно (ниже цены - " + ask_str + ")!!!", 1 ); } // - - минимальный отступ - stoplevel else { _info ( 2, "Open Price = " + _OpenPrice_str + " - слишком близко к рынку (" + ask_str + ")!!!", 1 ); } return_tmp = -1; } // - - время истечения (если есть) - должно быть > текущего серверного времени if ( _Expiration > 0 && _Expiration <= CurTime() ) { _info ( 4, "Expiration Time = " + _Expiration_str + " - Время истечения нельзя установить в прошлом!!!", 1 ); return_tmp = -1; } } // Проверки всех "длинных" ордеров/позиций // - _StopLoss (если есть) должен быть ниже _OpenPrice if ( _StopLoss > 0 && ( _OpenPrice - _StopLoss ) / point < stoplevel ) { if ( ( _OpenPrice - _StopLoss ) / point < 0 ) { _info ( 3, "Stop Loss = " + _StopLoss_str + " - Неправильно (выше цены - " + _OpenPrice_str + ")!!!", 1 ); } // - - минимальный отступ - stoplevel else { _info ( 3, "Stop Loss = " + _StopLoss_str + " - слишком близко (" + _OpenPrice_str + ")!!!", 1 ); } return_tmp = -1; } // - _TakeProfit (если есть) должен быть выше _OpenPrice if ( _TakeProfit > 0 && ( _TakeProfit - _OpenPrice ) / point < stoplevel ) { if ( ( _TakeProfit - _OpenPrice ) / point < 0 ) { _info ( 4, "Take Profit = " + _TakeProfit_str + " - Неправильно (ниже цены - " + _OpenPrice_str + ")!!!", 1 ); } // - - минимальный отступ - stoplevel else { _info ( 4, "Take Profit = " + _TakeProfit_str + " - слишком близко (" + _OpenPrice_str + ")!!!", 1 ); } return_tmp = -1; } } if ( _OrderType == OP_SELL || _OrderType == OP_SELLLIMIT || _OrderType == OP_SELLSTOP ) { // - OP_SELL if ( _OrderType == OP_SELL ) { // - - время истечения - должно быть 0 if ( _Expiration > 0 ) { _info ( 4, "Expiration Time = " + _Expiration_str + " - Для маркет-ордера нельзя установить время истечения!!!", 1 ); return_tmp = -1; } } // - OP_SELLLIMIT if ( _OrderType == OP_SELLLIMIT ) { // - - цена открытия - должна быть выше Bid if ( _OpenPrice - bid < stoplevel*point ) { if ( _OpenPrice - bid < 0 ) { _info ( 2, "Open Price = " + _OpenPrice_str + " - Неправильно (ниже цены - " + bid_str + ")!!!", 1 ); } // - - минимальный отступ - stoplevel else { _info ( 2, "Open Price = " + _OpenPrice_str + " - слишком близко к рынку (" + bid_str + ")!!!", 1 ); } return_tmp = -1; } // - - время истечения (если есть) - должно быть > текущего серверного времени if ( _Expiration > 0 && _Expiration <= CurTime() ) { _info ( 4, "Expiration Time = " + _Expiration_str + " - Время истечения нельзя установить в прошлом!!!", 1 ); return_tmp = -1; } } // - OP_SELLSTOP if ( _OrderType == OP_SELLSTOP ) { // - - цена открытия - должна быть ниже Bid if ( bid - _OpenPrice < stoplevel * point ) { if ( bid - _OpenPrice < 0 ) { _info ( 2, "Open Price = " + _OpenPrice_str + " - Неправильно (выше цены - " + bid_str + ")!!!", 1 ); } // - - минимальный отступ - stoplevel else { _info ( 2, "Open Price = " + _OpenPrice_str + " - слишком близко к рынку (" + bid_str + ")!!!", 1 ); } return_tmp = -1; } // - - время истечения (если есть) - должно быть > текущего серверного времени if ( _Expiration > 0 && _Expiration <= CurTime() ) { _info ( 4, "Expiration Time = " + _Expiration_str + " - Время истечения нельзя установить в прошлом!!!", 1 ); return_tmp = -1; } } // Проверки всех "коротких" ордеров/позиций // - _StopLoss (если есть) должен быть выше _OpenPrice if ( _StopLoss > 0 && ( _StopLoss - _OpenPrice ) / point < stoplevel ) { if ( ( _StopLoss - _OpenPrice ) / point < 0 ) { _info ( 3, "Stop Loss = " + _StopLoss_str + " - Неправильно (ниже цены - " + _OpenPrice_str + ")!!!", 1 ); } // - - минимальный отступ - stoplevel else { _info ( 3, "Stop Loss = " + _StopLoss_str + " - слишком близко (" + _OpenPrice_str + ")!!!", 1 ); } return_tmp = -1; } // - _TakeProfit (если есть) должен быть ниже _OpenPrice if ( _TakeProfit > 0 && ( _OpenPrice - _TakeProfit ) / point < stoplevel ) { if ( ( _OpenPrice - _TakeProfit ) / point < 0 ) { _info ( 4, "Take Profit = " + _TakeProfit_str + " - Неправильно (выше цены - " + _OpenPrice_str + ")!!!", 1 ); } // - - минимальный отступ - stoplevel else { _info ( 4, "Take Profit = " + _TakeProfit_str + " - слишком близко (" + _OpenPrice_str + ")!!!", 1 ); } return_tmp = -1; } } // Обьём должен быть больше 0.1 if ( _Volume < 0.1 ) { _info ( 1, "Lots < 0.1 !!!", 1 ); return_tmp = -1; } // если есть хоть одна ошибка, возвращаем -1 if ( return_tmp < 0 ) { // Print( "_OrderCheck( ", _Symbol, ", ", _OrderType, ", ", _Volume, ", ", _OpenPrice, ", ", _StopLoss, ", ", _TakeProfit, ", ", _Expiration, " ) - some error was found. return(-1);" ); return(-1); } // если все проверки прошли успешно, возвращаем 1 //Print( "_OrderCheck( ", _Symbol, ", ", _OrderType, ", ", _Volume, ", ", _OpenPrice, ", ", _StopLoss, ", ", _TakeProfit, ", ", _Expiration, " ) - no errors found. return(1);" ); return(1); } ///////////////////////////////////////////////////////////////////////////////// /**/ string _OrderType_str ( int _OrderType ) ///////////////////////////////////////////////////////////////////////////////// // возвращает OrderType в виде текста ///////////////////////////////////////////////////////////////////////////////// { //Print( "_OrderType_str( ", _OrderType, " ) - loaded..." ); string _OrderType_str; switch ( _OrderType ) { case OP_BUY: _OrderType_str = "Buy"; break; case OP_SELL: _OrderType_str = "Sell"; break; case OP_BUYLIMIT: _OrderType_str = "BuyLimit"; break; case OP_BUYSTOP: _OrderType_str = "BuyStop"; break; case OP_SELLLIMIT: _OrderType_str = "SellLimit"; break; case OP_SELLSTOP: _OrderType_str = "SellStop"; break; } //Print( "_OrderType_str( ", _OrderType, " ) - return( ", _OrderType_str, " );" ); return(_OrderType_str); } ///////////////////////////////////////////////////////////////////////////////// /**/ string TimeFrame_str ( int TimeFrame ) ///////////////////////////////////////////////////////////////////////////////// { string TimeFrame_str; switch ( TimeFrame ) { case PERIOD_MN1: TimeFrame_str = "Monthly"; break; case PERIOD_W1: TimeFrame_str = "Weekly"; break; case PERIOD_D1: TimeFrame_str = "Daily"; break; case PERIOD_H4: TimeFrame_str = "H4"; break; case PERIOD_H1: TimeFrame_str = "H1"; break; case PERIOD_M15: TimeFrame_str = "M15"; break; case PERIOD_M5: TimeFrame_str = "M5"; break; case PERIOD_M1: TimeFrame_str = "M1"; break; } return(TimeFrame_str); } ///////////////////////////////////////////////////////////////////////////////// /**/ void Processing_Error ( int ErrorCode ) ///////////////////////////////////////////////////////////////////////////////// { string ErrorDescription = ErrorDescription( ErrorCode ); int ErrorAction = 0; if ( ErrorCode == 8 || ErrorCode == 64 || ErrorCode == 65 || ErrorCode == 141 ) ErrorAction = 1; string ActionStr = "Эксперт продолжает роботу..."; switch ( ErrorAction ) { case 1: { ActionStr = "Эксперт не будет торговать 5 минут..."; GlobalVariableSet( "LastTradeTime", LocalTime() + 300 ); break; } case 2: { ActionStr = "Эксперт прекращает роботу..."; GlobalVariableSet( ExpertName + " - return!", -ErrorCode ); break; } } _info ( 2, "GetLastError = " + ErrorCode, 1 ); _info ( 3, ErrorDescription, 1 ); _info ( 4, ActionStr, 1 ); string subject = "\"" + ExpertName + "\" Error " + ErrorCode + " (" + ErrorDescription + ") !!!"; string text = "+--------------------Expert-Information----------------------------+\n" + "+ ExpertName = " + ExpertName + "\n" + "+------------------------------------------------------------------+\n" + "\n" + "+--------------------Error--Information----------------------------+\n" + "+ LocalTime = " + TimeToStr( LocalTime(), TIME_DATE | TIME_SECONDS ) + "\n" + "+ GetLastError = " + ErrorCode + "\n" + "+ ErrorDescription = " + ErrorDescription + "\n" + "+ Action = " + ActionStr + "\n" + "+------------------------------------------------------------------+\n" + "\n" + "+--------------------Server-Information----------------------------+\n" + "+ ServerAddress = " + ServerAddress() + "\n" + "+ ServerTime = " + TimeToStr( CurTime(), TIME_DATE | TIME_SECONDS ) + "\n" + "+------------------------------------------------------------------+\n" + "\n" + "+--------------------AccountInformation----------------------------+\n" + "+ AccountNumber = " + AccountNumber() + "\n" + "+ AccountName = " + AccountName() + "\n" + "+ AccountEquity = " + DoubleToStr( AccountEquity(), 2 ) + "\n" + "+ AccountFreeMargin = " + DoubleToStr( AccountFreeMargin(), 2 ) + "\n" + "+ AccountMargin = " + DoubleToStr( AccountMargin(), 2 ) + "\n" + "+ \n" + "+ AccountBalance = " + DoubleToStr( AccountBalance(), 2 ) + "\n" + "+ AccountProfit = " + DoubleToStr( AccountProfit(), 2 ) + "\n" + "+ AccountCredit = " + DoubleToStr( AccountCredit(), 2 ) + "\n" + "+ AccountCurrency = " + AccountCurrency() + "\n" + "+ AccountLeverage = " + AccountLeverage() + "\n" + "+------------------------------------------------------------------+\n"; SendMail( subject, text ); }