#ifndef FRAMEWORK_KERNEL_ORDER_MQH #define FRAMEWORK_KERNEL_ORDER_MQH TICKET_TYPE _kernel_order_current_ticket = -255; class kernel_order { public: static bool CheckPrice(enum_order_operation_type order_type, double price, double min_dev) { MqlTick m_tick; if( SymbolInfoTick(CURRENT_SYMBOL,m_tick)) { switch (order_type) { case order_operation_buy: case order_operation_buy_stop: case order_operation_buy_limit: //--- if( (price - m_tick.bid) < ((m_tick.ask - m_tick.bid) * min_dev)) return false; break; case order_operation_sell: case order_operation_sell_stop: case order_operatione_sell_limit: //--- if( (m_tick.ask - price) < ((m_tick.ask - m_tick.bid) * min_dev)) return false; break; } } else return false; return true; } static bool CheckStops( double price, double min_dev) { MqlTick m_tick; if ( price == 0 ) return true; if( SymbolInfoTick(CURRENT_SYMBOL,m_tick)) { if(price < (m_tick.bid - m_tick.bid*min_dev)||price > (m_tick.bid + m_tick.bid*min_dev)) return false; } else return false; return true; } static int count() { int cnt = 0, res = 0; string symbol = ""; cnt = PositionsTotal(); for ( int i=0; i < cnt; i++ ){ symbol = PositionGetSymbol( i ); if ( symbol != CURRENT_SYMBOL ) continue; res++; }; cnt = OrdersTotal(); for ( int i=0; i < cnt; i++){ ResetLastError(); //--- скопируем в кэш ордер по его номеру в списке TICKET_TYPE ticket=OrderGetTicket(i); if(ticket!=0)// если ордер успешно скопирован в кэш, работаем с ним { double price_open =OrderGetDouble(ORDER_PRICE_OPEN); datetime time_setup=(datetime)OrderGetInteger(ORDER_TIME_SETUP); symbol =OrderGetString(ORDER_SYMBOL); long magic_number =OrderGetInteger(ORDER_MAGIC); if ( symbol != CURRENT_SYMBOL ) continue; res++; }; }; return res; } static int positions_count() { return PositionsTotal(); } static int orders_count() { return OrdersTotal(); } static int count_history() { HistorySelect(0,TimeCurrent()); return HistoryOrdersTotal(); } //--- Не используется. static double get_profit(bool is_buy) { //return PositionGetDouble(POSITION_PROFIT); double profit =0; MqlTick tick; SymbolInfoTick(PositionGetString(POSITION_SYMBOL),tick); bool res = OrderCalcProfit(is_buy?ORDER_TYPE_BUY:ORDER_TYPE_SELL, PositionGetString(POSITION_SYMBOL), PositionGetDouble(POSITION_VOLUME), PositionGetDouble(POSITION_PRICE_OPEN), //tick.last, is_buy?tick.bid:tick.ask, //SymbolInfoDouble(PositionGetString(POSITION_SYMBOL),is_buy?SYMBOL_BID:SYMBOL_ASK), profit); return profit; } //--- static bool select_by_index ( int index ) { // HistorySelect(0,TimeCurrent()); bool res; _kernel_order_current_ticket = PositionGetTicket ( index ); if ( _kernel_order_current_ticket > 0 ) res = PositionSelectByTicket( _kernel_order_current_ticket ); else { _kernel_order_current_ticket = OrderGetTicket( index); res = OrderSelect( _kernel_order_current_ticket ); } return res && (_kernel_order_current_ticket > 0 ); //return ( _kernel_order_current_ticket = PositionGetTicket ( index ) ) > 0 // && PositionSelectByTicket ( position_id() ); } static bool select_order_by_index ( int index ) { // HistorySelect(0,TimeCurrent()); bool res; _kernel_order_current_ticket = OrderGetTicket ( index ); if ( _kernel_order_current_ticket > 0 ) res = OrderSelect( _kernel_order_current_ticket ); else { _kernel_order_current_ticket = OrderGetTicket( index); res = OrderSelect( _kernel_order_current_ticket ); } return res && (_kernel_order_current_ticket > 0 ); //return ( _kernel_order_current_ticket = PositionGetTicket ( index ) ) > 0 // && PositionSelectByTicket ( position_id() ); } static bool select_by_ticket ( TICKET_TYPE ticket ) { // HistorySelect(0,TimeCurrent()); _kernel_order_current_ticket = ticket; Print ( StringFormat ( "Pos %d", position_id() ) ); bool res, pos, ord; pos = PositionSelectByTicket ( _kernel_order_current_ticket); ord = HistoryOrderSelect( _kernel_order_current_ticket ); if ( !pos ) { pos = OrderSelect( _kernel_order_current_ticket ); return pos; } else { res = pos && ord; return res; }; //return ( _kernel_order_current_ticket = ticket ) > 0 // && PositionSelectByTicket ( position_id()) && OrderSelect( ticket ) ); } static bool select_by_index_history ( int index ) { HistorySelect(0,TimeCurrent()); // return ( _kernel_order_current_ticket = HistoryOrderGetTicket ( index ) ) > 0; return ( HistoryOrderSelect(HistoryOrderGetTicket ( index ) ) && HistoryDealSelect( HistoryOrderGetTicket( index ) ) ); } static bool select_by_ticket_history ( TICKET_TYPE ticket ) { // HistorySelect(0,TimeCurrent()); //return HistoryOrderSelect ( _kernel_order_current_ticket = ticket ); return HistoryOrderSelect ( _kernel_order_current_ticket = ticket ) && HistoryDealSelect( _kernel_order_current_ticket ); } static ulong send ( int magic_number, enum_order_operation_type order_type, double price, double lot, int slippage, string comment, color col ) { if(CheckPrice(order_type,price, 0.2)) { Print( "Order SEND reqest error price too close" ); return false; } MqlTradeRequest request = { 0 }; request.action = TRADE_ACTION_DEAL; request.magic = magic_number; request.order = 0; request.symbol = CURRENT_SYMBOL; request.volume = lot; request.price = NormalizeDouble(price,_Digits); request.stoplimit = 0.0; request.sl = 0.0; request.tp = 0.0; request.deviation = slippage; request.type = convert_order_operation_type ( order_type ); request.type_filling = ORDER_FILLING_FOK; request.type_time = ORDER_TIME_GTC; request.expiration = 0; request.comment = comment; request.position = 0; request.position_by = 0; MqlTradeCheckResult check_result= {0}; if(!OrderCheck(request,check_result)){ Print( "Order SEND reqest error ",check_result.retcode,", ",check_result.comment); return(false); } MqlTradeResult result = { 0 }; if ( OrderSend ( request, result ) ) { if ( result.retcode == TRADE_RETCODE_DONE ) { return result.order; } Print ( StringFormat ( "RetCode %d", result.retcode ) ); } return -1; } static ulong send_stop ( int magic_number, enum_order_operation_type order_stop_type, double price, double lot, string comment, color col ) { if(CheckPrice(order_stop_type,price, 0.2)) { Print( "Order SEND reqest error price too close" ); return false; } MqlTradeRequest request = { 0 }; request.action = TRADE_ACTION_PENDING; request.magic = magic_number; request.order = 0; request.symbol = CURRENT_SYMBOL; request.volume = lot; request.price = NormalizeDouble(price, _Digits); request.stoplimit = price; request.sl = 0.0; request.tp = 0.0; //order_operation_buy_stop = 253, //order_operation_buy_limit = 252, //order_operation_sell_stop = 251, //order_operatione_sell_limit = 250 // request.type =ORDER_TYPE_BUY_STOP; request.type_filling = ORDER_FILLING_FOK; request.type_time = ORDER_TIME_GTC; request.expiration = 0; request.comment = comment; request.position = 0; request.position_by = 0; request.type = convert_order_operation_type ( order_stop_type ); MqlTradeCheckResult check_result= {0}; if(!OrderCheck(request,check_result)){ Print( "Send STOP reqest error ",check_result.retcode,", ",check_result.comment); return(false); } MqlTradeResult result = { 0 }; if ( OrderSend ( request, result ) ) { if ( result.retcode == TRADE_RETCODE_DONE ) { return result.order; } Print ( StringFormat ( "RetCode %d", result.retcode ) ); } return -1; } static bool set_price ( TICKET_TYPE ticket, double price, color order_color ) { //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ if ( !select_by_ticket ( ticket ) ) { // if (HistoryOrderSelect( ticket )) return false; return false; } if ( layer::correct_price ( price ) == OrderGetDouble( ORDER_PRICE_OPEN) ) { return true; } //return OrderModify ( ticket, // price, // OrderStopLoss(), // OrderTakeProfit(), // 0, // order_color ); MqlTradeRequest request = { 0 }; request.action = TRADE_ACTION_MODIFY; request.order = ticket; request.symbol = CURRENT_SYMBOL; request.volume = OrderGetDouble(ORDER_VOLUME_INITIAL); request.price = layer::correct_price ( price ); request.stoplimit = 0.0; request.sl = 0.0; request.tp = 0.0; request.type_filling = ORDER_FILLING_FOK; request.type_time = ORDER_TIME_GTC; request.expiration = 0; request.position = 0; request.position_by = 0; MqlTradeCheckResult check_result= {0}; if(!OrderCheck(request,check_result)){ Print( "Set PRICE reqest error ",check_result.retcode,", ",check_result.comment); return(false); } MqlTradeResult result = { 0 }; if ( OrderSend ( request, result ) ) { if ( result.retcode == TRADE_RETCODE_DONE ) { return (bool)result.order; } Print ( StringFormat ( "RetCode %d", result.retcode ) ); } //--- return false; } static bool delete_stop ( TICKET_TYPE ticket, color order_color ) { MqlTradeRequest request = { 0 }; request.action = TRADE_ACTION_REMOVE; request.order = ticket; MqlTradeResult result = { 0 }; bool res = OrderSend ( request, result ); return res; // return OrderSend ( request, result ); } static bool close ( TICKET_TYPE ticket, double lot, double price_close, double slippage, color order_color ) { if ( !select_by_ticket ( ticket ) ) { // if (HistoryOrderSelect( ticket )) return false; return false; } double volume = PositionGetDouble( POSITION_VOLUME ) ; MqlTradeRequest request = { 0 }; MqlTradeResult result = { 0 }; request.action = TRADE_ACTION_REMOVE; request.order = ticket; ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); // тип позиции //--- обнуление значений запроса и результата ZeroMemory(request); ZeroMemory(result); //--- установка параметров операции request.action = TRADE_ACTION_DEAL; // тип торговой операции request.position = ticket; // тикет позиции request.symbol = CURRENT_SYMBOL; // символ request.volume = volume; // объем позиции request.deviation= (ulong)slippage; // допустимое отклонение от цены request.magic = PositionGetInteger( POSITION_MAGIC ); // MagicNumber позиции //--- установка цены и типа ордера в зависимости от типа позиции if(type==POSITION_TYPE_BUY) { request.price=SymbolInfoDouble( CURRENT_SYMBOL, SYMBOL_BID ); request.type =ORDER_TYPE_SELL; } else { request.price=SymbolInfoDouble( CURRENT_SYMBOL,SYMBOL_ASK ); request.type =ORDER_TYPE_BUY; } bool res = OrderSend ( request, result ); return res; // return OrderSend ( request, result ); // return false; } static bool set_tp ( int magic_number, TICKET_TYPE ticket, double tp ) { MqlTradeRequest request = { 0 }; // if ( !select_by_ticket ( ticket ) ) { // if (HistoryOrderSelect( ticket )) return false; // return false; // } if (!CheckStops(tp,0.2)) return false; if ( PositionSelectByTicket( ticket ) ) { request.action = TRADE_ACTION_SLTP; request.position = ticket; } else if ( OrderSelect( ticket ) ) { request.action = TRADE_ACTION_MODIFY; request.order = ticket; request.price = NormalizeDouble( OrderGetDouble( ORDER_PRICE_OPEN ), _Digits ); }; if ( PositionGetDouble( POSITION_TP ) == tp ) return( true ); // request.action = TRADE_ACTION_SLTP; request.symbol = CURRENT_SYMBOL; // request.order = ticket; //request.tp = tp; request.sl = 0.0; // request.sl = (sl == 0 ? OrderGetDouble(ORDER_SL) : NormalizeDouble( sl, _Digits )); request.tp = NormalizeDouble( tp, _Digits ); //(tp == 0 ? OrderGetDouble(ORDER_TP) : NormalizeDouble( tp, _Digits )); request.magic = magic_number; // request.position = _kernel_order_current_ticket; MqlTradeCheckResult check_result= {0}; if(!OrderCheck(request,check_result)){ Print( "Set TP reqest error ",check_result.retcode,", ",check_result.comment); return(false); } MqlTradeResult result = { 0 }; bool res = OrderSend ( request, result ); if ( result.retcode != TRADE_RETCODE_DONE ) { return false; }; return res; // return OrderSend ( request, result ); } static bool set_sl_tp ( TICKET_TYPE ticket, double sl, double tp ) { MqlTradeRequest request = { 0 }; // if ( !select_by_ticket ( ticket ) ) { //// if (HistoryOrderSelect( ticket )) return false; // return false; // } if (!CheckStops(tp,0.2)||!CheckStops(sl, 0.2)) return false; if ( PositionSelectByTicket( ticket ) ) { request.action = TRADE_ACTION_SLTP; request.position = ticket; } else if ( OrderSelect( ticket ) ) { request.action = TRADE_ACTION_MODIFY; request.order = ticket; request.price = NormalizeDouble( OrderGetDouble( ORDER_PRICE_OPEN ), _Digits ); }; request.sl = sl; request.tp = tp; MqlTradeCheckResult check_result= {0}; if(!OrderCheck(request,check_result)){ Print( "Set SL TP reqest error ",check_result.retcode,", ",check_result.comment); return(false); } MqlTradeResult result = { 0 }; return OrderSend ( request, result ); } static bool set_sl_tp_price ( TICKET_TYPE ticket, double sl, double tp, double price ) { MqlTradeRequest request = { 0 }; // if ( !select_by_ticket ( ticket ) ) { // if (HistoryOrderSelect( ticket )) return false; if ( !OrderSelect ( ticket ) ) { return false; } //double PriceOld = OrderGetDouble( ORDER_PRICE_OPEN ), // PosPrice = PositionGetDouble(POSITION_PRICE_OPEN); if(CheckPrice(convert_to_order_operation_type((ENUM_ORDER_TYPE) OrderGetInteger(ORDER_TYPE)),price, 0.2)) { Print( "Order SET_CL_TP_PRICE reqest error price too close" ); return false; } if (!CheckStops(sl, 0.2)||!CheckStops(tp, 0.2)) return false; request.symbol = Symbol(); request.action = TRADE_ACTION_MODIFY; request.order = ticket; request.price = NormalizeDouble( price, _Digits); request.sl = (sl == 0 ? OrderGetDouble(ORDER_SL) : NormalizeDouble( sl, _Digits )); request.tp = (tp == 0 ? OrderGetDouble(ORDER_TP) : NormalizeDouble( tp, _Digits )); // request.tp = NormalizeDouble( tp, _Digits ); request.deviation = 5; // request.position = _kernel_order_current_ticket; MqlTradeCheckResult check_result= {0}; if(!OrderCheck(request,check_result)){ Print( "Set SL TP PRICE reqest error ",check_result.retcode,", ",check_result.comment); return(false); } MqlTradeResult result = { 0 }; bool res = OrderSend ( request, result ); return res; // return OrderSend ( request, result ); } static string symbol() { if (PositionSelectByTicket( _kernel_order_current_ticket ) ) return PositionGetString( POSITION_SYMBOL ); if ( OrderSelect( _kernel_order_current_ticket )) return OrderGetString( ORDER_SYMBOL ); return HistoryOrderGetString ( _kernel_order_current_ticket, ORDER_SYMBOL ); } static long magic_number() { if (PositionSelectByTicket( _kernel_order_current_ticket ) ) return PositionGetInteger( POSITION_MAGIC ); if ( OrderSelect( _kernel_order_current_ticket )) return OrderGetInteger( ORDER_MAGIC ); return HistoryOrderGetInteger ( _kernel_order_current_ticket, ORDER_MAGIC ); } static enum_order_operation_type type() { if ( PositionSelectByTicket( _kernel_order_current_ticket )) return convert_to_position_operation_type ( ( ENUM_POSITION_TYPE ) PositionGetInteger( POSITION_TYPE ) ); if ( OrderSelect( _kernel_order_current_ticket ) ) return convert_to_order_operation_type ( ( ENUM_ORDER_TYPE ) OrderGetInteger( ORDER_TYPE ) ); return convert_to_order_operation_type ( ( ENUM_ORDER_TYPE ) HistoryOrderGetInteger ( _kernel_order_current_ticket, ORDER_TYPE ) ); } static TICKET_TYPE ticket() { return _kernel_order_current_ticket; } static double lots() { if (PositionSelectByTicket( _kernel_order_current_ticket ) ) return PositionGetDouble( POSITION_VOLUME ); if ( OrderSelect( _kernel_order_current_ticket )) return OrderGetDouble( ORDER_VOLUME_INITIAL ); return HistoryOrderGetDouble ( _kernel_order_current_ticket, ORDER_VOLUME_INITIAL ); } static double open_price() { if (PositionSelectByTicket( _kernel_order_current_ticket ) ) return PositionGetDouble( POSITION_PRICE_OPEN ); if ( OrderSelect( _kernel_order_current_ticket )) return OrderGetDouble( ORDER_PRICE_OPEN ); return HistoryOrderGetDouble ( _kernel_order_current_ticket, ORDER_PRICE_OPEN ); } static double take_profit() { if (PositionSelectByTicket( _kernel_order_current_ticket ) ) return PositionGetDouble( POSITION_TP ); if ( OrderSelect( _kernel_order_current_ticket )) return OrderGetDouble( ORDER_TP ); return HistoryOrderGetDouble ( _kernel_order_current_ticket, ORDER_TP ); } static double stop_loss() { if (PositionSelectByTicket( _kernel_order_current_ticket ) ) return PositionGetDouble( POSITION_SL ); if ( OrderSelect( _kernel_order_current_ticket )) return OrderGetDouble( ORDER_SL ); return HistoryOrderGetDouble ( _kernel_order_current_ticket, ORDER_SL ); } static double commission() { return HistoryDealGetDouble( _kernel_order_current_ticket, DEAL_COMMISSION ); } static double swap() { if (PositionSelectByTicket(_kernel_order_current_ticket)) return PositionGetDouble( POSITION_SWAP ); return HistoryDealGetDouble( _kernel_order_current_ticket, DEAL_SWAP ); } static datetime open_time() { if (PositionSelectByTicket( _kernel_order_current_ticket ) ) return (datetime)PositionGetInteger( POSITION_TIME ); if ( OrderSelect( _kernel_order_current_ticket )) return (datetime)OrderGetInteger( ORDER_TIME_SETUP ); return (datetime)HistoryOrderGetInteger ( _kernel_order_current_ticket, ORDER_TIME_SETUP ); } static datetime close_time() { if ( OrderSelect( _kernel_order_current_ticket )) return (datetime)OrderGetInteger( ORDER_TIME_DONE ); return (datetime)HistoryOrderGetInteger ( _kernel_order_current_ticket, ORDER_TIME_DONE ); } static long position_id() { if ( PositionSelectByTicket( _kernel_order_current_ticket ) ) return PositionGetInteger( POSITION_IDENTIFIER ); if ( HistoryDealSelect( _kernel_order_current_ticket ) ) return HistoryDealGetInteger( _kernel_order_current_ticket, DEAL_POSITION_ID ); return HistoryOrderGetInteger ( _kernel_order_current_ticket, ORDER_POSITION_ID ); } private: static enum_order_operation_type convert_to_order_operation_type ( ENUM_ORDER_TYPE type ) { switch ( type ) { case ORDER_TYPE_BUY: return order_operation_buy; case ORDER_TYPE_SELL: return order_operation_sell; // case POSITION_TYPE_BUY: // return order_operation_buy; // // case POSITION_TYPE_SELL: // return order_operation_sell; case ORDER_TYPE_BUY_STOP: return order_operation_buy_stop; case ORDER_TYPE_BUY_LIMIT: return order_operation_buy_limit; case ORDER_TYPE_SELL_STOP: return order_operation_sell_stop; case ORDER_TYPE_SELL_LIMIT: return order_operatione_sell_limit; default: return order_operation_none; } } static enum_order_operation_type convert_to_position_operation_type ( ENUM_POSITION_TYPE type ) { switch ( type ) { case POSITION_TYPE_BUY: return order_operation_buy; case POSITION_TYPE_SELL: return order_operation_sell; default: return order_operation_none; } } static ENUM_ORDER_TYPE convert_order_operation_type ( enum_order_operation_type type ) { switch ( type ) { case order_operation_buy: return ORDER_TYPE_BUY; case order_operation_sell: return ORDER_TYPE_SELL; case order_operation_buy_stop: return ORDER_TYPE_BUY_STOP; case order_operation_buy_limit: return ORDER_TYPE_BUY_LIMIT; case order_operation_sell_stop: return ORDER_TYPE_SELL_STOP; case order_operatione_sell_limit: return ORDER_TYPE_SELL_LIMIT; case order_operation_none: default: return -1; } } }; #endif