446 lines
No EOL
15 KiB
MQL5
446 lines
No EOL
15 KiB
MQL5
#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 |