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

666 lines
No EOL
43 KiB
MQL5

#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