//+------------------------------------------------------------------+ //| Study.mq5 | //| Copyright 2026, DNG | //| https://www.mql5.com/ru/users/dng | //+------------------------------------------------------------------+ #property copyright "Copyright 2026, DNG" #property version "1.00" #property description "DPCC offline Actor and Critic training with a frozen Market encoder" #property description "Uses historical bars and Oracle targets for supervised policy learning" #property description "Saves the latest Actor and Critic weights and optimizer moments" #property strict //--- This Expert Advisor advances one committed history row per timer event. #define DPCC_TRAJECTORY_ENTRY_STUDY #include "Trajectory.mqh" #undef DPCC_TRAJECTORY_ENTRY_STUDY input group "---- История и период обучения ----" input ENUM_TIMEFRAMES InpTimeframe = PERIOD_CURRENT; // PERIOD_CURRENT использует таймфрейм графика. input datetime InpTrainingStart = D'2025.01.01 00:00'; // Серверное время открытия бара; начало включительно. //--- Конец не включается; 12 будущих баров должны быть внутри периода. input datetime InpTrainingEnd = D'2026.01.01 00:00'; //--- История захватывается автоматически из выбранных закрытых баров. input group "---- Лимит и режим запуска ----" //--- Всего обновлений; 0 — один проход. При превышении окна оно повторяется. input ulong InpStopAfterUpdates = 0; //--- Начать с текущих весов или инициализировать новый запуск. input ENUM_DPCC_RESUME_MODE InpResumeMode = DPCC_RESUME_NEW; input ENUM_DPCC_MODE InpMode = DPCC_P0; // Режим DPCC P0/P1/P2. //--- Только подготовить и проверить входы, без обновления весов. input bool InpPreflightOnly = false; input group "---- Actor: параметры генерации действий ----" input ulong InpDiffusionSeed = 20261007; // Начальное значение генератора случайных чисел. input double InpDiffusionS = 0.008; // Масштаб шума при генерации торгового плана. input double InpDiffusionBetaCap = 0.999; // Верхняя граница beta расписания диффузии. input group "---- Critic: цель и дисконтирование ----" input int InpRiskType = defSRM_MEAN_CVAR; // Функция риска для распределительной цели Critic. input double InpRiskParameter = 0.1; // Параметр выбранной функции риска. input double InpMeanWeight = 0.0; // Вес средней доходности в SRM-цели. input double InpGamma = 0.5; // Коэффициент дисконтирования будущей награды. input group "---- Oracle: поиск целевого плана ----" input uint InpProjectionMaxIterations = 16; // Максимум итераций локального поиска. input uint InpProjectionMaxEvaluations = 160; // Максимум оценок кандидатов за одну строку. input uint InpProjectionLookbackSteps = 12; // Число шагов горизонта, используемых проекцией. input double InpProjectionImprovementAtol = 0.000001; // Минимальное абсолютное улучшение для продолжения поиска. input double InpProjectionDistanceTieAtol = 0.00000001; // Допуск расстояния при выборе равных кандидатов. input double InpOracleDelta1 = 0.1; // Шаг локального изменения координаты операции 1. input double InpOracleDelta2 = 0.1; // Шаг локального изменения координаты операции 2. input double InpOracleDelta3 = 0.1; // Шаг локального изменения координаты операции 3. input double InpOracleDelta4 = 0.1; // Шаг локального изменения координаты операции 4. input double InpOracleDelta5 = 0.1; // Шаг локального изменения координаты операции 5. input double InpOracleDelta6 = 0.1; // Шаг локального изменения координаты операции 6. input group "---- Ограничения счёта и защиты ----" input double InpMinEquity = 50.0; // Остановить обучение при эквити ниже этого значения. input double InpMaxSLPoints = 1000.0; // Максимальное расстояние Stop Loss в points. input double InpMaxTPPoints = 1000.0; // Максимальное расстояние Take Profit в points. const string DPCC_PACKAGE_ROOT = "DPCC/StudyForecast_M05_20261017"; const string DPCC_STUDY_OUTPUT_STEM = "M/Study"; const bool DPCC_RESTORE_LATEST_TRAINING_WEIGHTS = true; const string DPCC_TRAINING_STATE_PATH = "DPCC/StudyAction6.latest"; const bool DPCC_COMMON_FILES = true; string g_dpcc_market_path = ""; string g_dpcc_market_profile_text = ""; ENUM_TIMEFRAMES g_dpcc_timeframe = PERIOD_CURRENT; SDPCCAPNativeLoadContract g_dpcc_market_contract; float g_dpcc_condition_scale[], g_dpcc_condition_bias[]; SDPCCRuntimeConfig g_dpcc_runtime; float g_dpcc_limits[]; SDPCCOracleHistoryInput g_dpcc_input_source; CDPCCMarketClock g_dpcc_clock; CDPCCStudyStageConsumer g_dpcc_runner; CDPCCStopButton g_dpcc_stop_button; bool g_dpcc_initialized = false; bool g_dpcc_finalize_pending = false; bool g_dpcc_policy_state_restored = false; bool g_dpcc_floor_reached = false; bool g_dpcc_stop_save_failed = false; ulong g_dpcc_completed = 0; ulong g_dpcc_update_target = 0; ulong g_dpcc_completed_epochs = 0; uint g_dpcc_epoch_row = 0; //+------------------------------------------------------------------+ //| Study progress metrics | //+------------------------------------------------------------------+ double EXTDPCCRewardSum = 0.0; double EXTDPCCTeacherScoreSum = 0.0; double EXTDPCCLastReward = 0.0; double EXTDPCCLastTeacherScore = 0.0; //+------------------------------------------------------------------+ //| Initialize source, model graphs, and optional weights-only state | //+------------------------------------------------------------------+ bool DPCCStudyInitialize(string &reason) { reason = ""; float oracle_deltas[6]; oracle_deltas[0] = (float)InpOracleDelta1; oracle_deltas[1] = (float)InpOracleDelta2; oracle_deltas[2] = (float)InpOracleDelta3; oracle_deltas[3] = (float)InpOracleDelta4; oracle_deltas[4] = (float)InpOracleDelta5; oracle_deltas[5] = (float)InpOracleDelta6; if(!DPCCBuildAction6RuntimeFromInputs(InpMode, InpDiffusionSeed, InpDiffusionS, InpDiffusionBetaCap, InpRiskType, InpRiskParameter, InpMeanWeight, InpGamma, InpProjectionMaxIterations, InpProjectionMaxEvaluations, InpProjectionLookbackSteps, InpProjectionImprovementAtol, InpProjectionDistanceTieAtol, InpMinEquity, InpMaxSLPoints, InpMaxTPPoints, g_dpcc_runtime, g_dpcc_limits, reason)) { reason = "action6_runtime=" + reason; return(false); } const long period_seconds = (long)PeriodSeconds(g_dpcc_timeframe); const long warmup_seconds = (long)DPCC_ENCODER_WARMUP_HISTORY * period_seconds; const datetime capture_from = (datetime)((long)InpTrainingStart - warmup_seconds); string raw_path = "", raw_sha = "", capture_reason = ""; uint raw_rows = 0; if(period_seconds <= 0 || capture_from <= 0 || !DPCCCaptureStudyForecastRaw(_Symbol, g_dpcc_timeframe, capture_from, InpTrainingEnd, raw_path, raw_sha, raw_rows, capture_reason, false, RSIPrice, CCIPrice, MACDPrice, true, DPCC_COMMON_FILES)) { reason = "source_capture=" + (capture_reason == "" ? "invalid_history_range" : capture_reason); return(false); } Print("DPCC_STUDY_RAW_INPUT_CAPTURE timeframe=", EnumToString(g_dpcc_timeframe), " rows=", raw_rows, " from=", (string)capture_from, " to=", (string)InpTrainingEnd); if(!DPCCLoadOracleHistoryInput(DPCC_PACKAGE_ROOT, InpTrainingStart, InpTrainingEnd, g_dpcc_runtime, g_dpcc_limits, raw_path, DPCC_STUDY_OUTPUT_STEM, oracle_deltas, DPCC_COMMON_FILES, g_dpcc_timeframe, g_dpcc_market_path, g_dpcc_market_profile_text, g_dpcc_market_contract, g_dpcc_input_source, reason)) { if(reason == "") reason = "terminal_files_required"; return(false); } long server_opens[]; const int count = ArraySize(g_dpcc_input_source.raw_bars); if(ArrayResize(server_opens, count) != count) { reason = "server_calendar_capacity"; return(false); } for(int i = 0; i < count; i++) server_opens[i] = g_dpcc_input_source.raw_bars[i].server_open; if(!g_dpcc_clock.InitializeHistoricalServerCalendar(server_opens, reason, g_dpcc_timeframe)) return(false); if(!g_dpcc_runner.InitializeAction6History(g_dpcc_input_source.config, (uint)ArraySize(g_dpcc_input_source.decision_bars), g_dpcc_input_source.deltas, g_dpcc_input_source.actor_beta, g_dpcc_input_source.actor_alpha_bar, g_dpcc_input_source.actor_sigma, InpMode, g_dpcc_timeframe, g_dpcc_input_source.raw_bars, g_dpcc_input_source.source_server, g_dpcc_input_source.raw_indicator_params, g_dpcc_input_source.raw_successor_open_server, g_dpcc_input_source.raw_path, g_dpcc_market_profile_text, g_dpcc_market_path, g_dpcc_market_contract, g_dpcc_condition_scale, g_dpcc_condition_bias, DPCC_COMMON_FILES, reason)) { reason = "action6_init=" + reason; return(false); } if(!g_dpcc_runner.BindHistoryProvenance(g_dpcc_input_source, reason)) { reason = "action6_provenance=" + reason; return(false); } if(!InpPreflightOnly && DPCC_RESTORE_LATEST_TRAINING_WEIGHTS) { const string checkpoint_manifest = DPCC_TRAINING_STATE_PATH + ".manifest"; const int file_flags = (DPCC_COMMON_FILES ? FILE_COMMON : 0); if(FileIsExist(checkpoint_manifest, file_flags)) { string restored_manifest = ""; if(!g_dpcc_runner.LoadAction6TrainingStateOnly(DPCC_TRAINING_STATE_PATH, DPCC_COMMON_FILES, restored_manifest, reason)) { reason = "training_state_restore=" + reason; return(false); } g_dpcc_policy_state_restored = true; Print("DPCC_STUDY_POLICY_STATE restored=1 scope=weights_and_adam_only manifest=", restored_manifest, " data_binding=NONE row_cursor=NOT_SAVED account=NOT_SAVED"); } else Print("DPCC_STUDY_POLICY_STATE restored=0 source=initialized_parameters"); } const int rows = ArraySize(g_dpcc_input_source.decision_bars); if(rows <= 0) { reason = "study.history.no_decision_rows"; return(false); } g_dpcc_completed = 0; g_dpcc_completed_epochs = 0; g_dpcc_epoch_row = 0; g_dpcc_update_target = (InpStopAfterUpdates > 0 ? InpStopAfterUpdates : (ulong)rows); reason = ""; return(true); } //+------------------------------------------------------------------+ //| Emit the existing read-only Study preflight receipt | //+------------------------------------------------------------------+ void DPCCStudyLogPreflight(void) { Print("DPCC_STUDY_PREFLIGHT_COMPLETE rows=", ArraySize(g_dpcc_input_source.decision_bars), " no_training_updates=1 no_model_exports=1 no_orders=1"); Print("DPCC_STUDY_PREFLIGHT_INPUT package_root=", DPCC_PACKAGE_ROOT, " raw_rows=", ArraySize(g_dpcc_input_source.raw_bars), " output_stem=", DPCC_STUDY_OUTPUT_STEM); Print("DPCC_STUDY_PREFLIGHT_SOURCE symbol=", _Symbol, " timeframe=", EnumToString(g_dpcc_timeframe), " server=", g_dpcc_input_source.source_server); Print("DPCC_STUDY_PREFLIGHT_CLOCK time_domain=", g_dpcc_clock.TimeDomain()); Print("DPCC_STUDY_PREFLIGHT_MODEL market_profile_sha256=", g_dpcc_input_source.model_sha, " config_sha256=", g_dpcc_input_source.config_sha, " market=", g_dpcc_market_path, " market_profile_sha256=", g_dpcc_market_contract.profile_sha256); for(int i = 0; i < ArraySize(g_dpcc_input_source.source_labels); i++) Print("DPCC_STUDY_PREFLIGHT_PIN label=", g_dpcc_input_source.source_labels[i], " path=", g_dpcc_input_source.source_paths[i], " sha256=", g_dpcc_input_source.source_hashes[i]); } //+------------------------------------------------------------------+ //| Render Study progress and committed learning metrics | //+------------------------------------------------------------------+ void DPCCStudyRenderProgress(const int rows, const int active_row) { const ulong target_updates = g_dpcc_update_target; if(rows <= 0 || target_updates == 0) { Comment(""); return; } const double percent = 100.0 * (double)g_dpcc_completed / (double)target_updates; const ulong total_epochs = target_updates / (ulong)rows + (target_updates % (ulong)rows > 0 ? 1 : 0); ulong current_epoch = g_dpcc_completed_epochs + 1; uint current_row = (active_row > 0 ? (uint)active_row : g_dpcc_epoch_row); if(current_row > (uint)rows) current_row = (uint)rows; if(g_dpcc_completed >= target_updates && target_updates % (ulong)rows == 0) { current_epoch = total_epochs; current_row = (uint)rows; } string status = "Study ACTION6: " + DoubleToString(percent, 2) + "% (" + (string)g_dpcc_completed + "/" + (string)target_updates + ")"; status += "\nEpoch: " + (string)current_epoch + "/" + (string)total_epochs + " | row: " + (string)current_row + "/" + (string)rows; if(active_row > 0) status += " | processing"; if(g_dpcc_completed > 0) { const double count = (double)g_dpcc_completed; status += "\nReward last/mean: " + DoubleToString(EXTDPCCLastReward, 2) + " / " + DoubleToString(EXTDPCCRewardSum / count, 2); status += "\nOracle last/mean: " + DoubleToString(EXTDPCCLastTeacherScore, 2) + " / " + DoubleToString(EXTDPCCTeacherScoreSum / count, 2) + " | floor=" + (g_dpcc_floor_reached ? "true" : "false"); } else status += "\nReward: waiting | Oracle: waiting"; Comment(status); ChartRedraw(0); } //+------------------------------------------------------------------+ //| Save only current policy weights and Adam moments | //+------------------------------------------------------------------+ bool DPCCStudySaveTrainingState(const string cause) { if(g_dpcc_completed == 0) return(true); string manifest = "", sha = "", reason = ""; const bool saved = g_dpcc_runner.SaveAction6TrainingStateOnly(DPCC_TRAINING_STATE_PATH, DPCC_COMMON_FILES, manifest, sha, reason); Print("DPCC_STUDY_POLICY_STATE cause=", cause, " saved=", (saved ? 1 : 0), " updates=", g_dpcc_completed, " contents=actor_q1_q2_weights_and_adam", " row_cursor=NOT_SAVED account=NOT_SAVED data_binding=NONE", " manifest=", manifest, " sha256=", sha, " reason=", reason); return(saved); } //+------------------------------------------------------------------+ //| Publish completed Study output only at an accepted phase | //| boundary | //+------------------------------------------------------------------+ void DPCCStudyFinalize(void) { EventKillTimer(); DPCCStudyRenderProgress(ArraySize(g_dpcc_input_source.decision_bars), 0); if(!DPCCStudySaveTrainingState("TRAINING_BOUNDARY")) { g_dpcc_stop_save_failed = true; g_dpcc_stop_button.SetText("Retry save and stop"); DPCCStudyRenderProgress(ArraySize(g_dpcc_input_source.decision_bars), 0); Print("DPCC_STUDY_HISTORY_BLOCKED phase=training_state_save updates=", g_dpcc_completed, " action=await_button_retry"); return; } const ulong target_updates = g_dpcc_update_target; const bool complete = (g_dpcc_completed >= target_updates); if(complete || g_dpcc_floor_reached) { string manifest = "", sha = "", reason = ""; if(!g_dpcc_runner.SaveAction6HistoryModels(g_dpcc_completed, g_dpcc_completed_epochs, manifest, sha, reason)) Print("DPCC_STUDY_HISTORY_BLOCKED phase=action6_export reason=", reason, " updates=", g_dpcc_completed, "/", target_updates); else Print("DPCC_STUDY_ACTION6_ROWS_COMPLETE updates=", g_dpcc_completed, "/", target_updates, " floor=", (g_dpcc_floor_reached ? "true" : "false"), " model_export=PASS manifest=", manifest, " sha256=", sha); } else Print("DPCC_STUDY_ACTION6_ROWS_COMPLETE updates=", g_dpcc_completed, "/", target_updates, " model_export=SKIPPED_partial_pass training_state=LATEST_WEIGHTS_ONLY"); g_dpcc_stop_button.RemoveAdvisor(); } //+------------------------------------------------------------------+ //| Expert lifecycle | //+------------------------------------------------------------------+ int OnInit() { SDPCCExecutionControl control; string control_reason = ""; if(!DPCCConfigureExecutionControl(DPCC_PACKAGE_ROOT, InpTimeframe, DPCC_STAGE_STUDY, "", InpStopAfterUpdates, InpResumeMode, InpMode, DPCC_STAGE_STUDY, control, control_reason, true)) { Print("DPCC_STUDY_BLOCKED phase=profile_control reason=", control_reason); return(INIT_PARAMETERS_INCORRECT); } g_dpcc_timeframe = control.timeframe; if(!DPCCLoadMarketExecutionProfile(control, DPCC_COMMON_FILES, control_reason)) { Print("DPCC_STUDY_BLOCKED phase=market_training_admission reason=", control_reason); return(INIT_PARAMETERS_INCORRECT); } g_dpcc_market_path = control.market_path; g_dpcc_market_profile_text = control.profile_text; g_dpcc_market_contract = control.market_contract; if(ArrayCopy(g_dpcc_condition_scale, control.condition_scale) != 109 || ArrayCopy(g_dpcc_condition_bias, control.condition_bias) != 109) { Print("DPCC_STUDY_BLOCKED phase=market_condition_binding reason=condition_vector_shape"); return(INIT_PARAMETERS_INCORRECT); } Print("DPCC_STUDY_MARKET_ADMITTED ready=", g_dpcc_market_contract.market_ready, " OMPB_calibration_completed=", g_dpcc_market_contract.calibration_completed, " OMPB_quality_pass=", g_dpcc_market_contract.stage02_quality_pass, " stage=", g_dpcc_market_contract.stage); if(!InpPreflightOnly && !g_dpcc_stop_button.Create("STUDY", "Stop and save")) { Print("DPCC_STUDY_BLOCKED phase=stop_button reason=chart_object_create_failed error=", GetLastError()); return(INIT_FAILED); } if(!EventSetMillisecondTimer(1)) { g_dpcc_stop_button.Delete(); Print("DPCC_STUDY_TIMER_INIT_FAILED error=", GetLastError()); return(INIT_FAILED); } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Function OnDeinit | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { EventKillTimer(); Comment(""); g_dpcc_stop_button.Delete(); } //+------------------------------------------------------------------+ //| Initialize once, then process at most one history bar per timer | //+------------------------------------------------------------------+ void OnTimer(void) { if(!g_dpcc_initialized) { if(!InpPreflightOnly) Comment("Study ACTION6: initializing history and model..."); string reason = ""; if(!DPCCStudyInitialize(reason)) { EventKillTimer(); Comment(""); Print("DPCC_STUDY_HISTORY_BLOCKED ", reason); g_dpcc_stop_button.RemoveAdvisor(); return; } g_dpcc_initialized = true; if(InpPreflightOnly) { Comment(""); DPCCStudyLogPreflight(); EventKillTimer(); g_dpcc_stop_button.RemoveAdvisor(); return; } Print("DPCC_STUDY_ACTION6_GRAPH_READY market=", g_dpcc_market_path, " actor=initialized q1=initialized q2=initialized legacy_z_route=inactive", " row_update=enabled mode=", EnumToString(InpMode), " updates_target=", g_dpcc_update_target, " restored_policy_weights=", (g_dpcc_policy_state_restored ? "true" : "false"), " stop_control=ready"); DPCCStudyRenderProgress(ArraySize(g_dpcc_input_source.decision_bars), 0); return; } if(g_dpcc_finalize_pending) { DPCCStudyFinalize(); return; } if(IsStopped()) { EventKillTimer(); Print("DPCC_STUDY_HISTORY_STOPPED rows=", g_dpcc_completed, " checkpoint=use_chart_stop_button_for_controlled_save"); g_dpcc_stop_button.RemoveAdvisor(); return; } const int rows = ArraySize(g_dpcc_input_source.decision_bars); if(g_dpcc_completed >= g_dpcc_update_target) { g_dpcc_finalize_pending = true; return; } if(g_dpcc_epoch_row >= (uint)rows) { string reason = ""; if(!g_dpcc_runner.BeginAction6HistoryPass(reason)) { EventKillTimer(); Print("DPCC_STUDY_HISTORY_BLOCKED phase=epoch_reset epoch=", g_dpcc_completed_epochs + 1, " reason=", reason); g_dpcc_stop_button.RemoveAdvisor(); return; } g_dpcc_completed_epochs++; g_dpcc_epoch_row = 0; g_dpcc_floor_reached = false; Print("DPCC_STUDY_EPOCH_COMPLETE epoch=", g_dpcc_completed_epochs, " rows=", rows, " updates=", g_dpcc_completed, "/", g_dpcc_update_target); DPCCStudyRenderProgress(rows, 1); return; } DPCCStudyRenderProgress(rows, (int)g_dpcc_epoch_row + 1); SDPCCOracleHistoryRow row; SDPCCOfflineRowResult result; string reason = ""; if(!DPCCBuildOracleHistoryRow(g_dpcc_input_source, (int)g_dpcc_epoch_row, g_dpcc_clock, row, reason)) { DPCCStudyRenderProgress(rows, 0); EventKillTimer(); Print("DPCC_STUDY_HISTORY_BLOCKED epoch=", g_dpcc_completed_epochs + 1, " row=", g_dpcc_epoch_row, " phase=row_build reason=", reason); g_dpcc_stop_button.RemoveAdvisor(); return; } if(!g_dpcc_runner.StepAction6History(g_dpcc_clock, row, result, reason) || !result.committed) { DPCCStudyRenderProgress(rows, 0); EventKillTimer(); Print("DPCC_STUDY_HISTORY_BLOCKED epoch=", g_dpcc_completed_epochs + 1, " row=", g_dpcc_epoch_row, " phase=action6_update reason=", reason); g_dpcc_stop_button.RemoveAdvisor(); return; } g_dpcc_epoch_row = (uint)result.next_row; g_dpcc_completed++; g_dpcc_floor_reached = result.floor_reached; EXTDPCCLastReward = result.reward; EXTDPCCLastTeacherScore = result.teacher_score; EXTDPCCRewardSum += result.reward; EXTDPCCTeacherScoreSum += result.teacher_score; DPCCStudyRenderProgress(rows, 0); if(result.next_row % 1000 == 0 || result.floor_reached || g_dpcc_epoch_row >= (uint)rows) Print("DPCC_STUDY_HISTORY_PROGRESS epoch=", g_dpcc_completed_epochs + 1, " row=", result.next_row, "/", rows, " updates=", g_dpcc_completed, "/", g_dpcc_update_target, " reward=", DoubleToString(result.reward, 2), " oracle_return=", DoubleToString(result.teacher_score, 2), " floor=", (result.floor_reached ? "true" : "false")); if(result.floor_reached || g_dpcc_completed >= g_dpcc_update_target) g_dpcc_finalize_pending = true; } //+------------------------------------------------------------------+ //| Function OnChartEvent | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(!g_dpcc_stop_button.Clicked(id, sparam)) return; DPCCStudyRenderProgress(ArraySize(g_dpcc_input_source.decision_bars), 0); EventKillTimer(); g_dpcc_stop_button.SetText(g_dpcc_stop_save_failed ? "Retrying save..." : "Saving and stopping..."); if(g_dpcc_initialized && g_dpcc_completed > 0) { if(!DPCCStudySaveTrainingState("CONTROLLED_STOP")) { g_dpcc_stop_save_failed = true; g_dpcc_stop_button.SetText("Retry save and stop"); DPCCStudyRenderProgress(ArraySize(g_dpcc_input_source.decision_bars), 0); return; } } else Print("DPCC_STUDY_CONTROLLED_STOP no_policy_update=1 existing_checkpoint_unchanged=1"); g_dpcc_stop_save_failed = false; Print("DPCC_STUDY_CONTROLLED_STOP saved=", (g_dpcc_completed > 0 ? "true" : "not_needed"), " action=remove_advisor"); g_dpcc_stop_button.RemoveAdvisor(); } //+------------------------------------------------------------------+