using System; using System.Windows.Forms; using WeifenLuo.WinFormsUI.Docking; using Sq1.Core; using Sq1.Core.DataFeed; using Sq1.Core.DataTypes; using Sq1.Core.StrategyBase; using Sq1.Core.Charting; using Sq1.Core.Streaming; using Sq1.Widgets.RangeBar; using Sq1.Widgets; using Sq1.Gui.Singletons; namespace Sq1.Gui.Forms { public class ChartFormInterformEventsConsumer { ChartFormManager chartFormManager; private bool backtestAlreadyFinished; public ChartFormInterformEventsConsumer(ChartFormManager chartFormManager, ChartForm chartFormNotAssignedToManagerInTheFactoryYet = null) { this.chartFormManager = chartFormManager; chartFormNotAssignedToManagerInTheFactoryYet.FormClosing += ChartForm_FormClosing; chartFormNotAssignedToManagerInTheFactoryYet.Load += ChartForm_Load; } void ChartForm_Load(object sender, EventArgs e) { // ON_DESERIALIZATION_BACKTESTER_LAUNCHES_FASTER_THAN_CHART_FORM_GETS_LOADED; see ON_REQUESTING_ABORT_TASK_DIES_WITHOUT_INVOKING_CONTINUE_WITH this.chartFormManager.Executor.EventGenerator.OnBacktesterContextInitialized_step2of4 += this.Executor_BacktesterContextInitialized_step2of4; this.chartFormManager.Executor.EventGenerator.OnBacktesterSimulatedChunk_step3of4 += this.Executor_BacktesterChunkSimulated_step3of4; this.chartFormManager.Executor.EventGenerator.OnBacktesterContextRestoredAfterExecutingAllBars_step4of4 += this.Executor_BacktesterSimulatedAllBars_step4of4; //this.chartFormsManager.Executor.EventGenerator.OnBacktesterBarsChanged += this.Executor_BacktesterChangedQuotesWillGenerate; this.chartFormManager.Executor.EventGenerator.OnQuoteReceived_butWasntPushedAnywhere_dueToZeroSubscribers_tunnelToInterChartForm -= new EventHandler<QuoteEventArgs>(eventGenerator_OnQuoteReceived_butWasntPushedAnywhere_dueToZeroSubscribers_tunnelToInterChartForm); this.chartFormManager.Executor.EventGenerator.OnQuoteReceived_butWasntPushedAnywhere_dueToZeroSubscribers_tunnelToInterChartForm += new EventHandler<QuoteEventArgs>(eventGenerator_OnQuoteReceived_butWasntPushedAnywhere_dueToZeroSubscribers_tunnelToInterChartForm); } void eventGenerator_OnQuoteReceived_butWasntPushedAnywhere_dueToZeroSubscribers_tunnelToInterChartForm(object sender, QuoteEventArgs e) { string msg = "DEAD_END DataSourceTree.olvTree_FormatRow() gets BackColor from ChartControl; if there is no ChartControl I have no way to transfer it; unblinker should be there, too"; } void ChartForm_FormClosing(object sender, FormClosingEventArgs e) { this.chartFormManager.Executor.EventGenerator.OnBacktesterContextInitialized_step2of4 -= this.Executor_BacktesterContextInitialized_step2of4; this.chartFormManager.Executor.EventGenerator.OnBacktesterSimulatedChunk_step3of4 -= this.Executor_BacktesterChunkSimulated_step3of4; this.chartFormManager.Executor.EventGenerator.OnBacktesterContextRestoredAfterExecutingAllBars_step4of4 -= this.Executor_BacktesterSimulatedAllBars_step4of4; //this.chartFormsManager.Executor.EventGenerator.OnBacktesterBarsChanged -= this.Executor_BacktesterChangedQuotesWillGenerate; if (Assembler.InstanceInitialized.MainFormClosingIgnoreReLayoutDockedForms) return; string reporterCurrent = ""; try { foreach (DockContent reporterWrapper in this.chartFormManager.ReportersFormsManager.FormsAllRelated.Values) { reporterCurrent = reporterWrapper.Text; reporterWrapper.Close(); } this.chartFormManager.MainForm.MainFormSerialize(); } catch (Exception ex) { string msg = "REPORTER_CLOSING_FAILED reporterCurrent[" + reporterCurrent + "] COULDNT_TUNNEL_EXCEPTION_INTO_FORM_CLOSING"; Assembler.PopupException(msg, ex); } } internal void DataSourcesTree_OnSymbolSelected(object sender, DataSourceSymbolEventArgs e) { string msig = " //DataSourcesTree_OnSymbolSelected(" + e.Symbol + ")"; if ( this.chartFormManager.Executor.DataSource_fromBars.StreamingAdapter != null && this.chartFormManager.Executor.Strategy != null //&& this.chartFormManager.Executor.IsStreamingTriggeringScript && this.chartFormManager.ContextCurrentChartOrStrategy.DownstreamSubscribed == true ) { string msg = "I_REFUSE_TO_CHANGE_SYMBOL" //+ " CURRENT_CHART_HAS_STRATEGY_RUNNING_ON_STREAMING" + " CURRENT_CHART_HAS_STRATEGY_SUBSCRIBED" + " to prevent occasional order execution, click [" + this.chartFormManager.StreamingButtonIdent + "] button on ChartForm to unsubscribe"; Assembler.PopupException(msg + msig, null, false); return; } try { ContextChart contextChart = this.chartFormManager.ContextCurrentChartOrStrategy; #region subscribed strategies are not allowed to swap the horses; chartsWithoutStrategies are updated by Bars.OnBarStreamingUpdatedMerged //string symbol_beforeChange = contextChart.Symbol; //string dataSource_beforeChange = contextChart.DataSourceName; //string reasonToSubscribeUnsubscribe = "USER_MADE_CHART?_CHANGE_BARS[" + symbol_beforeChange + "@" + dataSource_beforeChange + "]=>[" + e.Symbol + "@" + e.DataSource.Name + "]"; //ChartStreamingConsumer amIsubscribed = this.chartFormManager.ChartForm.ChartControl.ChartStreamingConsumer; //Distributor hopefullyLiveStreaming = this.chartFormManager.Executor.DataSource_fromBars.StreamingAdapter.Distributor_replacedForLivesim; //bool chartMustBeSubscribedToNewBars = contextChart.DownstreamSubscribed; //if (chartMustBeSubscribedToNewBars) { // BarScaleInterval scaleInterval_beforeChange = contextChart.ScaleInterval; // //bool barsUnsubscribed = hopefullyLiveStreaming.ConsumerBarUnsubscribe (symbol_beforeChange, scaleInterval_beforeChange, amIsubscribed); // //bool quotesUnsubscribed = hopefullyLiveStreaming.ConsumerQuoteUnsubscribe (symbol_beforeChange, scaleInterval_beforeChange, amIsubscribed); // amIsubscribed.StreamingUnsubscribe(reasonToSubscribeUnsubscribe); //} #endregion if (contextChart.DataSourceName != e.DataSource.Name) contextChart.DataSourceName = e.DataSource.Name; if (contextChart.Symbol != e.Symbol) contextChart.Symbol = e.Symbol; this.chartFormManager.PopulateSelectors_fromCurrentChartOrScriptContext_loadBars_saveStrategyOrCtx_backtestIfStrategy("DataSourcesTree_OnSymbolSelected"); #region subscribed strategies are not allowed to swap the horses; chartsWithoutStrategies are updated by Bars.OnBarStreamingUpdatedMerged //if (chartMustBeSubscribedToNewBars) { // string symbol_afterChange = contextChart.Symbol; // BarScaleInterval scaleInterval_afterChange = contextChart.ScaleInterval; // //bool barsSubscribed = hopefullyLiveStreaming.ConsumerBarSubscribe (symbol_afterChange, scaleInterval_afterChange, amIsubscribed, true); // //bool quotesSubscribed = hopefullyLiveStreaming.ConsumerQuoteSubscribe (symbol_afterChange, scaleInterval_afterChange, amIsubscribed, true); // amIsubscribed.StreamingSubscribe(reasonToSubscribeUnsubscribe); //} #endregion DataSourcesForm.Instance.DataSourcesTreeControl.Refresh(); this.chartFormManager.SequencerFormIfOpenPropagateTextboxesOrMarkStaleResultsAndDeleteHistory(); //copypaste from MainFormEventManager.DockPanel_ActiveDocumentChanged() ChartForm chartFormCurrentlyOpen = this.chartFormManager.ChartForm; ChartSettingsEditorForm.Instance.PopulateWithChartSettings(chartFormCurrentlyOpen.ChartControl.ChartSettings); if (chartFormCurrentlyOpen.ChartFormManager.Executor.Bars != null) { SymbolInfoEditorForm.Instance.SymbolEditorControl.PopulateWithSymbolInfo(chartFormCurrentlyOpen.ChartFormManager.Executor.Bars.SymbolInfo); } } catch (Exception ex) { Assembler.PopupException(msig, ex); } } internal void MainForm_ActivateDocumentPane_WithChart(object sender, EventArgs e) { if (this.chartFormManager.Strategy != null && this.chartFormManager.Strategy.ActivatedFromDll == false) { this.chartFormManager.ScriptEditorFormConditionalInstance.ActivateDockContentPopupAutoHidden(true, true); } this.chartFormManager.ReportersFormsManager.PopupReporters_OnParentChartActivated(sender, e); //this.chartFormManager.ChartForm.ChartControl.RangeBar.Enabled = false; // WHY false?? YOU_SHOULD_NOT_CHANGE_VISIBILITY_OF_RANGEBAR this.chartFormManager.ChartForm.ChartControl.InvalidateAllPanels(); // CHART_WAS_INVOKED_WITH_SIZE_DIFFERENT_ON_START__HELPS_TO_STRETCH_CHART_TO_ACTUAL_SIZE__COVERED_WAS_FIRST_TIME_SHOWN__ACTIVE_IS_OK //if (this.chartFormManager.SequencerForm == null) { if (DockContentImproved.IsNullOrDisposed(this.chartFormManager.SequencerForm) == true) { string msg = "don't even try to access SequencerConditionalInstance if user didn't click implicitly; TODO where to can I incapsulate it?"; //Assembler.PopupException(msg, null, false); } else { if (this.chartFormManager.SequencerForm.IsShown) this.chartFormManager.SequencerFormShow(true); } //if (this.chartFormManager.CorrelatorForm == null) { if (DockContentImproved.IsNullOrDisposed(this.chartFormManager.CorrelatorForm) == true) { string msg = "don't even try to access CorrelatorConditionalInstance if user didn't click implicitly; TODO where to can I incapsulate it?"; //Assembler.PopupException(msg, null, false); } else { if (this.chartFormManager.CorrelatorForm.IsShown) this.chartFormManager.CorrelatorFormShow(true); } //if (this.chartFormManager.LivesimForm == null) { if (DockContentImproved.IsNullOrDisposed(this.chartFormManager.LivesimForm) == true) { string msg = "don't even try to access LivesimConditionalInstance if user didn't click implicitly; TODO where to can I incapsulate it?"; //Assembler.PopupException(msg, null, false); } else { if (this.chartFormManager.LivesimForm.IsShown) this.chartFormManager.LivesimFormShow(true); } } internal void Executor_BacktesterContextInitialized_step2of4(object sender, EventArgs e) { string msig = " Executor_BacktesterContextInitialized_step2of4()" + this.chartFormManager.ToString(); if (this.chartFormManager.ChartForm == null) return; if (this.chartFormManager.Executor == null) return; if (this.chartFormManager.Executor.BacktesterOrLivesimulator.BarsOriginal == null) { string msg = "I_RESTORED_CONTEXT__END_OF_BACKTEST_ORIGINAL_BECAME_NULL"; if (this.chartFormManager.ChartForm.InvokeRequired == false) { msg = "NO_NEED_TO_REPORT_ITS_NOT_AN_ERROR I_REFUSE_TO_CALCULATE_PERCENTAGE_COMPLETED BACKTEST_ALREADY_FINISHED_WHILE_SWTICHING_TO_GUI_THREAD"; //Assembler.PopupException(msg + msig, null, false); } else { Assembler.PopupException(msg + msig, null, false); } return; } if (this.chartFormManager.Executor.BacktesterOrLivesimulator.QuotesGenerator == null) return; int quotesTotal = this.chartFormManager.Executor.BacktesterOrLivesimulator.QuotesTotalToGenerate; if (quotesTotal == -1) { string msg = "I_RESTORED_CONTEXT__END_OF_BACKTEST_ORIGINAL_BECAME_NULL: Backtester.QuotesTotalToGenerate=-1 due to Backtester.BarsOriginal=null"; Assembler.PopupException(msg); return; } this.backtestAlreadyFinished = false; if (this.chartFormManager.ChartForm.InvokeRequired) { this.chartFormManager.ChartForm.BeginInvoke(new MethodInvoker(delegate { this.Executor_BacktesterContextInitialized_step2of4(sender, e); })); return; } this.chartFormManager.ChartForm.TsiProgressBarETA.ETALabelText = this.chartFormManager.Executor.BacktesterOrLivesimulator.ProgressStats; // CHART_NOT_NOTIFIED_OF_BACKTEST_PROGRESS_AFTER_DESERIALIZATION_BACKTESTER_LAUNCHES_BEFORE_IM_SUBSCRIBED BEGIN //if (this.chartFormsManager.ChartForm.TsiProgressBarETA.ETAProgressBarMaximum != quotesTotal) { this.chartFormManager.ChartForm.TsiProgressBarETA.ETAProgressBarMaximum = quotesTotal; //} this.chartFormManager.ChartForm.TsiProgressBarETA.Visible = true; //this.chartFormManager.ChartForm.btnStrategyEmittingOrders.Visible = false; //this.chartFormManager.ChartForm.btnStreamingTriggersScript.Visible = false; this.chartFormManager.ChartForm.PropagateSelectors_disabledIfStreaming_forCurrentChart(); // CHART_NOT_NOTIFIED_OF_BACKTEST_PROGRESS_AFTER_DESERIALIZATION_BACKTESTER_LAUNCHES_BEFORE_IM_SUBSCRIBED END this.chartFormManager.ChartForm.AbsorbContextBarsToGui(); } internal void Executor_BacktesterChunkSimulated_step3of4(object sender, EventArgs e) { string msig = " //Executor_BacktesterChunkSimulated_step3of4() " + this.chartFormManager.ToString(); if (sender != this.chartFormManager.Executor.EventGenerator) return; if (this.chartFormManager.Executor == null) { string msg = "invoked by Backtester.SubstituteAndRunSimulation() I don't remember whether Tag=null is ok or not..."; return; } //if (this.chartFormManager.Executor.Backtester.IsBacktestingNoLivesimNow == false) { //if (this.chartFormManager.ChartForm.ChartControl.PaintAllowedDuringLivesimOrAfterBacktestFinished == false) { if (this.backtestAlreadyFinished) { string msg = "Livesimulator.afterBacktesterComplete()_ALREADY_RESTORED_BACKTESTER_WHILE_SWITCHING_TO_GUI_THREAD [base.Executor.Backtester = this.BacktesterBackup]"; return; } if (this.chartFormManager.Executor.BacktesterOrLivesimulator.QuotesGenerator == null) { string msg = "YOU_DIDNT_INVOKE_Backtester.Initialize() AVOIDING_EXCEPTIONS_IN_QuotesGeneratedSoFar"; Assembler.PopupException(msg, null, false); return; } int quotesTotal = this.chartFormManager.Executor.BacktesterOrLivesimulator.QuotesTotalToGenerate; if (quotesTotal == -1) { string msg = "CANT_CALCULATE_PERCENTAGE_KOZ_BARS_ORIGINAL_NULL" + " : Backtester.QuotesTotalToGenerate=-1 due to Backtester.BarsOriginal=null"; //Assembler.PopupException(msg + msig, null, false); return; } if (this.chartFormManager.ChartForm.InvokeRequired) { this.chartFormManager.ChartForm.BeginInvoke(new MethodInvoker(delegate { this.Executor_BacktesterChunkSimulated_step3of4(sender, e); })); return; } // HACK FOR CHART_NOT_NOTIFIED_OF_BACKTEST_PROGRESS_AFTER_DESERIALIZATION_BACKTESTER_LAUNCHES_BEFORE_IM_SUBSCRIBED BEGIN COPYPASTE if (this.chartFormManager.ChartForm.TsiProgressBarETA.Visible == false) { //int quotesTotal = this.chartFormManager.Executor.Backtester.QuotesTotalToGenerate; //if (quotesTotal == -1) { // string msg = "Backtester.QuotesTotalToGenerate=-1 due to Backtester.BarsOriginal=null"; // Assembler.PopupException(msg + msig); // return; //} this.chartFormManager.ChartForm.TsiProgressBarETA.ETAProgressBarMaximum = quotesTotal; this.chartFormManager.ChartForm.TsiProgressBarETA.Visible = true; //this.chartFormManager.ChartForm.btnStrategyEmittingOrders.Visible = false; //this.chartFormManager.ChartForm.btnStreamingTriggersScript.Visible = false; this.chartFormManager.ChartForm.PropagateSelectors_disabledIfStreaming_forCurrentChart(); } // HACK FOR CHART_NOT_NOTIFIED_OF_BACKTEST_PROGRESS_AFTER_DESERIALIZATION_BACKTESTER_LAUNCHES_BEFORE_IM_SUBSCRIBED END COPYPASTE this.chartFormManager.ChartForm.TsiProgressBarETA.ETALabelText = this.chartFormManager.Executor.BacktesterOrLivesimulator.ProgressStats; int currentValue = this.chartFormManager.Executor.BacktesterOrLivesimulator.QuotesGeneratedSoFar; if (currentValue > this.chartFormManager.ChartForm.TsiProgressBarETA.ETAProgressBarMaximum) return; this.chartFormManager.ChartForm.TsiProgressBarETA.ETAProgressBarValue = currentValue; // ETALabelText isn't refreshed fast enough; windows don't feel mouse clicks&moves, GUI freezes; REMOVE after backtester goes to its own thread! ////DEBUGGER_SHOWS_RECURSIVE_CALLS_TO_BuildOnceAllReports /// uncommented to make GUI more responsive during backtests; GUI didn't fully unhalt, lagging.... FIXME //Application.DoEvents(); } internal void Executor_BacktesterSimulatedAllBars_step4of4(object sender, EventArgs e) { if (this.chartFormManager.Executor == null) return; if (sender != this.chartFormManager.Executor.EventGenerator) return; this.backtestAlreadyFinished = true; if (this.chartFormManager.ChartForm.InvokeRequired) { this.chartFormManager.ChartForm.BeginInvoke(new MethodInvoker(delegate { this.Executor_BacktesterSimulatedAllBars_step4of4(sender, e); })); return; } this.chartFormManager.ChartForm.TsiProgressBarETA.ETALabelText = this.chartFormManager.Executor.BacktesterOrLivesimulator.ProgressStats; this.chartFormManager.ChartForm.TsiProgressBarETA.ETAProgressBarValue = 0; this.chartFormManager.ChartForm.TsiProgressBarETA.Visible = false; //this.chartFormManager.ChartForm.btnStrategyEmittingOrders.Visible = true; //this.chartFormManager.ChartForm.btnStreamingTriggersScript.Visible = true; this.chartFormManager.ChartForm.PropagateSelectors_disabledIfStreaming_forCurrentChart(); this.chartFormManager.ChartForm.AbsorbContextBarsToGui(); this.chartFormManager.OnBacktestedOrLivesimmed(); } internal void ChartRangeBar_OnAnyValueChanged(object sender, RangeArgs<DateTime> e) { BarDataRange newRange = new BarDataRange(e.ValueMin, e.ValueMax); try { this.chartFormManager.UserSelectedRange_loadBars_backtest_populate(newRange); } catch (Exception ex) { Assembler.PopupException("ChartRangeBar_AnyValueChanged", ex); } } } }