EA-Setka-2/framework/kernel/mql4/kernel_order.mqh
super.admin a4b861dd93 convert
2025-05-30 14:50:44 +02:00

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