483 lines
21 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| Test.mq5 |
| |||
//| Copyright 2026, DNG |
| |||
//| https://www.mql5.com/ru/users/dng |
| |||
//+------------------------------------------------------------------+
| |||
#property copyright "Copyright 2026, DNG"
| |||
#property version "3.00"
| |||
#property description "Evaluates a frozen DPCC Action6 policy in Strategy Tester"
| |||
#property description "Uses the chart symbol, configured timeframe, and current account context"
| |||
#property description "Runs across the configured tester interval"
| |||
#property strict
| |||
| |||
#define DPCC_TRAJECTORY_ENTRY_STUDY_FORECAST
| |||
#include "Trajectory.mqh"
| |||
#undef DPCC_TRAJECTORY_ENTRY_STUDY_FORECAST
| |||
| |||
input group "---- Таймфрейм данных ----"
| |||
| |||
input ENUM_TIMEFRAMES InpTimeframe = PERIOD_CURRENT; // Таймфрейм; PERIOD_CURRENT — таймфрейм графика/тестера.
| |||
| |||
input group "---- Режим оценки и исполнение ----"
| |||
input ENUM_DPCC_MODE InpMode = DPCC_P0; // Режим DPCC: P0, P1 или P2.
| |||
input long InpMagic = 33062; // Magic-номер заявок этого советника.
| |||
| |||
input group "---- Замер производительности ----"
| |||
input bool InpMeasureLatency = false; // Измерять задержку принятия решения.
| |||
| |||
const string DPCC_PACKAGE_ROOT = "DPCC/StudyForecast_M05_20261017";
| |||
const bool DPCC_COMMON_FILES = true;
| |||
//+------------------------------------------------------------------+
| |||
//| Frozen policy owners used throughout the Tester interval |
| |||
//+------------------------------------------------------------------+
| |||
CDPCCStudyForecastCore EXTMarket;
| |||
CDPCCAction6ChartContextOwner EXTDecisionContext;
| |||
CNet *EXTActor = NULL;
| |||
CNet *EXTQ1 = NULL;
| |||
CNet *EXTQ2 = NULL;
| |||
SDPCCExecutionControl EXTControl;
| |||
SDPCCRuntimeConfig EXTRuntime;
| |||
float EXTTradingLimits[];
| |||
CBufferFloat EXTCurrentZ;
| |||
CBufferFloat EXTActorAccount;
| |||
int EXTIndicators[4];
| |||
long EXTBarOpen = 0;
| |||
long EXTFirstDecision = 0;
| |||
double EXTInitialBalance = 0;
| |||
double EXTInitialEquity = 0;
| |||
uint EXTDecisions = 0;
| |||
ulong EXTNoiseSeed = 0;
| |||
double EXTTPCapPoints = 0;
| |||
double EXTSLCapPoints = 0;
| |||
bool EXTReady = false;
| |||
bool EXTStopped = false;
| |||
bool EXTWindowCompleted = false;
| |||
string EXTMarketSHA = "";
| |||
string EXTTradingSHA = "";
| |||
ulong EXTLatencySamples = 0;
| |||
ulong EXTMarketLatencyUs = 0;
| |||
ulong EXTActorLatencyUs = 0;
| |||
ulong EXTExecutionLatencyUs = 0;
| |||
ulong EXTDecisionLatencyUs = 0;
| |||
ulong EXTDecisionLatencyMaxUs = 0;
| |||
//+------------------------------------------------------------------+
| |||
//| Stop before another decision or execution request |
| |||
//+------------------------------------------------------------------+
| |||
void DPCCTestStop(const string phase, const string reason)
| |||
{
| |||
EXTStopped = true;
| |||
Print("DPCC_TEST_BLOCKED phase=", phase, " reason=", reason, " bar=", EXTBarOpen);
| |||
if(MQLInfoInteger(MQL_TESTER))
| |||
TesterStop();
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Shared D01 restore boundary for Market and Trading inference |
| |||
//| roles |
| |||
//+------------------------------------------------------------------+
| |||
bool DPCCTestRestoreFrozenTrading(string &reason)
| |||
{
| |||
CNet *target_actor = NULL;
| |||
CNet *target_q1 = NULL;
| |||
CNet *target_q2 = NULL;
| |||
SDPCCAction6TradingRestore restored;
| |||
if(!DPCCLoadAction6Trading(EXTControl, DPCC_COMMON_FILES, EXTMarket, EXTActor, EXTQ1, EXTQ2,
| |||
target_actor, target_q1, target_q2, restored, reason))
| |||
return(false);
| |||
//--- Test keeps only the frozen online policy and its ranking dependencies.
| |||
delete target_actor;
| |||
delete target_q1;
| |||
delete target_q2;
| |||
EXTRuntime = restored.runtime;
| |||
EXTMarketSHA = restored.market_sha256;
| |||
EXTTradingSHA = restored.trading_sha256;
| |||
EXTNoiseSeed = restored.diffusion_seed;
| |||
EXTTPCapPoints = MaxTP;
| |||
EXTSLCapPoints = MaxSL;
| |||
if(ArrayCopy(EXTTradingLimits, restored.limits) != 24)
| |||
{
| |||
reason = "test.restore.financial_limits_capacity";
| |||
return(false);
| |||
}
| |||
if(EXTNoiseSeed == 0)
| |||
{
| |||
reason = "BLOCKED:test.assigned_profile.diffusion.seed_must_be_nonzero_for_Action6";
| |||
return(false);
| |||
}
| |||
reason = "";
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Shared physical-account and causal financial-context boundary |
| |||
//+------------------------------------------------------------------+
| |||
bool DPCCTestDecisionContext(const long decision_open, CBufferFloat *native_ohlc,
| |||
CBufferFloat *&context, float &account13[], string &reason)
| |||
{
| |||
return(EXTDecisionContext.Build(EXTRuntime, EXTTradingLimits, native_ohlc,
| |||
decision_open, context, account13, reason));
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Verify frozen Market, Actor and the two inference-only critics |
| |||
//+------------------------------------------------------------------+
| |||
bool DPCCTestFrozenPolicy(string &reason)
| |||
{
| |||
CNet *market = EXTMarket.ReadyMarketNetwork();
| |||
CNet *networks[] = {market, EXTActor, EXTQ1, EXTQ2};
| |||
const int layers[] = {8, 2, 5, 5};
| |||
COpenCLMy *context = EXTMarket.ReadyEncoderContext();
| |||
if(CheckPointer(context) == POINTER_INVALID)
| |||
{
| |||
reason = "test.frozen.market_context";
| |||
return(false);
| |||
}
| |||
for(int i = 0; i < ArraySize(networks); i++)
| |||
{
| |||
if(CheckPointer(networks[i]) == POINTER_INVALID || !networks[i].IsOpenCLTransferReady() ||
| |||
networks[i].GetOpenCL() != context || networks[i].WeightsUpdateEnabled() ||
| |||
networks[i].Layer(layers[i]) != NULL)
| |||
{
| |||
reason = StringFormat("test.frozen.graph_or_permission.%d", i);
| |||
return(false);
| |||
}
| |||
for(int j = 0; j < i; j++)
| |||
if(networks[i] == networks[j])
| |||
{
| |||
reason = "test.frozen.network_alias";
| |||
return(false);
| |||
}
| |||
for(int l = 0; l < layers[i]; l++)
| |||
{
| |||
CNeuronBaseOCL *layer = networks[i].Layer(l);
| |||
if(CheckPointer(layer) == POINTER_INVALID || layer.GetOpenCL() != context || layer.TrainMode())
| |||
{
| |||
reason = StringFormat("test.frozen.layer.%d.%d", i, l);
| |||
return(false);
| |||
}
| |||
}
| |||
}
| |||
CNeuronDPCCOCL *actor = dynamic_cast<CNeuronDPCCOCL*>(EXTActor.Layer(1));
| |||
if(!actor || actor.Type() != defNeuronDPCCOCL || actor.ActorABI() != 3 ||
| |||
!NNQCriticGraph(EXTQ1) || !NNQCriticGraph(EXTQ2))
| |||
{
| |||
reason = "test.frozen.Action6_graph";
| |||
return(false);
| |||
}
| |||
reason = "";
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Allocate the live Market Z snapshot from its actual frozen axes |
| |||
//+------------------------------------------------------------------+
| |||
bool DPCCTestPrepareMarketSnapshot(string &reason)
| |||
{
| |||
CNet *market = EXTMarket.ReadyMarketNetwork();
| |||
COpenCLMy *context = EXTMarket.ReadyEncoderContext();
| |||
CNeuronScenarioForecastPriceOCL *forecast = NULL;
| |||
if(CheckPointer(market) != POINTER_INVALID)
| |||
forecast = dynamic_cast<CNeuronScenarioForecastPriceOCL*>(market.Layer(6));
| |||
ulong count = 0;
| |||
if(!forecast || CheckPointer(context) == POINTER_INVALID || forecast.GetOpenCL() != context ||
| |||
forecast.Type() != defNeuronScenarioForecastPriceOCL || forecast.CodebookUpdate() ||
| |||
!DPCCRolloutProduct(forecast.Scenarios(), forecast.Variables(), count) ||
| |||
!DPCCRolloutProduct(count, forecast.Horizon(), count) ||
| |||
!DPCCRolloutProduct(count, forecast.Dimension(), count) || count == 0 ||
| |||
count > (ulong)INT_MAX || count > (ulong)UINT_MAX / sizeof(float))
| |||
{
| |||
reason = "test.market.snapshot_axes_or_frozen_contract";
| |||
return(false);
| |||
}
| |||
if(!EXTCurrentZ.BufferInit((uint)count, 0) || !EXTCurrentZ.BufferCreate(context))
| |||
{
| |||
reason = "test.market.snapshot_allocation";
| |||
return(false);
| |||
}
| |||
reason = "";
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Close the Actor frame before releasing its Market generation |
| |||
//+------------------------------------------------------------------+
| |||
bool DPCCTestReleaseGeneration(const ulong generation, string &reason)
| |||
{
| |||
if(generation == 0)
| |||
{
| |||
reason = "test.market.zero_generation";
| |||
return(false);
| |||
}
| |||
CNeuronDPCCOCL *actor = CheckPointer(EXTActor) == POINTER_INVALID ? NULL :
| |||
dynamic_cast<CNeuronDPCCOCL*>(EXTActor.Layer(1));
| |||
if(!actor || !actor.CancelGeneration())
| |||
{
| |||
reason = "test.Actor_frame_release";
| |||
return(false);
| |||
}
| |||
return(EXTMarket.ReleaseReadyEncoderZ(generation, reason));
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Initialize the assigned frozen policy for February 2026 |
| |||
//+------------------------------------------------------------------+
| |||
int OnInit(void)
| |||
{
| |||
for(int i = 0; i < 4; i++)
| |||
EXTIndicators[i] = INVALID_HANDLE;
| |||
string reason = "";
| |||
//--- Configure the package and load its embedded Market profile before restoration.
| |||
if(!DPCCConfigureExecutionControl(DPCC_PACKAGE_ROOT, InpTimeframe, DPCC_STAGE_TEST, "",
| |||
0, DPCC_RESUME_NEW, InpMode, DPCC_STAGE_TEST, EXTControl, reason) ||
| |||
!DPCCLoadMarketExecutionProfile(EXTControl, DPCC_COMMON_FILES, reason))
| |||
{
| |||
DPCCTestStop("execution_control", reason);
| |||
return(INIT_PARAMETERS_INCORRECT);
| |||
}
| |||
if(InpMagic < 1)
| |||
{
| |||
DPCCTestStop("profile_control", "H1_frozen_Test_without_update_budget_required");
| |||
return(INIT_PARAMETERS_INCORRECT);
| |||
}
| |||
if(!DPCCTesterOnly(reason) || !DPCCRequireTesterOneDirection(reason))
| |||
{
| |||
DPCCTestStop("environment", reason);
| |||
return(INIT_FAILED);
| |||
}
| |||
if(_Symbol == "" || AccountInfoString(ACCOUNT_CURRENCY) == "" ||
| |||
PositionsTotal() != 0 || OrdersTotal() != 0)
| |||
{
| |||
DPCCTestStop("environment", "flat_owned_Tester_start_required");
| |||
return(INIT_FAILED);
| |||
}
| |||
//--- D01 role validation and shared-context restoration belong to the shared loader.
| |||
if(!DPCCTestRestoreFrozenTrading(reason))
| |||
{
| |||
DPCCTestStop("D01_frozen_restore", reason);
| |||
return(INIT_FAILED);
| |||
}
| |||
if(!DPCCResolverLowerSha256(EXTMarketSHA) || !DPCCResolverLowerSha256(EXTTradingSHA) ||
| |||
EXTNoiseSeed == 0 || !MathIsValidNumber(EXTTPCapPoints) || EXTTPCapPoints <= 0 ||
| |||
!MathIsValidNumber(EXTSLCapPoints) || EXTSLCapPoints <= 0 ||
| |||
EXTRuntime.financial.mode != EXTControl.mode || !DPCCTestFrozenPolicy(reason))
| |||
{
| |||
DPCCTestStop("frozen_policy", reason == "" ? "authenticated_policy_contract_required" : reason);
| |||
return(INIT_FAILED);
| |||
}
| |||
CNeuronDPCCOCL *actor = dynamic_cast<CNeuronDPCCOCL*>(EXTActor.Layer(1));
| |||
if(!actor.BindPolicyNetworks(EXTMarket.ReadyMarketNetwork(), EXTQ1, EXTQ2))
| |||
{
| |||
DPCCTestStop("frozen_policy", "Actor_inference_dependencies");
| |||
return(INIT_FAILED);
| |||
}
| |||
if(!DPCCTestPrepareMarketSnapshot(reason))
| |||
{
| |||
DPCCTestStop("market_snapshot", reason);
| |||
return(INIT_FAILED);
| |||
}
| |||
if(!EXTActorAccount.BufferInit(13, 0) ||
| |||
!EXTActorAccount.BufferCreate(EXTMarket.ReadyEncoderContext()))
| |||
{
| |||
DPCCTestStop("account_input", "persistent_Account13_buffer");
| |||
return(INIT_FAILED);
| |||
}
| |||
EXTIndicators[0] = iRSI(_Symbol, EXTControl.timeframe, RSIPeriod, RSIPrice);
| |||
EXTIndicators[1] = iCCI(_Symbol, EXTControl.timeframe, CCIPeriod, CCIPrice);
| |||
EXTIndicators[2] = iATR(_Symbol, EXTControl.timeframe, ATRPeriod);
| |||
EXTIndicators[3] = iMACD(_Symbol, EXTControl.timeframe, FastPeriod, SlowPeriod, SignalPeriod, MACDPrice);
| |||
for(int i = 0; i < 4; i++)
| |||
if(EXTIndicators[i] == INVALID_HANDLE)
| |||
{
| |||
DPCCTestStop("indicators", (string)GetLastError());
| |||
return(INIT_FAILED);
| |||
}
| |||
EXTInitialBalance = AccountInfoDouble(ACCOUNT_BALANCE);
| |||
EXTInitialEquity = AccountInfoDouble(ACCOUNT_EQUITY);
| |||
if(!MathIsValidNumber(EXTInitialBalance) || !MathIsValidNumber(EXTInitialEquity) ||
| |||
EXTInitialBalance < 50 || EXTInitialEquity < 50)
| |||
{
| |||
DPCCTestStop("account", "actual_Tester_start_below_floor");
| |||
return(INIT_FAILED);
| |||
}
| |||
EXTReady = true;
| |||
Print("DPCC_TEST_READY policy=FROZEN_ACTION6 Q1_Q2=FROZEN_INFERENCE_ONLY tester_interval=FULL",
| |||
" market_sha256=", EXTMarketSHA,
| |||
" trading_sha256=", EXTTradingSHA, " profile_sha256=", EXTControl.profile_sha256);
| |||
return(INIT_SUCCEEDED);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Evaluate the first quote of each H1 bar in the Tester interval |
| |||
//+------------------------------------------------------------------+
| |||
void OnTick(void)
| |||
{
| |||
if(!EXTReady || EXTStopped || IsStopped())
| |||
return;
| |||
const long open = (long)iTime(_Symbol, EXTControl.timeframe, 0);
| |||
if(open <= 0 || open == EXTBarOpen)
| |||
return;
| |||
string reason = "";
| |||
if(!DPCCRequireTesterOneDirection(reason))
| |||
{
| |||
DPCCTestStop("environment", reason);
| |||
return;
| |||
}
| |||
if(iVolume(_Symbol, EXTControl.timeframe, 0) != 1 ||
| |||
(EXTBarOpen > 0 && (long)iTime(_Symbol, EXTControl.timeframe, 1) != EXTBarOpen))
| |||
{
| |||
DPCCTestStop("chronology", "first_H1_quote_required_no_hindsight_repair");
| |||
return;
| |||
}
| |||
const double balance = AccountInfoDouble(ACCOUNT_BALANCE);
| |||
const double equity = AccountInfoDouble(ACCOUNT_EQUITY);
| |||
if(!MathIsValidNumber(balance) || !MathIsValidNumber(equity) || balance < 50 || equity < 50)
| |||
{
| |||
DPCCTestStop("floor", "actual_balance_or_equity_below_50");
| |||
return;
| |||
}
| |||
//--- Capture the closed predecessor and only the observed first quote of its successor.
| |||
const ulong decision_started = GetMicrosecondCount();
| |||
SDPCCClosedHistoryRow closed;
| |||
MqlTick tick;
| |||
long quote_mode = -1;
| |||
double tick_size = 0;
| |||
if(!DPCCCaptureTesterClosedRow(_Symbol, EXTIndicators, 1, closed, reason) ||
| |||
closed.successor_open_server != open || !SymbolInfoTick(_Symbol, tick) ||
| |||
tick.time_msc < open * 1000 || tick.time_msc >= (open + 3600) * 1000 ||
| |||
!SymbolInfoInteger(_Symbol, SYMBOL_CHART_MODE, quote_mode) ||
| |||
!SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE, tick_size) ||
| |||
(quote_mode != SYMBOL_CHART_MODE_BID && quote_mode != SYMBOL_CHART_MODE_LAST))
| |||
{
| |||
DPCCTestStop("closed_history", reason == "" ? "causal_H1_quote_binding" : reason);
| |||
return;
| |||
}
| |||
//--- Replay pre-start chart history before the first policy decision.
| |||
if(EXTDecisions == 0 &&
| |||
!DPCCPrepareReadyMarketLiveStart(EXTMarket, _Symbol, EXTIndicators,
| |||
closed.bar.server_open, reason))
| |||
{
| |||
DPCCTestStop("market_warmup", reason);
| |||
return;
| |||
}
| |||
const double first_quote = (quote_mode == SYMBOL_CHART_MODE_LAST ? tick.last : tick.bid);
| |||
ulong generation = 0;
| |||
const ulong market_started = GetMicrosecondCount();
| |||
if(!EXTMarket.InferReadyMarketLive(closed, first_quote, tick.time_msc, tick_size,
| |||
GetPointer(EXTCurrentZ), generation, reason))
| |||
{
| |||
DPCCTestStop("market_inference", reason);
| |||
return;
| |||
}
| |||
const ulong market_us = GetMicrosecondCount() - market_started;
| |||
//--- Build the physical context without future bars and evaluate the frozen policy.
| |||
CBufferFloat *context = NULL;
| |||
float account[], action[];
| |||
bool prepared = DPCCTestDecisionContext(open, EXTMarket.ReadyMarketNativeOHLC(), context, account, reason);
| |||
if(prepared)
| |||
prepared = (ArraySize(account) == 13 && CheckPointer(context) != POINTER_INVALID);
| |||
if(prepared)
| |||
for(int i = 0; i < 13; i++)
| |||
if(!MathIsValidNumber(account[i]) || !EXTActorAccount.Update(i, account[i]))
| |||
{
| |||
reason = "test.Account13_input";
| |||
prepared = false;
| |||
break;
| |||
}
| |||
CNeuronDPCCOCL *actor = dynamic_cast<CNeuronDPCCOCL*>(EXTActor.Layer(1));
| |||
SDPCCDecisionMeta meta;
| |||
ZeroMemory(meta);
| |||
meta.decision_id = (ulong)EXTDecisions + 1;
| |||
meta.market_state_id = generation;
| |||
meta.q1_state_id = meta.decision_id;
| |||
meta.q2_state_id = meta.decision_id + 1;
| |||
meta.noise_seed = EXTNoiseSeed;
| |||
meta.decision_server_time = open;
| |||
meta.bar_index = (long)EXTDecisions;
| |||
meta.mode = (uint)EXTControl.mode;
| |||
meta.market_sha256 = EXTMarketSHA;
| |||
meta.profile_sha256 = EXTControl.profile_sha256;
| |||
const ulong actor_started = GetMicrosecondCount();
| |||
if(prepared)
| |||
prepared = EXTActorAccount.BufferWrite() && actor.BindDecisionContext(context, meta);
| |||
bool actor_forwarded = false;
| |||
if(prepared)
| |||
actor_forwarded = EXTActor.feedForward(GetPointer(EXTActorAccount), 1, false,
| |||
EXTMarket.ReadyMarketNetwork(), 6);
| |||
if(prepared)
| |||
{
| |||
string action_reason = "";
| |||
prepared = DPCCResolveAction6Output(actor, actor_forwarded, action, action_reason);
| |||
if(!prepared)
| |||
reason = "test." + action_reason;
| |||
}
| |||
if(!prepared && reason == "")
| |||
reason = "test.Action6_forward_or_output";
| |||
const ulong actor_us = GetMicrosecondCount() - actor_started;
| |||
string release_reason = "";
| |||
const bool released = DPCCTestReleaseGeneration(generation, release_reason);
| |||
if(!prepared || !released)
| |||
{
| |||
DPCCTestStop("policy_generation", !released ? "release:" + release_reason + ";" + reason : reason);
| |||
return;
| |||
}
| |||
//--- Execute only the published first Action6 through the existing Tester adapter.
| |||
const ulong execution_started = GetMicrosecondCount();
| |||
if(!DPCCExecuteTesterAction(_Symbol, InpMagic, action, EXTTPCapPoints, EXTSLCapPoints, reason))
| |||
{
| |||
DPCCTestStop("Tester_execution", reason);
| |||
return;
| |||
}
| |||
const ulong execution_us = GetMicrosecondCount() - execution_started;
| |||
const ulong decision_us = GetMicrosecondCount() - decision_started;
| |||
EXTBarOpen = open;
| |||
if(EXTFirstDecision == 0)
| |||
EXTFirstDecision = open;
| |||
EXTDecisions++;
| |||
if(InpMeasureLatency)
| |||
{
| |||
EXTLatencySamples++;
| |||
EXTMarketLatencyUs += market_us;
| |||
EXTActorLatencyUs += actor_us;
| |||
EXTExecutionLatencyUs += execution_us;
| |||
EXTDecisionLatencyUs += decision_us;
| |||
EXTDecisionLatencyMaxUs = MathMax(EXTDecisionLatencyMaxUs, decision_us);
| |||
}
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Mark normal completion of the Strategy Tester interval |
| |||
//+------------------------------------------------------------------+
| |||
double OnTester(void)
| |||
{
| |||
if(EXTReady && !EXTStopped)
| |||
EXTWindowCompleted = true;
| |||
return(0.0);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| Report observed results and release policy borrowers first |
| |||
//+------------------------------------------------------------------+
| |||
void OnDeinit(const int reason)
| |||
{
| |||
if(EXTReady)
| |||
Print("DPCC_TEST_RESULT decisions=", EXTDecisions, " first_server_open=", EXTFirstDecision,
| |||
" window_completed=", EXTWindowCompleted, " stopped=", EXTStopped,
| |||
" initial_balance=", DoubleToString(EXTInitialBalance, 2),
| |||
" final_balance=", DoubleToString(AccountInfoDouble(ACCOUNT_BALANCE), 2),
| |||
" initial_equity=", DoubleToString(EXTInitialEquity, 2),
| |||
" final_equity=", DoubleToString(AccountInfoDouble(ACCOUNT_EQUITY), 2),
| |||
" market_sha256=", EXTMarketSHA, " trading_sha256=", EXTTradingSHA, " deinit_reason=", reason);
| |||
if(InpMeasureLatency && EXTLatencySamples > 0)
| |||
PrintFormat("DPCC_TEST_LATENCY samples=%I64u market_mean_us=%.2f " +
| |||
"actor_mean_us=%.2f execution_mean_us=%.2f " +
| |||
"total_mean_us=%.2f total_max_us=%I64u",
| |||
EXTLatencySamples, (double)EXTMarketLatencyUs / (double)EXTLatencySamples,
| |||
(double)EXTActorLatencyUs / (double)EXTLatencySamples,
| |||
(double)EXTExecutionLatencyUs / (double)EXTLatencySamples,
| |||
(double)EXTDecisionLatencyUs / (double)EXTLatencySamples, EXTDecisionLatencyMaxUs);
| |||
EXTDecisionContext.Reset();
| |||
if(CheckPointer(EXTActor) != POINTER_INVALID)
| |||
delete EXTActor;
| |||
EXTActor = NULL;
| |||
if(CheckPointer(EXTQ2) != POINTER_INVALID)
| |||
delete EXTQ2;
| |||
EXTQ2 = NULL;
| |||
if(CheckPointer(EXTQ1) != POINTER_INVALID)
| |||
delete EXTQ1;
| |||
EXTQ1 = NULL;
| |||
for(int i = 0; i < 4; i++)
| |||
if(EXTIndicators[i] != INVALID_HANDLE)
| |||
IndicatorRelease(EXTIndicators[i]);
| |||
}
| |||
//+------------------------------------------------------------------+
|