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

427 lines
No EOL
14 KiB
MQL5

#ifndef FRAMEWORK_LAYER_ORDER_MQH
#define FRAMEWORK_LAYER_ORDER_MQH
#include "order.mqh"
#include "order_count.mqh"
#include "order_operation.mqh"
#include "order_symbol.mqh"
#include "layer_order_setting.mqh"
#include "layer_order_data.mqh"
list<layer_order_data *> *order_layer_orders;
list<order_symbol *> *order_layer_symbols;
#ifdef FOR_OPTIMIZATION
#define LAYER_ORDER_CHECK_SYMBOL(sym) true
#define LAYER_ORDER_CHECK_MAGIC(mag) true
#else
#define LAYER_ORDER_CHECK_SYMBOL(sym) (kernel_order::symbol() == sym)
#define LAYER_ORDER_CHECK_MAGIC(mag) (kernel_order::magic_number() == mag)
#endif
#define LAYER_ORDER_CHECK_TYPE(order_type, order_stop_type) (kernel_order::type() == order_type || kernel_order::type() == order_stop_type)
class layer_order {
public:
static void init() {
if (!GC_CHECK_PTR(order_layer_orders))
order_layer_orders=NULL;
if (!GC_CHECK_PTR(order_layer_symbols))
order_layer_symbols=NULL;
order_layer_orders = new list<layer_order_data *> ( 2 );
order_layer_orders.add ( new layer_order_data() );
order_layer_orders.add ( new layer_order_data() );
gc::push ( gc_dispose_type_on_end_deinit, order_layer_orders );
}
static order_symbol *get_order_layer_symbol_current_symbol() {
TOOL_CACHED ( order_symbol *,
_order_layer_symbol_current_symbol, {
_order_layer_symbol_current_symbol = order_symbol::create ( Symbol() );
gc::push ( gc_dispose_type_on_end_deinit, _order_layer_symbol_current_symbol );
} );
}
static void push_settings ( layer_order_setting *settings_ptr ) {
get_by_setting ( settings_ptr ).set ( settings_ptr );
if ( settings_ptr.max_trade_pairs != 0
|| settings_ptr.currency_block != 0 ) {
ACTION_ON_NONVALUE_OR_DEFAULT ( order_layer_symbols, {
order_layer_symbols = new list<order_symbol *>();
gc::push ( gc_dispose_type_on_end_deinit, order_layer_symbols );
});
}
}
static void refresh_all() {
get_order_layer_symbol_current_symbol().reset_direction();
ACTION_ON_VALUE_OR_DEFAULT ( order_layer_symbols, order_layer_symbols.clear() );
LIST_FOREACH ( order_layer_orders, layer_order_data *, item, item.reset() );
int magic_number = order_layer_orders.items[0].settings.magic_number;
//#ifdef MQL4
int ordersCount = kernel_order::count();
//#endif
//#ifdef MQL5
// int ordersCount = kernel_order::positions_count();
//#endif
for ( int i = 0; i < ordersCount; i++ ) {
if ( !kernel_order::select_by_index ( i ) ) {
continue;
}
if ( !LAYER_ORDER_CHECK_SYMBOL ( CURRENT_SYMBOL ) ) {
if ( GC_CHECK_PTR ( order_layer_symbols ) ) {
string symbol = kernel_order::symbol();
LIST_FIRST_OR_DEFAULT ( order_layer_symbols, found_symbol, order_symbol *, item, item.full == symbol );
if ( !GC_CHECK_PTR ( found_symbol ) ) {
found_symbol = order_symbol::create ( symbol );
order_layer_symbols.add ( found_symbol );
}
found_symbol.set_contains_direction ( c_order::is_buy_direction ( kernel_order::type() ) );
}
continue;
}
if ( !LAYER_ORDER_CHECK_MAGIC ( magic_number ) ) {
continue;
}
LIST_FOREACH ( order_layer_orders, layer_order_data *, item, {
if ( !LAYER_ORDER_CHECK_TYPE ( item.settings.order_type, item.settings.order_stop_type ) ) {
continue;
}
c_order *for_add = factory_c_order::get();
refresh_order ( for_add );
if ( !GC_CHECK_PTR ( item.min_order )
|| ( !item.is_buy_direction && for_add.open_price < item.min_order.open_price )
|| ( item.is_buy_direction && for_add.open_price > item.min_order.open_price ) ) {
item.min_order = for_add;
}
if ( !GC_CHECK_PTR ( item.max_order )
|| ( !item.is_buy_direction && for_add.open_price > item.max_order.open_price )
|| ( item.is_buy_direction && for_add.open_price < item.max_order.open_price ) ) {
item.max_order = for_add;
}
item.orders.add ( for_add );
item.count.inc_by_type ( for_add.order_type );
ACTION_ON_VALUE_OR_DEFAULT ( order_layer_symbols, get_order_layer_symbol_current_symbol().set_contains_direction ( item.is_buy_direction ) );
break;
} );
}
//#ifdef MQL5
// ordersCount = kernel_order::orders_count();
// for ( int i = 0; i < ordersCount; i++ ) {
// if ( !kernel_order::select_order_by_index ( i ) ) {
// continue;
// }
//
// if ( !LAYER_ORDER_CHECK_SYMBOL ( CURRENT_SYMBOL ) ) {
// if ( GC_CHECK_PTR ( order_layer_symbols ) ) {
// string symbol = kernel_order::symbol();
// LIST_FIRST_OR_DEFAULT ( order_layer_symbols, found_symbol, order_symbol *, item, item.full == symbol );
//
// if ( !GC_CHECK_PTR ( found_symbol ) ) {
// found_symbol = order_symbol::create ( symbol );
// order_layer_symbols.add ( found_symbol );
// }
//
// found_symbol.set_contains_direction ( c_order::is_buy_direction ( kernel_order::type() ) );
// }
//
// continue;
// }
//
// if ( !LAYER_ORDER_CHECK_MAGIC ( magic_number ) ) {
// continue;
// }
//
// LIST_FOREACH ( order_layer_orders, layer_order_data *, item, {
// if ( !LAYER_ORDER_CHECK_TYPE ( item.settings.order_type, item.settings.order_stop_type ) ) {
// continue;
// }
//
// c_order *for_add = factory_c_order::get();
// refresh_order ( for_add );
//
// if ( !GC_CHECK_PTR ( item.min_order )
// || ( !item.is_buy_direction && for_add.open_price < item.min_order.open_price )
// || ( item.is_buy_direction && for_add.open_price > item.min_order.open_price ) ) {
// item.min_order = for_add;
// }
//
// if ( !GC_CHECK_PTR ( item.max_order )
// || ( !item.is_buy_direction && for_add.open_price > item.max_order.open_price )
// || ( item.is_buy_direction && for_add.open_price < item.max_order.open_price ) ) {
// item.max_order = for_add;
// }
//
// item.orders.add ( for_add );
// item.count.inc_by_type ( for_add.order_type );
//
// ACTION_ON_VALUE_OR_DEFAULT ( order_layer_symbols, get_order_layer_symbol_current_symbol().set_contains_direction ( item.is_buy_direction ) );
// break;
// } );
// }
//#endif
}
// Вызывает после удаление ордеров надо бы как то это обыграть
static void refresh ( layer_order_setting *settings_ptr ) {
layer_order_data *pair = get_by_setting ( settings_ptr );
pair.orders.clear_without_dispoce();
pair.count.clear();
int ordersCount = kernel_order::count();
for ( int i = 0; i < ordersCount; i++ ) {
if ( !kernel_order::select_by_index ( i )
|| !LAYER_ORDER_CHECK_SYMBOL ( CURRENT_SYMBOL )
|| !LAYER_ORDER_CHECK_MAGIC ( pair.settings.magic_number )
|| !LAYER_ORDER_CHECK_TYPE ( pair.settings.order_type, pair.settings.order_stop_type ) ) {
continue;
}
c_order *for_add = factory_c_order::get();
refresh_order ( for_add );
pair.orders.add ( for_add );
pair.count.inc_by_type ( for_add.order_type );
}
}
static void push ( layer_order_setting *settings_ptr, TICKET_TYPE ticket ) {
bool t = !kernel_order::select_by_ticket ( ticket );
if ( /*!kernel_order::select_by_ticket ( ticket )*/ t ) {
return;
}
layer_order_data *collection = get_by_setting ( settings_ptr );
c_order *for_add = factory_c_order::get();
refresh_order ( for_add );
for_add.lvl = collection.orders.count + 1;
collection.orders.add ( for_add );
collection.max_order = for_add;
}
static void refresh ( layer_order_setting *settings_ptr, TICKET_TYPE ticket ) {
if ( !kernel_order::select_by_ticket ( ticket ) ) {
return;
}
list<c_order *> *orders = get ( settings_ptr );
LIST_FIRST_OR_DEFAULT ( orders, result, c_order *, item, item.ticket == ticket );
ACTION_ON_VALUE_OR_DEFAULT ( result, refresh_order ( result ) );
}
static list<c_order *> *get ( layer_order_setting *settings_ptr ) {
layer_order_data *collection = get_by_setting ( settings_ptr );
if ( !collection.is_sorted ) {
collection.is_sorted = true;
LIST_SORT_BUBBLE ( collection.orders,
open_price,
!collection.is_buy_direction );
LIST_FOREACH2 ( collection.orders,
c_order *,
item,
item.lvl = i_kdaskdgfgf + 1 );
}
return GET_VALUE_OR_DEFAULT ( collection, collection.orders );
}
static order_count_t *get_count ( layer_order_setting *settings_ptr ) {
layer_order_data *collection = get_by_setting ( settings_ptr );
return GET_VALUE_OR_DEFAULT ( collection, collection.count );
}
static c_order *get_min ( layer_order_setting *settings_ptr ) {
layer_order_data *collection = get_by_setting ( settings_ptr );
return GET_VALUE_OR_DEFAULT ( collection, collection.min_order );
}
static c_order *get_max ( layer_order_setting *settings_ptr ) {
layer_order_data *collection = get_by_setting ( settings_ptr );
return GET_VALUE_OR_DEFAULT ( collection, collection.max_order );
}
static int get_pair_count() {
return GET_VALUE_OR_MANUAL ( order_layer_symbols, order_layer_symbols.count, 0 );
}
static int get_base_count ( bool is_buy_direction ) {
if ( !GC_CHECK_PTR ( order_layer_symbols ) ) {
return 0;
}
order_symbol *check_symbol = get_order_layer_symbol_current_symbol();
LIST_COUNT ( order_layer_symbols,
result,
order_symbol *,
item,
item.check_base ( is_buy_direction, check_symbol ) );
return result;
}
static int get_profit_count ( bool is_buy_direction ) {
if ( !GC_CHECK_PTR ( order_layer_symbols ) ) {
return 0;
}
order_symbol *check_symbol = get_order_layer_symbol_current_symbol();
LIST_COUNT ( order_layer_symbols,
result,
order_symbol *,
item,
item.check_profit ( is_buy_direction, check_symbol ) );
return result;
}
static c_order *get_history_last_order ( layer_order_setting *settings_ptr ) {
layer_order_data *pair = get_by_setting ( settings_ptr );
for ( int i = kernel_order::count_history() - 1; i >= 0; i-- ) {
if ( !kernel_order::select_by_index_history ( i )
|| !LAYER_ORDER_CHECK_SYMBOL ( CURRENT_SYMBOL )
|| !LAYER_ORDER_CHECK_MAGIC ( pair.settings.magic_number )
|| !LAYER_ORDER_CHECK_TYPE ( pair.settings.order_type, pair.settings.order_stop_type ) ) {
continue;
}
c_order *result = factory_c_order::get();
refresh_order ( result );
return result;
}
return NULL;
}
static bool close_all ( int magic_number,
enum_order_operation_type order_type,
enum_order_operation_type order_stop_type,
int slippage ) {
bool result = false;
color order_color = c_order::get_order_color ( order_type );
for ( int i = 0; i < 3 && !result; i++ ) {
result = close_by_market ( magic_number,
order_type,
order_stop_type,
slippage,
order_color );
}
return result;
}
static bool close_by_market ( int magic_number,
enum_order_operation_type order_type,
enum_order_operation_type order_stop_type,
int slippage,
color order_color ) {
//#ifdef MQL4
for ( int i = kernel_order::count() - 1; i >= 0; i-- ) {
//#endif
//#ifdef MQL5
// for ( int i = kernel_order::positions_count() - 1; i >= 0; i-- ) {
//#endif
if ( !kernel_order::select_by_index ( i ) ) {
return false;
}
if ( !LAYER_ORDER_CHECK_SYMBOL ( CURRENT_SYMBOL )
|| !LAYER_ORDER_CHECK_MAGIC ( magic_number )
|| !LAYER_ORDER_CHECK_TYPE ( order_type, order_stop_type ) ) {
continue;
}
log_info_k ( StringFormat ( SRC_ORDER_TRY_CLOSE_ORDER, IntegerToString ( kernel_order::ticket() ) ) );
bool is_close = c_order::is_order_stop ( kernel_order::type() ) ?
kernel_order::delete_stop ( kernel_order::ticket(), order_color ) :
kernel_order::close ( kernel_order::ticket(),
kernel_order::lots(),
layer_market::price_close ( kernel_order::type() ),
slippage,
order_color );
if ( !is_close ) {
log_info_k ( SRC_ORDER_FAIL_CLOSE_ORDER );
return false;
}
}
//#ifdef MQL5
// for ( int i = kernel_order::orders_count() - 1; i >= 0; i-- ) {
// if ( !kernel_order::select_order_by_index ( i ) ) {
// return false;
// }
//
// if ( !LAYER_ORDER_CHECK_SYMBOL ( CURRENT_SYMBOL )
// || !LAYER_ORDER_CHECK_MAGIC ( magic_number )
// || !LAYER_ORDER_CHECK_TYPE ( order_type, order_stop_type ) ) {
// continue;
// }
//
// log_info_k ( StringFormat ( SRC_ORDER_TRY_CLOSE_ORDER, IntegerToString ( kernel_order::ticket() ) ) );
//
//// bool is_close = kernel_order::delete_stop ( kernel_order::ticket(), order_color );
// bool is_close = c_order::is_order_stop ( kernel_order::type() ) ?
// kernel_order::delete_stop ( kernel_order::ticket(), order_color ) :
// kernel_order::close ( kernel_order::ticket(),
// kernel_order::lots(),
// layer_market::price_close ( kernel_order::type() ),
// slippage,
// order_color );
//
// if ( !is_close ) {
// log_info_k ( SRC_ORDER_FAIL_CLOSE_ORDER );
// return false;
// }
// }
//#endif
return true;
}
static list<layer_order_data *> *get_all() {
return order_layer_orders;
}
static layer_order_data *get_by_setting ( layer_order_setting *settings_ptr ) {
return order_layer_orders.items[settings_ptr.order_type == order_operation_buy ? 0 : 1];
}
//private:
static void refresh_order ( c_order *value ) {
value.symbol = kernel_order::symbol();
value.magic_number = kernel_order::magic_number();
value.order_type = kernel_order::type();
value.ticket = kernel_order::ticket();
value.lot = kernel_order::lots();
value.open_price = kernel_order::open_price();
value.stop_loss = kernel_order::stop_loss();
value.take_profit = kernel_order::take_profit();
value.commission = kernel_order::commission();
value.swap = kernel_order::swap();
value.open_time = kernel_order::open_time();
value.close_time = kernel_order::close_time();
}
};
#endif