#ifndef FRAMEWORK_KERNEL_ORDER_MQH #define FRAMEWORK_KERNEL_ORDER_MQH 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; } } return true; } static bool CheckStops( double price, double min_dev) { if ( price == 0 ) return true; MqlTick m_tick; 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() { return OrdersTotal(); } static int count_history() { return OrdersHistoryTotal(); } static double get_profit(bool is_buy) { //double profit =0; //OrderCalcProfit(is_buy?ORDER_TYPE_BUY:ORDER_TYPE_SELL,CURRENT_SYMBOL, // OrderGetDouble(ORDER_VOLUME_CURRENT), // OrderGetDouble(ORDER_PRICE_OPEN), // SymbolInfoDouble(CURRENT_SYMBOL,is_buy?SYMBOL_BID:SYMBOL_ASK)), // profit); //return profit; return OrderProfit(); } static bool select_by_index ( TICKET_TYPE tiket ) { return OrderSelect ( tiket, SELECT_BY_POS, MODE_TRADES ); } static bool select_by_ticket ( TICKET_TYPE tiket ) { return OrderSelect ( tiket, SELECT_BY_TICKET, MODE_TRADES ); } static bool select_by_index_history ( TICKET_TYPE tiket ) { return OrderSelect ( tiket, SELECT_BY_POS, MODE_HISTORY ); } static bool select_by_ticket_history ( TICKET_TYPE tiket ) { return OrderSelect ( tiket, SELECT_BY_TICKET, MODE_HISTORY ); } static TICKET_TYPE 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)) return false; return OrderSend ( CURRENT_SYMBOL, convert_order_operation_type ( order_type ), lot, NormalizeDouble(price,kernel_account::digits()), slippage, 0, 0, comment, magic_number, 0, col ); } static TICKET_TYPE 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)) return false; if((convert_order_operation_type ( order_stop_type ) == OP_BUYSTOP) && (CP(price) <= (kernel_market::price_buy(CURRENT_SYMBOL)+kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL)))) return(false); if((convert_order_operation_type ( order_stop_type ) == OP_SELLSTOP) && (CP(price) >= (kernel_market::price_sell(CURRENT_SYMBOL)-kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL)))) return(false); return OrderSend ( CURRENT_SYMBOL, convert_order_operation_type ( order_stop_type ), lot, NormalizeDouble(price,kernel_account::digits()), 0, 0, 0, comment, magic_number, 0, col ); } static bool set_price ( TICKET_TYPE ticket, double price, color order_color ) { double sl, tp; //Print("Set Price"); if ( !select_by_ticket ( ticket ) ) { return false; } if ( layer::correct_price ( price ) == OrderOpenPrice() ) { return true; } sl = OrderStopLoss() + (price - OrderOpenPrice()); tp = OrderTakeProfit() + (price - OrderOpenPrice()); //Print("\n\t Price: ", price, // "\n MarketPrice: ", kernel_market::price_buy(CURRENT_SYMBOL), // "\n OrderType: ",OrderType(), // "\n OrderPrice: ", OrderOpenPrice(), // "\n SL: ", sl, // "\n TP: ", tp // ); if(!CheckPrice(convert_to_order_operation_type(OrderType()), price, 0.2)) return false; if((OrderType() == OP_BUYSTOP) && (CP(price) <= (kernel_market::price_buy(CURRENT_SYMBOL)+kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL)))) { send_operation_to_log("Send stop ",ticket, convert_to_order_operation_type(OrderType()), price, 0, 0, __FUNCTION__); return(false); } if((OrderType() == OP_SELLSTOP) && (CP(price) >= (kernel_market::price_sell(CURRENT_SYMBOL)-kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL)))) { send_operation_to_log("Send stop ",ticket, convert_to_order_operation_type(OrderType()), price, 0, 0, __FUNCTION__); return(false); } return OrderModify ( ticket, NormalizeDouble(price,kernel_account::digits()), 0, //sl, //OrderStopLoss(), 0, //tp, //OrderTakeProfit(), 0, order_color ); } static bool delete_stop ( TICKET_TYPE ticket, color order_color ) { return select_by_ticket ( ticket ) && OrderDelete ( ticket, order_color ); } static bool close ( TICKET_TYPE ticket, double lot, double price_close, int slippage, color order_color ) { return select_by_ticket ( ticket ) && OrderClose ( ticket, lot, price_close, slippage, order_color ); } static bool set_tp ( int magic_number, TICKET_TYPE ticket, double tp ) { //Print("Set TP"); if (!CheckStops(tp, 0.2)) return false; if(!select_by_ticket ( ticket )) return(false); if ( CP(layer::correct_price ( tp )) == OrderTakeProfit() ) { return true; } if(((OrderType() == OP_BUY)) && (CP(tp) <= (kernel_market::price_sell(CURRENT_SYMBOL)+kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL)))) { send_operation_to_log("Set TP ",ticket, convert_to_order_operation_type(OrderType()), kernel_market::price_sell(CURRENT_SYMBOL)+kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL), 0, tp, __FUNCTION__); return(false); } if(((OrderType() == OP_SELL)) && (CP(tp) >= (kernel_market::price_buy(CURRENT_SYMBOL)-kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL)))) { send_operation_to_log("Set TP ",ticket, convert_to_order_operation_type(OrderType()), kernel_market::price_buy(CURRENT_SYMBOL)-kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL), 0, tp, __FUNCTION__); return(false); } return OrderModify ( ticket, OrderOpenPrice(), 0, NormalizeDouble(tp, kernel_account::digits()), 0, Yellow ); } static bool set_sl_tp ( TICKET_TYPE ticket, double sl, double tp ) { //return if(!CheckStops(tp,0.2)||!CheckStops(sl,0.2)) return false; if (!select_by_ticket ( ticket )) return false; if ( (CP(layer::correct_price ( tp )) == OrderTakeProfit()) &&(CP(layer::correct_price ( sl )) == OrderStopLoss()) ) { return true; } if((OrderType() == OP_BUY) && (CP(tp) <= (kernel_market::price_buy(CURRENT_SYMBOL)+kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL)))) { send_operation_to_log("Set SL TP ",ticket, convert_to_order_operation_type(OrderType()), kernel_market::price_sell(CURRENT_SYMBOL)+kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL), sl, tp, __FUNCTION__); return(false); } if((OrderType() == OP_SELL) && (CP(tp) >= (kernel_market::price_sell(CURRENT_SYMBOL)-kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL)))) { send_operation_to_log("Set SL TP ",ticket, convert_to_order_operation_type(OrderType()), kernel_market::price_sell(CURRENT_SYMBOL)-kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL), sl, tp, __FUNCTION__); return(false); } if(((OrderType() == OP_BUY)) && (CP(sl) >= (kernel_market::price_sell(CURRENT_SYMBOL)-kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL)))) { send_operation_to_log("Set SL TP ",ticket, convert_to_order_operation_type(OrderType()), kernel_market::price_sell(CURRENT_SYMBOL)-kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL), sl, tp, __FUNCTION__); return(false); } if(((OrderType() == OP_SELL)) && (CP(sl) <= (kernel_market::price_buy(CURRENT_SYMBOL)+kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL)))) { send_operation_to_log("Set SL TP ",ticket, convert_to_order_operation_type(OrderType()), kernel_market::price_sell(CURRENT_SYMBOL)+kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL), sl, tp, __FUNCTION__); return(false); } if(!OrderModify ( ticket, OrderOpenPrice(), NormalizeDouble(sl, kernel_account::digits()), NormalizeDouble(tp, kernel_account::digits()), 0, Yellow )){ //Print( // "Order modify Error! ", GetLastError(), // "/n OpenPrice: ", OrderOpenPrice(), // "/n SL: ", sl, // "/n TP: ",tp // ); return false; } return(true); } static bool set_sl_tp_price ( TICKET_TYPE ticket, double sl, double tp, double price ) { //Print("Set SL TP"); //return select_by_ticket ( ticket ) // && OrderModify ( ticket, // price, // sl, // tp, // 0, // Yellow ); if(!select_by_ticket ( ticket )) return(false); if ( (CP(layer::correct_price ( tp )) == OrderTakeProfit()) &&(CP(layer::correct_price ( sl )) == OrderStopLoss()) &&(CP(layer::correct_price ( price )) == OrderOpenPrice()) ) { return true; } if(!CheckPrice(convert_to_order_operation_type(OrderType()), price, 0.2) || !CheckStops(sl,0.2) || !CheckStops(tp,0.2)) return false; if((OrderType() == OP_BUYSTOP) && (CP(price) < (kernel_market::price_buy(CURRENT_SYMBOL)+kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL))) ) { send_operation_to_log("",ticket, convert_to_order_operation_type(OrderType()), price, sl, tp, __FUNCTION__); return(false); } if((OrderType() == OP_SELLSTOP) && (CP(price) > (kernel_market::price_sell(CURRENT_SYMBOL)-kernel_market::stop_level(CURRENT_SYMBOL)*kernel_market::point(CURRENT_SYMBOL)))) //if((OrderType() == OP_SELLSTOP) && //(tp!=0)&&(CP(tp) >= (kernel_market::price_sell(CURRENT_SYMBOL)-kernel_market::stop_level(CURRENT_SYMBOL)))) { send_operation_to_log("",ticket, convert_to_order_operation_type(OrderType()), price, sl, tp, __FUNCTION__); return(false); } //if((OrderType() == OP_BUYSTOP) && (CP(sl) >= (kernel_market::price_sell(CURRENT_SYMBOL)-kernel_market::stop_level(CURRENT_SYMBOL)))) // return(false); //if((OrderType() == OP_SELLSTOP) && (CP(sl) <= (kernel_market::price_buy(CURRENT_SYMBOL)+kernel_market::stop_level(CURRENT_SYMBOL)))) // return(false); //if((OrderType() == OP_BUYSTOP) && (CP(price) <= (kernel_market::price_buy(CURRENT_SYMBOL)+kernel_market::stop_level(CURRENT_SYMBOL)))) // return(false); //if((OrderType() == OP_SELLSTOP) && (CP(price) >= (kernel_market::price_sell(CURRENT_SYMBOL)-kernel_market::stop_level(CURRENT_SYMBOL)))) // return(false); if(!OrderModify ( ticket, NormalizeDouble(price, kernel_account::digits()), NormalizeDouble(sl, kernel_account::digits()), NormalizeDouble(tp, kernel_account::digits()), 0, Yellow )){ //Print( // "Order modify Error! ", GetLastError(), // "/n Price: ", price, // "/n SL: ", sl, // "/n TP: ",tp // ); return(false); }; return(true); } static string symbol() { return OrderSymbol(); } static long magic_number() { return OrderMagicNumber(); } static enum_order_operation_type type() { return convert_to_order_operation_type ( OrderType() ); } static TICKET_TYPE ticket() { return OrderTicket(); } static double lots() { return OrderLots(); } static double open_price() { return OrderOpenPrice(); } static double take_profit() { return OrderTakeProfit(); } static double stop_loss() { return OrderStopLoss(); } static double commission() { return OrderCommission(); } static double swap() { return OrderSwap(); } static datetime open_time() { return OrderOpenTime(); } static datetime close_time() { return OrderCloseTime(); } static int convert_order_operation_type ( enum_order_operation_type type ) { switch ( type ) { case order_operation_buy: return OP_BUY; case order_operation_sell: return OP_SELL; case order_operation_buy_stop: return OP_BUYSTOP; case order_operation_buy_limit: return OP_BUYLIMIT; case order_operation_sell_stop: return OP_SELLSTOP; case order_operatione_sell_limit: return OP_SELLLIMIT; case order_operation_none: default: return -1; } } private: static enum_order_operation_type convert_to_order_operation_type ( int type ) { switch ( type ) { case OP_BUY: return order_operation_buy; case OP_SELL: return order_operation_sell; case OP_BUYSTOP: return order_operation_buy_stop; case OP_BUYLIMIT: return order_operation_buy_limit; case OP_SELLSTOP: return order_operation_sell_stop; case OP_SELLLIMIT: return order_operatione_sell_limit; default: return order_operation_none; } } static void send_operation_to_log(string msg,TICKET_TYPE ticket, enum_order_operation_type type, double price, double sl, double tp, string function) { if (ticket != 0) { if(::OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)){ log_info( StringFormat(msg+"%s ERROR detected! order %i, %s order_price: %.5f, market price: %.5f, SL: %.5f, TP: %.5f", function,ticket,EnumToString(type), price,price,sl,tp));}; }else { log_info( StringFormat(msg+"%s ERROR detected! order %i, %s order_price: %.5f, market price: %.5f, SL: %.5f, TP: %.5f", function,ticket,EnumToString(type), price,price,sl,tp)); } } }; #endif