EA-Setka-2/logic/entry_point.mqh

881 lines
52 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 14:50:44 +02:00
<EFBFBD><EFBFBD>#ifndef SETKA_MQH
#define SETKA_MQH
// A?>;L7>20=85 181;8>B5:8 CLog4mql
#ifdef USE_LOG4MQL
#include "..\Libs\log4mql.mqh"
CLog4mql* log4 = CLog4mql::getInstance();
#else
#define _TRACE(msg) ;
#define _DEBUG(msg) ;
#define _INFO(msg) ;
#define _WARN(msg) ;
#define _ERROR(msg) ;
#define _CRIT(msg) ;
#define _B2S(B) ((B)?"True":"False")
#define _CHECK_TRACE(name,cache, val) ;
#endif
#ifdef TRACE
#define adx m5t_adx
#include <MQL5Trace\View\TraceView.mqh>
#undef adx
#else
#define _IN(desc) ;
#define _IN1(desc) ;
#define _IN2(desc) ;
#define _IN3(desc) ;
#define _IN4(desc) ;
#define _IN5(desc) ;
#define _WATCH(w, v) ;
#define _BRKUSES(u) ;
#endif // TRACE
#include "enum/enum.mqh"
#include "defines.mqh"
#include "logic_handler.mqh"
#include "api.mqh"
#ifndef FOR_OPTIMIZATION
#include "..\Libs\CtrlPanel\CtrlPanel.mqh"
CCtrlPanelBase* CtrlPanel=NULL;
#endif //FOR_OPTIMIZATION
#property version VER
#define TOSTR(A) " " + #A + " = " + (string)Tick.A
logic_handler *short_hd;
logic_handler *long_hd;
timer_t *life_timer;
bool _init_failed = false;
#ifdef FOR_OPTIMIZATION
int _last_order_count;
MqlDateTime _prev_date;
//datetime _prev_date;
#endif //FOR_OPTIMIZATION
#ifdef USE_FILTERS
#include "filters/entry_point.mqh"
#endif
#ifdef RSI_CCI
#include "rsi_cci/calc_rc.mqh"
#include "rsi_cci/entry_point.mqh"
#endif
#ifndef FOR_OPTIMIZATION
#include "test/test.mqh"
//#define B2S(B) B?"True":"False"
void show_market_info()
{
_IN1("");
MqlTick Tick;
SymbolInfoTick(CURRENT_SYMBOL,Tick);
log_info ( StringFormat ( SRC_SETKA_MODE_LOW, dtos ( kernel_market::price_day_min ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_HIGH, dtos ( kernel_market::price_day_max ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_TIME, TimeToString ( kernel_market::tick_last_time ( ), TIME_DATE | TIME_MINUTES | TIME_SECONDS ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_BID, dtos ( layer_market::price_buy ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_ASK, dtos ( layer_market::price_sell ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_POINT, dtos ( layer_market::point ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_DIGITS, itos ( kernel_market::digits ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_SPREAD, itos ( layer_market::spread ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_STOPLEVEL, dtos ( layer_market::stop_level ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_LOTSIZE, dtos ( layer_market::lot_size ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_TICKVALUE, dtos ( layer_market::tick_value ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_TICKSIZE, dtos ( layer_market::tick_size ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_SWAPLONG, dtos ( kernel_market::swap_long ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_SWAPSHORT, dtos ( kernel_market::swap_short ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_STARTING, TimeToString ( kernel_market::starting ( ), TIME_DATE | TIME_MINUTES | TIME_SECONDS ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_EXPIRATION, TimeToString ( kernel_market::expiration ( ), TIME_DATE | TIME_MINUTES | TIME_SECONDS ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_TRADEALLOWED, kernel_market::trade_allowed ( ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_MINLOT, dtos ( layer_market::lot_min ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_LOTSTEP, dtos ( layer_market::lot_step ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_MAXLOT, dtos ( kernel_market::lot_max ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_SWAPTYPE, EnumToString ( kernel_market::swap_type ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_PROFITCALCMODE, EnumToString ( kernel_market::profit_calc_type ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_MARGINCALCMODE, EnumToString ( kernel_market::margin_calc_type ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_MARGININIT, dtos ( kernel_market::margin_init ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_MARGINMAINTENANCE, dtos ( kernel_market::margin_maintenance ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_MARGINHEDGED, dtos ( kernel_market::margin_hedged ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_MARGINREQUIRED, dtos ( layer_market::margin_required ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_MODE_FREEZELEVEL, dtos ( kernel_market::freeze_level ( ) ) ) );
log_info ( StringFormat ( SRC_SETKA_TERMINAL_VERSION_MSG, itos ( TerminalInfoInteger ( TERMINAL_BUILD ) ) ) );
log_info ( StringFormat ( SRC_SETKA_VERSION_MSG, VER, itos(BUILD), ttos(__DATETIME__),(" " + "time=" + TimeToString(Tick.time) + "." + ::IntegerToString(Tick.time_msc % 1000, 3, '0')) ));
log_info ( StringFormat ( SRC_SETKA_ACCOUNT_COMPANY, kernel_account::company() ) );
log_info ( StringFormat ( SRC_SETKA_ACCOUNT_CURRENCY, layer_account::currency() ) );
log_info ( StringFormat ( SRC_SETKA_ACCOUNT_LEVERAGE, itos ( layer::account_leverage() ) ) );
log_info ( ext_string::get_hash ( itos ( kernel_account::number() ) ) );
log_info ( StringFormat ( SRC_SETKA_ACCOUNT_SERVER, kernel_account::server() ) );
log_info ( StringFormat ( SRC_SETKA_ACCOUNT_STOPOUT, itos ( (int)kernel_account::stopout_level() ) ) );
log_info ( StringFormat ( SRC_SETKA_ACCOUNT_STOPOUT_MODE, itos ( kernel_account::stopout_mode() ) ) );
}
int OnInit()
{
_IN1("");
#ifdef TRACE
//****************  TRACE
m_traceview=new CTraceView; // A>740;8 >B>1@065=85 3@0D
m_trace=new CTraceCtrl; // A>740;8 3@0D
m_traceview.m_trace=m_trace; // ?>4A>548=8;8 3@0D
m_trace.m_traceview=m_traceview; // ?>4A>548=8;8 >B>1@065=85 3@0D0
if(!kernel_account::is_testing())
m_traceview.Create(ChartID()); // A>740;8 G0@B
//****************
#endif //TRACE
//---
//--- run timer
if(!kernel_account::is_testing())
EventSetTimer(1);
OnTimer();
//--- done
_init_failed = false;
gc::init();
tool_cache::update_instance_state();
if ( !layer_account::is_testing() ) {
_IN2("");
life_timer = timer_t::create ( 60 );
gc::push ( gc_dispose_type_on_end_deinit, life_timer );
}
show_market_info();
double lot_step = layer_market::lot_step ();
int lot_exp = get_lot_exp_by_minlot ( lot_step );
log_info ( StringFormat ( SRC_SETKA_COUNT_SYMBOL_FOR_AVG, ( int ) lot_exp ) );
if ( lot_exp == -1 ) {
_IN2("");
log_error ( StringFormat ( SRC_SETKA_NOT_GOOD_LOTSTEP, lot_step ) );
_init_failed = true;
return INIT_FAILED;
}
if ( !defines_validate() ) {
_IN2("");
log_error ( SRC_SETKA_VALID_NOT_GOOD );
_init_failed = true;
return INIT_FAILED;
}
if ( !test::all() ) {
_IN2("");
log_error ( SRC_SETKA_TEST_NOT_GOOD );
_init_failed = true;
return INIT_FAILED;
}
log_info ( SRC_SETKA_TEST_GOOD );
setting_t *short_settings = defines_create ( false, lot_exp );
gc::push ( gc_dispose_type_on_end_deinit, short_settings );
setting_t *long_settings = defines_create ( true, lot_exp );
gc::push ( gc_dispose_type_on_end_deinit, long_settings );
layer_order::init();
short_hd = new logic_handler ( false, short_settings );
long_hd = new logic_handler ( true, long_settings );
int max_order_count = short_settings.max_open_orders + long_settings.max_open_orders;
factory_c_order::init ( max_order_count );
factory_order_operation::init ( max_order_count );
if ( !layer_account::is_testing() ) {
_IN2("");
api::set_short_handler ( short_hd );
api::set_long_handler ( long_hd );
api::set_times ( GlobalParamsUpdateTiming );
api::init();
}
defines_init_scheduler();
#ifdef USE_FILTERS
// Indicators intitialisation---
if( calc_adx::Init(short_settings) ){
_IN2("");
return(INIT_FAILED);
};
if( calc_osc::Init(short_settings) ){
_IN2("");
return(INIT_FAILED);
};
#endif
#ifdef RSI_CCI
if( calc_rc::Init(short_settings) ){
_IN2("");
return(INIT_FAILED);
};
#endif
//--- elavr 20201102 CtrlPanel
CtrlPanel = CreateCtrlPanel();
if (CtrlPanel==NULL||!CtrlPanel.OnInitEvent())
{
return(INIT_FAILED);
}
CtrlPanel.DrawPanelInfo();
log_info ( SRC_SETKA_INIT_COMPLETED );
return INIT_SUCCEEDED;
}
#else //FOR_OPTIMIZATION
int OnInit()
{
_IN1("");
#ifdef TRACE
//****************  TRACE
m_traceview=new CTraceView; // A>740;8 >B>1@065=85 3@0D
m_trace=new CTraceCtrl; // A>740;8 3@0D
m_traceview.m_trace=m_trace; // ?>4A>548=8;8 3@0D
m_trace.m_traceview=m_traceview; // ?>4A>548=8;8 >B>1@065=85 3@0D0
m_traceview.Create(ChartID()); // A>740;8 G0@B
//****************
#endif //TRACE
//--- run timer
if(!kernel_account::is_testing())
EventSetTimer(1);
OnTimer();
//--- done
ZeroMemory(_prev_date);
_init_failed = false;
if ( !layer_account::is_optimization()
&& !layer_account::is_testing() )
{
_init_failed = true;
Alert(StringFormat("%s", SRC_SETKA_ERROR_OPT_FOR_REAL) );
return INIT_FAILED;
}
gc::init();
tool_cache::update_instance_state();
double lot_step = layer_market::lot_step ();
int lot_exp = get_lot_exp_by_minlot ( lot_step );
log_info ( StringFormat ( SRC_SETKA_COUNT_SYMBOL_FOR_AVG, ( int ) lot_exp ) );
if ( lot_exp == -1 ) {
_IN2("");
log_error ( StringFormat ( SRC_SETKA_NOT_GOOD_LOTSTEP, lot_step ) );
_init_failed = true;
return INIT_FAILED;
}
if ( !defines_validate() ) {
_IN2("");
log_error ( SRC_SETKA_VALID_NOT_GOOD );
_init_failed = true;
return INIT_PARAMETERS_INCORRECT;
}
setting_t *short_settings = defines_create ( false, lot_exp );
gc::push ( gc_dispose_type_on_end_deinit, short_settings );
setting_t *long_settings = defines_create ( true, lot_exp );
gc::push ( gc_dispose_type_on_end_deinit, long_settings );
layer_order::init();
short_hd = new logic_handler ( false, short_settings );
long_hd = new logic_handler ( true, long_settings );
int max_order_count = short_settings.max_open_orders + long_settings.max_open_orders;
factory_c_order::init ( max_order_count );
factory_order_operation::init ( max_order_count );
defines_init_scheduler();
#ifdef RSI_CCI
if( calc_rc::Init(short_settings) ){
_IN2("");
return(INIT_FAILED);
};
#endif
#ifdef USE_FILTERS
// Indicators intitialisation---
if( calc_adx::Init(short_settings) ){
_IN2("");
return(INIT_FAILED);
};
if( calc_osc::Init(short_settings) ){
_IN2("");
return(INIT_FAILED);
};
#endif
return INIT_SUCCEEDED;
}
#endif
void OnDeinit ( const int reason )
{
_IN1("");
string reason_str = error_deinit_reason ( reason );
if ( reason_str != NULL ) {
_IN2("");
log_info ( StringFormat ( SRC_SETKA_DEINIT_REASON, reason_str ) );
}
//--- elavr :>=B@>; ?0=5;L
#ifndef FOR_OPTIMIZATION
if (CtrlPanel!=NULL)
{
CtrlPanel.OnDeinitEvent(reason);
delete CtrlPanel;
CtrlPanel=NULL;
}
#endif
if ( short_hd != NULL ) {
_IN2("");
delete short_hd;
}
if ( long_hd != NULL ) {
_IN2("");
delete long_hd;
}
api::deinit();
gc::deinit();
#ifndef FOR_OPTIMIZATION
//--- Log4MQL deinit
// A?>;L7>20=85 181;8>B5:8 CLog4mql
#ifdef USE_LOG4MQL
log4.release();
#endif
#endif
#ifdef TRACE
//****************  TRACE
delete m_traceview;
delete m_trace;
//****************
#endif // TRACE
//--- capteen 190422
#ifdef RSI_CCI
calc_rc::Deinit();
#endif
//--- capteen 190422
//--- capteen 190322 ----------------
#ifdef USE_FILTERS
calc_adx::Deinit();
calc_osc::Deinit();
#endif
Print ( StringFormat ( SRC_SETKA_DEINIT_REASON, BOT_NAME, VER, reason_str,TesterStatistics(STAT_GROSS_PROFIT),TesterStatistics(STAT_GROSS_LOSS),TesterStatistics(STAT_EQUITY_DD) ) );
}
double get_recovery_factor()
{
_IN1("");
double rf = 0,
tt = TesterStatistics( STAT_TRADES ),
dd = TesterStatistics( STAT_EQUITY_DD ),
ddp = TesterStatistics( STAT_EQUITYDD_PERCENT ),
gp = TesterStatistics( STAT_GROSS_PROFIT ),
gl = MathAbs(TesterStatistics( STAT_GROSS_LOSS )),
ctl = TesterStatistics( STAT_MAX_CONLOSS_TRADES );
if (OnTester_Min_Trade!=0)
{
if (OnTester_Min_Trade>tt && tt>0)
return -2;
}
if (OnTester_Max_DD_Percent!=0)
{
if (OnTester_Max_DD_Percent<ddp && ddp>0)
return -1;
}
rf= ( CP(dd) != 0.0) ? NormalizeDouble((gp - gl) / dd, 5) : TesterStatistics(STAT_RECOVERY_FACTOR);
if (OnTester_Max_Conloss_Trades!=0)
{
if (ctl>OnTester_Max_Conloss_Trades)
rf-=(ctl/100.0);
}
Print( StringFormat(SRC_SETKA_PROFIT_RECOVERY_FACTOR, TesterStatistics(STAT_PROFIT_FACTOR),rf));
return rf;
}
double OnTester( )
{
_IN1("");
return get_recovery_factor();
}
void OnTick()
{
_IN1("");
if ( _init_failed ) {
_IN2("");
return;
}
pre_tick_handler();
tick_handler();
post_tick_handler();
//--- elavr :>=B@>;L ?0=5;L.
#ifndef FOR_OPTIMIZATION
if (CtrlPanel!=NULL && (CtrlPanel.IsEnableTickCalculateEvent()))
{
CtrlPanel.OnTickCalculateEvent();
if (CtrlPanel.IsReadyForUpdate())
CtrlPanel.DrawPanelInfo();
}
#endif
}
//+------------------------------------------------------------------+
//| OnChartEvent |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
_IN1("");
//--- elavr :>=B@>;L ?0=5;L.
#ifndef FOR_OPTIMIZATION
if (CtrlPanel!=NULL)
{
CtrlPanel.OnEvent(id,lparam,dparam,sparam);
}
#endif
#ifdef TRACE
//****************  TRACE
m_traceview.OnChartEvent(id, lparam, dparam, sparam);
Sleep(50);
//****************
#endif
}
//+------------------------------------------------------------------+
//| OnTimer |
//+------------------------------------------------------------------+
void OnTimer(void)
{
_IN1("");
//--- elavr :>=B@>;L ?0=5;L.
#ifndef FOR_OPTIMIZATION
if (CtrlPanel!=NULL)
{
CtrlPanel.OnTimerEvent();
}
#endif
#ifdef TRACE
//****************  TRACE
if (!m_traceview.IsOpenView()) { m_traceview.Deinit(); m_traceview.Create(ChartID()); } // 5A;8 >:=> 1K;> A;CG09=> 70:@KB>
else m_traceview.OnTimer();
//****************
#endif // TRACE
}
void pre_tick_handler()
{
_IN1("");
MqlTick Tick;
SymbolInfoTick(Symbol(),Tick);
OnTimer();
layer_error::reset();
tool_cache::update_tick_state();
if ( short_hd.is_strong_sleep() && long_hd.is_strong_sleep() )
{
_IN2("");
return;
}
#ifndef FOR_OPTIMIZATION
factory_c_order::reset();
factory_order_operation::reset();
layer_order::refresh_all();
#else // FOR_OPTIMIZATION
MqlDateTime _current_date;
TimeCurrent(_current_date);
datetime _current_date_t = TimeCurrent();
static ushort tick_counter=0;
if (_last_order_count != kernel_order::count()
//||(_last_ticket != !GC_CHECK_PTR ( _last_order ) ? -1.0 : _last_order.ticket)
|| (_prev_date.day_of_year < _current_date.day_of_year && _current_date.min >= 0)
|| _current_date.day_of_year == 0
//|| _current_date_t - _prev_date > 300 //BAG8BK205< 15 A5@:C=4
//|| _prev_date == 0
//|| tick_counter >= 10000
)
{
_IN2("");
factory_c_order::reset();
factory_order_operation::reset();
layer_order::refresh_all();
_last_order_count = kernel_order::count();
_prev_date = _current_date;
tick_counter = 0;
}
tick_counter++;
#endif // FOR_OPTIMIZATION
}
void tick_handler()
{
#ifdef INFO_PANEL
return;
#endif
_IN1("");
if ( short_hd.is_strong_sleep() && long_hd.is_strong_sleep() ) {
_IN2("");
return;
}
if ( !layer_account::is_trade_allowed() ) {
_IN2("");
log_info ( SRC_SETKA_TRADE_NOT_ALLOWED );
return;
}
enum_trade_mode_type trade_mode = layer_symbol::trade_mode ( CURRENT_SYMBOL );
if ( trade_mode != trade_mode_type_full ) {
_IN2("");
switch ( trade_mode ) {
case trade_mode_type_disabled:
log_info ( SRC_SETKA_SYMBOL_TRADE_MODE_DISABLED );
return;
case trade_mode_type_long_only:
log_info ( SRC_SETKA_SYMBOL_TRADE_MODE_LONGONLY );
break;
case trade_mode_type_short_only:
log_info ( SRC_SETKA_SYMBOL_TRADE_MODE_SHORTONLY );
break;
case trade_mode_type_close_only:
log_info ( SRC_SETKA_SYMBOL_TRADE_MODE_CLOSEONLY );
break;
}
}
double account_balance = kernel_account::balance();
if ( account_balance == 0.00 ) {
_IN2("");
log_info ( SRC_SETKA_NO_MONEY );
return;
}
double account_drawdown_percent = ( 1 - ( kernel_account::equity() / account_balance ) ) * 100;
short_hd.drawdown_changed_handler ( account_drawdown_percent );
long_hd.drawdown_changed_handler ( account_drawdown_percent );
short_hd.mark_block_work_by_stop_trade ( false );
long_hd.mark_block_work_by_stop_trade ( false );
bool is_close_by_profit_percent = (CloseAllOrders_ByProfitPercent > 0 ) && is_close_orders_profit_in_percent ( layer_account::profit_clear_percent());
bool is_close_by_profit_currency = CloseAllOrders_ByProfitMoney > 0 && is_close_orders_profit_in_money ( layer_account::profit_clear_currency() );
bool is_close_by_drawdown_percent = CloseAllOrders_ByDrawdownPercent > 0 && is_close_orders_drawdown_in_percent ( layer_account::drawdown_percent() );
bool is_close_by_drawdown_currency = CloseAllOrders_ByDrawdownMoney > 0 && is_close_orders_drawdown_in_money ( layer_account::drawdown_currency() );
bool is_close_by_dd_001lot_short = is_close_orders_drawdown_in_money_by_001lot ( short_hd );
bool is_close_by_dd_001lot_long = is_close_orders_drawdown_in_money_by_001lot ( long_hd );
bool is_close_by_dd_tpratio_short = is_close_orders_drawdown_tp_ratio ( short_hd );
bool is_close_by_dd_tpratio_long = is_close_orders_drawdown_tp_ratio ( long_hd );
bool is_close_by_profit = is_close_by_profit_currency
|| is_close_by_profit_percent;
bool is_close_by_drawdown = is_close_by_drawdown_currency
|| is_close_by_drawdown_percent;
bool is_need_close = is_close_by_profit
|| is_close_by_drawdown;
bool is_close_by_percent = is_close_by_profit_percent
|| is_close_by_drawdown_percent;
if ( (!short_hd.is_close_module_activated()&& short_hd.is_can_close()&& (is_close_by_dd_001lot_short||is_close_by_dd_tpratio_short ))
||(!long_hd.is_close_module_activated()&& long_hd.is_can_close()&&(is_close_by_dd_001lot_long||is_close_by_dd_tpratio_long ))) {
if ( is_close_by_dd_001lot_short || is_close_by_dd_tpratio_short )
{
log_alert ( StringFormat ( SRC_SETKA_DRAWDOWN_CLOSE_ALL_BY_DRAWDOWN_MSG,
DoubleToString ( (short_hd.get_profit()*-1), 2 ),
DoubleToString ( is_close_by_dd_001lot_short ? short_hd.calc_drawdown_per_001lot() : short_hd.calc_drawdown_tp_ratio() , 2 ) ) );
short_hd.mark_close_all_orders ( 0, true, (is_close_by_dd_001lot_short || is_close_by_dd_tpratio_short) );
if ( short_hd._is_block_work ) {
log_alert ( SRC_SETKA_DRAWDOWN_CLOSE_ALL_STOP_TRADE_MSG );
}
}
if (is_close_by_dd_001lot_long || is_close_by_dd_tpratio_long)
{
log_alert ( StringFormat ( SRC_SETKA_DRAWDOWN_CLOSE_ALL_BY_DRAWDOWN_MSG,
DoubleToString ( (long_hd.get_profit()*-1), 2 ),
DoubleToString ( is_close_by_dd_001lot_long ? long_hd.calc_drawdown_per_001lot() : long_hd.calc_drawdown_tp_ratio(), 2 ) ) );
long_hd.mark_close_all_orders ( 0, true, (is_close_by_dd_001lot_long || is_close_by_dd_tpratio_long) );
if ( long_hd._is_block_work ) {
log_alert ( SRC_SETKA_DRAWDOWN_CLOSE_ALL_STOP_TRADE_MSG );
}
}
}
else if ( !short_hd.is_close_module_activated()
&& !long_hd.is_close_module_activated()
&& short_hd.is_can_close()
&& long_hd.is_can_close()
&& is_need_close ) {
_IN2("");
if ( is_close_by_drawdown ) {
_IN3("");
log_alert ( StringFormat ( SRC_SETKA_DRAWDOWN_CLOSE_ALL_BY_DRAWDOWN_MSG,
is_close_by_percent ?
DoubleToString ( layer_account::drawdown_percent(), 2 ) + "%" :
DoubleToString ( layer_account::drawdown_currency(), 2 ),
is_close_by_percent ?
DoubleToString ( CloseAllOrders_ByDrawdownPercent, 2 ) + "%" :
DoubleToString ( CloseAllOrders_ByDrawdownMoney, 2 ) ) );
} else {
_IN3("");
log_alert ( StringFormat ( SRC_SETKA_DRAWDOWN_CLOSE_ALL_BY_PROFIT_MSG,
is_close_by_percent ?
DoubleToString ( layer_account::profit_clear_percent(), 2 ) + "%" :
DoubleToString ( layer_account::profit_clear_currency(), 2 ),
is_close_by_percent ?
DoubleToString ( CloseAllOrders_ByProfitPercent, 2 ) + "%" :
DoubleToString ( CloseAllOrders_ByProfitMoney, 2 ) ) );
}
short_hd.mark_close_all_orders ( 0, true, is_close_by_drawdown );
long_hd.mark_close_all_orders ( 0, true, is_close_by_drawdown );
if ( short_hd._is_block_work ) {
log_alert ( SRC_SETKA_DRAWDOWN_CLOSE_ALL_STOP_TRADE_MSG );
}
} else if ( is_stop_trade_drawdown_in_percent ( layer_account::drawdown_percent() )
|| is_stop_trade_drawdown_in_money ( layer_account::drawdown_currency() ) ) {
_IN2("");
log_info ( StringFormat ( SRC_SETKA_DRAWDOWN_MSG,
DoubleToString ( layer_account::drawdown_percent(), 0 ) + "%" ) );
if ( short_hd.get_profit() > long_hd.get_profit() ) {
_IN3("");
long_hd.mark_block_work_by_stop_trade ( true );
} else {
_IN3("");
short_hd.mark_block_work_by_stop_trade ( true );
}
}
if ( layer_market::is_closed() ) {
_IN2("");
return;
}
short_hd.tick_handler();
long_hd.tick_handler();
}
void post_tick_handler()
{
_IN1("");
if ( layer_market::is_closed() ) {
_IN2("");
log_info ( SRC_SETKA_MARKET_CLOSE_ERROR );
short_hd.reset_states();
long_hd.reset_states();
}
api::process();
gc::dispose();
if(kernel_account::is_testing()) {
_IN2("");
OnTimer();
long lparam = 0;
double dparam = 0;
string sparam = "";
OnChartEvent(0,lparam,dparam,sparam);
}
if ( life_timer != NULL && life_timer.is_elapsed() ) {
_IN2("");
life_timer.reset();
}
}
bool is_close_orders_drawdown_in_percent ( double drawdown_percent )
{
_IN1("");
return CloseAllOrders_ByDrawdownPercent > 0
&& drawdown_percent >= CloseAllOrders_ByDrawdownPercent;
}
bool is_close_orders_drawdown_in_money_by_001lot (logic_handler* hdl)
{
return hdl._settings.close_orders_by_drawdown_for_001lot > 0
&& hdl.calc_drawdown_per_001lot()>0
&& (hdl.get_profit()*-1) >= hdl.calc_drawdown_per_001lot();
}
bool is_close_orders_drawdown_tp_ratio (logic_handler* hdl)
{
return hdl._settings.close_orders_by_drawdown_tp_ratio > 0
&& hdl.calc_drawdown_tp_ratio()>0
&& (hdl.get_profit()*-1) >= hdl.calc_drawdown_tp_ratio();
}
bool is_close_orders_drawdown_in_money ( double drawdown_currency )
{
_IN1("");
return CloseAllOrders_ByDrawdownMoney > 0
&& drawdown_currency >= CloseAllOrders_ByDrawdownMoney;
}
bool is_close_orders_profit_in_percent ( double profit_percent )
{
_IN1("");
return CloseAllOrders_ByProfitPercent > 0
&& profit_percent >= CloseAllOrders_ByProfitPercent;
}
bool is_close_orders_profit_in_money ( double profit_currency )
{
_IN1("");
return CloseAllOrders_ByProfitMoney > 0
&& profit_currency >= CloseAllOrders_ByProfitMoney;
}
bool _stop_trade_by_drawdown_in_percent_enabled = false;
bool is_stop_trade_drawdown_in_percent ( double drawdown_percent )
{
_IN1("");
if ( StopTrade_ByDrawdownPercent == 0 ) {
_IN2("");
return false;
}
if ( _stop_trade_by_drawdown_in_percent_enabled ) {
_IN2("");
if ( drawdown_percent >= StopTrade_ByDrawdownPercent_Off ) {
_IN3("");
return true;
}
log_alert ( StringFormat ( SRC_SETKA_STOP_DRAWDOWN_OFF,
DoubleToString ( drawdown_percent, 2 ) + "%",
DoubleToString ( StopTrade_ByDrawdownPercent_Off, 2 ) + "%" ) );
_stop_trade_by_drawdown_in_percent_enabled = false;
return false;
}
bool result = drawdown_percent >= StopTrade_ByDrawdownPercent;
if ( result
&& StopTrade_ByDrawdownPercent_Off != 0 ) {
_IN2("");
log_alert ( StringFormat ( SRC_SETKA_STOP_DRAWDOWN_ON,
DoubleToString ( drawdown_percent, 2 ) + "%",
DoubleToString ( StopTrade_ByDrawdownPercent_Off, 2 ) + "%" ) );
_stop_trade_by_drawdown_in_percent_enabled = true;
}
return result;
}
bool _stop_trade_by_drawdown_in_money_enabled = false;
bool is_stop_trade_drawdown_in_money ( double drawdown_currency )
{
_IN1("");
if ( StopTrade_ByDrawdownMoney == 0 ) {
_IN2("");
return false;
}
if ( _stop_trade_by_drawdown_in_money_enabled ) {
_IN2("");
if ( drawdown_currency >= StopTrade_ByDrawdownMoney_Off ) {
_IN3("");
return true;
}
log_alert ( StringFormat ( SRC_SETKA_STOP_DRAWDOWN_OFF,
DoubleToString ( drawdown_currency, 2 ),
DoubleToString ( StopTrade_ByDrawdownMoney_Off, 2 ) ) );
_stop_trade_by_drawdown_in_money_enabled = false;
return false;
}
bool result = drawdown_currency >= StopTrade_ByDrawdownMoney;
if ( result
&& StopTrade_ByDrawdownMoney_Off != 0 ) {
_IN2("");
log_alert ( StringFormat ( SRC_SETKA_STOP_DRAWDOWN_ON,
DoubleToString ( drawdown_currency, 2 ),
DoubleToString ( StopTrade_ByDrawdownMoney_Off, 2 ) ) );
_stop_trade_by_drawdown_in_money_enabled = true;
}
return result;
}
int get_lot_exp_by_minlot ( double minlot )
{
_IN1("");
int result = -1;
if ( minlot >= 1.0 ) {
_IN2("");
return result;
}
do {
_IN2("");
result++;
} while ( ( minlot *= 10 ) <= 1.0 );
return result;
}
#endif