779 lines
No EOL
48 KiB
MQL5
779 lines
No EOL
48 KiB
MQL5
#ifndef SCHEDULER_MQH
|
|
#define SCHEDULER_MQH
|
|
|
|
#define MIN_DATE D'1970.01.01 00:00:00'
|
|
|
|
enum day_of_week_t {
|
|
day_of_week_t_sunday = 0,
|
|
day_of_week_t_monday = 1,
|
|
day_of_week_t_tuesday = 2,
|
|
day_of_week_t_wednesday = 3,
|
|
day_of_week_t_thursday = 4,
|
|
day_of_week_t_friday = 5,
|
|
day_of_week_t_saturday = 6
|
|
};
|
|
|
|
//TODO: почему-то нельзя сделать внутри класса ... блядский mql
|
|
bool scheduler_is_trade_enabled;
|
|
day_of_week_t scheduler_trade_start_day;
|
|
int scheduler_start_hour;
|
|
int scheduler_start_minutes;
|
|
int scheduler_start_total_minutes;
|
|
day_of_week_t scheduler_trade_end_day;
|
|
int scheduler_end_hour;
|
|
int scheduler_end_minutes;
|
|
int scheduler_end_total_minutes;
|
|
|
|
bool scheduler_new_position_pause_enabled;
|
|
datetime scheduler_new_position_pause_start[];
|
|
datetime scheduler_new_position_pause_end[];
|
|
char scheduler_new_position_pause_newyear_day_start;
|
|
char scheduler_new_position_pause_newyear_day_end;
|
|
|
|
bool scheduler_is_trade_pause_enabled;
|
|
datetime scheduler_start_pause[];
|
|
datetime scheduler_end_pause[];
|
|
|
|
bool scheduler_is_intraday_enabled;
|
|
int scheduler_start_intraday_hour[];
|
|
int scheduler_start_intraday_minutes[];
|
|
int scheduler_start_intraday_total_minutes[];
|
|
int scheduler_end_intraday_hour[];
|
|
int scheduler_end_intraday_minutes[];
|
|
int scheduler_end_intraday_total_minutes[];
|
|
|
|
bool scheduler_is_intraday_stop_trade_enabled;
|
|
int scheduler_start_intraday_stop_trade_hour[];
|
|
int scheduler_start_intraday_stop_trade_minutes[];
|
|
int scheduler_start_intraday_stop_trade_total_minutes[];
|
|
int scheduler_end_intraday_stop_trade_hour[];
|
|
int scheduler_end_intraday_stop_trade_minutes[];
|
|
int scheduler_end_intraday_stop_trade_total_minutes[];
|
|
|
|
bool scheduler_close_all_orders_enabled;
|
|
int scheduler_close_all_orders_hour;
|
|
int scheduler_close_all_orders_minute;
|
|
int scheduler_close_all_orders_total_minute;
|
|
int scheduler_close_all_orders_total_minute_with_wait;
|
|
|
|
class scheduler_close_all_orders_locker {
|
|
public:
|
|
layer_order_setting *settings;
|
|
bool lock;
|
|
};
|
|
|
|
list<scheduler_close_all_orders_locker *> *scheduler_close_all_orders_lockers;
|
|
class scheduler {
|
|
private:
|
|
static int get_current_total_minutes() {
|
|
_IN1("");
|
|
TOOL_CACHED_TICK ( int,
|
|
_current_total_minutes,
|
|
_current_total_minutes = 60 * kernel_time::get_hour ( layer::time_current() ) + kernel_time::get_minute ( layer::time_current() ) );
|
|
}
|
|
|
|
public:
|
|
static void set_trade ( day_of_week_t start_day,
|
|
int start_hour,
|
|
int start_minute,
|
|
day_of_week_t end_day,
|
|
int end_hour,
|
|
int end_minute ) {
|
|
_IN1("");
|
|
scheduler_trade_start_day = start_day;
|
|
scheduler_start_hour = start_hour;
|
|
scheduler_start_minutes = start_minute;
|
|
scheduler_start_total_minutes = ( 60 * start_hour ) + start_minute;
|
|
|
|
scheduler_trade_end_day = end_day;
|
|
scheduler_end_hour = end_hour;
|
|
scheduler_end_minutes = end_minute;
|
|
scheduler_end_total_minutes = ( 60 * end_hour ) + end_minute;
|
|
|
|
scheduler_is_trade_enabled = true;
|
|
}
|
|
|
|
static void reset_trade () {
|
|
_IN1("");
|
|
scheduler_is_trade_enabled = false;
|
|
}
|
|
|
|
|
|
#define declare_new_position_pause( number ) \
|
|
datetime start##number, datetime end##number
|
|
#define declare_set_new_position_pause( number ) \
|
|
scheduler_new_position_pause_start[number] = start##number; \
|
|
scheduler_new_position_pause_end[number] = end##number;
|
|
|
|
static void set_new_position_pause ( declare_new_position_pause ( 0 ),
|
|
declare_new_position_pause ( 1 ),
|
|
declare_new_position_pause ( 2 ),
|
|
declare_new_position_pause ( 3 ),
|
|
declare_new_position_pause ( 4 ),
|
|
declare_new_position_pause ( 5 ),
|
|
declare_new_position_pause ( 6 ),
|
|
declare_new_position_pause ( 7 ),
|
|
declare_new_position_pause ( 8 ),
|
|
declare_new_position_pause ( 9 ),
|
|
char new_position_pause_newyear_day_start,
|
|
char new_position_pause_newyear_day_end ) {
|
|
_IN1("");
|
|
ArrayResize ( scheduler_new_position_pause_start, 10 );
|
|
ArrayInitialize ( scheduler_new_position_pause_start, MIN_DATE );
|
|
ArrayResize ( scheduler_new_position_pause_end, 10 );
|
|
ArrayInitialize ( scheduler_new_position_pause_end, MIN_DATE );
|
|
|
|
declare_set_new_position_pause ( 0 );
|
|
declare_set_new_position_pause ( 1 );
|
|
declare_set_new_position_pause ( 2 );
|
|
declare_set_new_position_pause ( 3 );
|
|
declare_set_new_position_pause ( 4 );
|
|
declare_set_new_position_pause ( 5 );
|
|
declare_set_new_position_pause ( 6 );
|
|
declare_set_new_position_pause ( 7 );
|
|
declare_set_new_position_pause ( 8 );
|
|
declare_set_new_position_pause ( 9 );
|
|
|
|
scheduler_new_position_pause_newyear_day_start=new_position_pause_newyear_day_start;
|
|
scheduler_new_position_pause_newyear_day_end=new_position_pause_newyear_day_end;
|
|
|
|
scheduler_new_position_pause_enabled = true;
|
|
}
|
|
|
|
static void reset_new_position_pause () {
|
|
_IN1("");
|
|
scheduler_new_position_pause_enabled = false;
|
|
}
|
|
|
|
#define declare_intraday_range( number ) \
|
|
int start_hour_##number, \
|
|
int start_minute_##number, \
|
|
int end_hour_##number, \
|
|
int end_minute_##number
|
|
#define set_intraday_range( number ) \
|
|
scheduler_start_intraday_hour[number] = start_hour_##number; \
|
|
scheduler_start_intraday_minutes[number] = start_minute_##number; \
|
|
scheduler_start_intraday_total_minutes[number] = ( 60 * start_hour_##number ) + start_minute_##number; \
|
|
scheduler_end_intraday_hour[number] = end_hour_##number; \
|
|
scheduler_end_intraday_minutes[number] = end_minute_##number; \
|
|
scheduler_end_intraday_total_minutes[number] = ( 60 * end_hour_##number ) + end_minute_##number;
|
|
|
|
static void set_intraday ( declare_intraday_range ( 0 ),
|
|
declare_intraday_range ( 1 ),
|
|
declare_intraday_range ( 2 ),
|
|
declare_intraday_range ( 3 ),
|
|
declare_intraday_range ( 4 ),
|
|
declare_intraday_range ( 5 ),
|
|
declare_intraday_range ( 6 ),
|
|
declare_intraday_range ( 7 ),
|
|
declare_intraday_range ( 8 ),
|
|
declare_intraday_range ( 9 ) ) {
|
|
_IN1("");
|
|
ArrayResize ( scheduler_start_intraday_hour, 10 );
|
|
ArrayInitialize ( scheduler_start_intraday_hour, 0 );
|
|
ArrayResize ( scheduler_start_intraday_minutes, 10 );
|
|
ArrayInitialize ( scheduler_start_intraday_minutes, 0 );
|
|
ArrayResize ( scheduler_start_intraday_total_minutes, 10 );
|
|
ArrayInitialize ( scheduler_start_intraday_total_minutes, 0 );
|
|
|
|
ArrayResize ( scheduler_end_intraday_hour, 10 );
|
|
ArrayInitialize ( scheduler_end_intraday_hour, 0 );
|
|
ArrayResize ( scheduler_end_intraday_minutes, 10 );
|
|
ArrayInitialize ( scheduler_end_intraday_minutes, 0 );
|
|
ArrayResize ( scheduler_end_intraday_total_minutes, 10 );
|
|
ArrayInitialize ( scheduler_end_intraday_total_minutes, 0 );
|
|
|
|
set_intraday_range ( 0 );
|
|
set_intraday_range ( 1 );
|
|
set_intraday_range ( 2 );
|
|
set_intraday_range ( 3 );
|
|
set_intraday_range ( 4 );
|
|
set_intraday_range ( 5 );
|
|
set_intraday_range ( 6 );
|
|
set_intraday_range ( 7 );
|
|
set_intraday_range ( 8 );
|
|
set_intraday_range ( 9 );
|
|
|
|
scheduler_is_intraday_enabled = true;
|
|
}
|
|
|
|
static void reset_intraday_stop_trade() {
|
|
_IN1("");
|
|
scheduler_is_intraday_stop_trade_enabled = false;
|
|
}
|
|
|
|
#define declare_trade_pause( number ) \
|
|
datetime start##number, datetime end##number
|
|
#define set_pause( number ) \
|
|
scheduler_start_pause[number] = start##number; \
|
|
scheduler_end_pause[number] = end##number;
|
|
|
|
static void set_trade_pause ( declare_trade_pause ( 0 ),
|
|
declare_trade_pause ( 1 ),
|
|
declare_trade_pause ( 2 ),
|
|
declare_trade_pause ( 3 ),
|
|
declare_trade_pause ( 4 ),
|
|
declare_trade_pause ( 5 ),
|
|
declare_trade_pause ( 6 ),
|
|
declare_trade_pause ( 7 ),
|
|
declare_trade_pause ( 8 ),
|
|
declare_trade_pause ( 9 ) ) {
|
|
_IN1("");
|
|
ArrayResize ( scheduler_start_pause, 10 );
|
|
ArrayInitialize ( scheduler_start_pause, MIN_DATE );
|
|
ArrayResize ( scheduler_end_pause, 10 );
|
|
ArrayInitialize ( scheduler_end_pause, MIN_DATE );
|
|
|
|
set_pause ( 0 );
|
|
set_pause ( 1 );
|
|
set_pause ( 2 );
|
|
set_pause ( 3 );
|
|
set_pause ( 4 );
|
|
set_pause ( 5 );
|
|
set_pause ( 6 );
|
|
set_pause ( 7 );
|
|
set_pause ( 8 );
|
|
set_pause ( 9 );
|
|
|
|
scheduler_is_trade_pause_enabled = true;
|
|
}
|
|
|
|
static void reset_trade_pause () {
|
|
_IN1("");
|
|
scheduler_is_trade_pause_enabled = false;
|
|
}
|
|
|
|
#define declare_intraday_stop_trade_range( number ) \
|
|
int start_hour_##number, \
|
|
int start_minute_##number, \
|
|
int end_hour_##number, \
|
|
int end_minute_##number
|
|
#define set_intraday_stop_trade_range( number ) \
|
|
scheduler_start_intraday_stop_trade_hour[number] = start_hour_##number; \
|
|
scheduler_start_intraday_stop_trade_minutes[number] = start_minute_##number; \
|
|
scheduler_start_intraday_stop_trade_total_minutes[number] = ( 60 * start_hour_##number ) + start_minute_##number; \
|
|
scheduler_end_intraday_stop_trade_hour[number] = end_hour_##number; \
|
|
scheduler_end_intraday_stop_trade_minutes[number] = end_minute_##number; \
|
|
scheduler_end_intraday_stop_trade_total_minutes[number] = ( 60 * end_hour_##number ) + end_minute_##number;
|
|
|
|
static void set_intraday_stop_trade ( declare_intraday_stop_trade_range ( 0 ),
|
|
declare_intraday_stop_trade_range ( 1 ),
|
|
declare_intraday_stop_trade_range ( 2 ),
|
|
declare_intraday_stop_trade_range ( 3 ),
|
|
declare_intraday_stop_trade_range ( 4 ),
|
|
declare_intraday_stop_trade_range ( 5 ),
|
|
declare_intraday_stop_trade_range ( 6 ),
|
|
declare_intraday_stop_trade_range ( 7 ),
|
|
declare_intraday_stop_trade_range ( 8 ),
|
|
declare_intraday_stop_trade_range ( 9 ) ) {
|
|
_IN1("");
|
|
ArrayResize ( scheduler_start_intraday_stop_trade_hour, 10 );
|
|
ArrayInitialize ( scheduler_start_intraday_stop_trade_hour, 0 );
|
|
ArrayResize ( scheduler_start_intraday_stop_trade_minutes, 10 );
|
|
ArrayInitialize ( scheduler_start_intraday_stop_trade_minutes, 0 );
|
|
ArrayResize ( scheduler_start_intraday_stop_trade_total_minutes, 10 );
|
|
ArrayInitialize ( scheduler_start_intraday_stop_trade_total_minutes, 0 );
|
|
|
|
ArrayResize ( scheduler_end_intraday_stop_trade_hour, 10 );
|
|
ArrayInitialize ( scheduler_end_intraday_stop_trade_hour, 0 );
|
|
ArrayResize ( scheduler_end_intraday_stop_trade_minutes, 10 );
|
|
ArrayInitialize ( scheduler_end_intraday_stop_trade_minutes, 0 );
|
|
ArrayResize ( scheduler_end_intraday_stop_trade_total_minutes, 10 );
|
|
ArrayInitialize ( scheduler_end_intraday_stop_trade_total_minutes, 0 );
|
|
|
|
set_intraday_stop_trade_range ( 0 );
|
|
set_intraday_stop_trade_range ( 1 );
|
|
set_intraday_stop_trade_range ( 2 );
|
|
set_intraday_stop_trade_range ( 3 );
|
|
set_intraday_stop_trade_range ( 4 );
|
|
set_intraday_stop_trade_range ( 5 );
|
|
set_intraday_stop_trade_range ( 6 );
|
|
set_intraday_stop_trade_range ( 7 );
|
|
set_intraday_stop_trade_range ( 8 );
|
|
set_intraday_stop_trade_range ( 9 );
|
|
|
|
scheduler_is_intraday_stop_trade_enabled = true;
|
|
}
|
|
|
|
static void reset_intraday () {
|
|
_IN1("");
|
|
scheduler_is_intraday_enabled = false;
|
|
}
|
|
|
|
static void set_close_all_orders ( int hour,
|
|
int minute ) {
|
|
_IN1("");
|
|
scheduler_close_all_orders_hour = hour;
|
|
scheduler_close_all_orders_minute = minute;
|
|
scheduler_close_all_orders_total_minute = ( 60 * hour ) + minute;
|
|
scheduler_close_all_orders_total_minute_with_wait = scheduler_close_all_orders_total_minute + 3;
|
|
|
|
scheduler_close_all_orders_enabled = true;
|
|
|
|
scheduler_close_all_orders_lockers = new list<scheduler_close_all_orders_locker *>();
|
|
gc::push ( gc_dispose_type_on_end_deinit, scheduler_close_all_orders_lockers );
|
|
}
|
|
|
|
static void reset_close_all_orders() {
|
|
_IN1("");
|
|
scheduler_close_all_orders_enabled = false;
|
|
}
|
|
|
|
static bool is_trade_time() {
|
|
_IN1("");
|
|
return pre_check_trade_pause();
|
|
}
|
|
|
|
static bool is_trade_time_for_first_order() {
|
|
_IN1("");
|
|
return pre_check_new_position_pause()
|
|
&& pre_check_trade_on_week()
|
|
&& pre_check_intraday();
|
|
}
|
|
|
|
static bool is_stop_trade_time() {
|
|
_IN1("");
|
|
return pre_check_intraday_stop_trade();
|
|
}
|
|
|
|
static bool is_close_all_orders ( layer_order_setting *settings_ptr ) {
|
|
_IN1("");
|
|
return pre_check_close_all_orders ( settings_ptr );
|
|
}
|
|
|
|
private:
|
|
static bool pre_check_trade_on_week() {
|
|
_IN1("");
|
|
if ( check_trade_on_week() ) {
|
|
_IN2("");
|
|
return true;
|
|
}
|
|
|
|
log_info ( StringFormat ( SRC_SCHEDULER_IS_NOT_TRADE_TIME_ON_WEEK,
|
|
get_day_of_week_str ( scheduler_trade_start_day ),
|
|
scheduler_start_hour,
|
|
scheduler_start_minutes,
|
|
get_day_of_week_str ( scheduler_trade_end_day ),
|
|
scheduler_end_hour,
|
|
scheduler_end_minutes ) );
|
|
return false;
|
|
}
|
|
|
|
static bool check_trade_on_week() {
|
|
_IN1("");
|
|
if ( !scheduler_is_trade_enabled ) {
|
|
_IN2("");
|
|
return true;
|
|
}
|
|
|
|
int day = kernel_time::get_day_of_week();
|
|
|
|
if ( scheduler_trade_start_day > day
|
|
|| scheduler_trade_end_day < day ) {
|
|
_IN2("");
|
|
return false;
|
|
}
|
|
|
|
int total_minutes = get_current_total_minutes();
|
|
|
|
if ( ( scheduler_trade_start_day == day && scheduler_start_total_minutes >= total_minutes )
|
|
|| ( scheduler_trade_end_day == day && scheduler_end_total_minutes < total_minutes ) ) {
|
|
_IN2("");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool pre_check_new_position_pause() {
|
|
_IN1("");
|
|
int new_position_pause_index = get_new_position_pause_index();
|
|
|
|
if ( new_position_pause_index == -1 ) {
|
|
_IN2("");
|
|
return true;
|
|
}
|
|
|
|
string from_time,to_time;
|
|
if ( new_position_pause_index == -2 ) {
|
|
|
|
datetime current_time = layer::time_current();
|
|
|
|
MqlDateTime dt;
|
|
int year_s=MIN_DATE,year_e=MIN_DATE;
|
|
if (TimeToStruct(current_time,dt)){
|
|
year_s=(dt.mon==12)?dt.year:(dt.year-1);
|
|
year_e=(dt.mon==1)?dt.year:(dt.year+1);
|
|
}
|
|
from_time = StringFormat("%d.12.%d 00:00:00",scheduler_new_position_pause_newyear_day_start,year_s);
|
|
to_time = StringFormat("%d.01.%d 00:00:00",scheduler_new_position_pause_newyear_day_end,year_e);
|
|
}
|
|
else
|
|
{
|
|
from_time = TimeToString ( scheduler_new_position_pause_start[new_position_pause_index], TIME_DATE | TIME_MINUTES );
|
|
to_time = TimeToString ( scheduler_new_position_pause_end[new_position_pause_index], TIME_DATE | TIME_MINUTES );
|
|
}
|
|
|
|
log_info ( StringFormat ( SRC_SCHEDULER_NEW_POSITION_PAUSE,
|
|
from_time,
|
|
to_time ) );
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
Проверяет не установлена ли пауза в открытии новой позиции
|
|
Возвращает индекс элементов массива для которого установлена пауза
|
|
либо -1 если шедулер не активен, -2 если установлена пауза в обход нового года
|
|
|
|
*/
|
|
static int get_new_position_pause_index() {
|
|
_IN1("");
|
|
if ( !scheduler_new_position_pause_enabled ) {
|
|
_IN2("");
|
|
return -1;
|
|
}
|
|
|
|
datetime current_time = layer::time_current();
|
|
int size = ArraySize ( scheduler_new_position_pause_start );
|
|
|
|
if (scheduler_new_position_pause_newyear_day_start||scheduler_new_position_pause_newyear_day_end){
|
|
MqlDateTime dt;
|
|
if (TimeToStruct(current_time,dt)){
|
|
if (scheduler_new_position_pause_newyear_day_start && dt.mon==12 && dt.day>=scheduler_new_position_pause_newyear_day_start)
|
|
return -2;
|
|
if (scheduler_new_position_pause_newyear_day_end && dt.mon==1 && dt.day < scheduler_new_position_pause_newyear_day_end)
|
|
return -2;
|
|
}
|
|
}
|
|
|
|
for ( int i = 0; i < size; i++ ) {
|
|
_IN2("");
|
|
if ( scheduler_new_position_pause_start[i] != MIN_DATE
|
|
&& scheduler_new_position_pause_end[i] != MIN_DATE
|
|
&& current_time >= scheduler_new_position_pause_start[i]
|
|
&& current_time < scheduler_new_position_pause_end[i] ) {
|
|
_IN3("");
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static bool pre_check_trade_pause() {
|
|
_IN1("");
|
|
int trade_pause_index = get_trade_pause_index();
|
|
|
|
if ( trade_pause_index == -1 ) {
|
|
_IN2("");
|
|
return true;
|
|
}
|
|
|
|
string from_time = TimeToString ( scheduler_start_pause[trade_pause_index], TIME_DATE | TIME_MINUTES );
|
|
string to_time = TimeToString ( scheduler_end_pause[trade_pause_index], TIME_DATE | TIME_MINUTES );
|
|
log_info ( StringFormat ( SRC_SCHEDULER_IS_TRADE_PAUSE,
|
|
from_time,
|
|
to_time ) );
|
|
return false;
|
|
}
|
|
|
|
static int get_trade_pause_index() {
|
|
_IN1("");
|
|
if ( !scheduler_is_trade_pause_enabled ) {
|
|
_IN2("");
|
|
return -1;
|
|
}
|
|
|
|
datetime current_time = layer::time_current();
|
|
int size = ArraySize ( scheduler_start_pause );
|
|
|
|
for ( int i = 0; i < size; i++ ) {
|
|
_IN2("");
|
|
if ( scheduler_start_pause[i] != MIN_DATE
|
|
&& scheduler_end_pause[i] != MIN_DATE
|
|
&& current_time >= scheduler_start_pause[i]
|
|
&& current_time < scheduler_end_pause[i] ) {
|
|
_IN3("");
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static bool pre_check_intraday() {
|
|
_IN1("");
|
|
if ( check_intraday() ) {
|
|
_IN2("");
|
|
return true;
|
|
}
|
|
|
|
int near_intraday_index = get_near_intraday_index();
|
|
log_info ( StringFormat ( SRC_SCHEDULER_IS_NOR_INTRADAY,
|
|
scheduler_start_intraday_hour[near_intraday_index],
|
|
scheduler_start_intraday_minutes[near_intraday_index],
|
|
scheduler_end_intraday_hour[near_intraday_index],
|
|
scheduler_end_intraday_minutes[near_intraday_index] ) );
|
|
return false;
|
|
}
|
|
|
|
static bool check_intraday() {
|
|
_IN1("");
|
|
if ( !scheduler_is_intraday_enabled ) {
|
|
_IN2("");
|
|
return true;
|
|
}
|
|
|
|
int total_minutes = get_current_total_minutes();
|
|
bool is_all_same = true;
|
|
|
|
int size = ArraySize ( scheduler_start_intraday_total_minutes );
|
|
|
|
for ( int i = 0; i < size; i++ ) {
|
|
_IN2("");
|
|
if ( scheduler_start_intraday_total_minutes[i] == scheduler_end_intraday_total_minutes[i] ) {
|
|
_IN3("");
|
|
continue;
|
|
}
|
|
|
|
is_all_same = false;
|
|
|
|
if ( check_total_minutes_range ( scheduler_start_intraday_total_minutes[i],
|
|
total_minutes,
|
|
scheduler_end_intraday_total_minutes[i] ) ) {
|
|
_IN3("");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return is_all_same;
|
|
}
|
|
|
|
static int get_near_intraday_index() {
|
|
_IN1("");
|
|
int result = -1;
|
|
int distance = 1440;
|
|
int total_minutes = get_current_total_minutes();
|
|
|
|
// Ищем ближайшее время внутри дня текущего дня
|
|
int size = ArraySize ( scheduler_start_intraday_total_minutes );
|
|
|
|
for ( int i = 0; i < size; i++ ) {
|
|
_IN2("");
|
|
if ( scheduler_start_intraday_total_minutes[i] == scheduler_end_intraday_total_minutes[i] ) {
|
|
_IN3("");
|
|
continue;
|
|
}
|
|
|
|
int tmp_distance = scheduler_start_intraday_total_minutes[i] - total_minutes;
|
|
|
|
if ( tmp_distance < 0 )
|
|
{
|
|
_IN3("");
|
|
continue;
|
|
}
|
|
|
|
if (distance > tmp_distance){
|
|
distance = tmp_distance;
|
|
result = i;
|
|
}
|
|
}
|
|
|
|
if ( result != -1 ) {
|
|
_IN2("");
|
|
return result;
|
|
}
|
|
|
|
// Ищем ближайшее время внутри дня следующего дня
|
|
for ( int i = 0; i < size; i++ ) {
|
|
_IN2("");
|
|
if ( scheduler_start_intraday_total_minutes[i] == scheduler_end_intraday_total_minutes[i] ) {
|
|
_IN3("");
|
|
continue;
|
|
}
|
|
|
|
if ( distance > scheduler_start_intraday_total_minutes[i] ) {
|
|
_IN3("");
|
|
distance = scheduler_start_intraday_total_minutes[i];
|
|
result = i;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static bool pre_check_intraday_stop_trade() {
|
|
_IN1("");
|
|
if ( !check_intraday_stop_trade() ) {
|
|
_IN2("");
|
|
return false;
|
|
}
|
|
|
|
int near_intraday_index = get_near_intraday_stop_trade_index();
|
|
log_info ( StringFormat ( SRC_SCHEDULER_IS_NOR_INTRADAY_STOP_TRADE,
|
|
scheduler_start_intraday_stop_trade_hour[near_intraday_index],
|
|
scheduler_start_intraday_stop_trade_minutes[near_intraday_index],
|
|
scheduler_end_intraday_stop_trade_hour[near_intraday_index],
|
|
scheduler_end_intraday_stop_trade_minutes[near_intraday_index] ) );
|
|
return true;
|
|
}
|
|
|
|
static bool check_intraday_stop_trade() {
|
|
_IN1("");
|
|
if ( !scheduler_is_intraday_stop_trade_enabled ) {
|
|
_IN2("");
|
|
return false;
|
|
}
|
|
|
|
int total_minutes = get_current_total_minutes();
|
|
int size = ArraySize ( scheduler_start_intraday_stop_trade_total_minutes );
|
|
|
|
for ( int i = 0; i < size; i++ ) {
|
|
_IN2("");
|
|
if ( scheduler_start_intraday_stop_trade_total_minutes[i] != scheduler_end_intraday_stop_trade_total_minutes[i]
|
|
&& check_total_minutes_range ( scheduler_start_intraday_stop_trade_total_minutes[i],
|
|
total_minutes,
|
|
scheduler_end_intraday_stop_trade_total_minutes[i] ) ) {
|
|
_IN3("");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static int get_near_intraday_stop_trade_index() {
|
|
_IN1("");
|
|
int result = -1;
|
|
int distance = 1440;
|
|
int total_minutes = get_current_total_minutes();
|
|
|
|
// Ищем ближайшее время внутри дня текущего дня
|
|
int size = ArraySize ( scheduler_start_intraday_stop_trade_total_minutes );
|
|
|
|
for ( int i = 0; i < size; i++ ) {
|
|
_IN2("");
|
|
if ( scheduler_start_intraday_stop_trade_total_minutes[i] == scheduler_end_intraday_stop_trade_total_minutes[i] ) {
|
|
_IN3("");
|
|
continue;
|
|
}
|
|
|
|
int tmp_distance = scheduler_start_intraday_stop_trade_total_minutes[i] - total_minutes;
|
|
|
|
if ( tmp_distance < 0
|
|
|| tmp_distance < distance ) {
|
|
_IN3("");
|
|
continue;
|
|
}
|
|
|
|
distance = tmp_distance;
|
|
result = i;
|
|
}
|
|
|
|
if ( result != -1 ) {
|
|
_IN2("");
|
|
return result;
|
|
}
|
|
|
|
// Ищем ближайшее время внутри дня следующего дня
|
|
for ( int i = 0; i < size; i++ ) {
|
|
_IN2("");
|
|
if ( scheduler_start_intraday_stop_trade_total_minutes[i] == scheduler_end_intraday_stop_trade_total_minutes[i] ) {
|
|
_IN3("");
|
|
continue;
|
|
}
|
|
|
|
if ( distance > scheduler_start_intraday_stop_trade_total_minutes[i] ) {
|
|
_IN3("");
|
|
distance = scheduler_start_intraday_stop_trade_total_minutes[i];
|
|
result = i;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static bool pre_check_close_all_orders ( layer_order_setting *settings_ptr ) {
|
|
_IN1("");
|
|
if ( !check_close_all_orders ( settings_ptr ) ) {
|
|
_IN2("");
|
|
return false;
|
|
}
|
|
|
|
log_info_k ( StringFormat ( SRC_SCHEDULER_CLOSE_ALLORDERS_EVERYDAY,
|
|
scheduler_close_all_orders_hour,
|
|
scheduler_close_all_orders_minute ) );
|
|
return true;
|
|
}
|
|
|
|
static bool check_close_all_orders ( layer_order_setting *settings_ptr ) {
|
|
_IN1("");
|
|
if ( !scheduler_close_all_orders_enabled ) {
|
|
_IN2("");
|
|
return false;
|
|
}
|
|
|
|
LIST_FIRST_OR_DEFAULT ( scheduler_close_all_orders_lockers, locker, scheduler_close_all_orders_locker *, item, item.settings == settings_ptr );
|
|
ACTION_ON_NONVALUE_OR_DEFAULT ( locker, {
|
|
_IN3("");
|
|
locker = new scheduler_close_all_orders_locker();
|
|
locker.settings = settings_ptr;
|
|
locker.lock = false;
|
|
scheduler_close_all_orders_lockers.add ( locker );
|
|
} );
|
|
|
|
bool result = check_total_minutes_range ( scheduler_close_all_orders_total_minute,
|
|
get_current_total_minutes(),
|
|
scheduler_close_all_orders_total_minute_with_wait );
|
|
|
|
if ( !result ) {
|
|
_IN2("");
|
|
locker.lock = false;
|
|
return false;
|
|
}
|
|
|
|
if ( locker.lock ) {
|
|
_IN2("");
|
|
return false;
|
|
}
|
|
|
|
locker.lock = true;
|
|
return true;
|
|
}
|
|
|
|
static bool check_total_minutes_range ( int start_range, int value, int end_range ) {
|
|
_IN1("");
|
|
return start_range <= value && value < end_range;
|
|
}
|
|
|
|
static string get_day_of_week_str ( int day_of_week ) {
|
|
_IN1("");
|
|
switch ( day_of_week ) {
|
|
case 0:
|
|
return SRC_SCHEDULER_SUNDAY;
|
|
|
|
case 1:
|
|
return SRC_SCHEDULER_MONDAY;
|
|
|
|
case 2:
|
|
return SRC_SCHEDULER_TUESDAY;
|
|
|
|
case 3:
|
|
return SRC_SCHEDULER_WEDNESDAY;
|
|
|
|
case 4:
|
|
return SRC_SCHEDULER_THURSDAY;
|
|
|
|
case 5:
|
|
return SRC_SCHEDULER_FRIDAY;
|
|
|
|
case 6:
|
|
return SRC_SCHEDULER_SATURDAY;
|
|
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif |