Esempio n. 1
0
    private static void InitializeLogging()
    {
        // Delete all log files older than 1 week
        try
        {
            var applicationDataDirectory = Catel.IO.Path.GetApplicationDataDirectory();
            if (Directory.Exists(applicationDataDirectory))
            {
                var logFiles = Directory.GetFiles(applicationDataDirectory, "*.log");
                foreach (var logFile in logFiles)
                {
                    var lastWriteTime = File.GetLastWriteTime(logFile);
                    if (lastWriteTime < DateTime.Now.AddDays(-7))
                    {
                        File.Delete(logFile);
                    }
                }
            }
        }
        catch (Exception)
        {
            // Ignore
        }

        var fileLogListener = new FileLogListener()
        {
            IgnoreCatelLogging = true,
            IsDebugEnabled     = false,
            IsInfoEnabled      = true,
            IsWarningEnabled   = true,
            IsErrorEnabled     = true
        };

        LogManager.AddListener(fileLogListener);
    }
Esempio n. 2
0
        static void Main(string[] args)
        {
            _trader = new QuikTrader();

            // объкт, управляющий логгированием
            _logManager = new LogManager();

            // слушатель - устройство вывода, куда будут записываться сообщения


            // слушатели:
            // консоль
            _logManager.Listeners.Add(new ConsoleLogListener());

            // окно вывода
            _logManager.Listeners.Add(new DebugLogListener());

            // файл
            var fileListener = new FileLogListener
            {
                Append          = false,                       // true - добавляет сообщения в конец существующего файла, false - перезаписывает существующий файл
                Extension       = "log",                       // расширение файла лога
                FileName        = "FirstLog",                  // имя файла лога
                MaxLength       = 1000000,                     // максимальная длинна файла лога в байтах / в данном случае 1мб
                LogDirectory    = "Logs",                      // максимальная длинна файла лога
                SeparateByDates = SeparateByDateModes.FileName // режим разделения логов по датам
            };

            _logManager.Listeners.Add(fileListener);

            // добавляем источник логов. В данном случае это коннектор.
            // Роль истоника логов может выполнять любой класс, наследующий от BaseLogReceiver, или реализующий интерфейс ILogSource
            _logManager.Sources.Add(_trader);

            _connection = new Connection(_trader, "NL0011100043", "SBER@QJSIM");


            // Уровни логирования
            // Off - логи не выводятся
            // Error - выводятся только сообщения об ошибках
            // Warning - выводятся предупреждения и сообщения об ошибках
            // Info - выводятся информационные сообщения, предупреждения и сообщения об ошибках
            // Debug - выводятся все сообщения

            _connection.LogLevel = LogLevels.Debug;

            // добавляем еще один источник логов.
            _logManager.Sources.Add(_connection);

            _connection.Connect();

            Console.Read();

            _connection.Disconnect();
        }
Esempio n. 3
0
        /// <summary>
        /// This is where the work is done.
        /// </summary>
        protected override void ExecuteTask()
        {
            IRecorder recorder = _recorders[LogName.FullName];

            switch (Action)
            {
            case ActionType.Start:
                if (recorder == null)
                {
                    recorder = new FileLogListener(LogName.FullName);
                    Recorders.Add(recorder);
                }
                recorder.AutoFlush        = AutoFlush;
                recorder.Logger.Threshold = ThresholdLevel;
                recorder.Start();
                AttachRecorder(recorder);
                break;

            case ActionType.Stop:
                if (recorder == null)
                {
                    throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                           "Tried to stop non-existent recorder '{0}'", LogName.FullName),
                                             Location);
                }
                recorder.Stop();
                break;

            case ActionType.Close:
                if (recorder == null)
                {
                    throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                           "Tried to close non-existent recorder '{0}'", LogName.FullName),
                                             Location);
                }
                DetachRecorder(recorder);
                recorder.Close();
                Recorders.Remove(recorder.Name);
                break;

            case ActionType.Flush:
                if (recorder == null)
                {
                    throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                           "Tried to flush non-existent recorder '{0}'", LogName.FullName),
                                             Location);
                }
                recorder.Flush();
                break;
            }
        }
Esempio n. 4
0
        private static void AddFileLogListener(string prefix)
        {
            Argument.IsNotNull(() => prefix);

            var fileName        = Path.Combine(Path.GetApplicationDataDirectory(), string.Format("{0}_{1}.txt", prefix, DateTime.Now.ToString("yyyyMMdd_HHmm")));
            var fileLogListener = new FileLogListener(fileName, 10 * 1024);

            //fileLogger.IgnoreCatelLogging = true;

            LogManager.AddListener(fileLogListener);

            Log.LogProductInfo();
            Log.LogDeviceInfo();
        }
Esempio n. 5
0
            public void ReturnsRightFullPath(string path, string expectedPath)
            {
                var assembly = GetType().Assembly;

                var fileLogListener = new FileLogListener(path, 25000, assembly);

                fileLogListener.FilePath = path;

                var returnedPath = fileLogListener.FilePath;
                var appDataPath  = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

                returnedPath = returnedPath.Replace(appDataPath, "{AppData}");

                Assert.AreEqual(expectedPath, returnedPath);
            }
Esempio n. 6
0
        public static ILogListener CreateFileLogListener(string prefix)
        {
            Argument.IsNotNull(() => prefix);

            var directory = Path.Combine(Path.GetApplicationDataDirectory(), "log");

            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            var fileName        = Path.Combine(directory, prefix + "_{Date}_{Time}_{ProcessId}");
            var fileLogListener = new FileLogListener(fileName, 10 * 1024);

            return(fileLogListener);
        }
Esempio n. 7
0
        protected override void OnStartup(StartupEventArgs e)
        {
#if DEBUG
            LogManager.AddDebugListener();
#endif

            var fileLogListener = new FileLogListener();
            fileLogListener.FilePath           = "{AppDir}/{AssemblyName}";
            fileLogListener.IgnoreCatelLogging = true;

            LogManager.AddListener(fileLogListener);

            Log.Info("Starting application");

            // To force the loading of all assemblies at startup, uncomment the lines below:

            //Log.Info("Preloading assemblies");
            //AppDomain.CurrentDomain.PreloadAssemblies();


            // Want to improve performance? Uncomment the lines below. Note though that this will disable
            // some features.
            //
            // For more information, see https://catelproject.atlassian.net/wiki/display/CTL/Performance+considerations

            // Log.Info("Improving performance");
            // Catel.Data.ModelBase.DefaultSuspendValidationValue = true;
            // Catel.Windows.Controls.UserControl.DefaultCreateWarningAndErrorValidatorForViewModelValue = false;
            // Catel.Windows.Controls.UserControl.DefaultSkipSearchingForInfoBarMessageControlValue = true;


            // TODO: Register custom types in the ServiceLocator
            //Log.Info("Registering custom types");
            //var serviceLocator = ServiceLocator.Default;
            //serviceLocator.RegisterType<IMyInterface, IMyClass>();

            StyleHelper.CreateStyleForwardersForDefaultStyles();

            Log.Info("Calling base.OnStartup");

            base.OnStartup(e);
        }
        private CommandHandler(IConnector connector)
        {
            _connector = connector;
            var logger = new FileLogListener
            {
                Append          = true,
                MaxLength       = 2048000,
                FileName        = "{0:00}_{1:00}_{2:00}_log.txt".Put(DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second),
                SeparateByDates = SeparateByDateModes.FileName,
                LogDirectory    = "logs"
            };

            _logManager = new LogManager();

            _userPositions = new Dictionary <string, UserPosition>();

            _messageManager              = new MessageManager();
            _messageManager.AutoMessage += DoAutoGeneralInfo;

            UserPosition.LoadFromXml()?.ForEach(up => { _userPositions.Add(up.SecCode, up); });

            _logManager.Listeners.Add(logger);
            _logManager.Sources.Add(_connector);
        }
Esempio n. 9
0
        public void Log_logs_an_entry_to_a_file()
        {
            DateTime testTime = DateTime.Now;

            Logger          logger   = new Logger(LogLevel.Message);
            FileLogListener listener = new FileLogListener(AppDomain.CurrentDomain.BaseDirectory);

            listener.TestTime = testTime;
            logger.Listeners.Add(listener);

            string message      = Guid.NewGuid().ToString();
            string expectedText = string.Format("{0} {1} {2}", testTime.ToString("s"), "Warning", message);

            string expectedFileName = "LogFile_" + testTime.ToString("yyyy-MM-dd") + ".txt";
            string expectedFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, expectedFileName);

            logger.LogWarning(message);

            Assert.IsTrue(File.Exists(expectedFilePath));

            string actual = File.ReadAllText(expectedFilePath);

            Assert.IsTrue(actual.Contains(expectedText));
        }
Esempio n. 10
0
        private void StartBtnClick(object sender, RoutedEventArgs e)
        {
            if (_connectors.Count > 0)
            {
                foreach (var connector in _connectors)
                {
                    connector.Start();
                }

                return;
            }

            if (HistoryPath.Folder.IsEmpty() || !Directory.Exists(HistoryPath.Folder))
            {
                MessageBox.Show(this, LocalizedStrings.Str3014);
                return;
            }

            if (_connectors.Any(t => t.State != EmulationStates.Stopped))
            {
                MessageBox.Show(this, LocalizedStrings.Str3015);
                return;
            }

            var id = SecId.Text.ToSecurityId();

            //if (secIdParts.Length != 2)
            //{
            //	MessageBox.Show(this, LocalizedStrings.Str3016);
            //	return;
            //}

            var timeFrame = TimeSpan.FromMinutes(TimeFrame.SelectedIndex == 0 ? 1 : 5);

            var secCode = id.SecurityCode;
            var board   = _exchangeInfoProvider.GetOrCreateBoard(id.BoardCode);

            // create test security
            var security = new Security
            {
                Id    = SecId.Text,              // sec id has the same name as folder with historical data
                Code  = secCode,
                Board = board,
            };

            if (FinamCandlesCheckBox.IsChecked == true)
            {
                _finamHistorySource.Refresh(new FinamSecurityStorage(security), security, s => {}, () => false);
            }

            // create backtesting modes
            var settings = new[]
            {
                Tuple.Create(
                    TicksCheckBox,
                    TicksProgress,
                    TicksParameterGrid,
                    // ticks
                    new EmulationInfo {
                    UseTicks = true, CurveColor = Colors.DarkGreen, StrategyName = LocalizedStrings.Ticks
                },
                    TicksChart,
                    TicksEquity,
                    TicksPosition),

                Tuple.Create(
                    TicksAndDepthsCheckBox,
                    TicksAndDepthsProgress,
                    TicksAndDepthsParameterGrid,
                    // ticks + order book
                    new EmulationInfo {
                    UseTicks = true, UseMarketDepth = true, CurveColor = Colors.Red, StrategyName = LocalizedStrings.XamlStr757
                },
                    TicksAndDepthsChart,
                    TicksAndDepthsEquity,
                    TicksAndDepthsPosition),

                Tuple.Create(
                    DepthsCheckBox,
                    DepthsProgress,
                    DepthsParameterGrid,
                    // order book
                    new EmulationInfo {
                    UseMarketDepth = true, CurveColor = Colors.OrangeRed, StrategyName = LocalizedStrings.MarketDepths
                },
                    DepthsChart,
                    DepthsEquity,
                    DepthsPosition),

                Tuple.Create(
                    CandlesCheckBox,
                    CandlesProgress,
                    CandlesParameterGrid,
                    // candles
                    new EmulationInfo {
                    UseCandleTimeFrame = timeFrame, CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.Candles
                },
                    CandlesChart,
                    CandlesEquity,
                    CandlesPosition),

                Tuple.Create(
                    CandlesAndDepthsCheckBox,
                    CandlesAndDepthsProgress,
                    CandlesAndDepthsParameterGrid,
                    // candles + orderbook
                    new EmulationInfo {
                    UseMarketDepth = true, UseCandleTimeFrame = timeFrame, CurveColor = Colors.Cyan, StrategyName = LocalizedStrings.XamlStr635
                },
                    CandlesAndDepthsChart,
                    CandlesAndDepthsEquity,
                    CandlesAndDepthsPosition),

                Tuple.Create(
                    OrderLogCheckBox,
                    OrderLogProgress,
                    OrderLogParameterGrid,
                    // order log
                    new EmulationInfo {
                    UseOrderLog = true, CurveColor = Colors.CornflowerBlue, StrategyName = LocalizedStrings.OrderLog
                },
                    OrderLogChart,
                    OrderLogEquity,
                    OrderLogPosition),

                Tuple.Create(
                    Level1CheckBox,
                    Level1Progress,
                    Level1ParameterGrid,
                    // order log
                    new EmulationInfo {
                    UseLevel1 = true, CurveColor = Colors.Aquamarine, StrategyName = LocalizedStrings.Level1
                },
                    Level1Chart,
                    Level1Equity,
                    Level1Position),

                Tuple.Create(
                    FinamCandlesCheckBox,
                    FinamCandlesProgress,
                    FinamCandlesParameterGrid,
                    // candles
                    new EmulationInfo {
                    UseCandleTimeFrame = timeFrame, HistorySource = d => _finamHistorySource.GetCandles(security, timeFrame, d.Date, d.Date), CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.FinamCandles
                },
                    FinamCandlesChart,
                    FinamCandlesEquity,
                    FinamCandlesPosition),

                Tuple.Create(
                    YahooCandlesCheckBox,
                    YahooCandlesProgress,
                    YahooCandlesParameterGrid,
                    // candles
                    new EmulationInfo {
                    UseCandleTimeFrame = timeFrame, HistorySource = d => new YahooHistorySource(_exchangeInfoProvider).GetCandles(security, timeFrame, d.Date, d.Date), CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.YahooCandles
                },
                    YahooCandlesChart,
                    YahooCandlesEquity,
                    YahooCandlesPosition),
            };

            // storage to historical data
            var storageRegistry = new StorageRegistry
            {
                // set historical path
                DefaultDrive = new LocalMarketDataDrive(HistoryPath.Folder)
            };

            var startTime = ((DateTime)From.Value).ChangeKind(DateTimeKind.Utc);
            var stopTime  = ((DateTime)To.Value).ChangeKind(DateTimeKind.Utc);

            // (ru only) ОЛ необходимо загружать с 18.45 пред дня, чтобы стаканы строились правильно
            if (OrderLogCheckBox.IsChecked == true)
            {
                startTime = startTime.Subtract(TimeSpan.FromDays(1)).AddHours(18).AddMinutes(45).AddTicks(1).ApplyTimeZone(TimeHelper.Moscow).UtcDateTime;
            }

            // ProgressBar refresh step
            var progressStep = ((stopTime - startTime).Ticks / 100).To <TimeSpan>();

            // set ProgressBar bounds
            _progressBars.ForEach(p =>
            {
                p.Value   = 0;
                p.Maximum = 100;
            });

            var logManager      = new LogManager();
            var fileLogListener = new FileLogListener("sample.log");

            logManager.Listeners.Add(fileLogListener);
            //logManager.Listeners.Add(new DebugLogListener());	// for track logs in output window in Vusial Studio (poor performance).

            var generateDepths = GenDepthsCheckBox.IsChecked == true;
            var maxDepth       = MaxDepth.Text.To <int>();
            var maxVolume      = MaxVolume.Text.To <int>();
            var secId          = security.ToSecurityId();

            SetIsEnabled(false, false, false);

            foreach (var set in settings)
            {
                if (set.Item1.IsChecked == false)
                {
                    continue;
                }

                var title = (string)set.Item1.Content;

                InitChart(set.Item5, set.Item6, set.Item7);

                var progressBar   = set.Item2;
                var statistic     = set.Item3;
                var emulationInfo = set.Item4;

                var level1Info = new Level1ChangeMessage
                {
                    SecurityId = secId,
                    ServerTime = startTime,
                }
                .TryAdd(Level1Fields.PriceStep, secCode == "RIZ2" ? 10m : 1)
                .TryAdd(Level1Fields.StepPrice, 6m)
                .TryAdd(Level1Fields.MinPrice, 10m)
                .TryAdd(Level1Fields.MaxPrice, 1000000m)
                .TryAdd(Level1Fields.MarginBuy, 10000m)
                .TryAdd(Level1Fields.MarginSell, 10000m);

                // test portfolio
                var portfolio = new Portfolio
                {
                    Name       = "test account",
                    BeginValue = 1000000,
                };

                // create backtesting connector
                var connector = new HistoryEmulationConnector(
                    new[] { security },
                    new[] { portfolio })
                {
                    EmulationAdapter =
                    {
                        Emulator             =
                        {
                            Settings         =
                            {
                                // match order if historical price touched our limit order price.
                                // It is terned off, and price should go through limit order price level
                                // (more "severe" test mode)
                                MatchOnTouch = false,
                            }
                        }
                    },

                    //UseExternalCandleSource = emulationInfo.UseCandleTimeFrame != null,

                    CreateDepthFromOrdersLog  = emulationInfo.UseOrderLog,
                    CreateTradesFromOrdersLog = emulationInfo.UseOrderLog,

                    HistoryMessageAdapter =
                    {
                        StorageRegistry             = storageRegistry,

                        // set history range
                        StartDate = startTime,
                        StopDate  = stopTime,

                        OrderLogMarketDepthBuilders =
                        {
                            {
                                secId,
                                LocalizedStrings.ActiveLanguage == Languages.Russian
                                                                        ? (IOrderLogMarketDepthBuilder) new PlazaOrderLogMarketDepthBuilder(secId)
                                                                        : new ItchOrderLogMarketDepthBuilder(secId)
                            }
                        }
                    },

                    // set market time freq as time frame
                    MarketTimeChangedInterval = timeFrame,
                };

                ((ILogSource)connector).LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info;

                logManager.Sources.Add(connector);

                var candleManager = new CandleManager(connector);

                var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame)
                {
                    BuildCandlesMode = emulationInfo.UseCandleTimeFrame == null ? BuildCandlesModes.Build : BuildCandlesModes.Load
                };

                _shortMa = new SimpleMovingAverage {
                    Length = 10
                };
                _shortElem = new ChartIndicatorElement
                {
                    Color          = Colors.Coral,
                    ShowAxisMarker = false,
                    FullTitle      = _shortMa.ToString()
                };

                var chart = set.Item5;

                chart.AddElement(_area, _shortElem);

                _longMa = new SimpleMovingAverage {
                    Length = 80
                };
                _longElem = new ChartIndicatorElement
                {
                    ShowAxisMarker = false,
                    FullTitle      = _longMa.ToString()
                };
                chart.AddElement(_area, _longElem);

                // create strategy based on 80 5-min и 10 5-min
                var strategy = new SmaStrategy(chart, _candlesElem, _tradesElem, _shortMa, _shortElem, _longMa, _longElem, candleManager, series)
                {
                    Volume    = 1,
                    Portfolio = portfolio,
                    Security  = security,
                    Connector = connector,
                    LogLevel  = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info,

                    // by default interval is 1 min,
                    // it is excessively for time range with several months
                    UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>()
                };

                logManager.Sources.Add(strategy);

                connector.NewSecurity += s =>
                {
                    if (s != security)
                    {
                        return;
                    }

                    // fill level1 values
                    connector.HistoryMessageAdapter.SendOutMessage(level1Info);

                    if (emulationInfo.HistorySource != null)
                    {
                        if (emulationInfo.UseCandleTimeFrame != null)
                        {
                            connector.RegisterHistorySource(security, MarketDataTypes.CandleTimeFrame, emulationInfo.UseCandleTimeFrame.Value, emulationInfo.HistorySource);
                        }

                        if (emulationInfo.UseTicks)
                        {
                            connector.RegisterHistorySource(security, MarketDataTypes.Trades, null, emulationInfo.HistorySource);
                        }

                        if (emulationInfo.UseLevel1)
                        {
                            connector.RegisterHistorySource(security, MarketDataTypes.Level1, null, emulationInfo.HistorySource);
                        }

                        if (emulationInfo.UseMarketDepth)
                        {
                            connector.RegisterHistorySource(security, MarketDataTypes.MarketDepth, null, emulationInfo.HistorySource);
                        }
                    }
                    else
                    {
                        if (emulationInfo.UseMarketDepth)
                        {
                            connector.RegisterMarketDepth(security);

                            if (
                                // if order book will be generated
                                generateDepths ||
                                // of backtesting will be on candles
                                emulationInfo.UseCandleTimeFrame != TimeSpan.Zero
                                )
                            {
                                // if no have order book historical data, but strategy is required,
                                // use generator based on last prices
                                connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security))
                                {
                                    Interval           = TimeSpan.FromSeconds(1),                           // order book freq refresh is 1 sec
                                    MaxAsksDepth       = maxDepth,
                                    MaxBidsDepth       = maxDepth,
                                    UseTradeVolume     = true,
                                    MaxVolume          = maxVolume,
                                    MinSpreadStepCount = 2,                                     // min spread generation is 2 pips
                                    MaxSpreadStepCount = 5,                                     // max spread generation size (prevent extremely size)
                                    MaxPriceStepCount  = 3                                      // pips size,
                                });
                            }
                        }

                        if (emulationInfo.UseOrderLog)
                        {
                            connector.RegisterOrderLog(security);
                        }

                        if (emulationInfo.UseTicks)
                        {
                            connector.RegisterTrades(security);
                        }

                        if (emulationInfo.UseLevel1)
                        {
                            connector.RegisterSecurity(security);
                        }
                    }

                    // start strategy before emulation started
                    strategy.Start();
                    candleManager.Start(series);

                    // start historical data loading when connection established successfully and all data subscribed
                    connector.Start();
                };

                // fill parameters panel
                statistic.Parameters.Clear();
                statistic.Parameters.AddRange(strategy.StatisticManager.Parameters);

                var equity = set.Item6;

                var pnlCurve           = equity.CreateCurve(LocalizedStrings.PnL + " " + emulationInfo.StrategyName, emulationInfo.CurveColor, LineChartStyles.Area);
                var unrealizedPnLCurve = equity.CreateCurve(LocalizedStrings.PnLUnreal + " " + emulationInfo.StrategyName, Colors.Black);
                var commissionCurve    = equity.CreateCurve(LocalizedStrings.Str159 + " " + emulationInfo.StrategyName, Colors.Red, LineChartStyles.DashedLine);
                var posItems           = set.Item7.CreateCurve(emulationInfo.StrategyName, emulationInfo.CurveColor);
                strategy.PnLChanged += () =>
                {
                    var pnl = new EquityData
                    {
                        Time  = strategy.CurrentTime,
                        Value = strategy.PnL - strategy.Commission ?? 0
                    };

                    var unrealizedPnL = new EquityData
                    {
                        Time  = strategy.CurrentTime,
                        Value = strategy.PnLManager.UnrealizedPnL ?? 0
                    };

                    var commission = new EquityData
                    {
                        Time  = strategy.CurrentTime,
                        Value = strategy.Commission ?? 0
                    };

                    pnlCurve.Add(pnl);
                    unrealizedPnLCurve.Add(unrealizedPnL);
                    commissionCurve.Add(commission);
                };

                strategy.PositionChanged += () => posItems.Add(new EquityData {
                    Time = strategy.CurrentTime, Value = strategy.Position
                });

                var nextTime = startTime + progressStep;

                // handle historical time for update ProgressBar
                connector.MarketTimeChanged += d =>
                {
                    if (connector.CurrentTime < nextTime && connector.CurrentTime < stopTime)
                    {
                        return;
                    }

                    var steps = (connector.CurrentTime - startTime).Ticks / progressStep.Ticks + 1;
                    nextTime = startTime + (steps * progressStep.Ticks).To <TimeSpan>();
                    this.GuiAsync(() => progressBar.Value = steps);
                };

                connector.StateChanged += () =>
                {
                    if (connector.State == EmulationStates.Stopped)
                    {
                        candleManager.Stop(series);
                        strategy.Stop();

                        SetIsChartEnabled(chart, false);

                        if (_connectors.All(c => c.State == EmulationStates.Stopped))
                        {
                            logManager.Dispose();
                            _connectors.Clear();

                            SetIsEnabled(true, false, false);
                        }

                        this.GuiAsync(() =>
                        {
                            if (connector.IsFinished)
                            {
                                progressBar.Value = progressBar.Maximum;
                                MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime), title);
                            }
                            else
                            {
                                MessageBox.Show(this, LocalizedStrings.cancelled, title);
                            }
                        });
                    }
                    else if (connector.State == EmulationStates.Started)
                    {
                        if (_connectors.All(c => c.State == EmulationStates.Started))
                        {
                            SetIsEnabled(false, true, true);
                        }

                        SetIsChartEnabled(chart, true);
                    }
                    else if (connector.State == EmulationStates.Suspended)
                    {
                        if (_connectors.All(c => c.State == EmulationStates.Suspended))
                        {
                            SetIsEnabled(true, false, true);
                        }
                    }
                };

                if (ShowDepth.IsChecked == true)
                {
                    MarketDepth.UpdateFormat(security);

                    connector.NewMessage += message =>
                    {
                        var quoteMsg = message as QuoteChangeMessage;

                        if (quoteMsg != null)
                        {
                            MarketDepth.UpdateDepth(quoteMsg);
                        }
                    };
                }

                _connectors.Add(connector);

                progressBar.Value = 0;
            }

            _startEmulationTime = DateTime.Now;

            // start emulation
            foreach (var connector in _connectors)
            {
                // raise NewSecurities and NewPortfolio for full fill strategy properties
                connector.Connect();

                // 1 cent commission for trade
                connector.SendInMessage(new CommissionRuleMessage
                {
                    Rule = new CommissionPerTradeRule {
                        Value = 0.01m
                    }
                });
            }

            TabControl.Items.Cast <TabItem>().First(i => i.Visibility == Visibility.Visible).IsSelected = true;
        }
Esempio n. 11
0
        private void StartBtnClick(object sender, RoutedEventArgs e)
        {
            if (HistoryPath.Text.IsEmpty() || !Directory.Exists(HistoryPath.Text))
            {
                MessageBox.Show(this, LocalizedStrings.Str3014);
                return;
            }

            if (Math.Abs(TestingProcess.Value - 0) > double.Epsilon)
            {
                MessageBox.Show(this, LocalizedStrings.Str3015);
                return;
            }

            var logManager      = new LogManager();
            var fileLogListener = new FileLogListener("sample.log");

            logManager.Listeners.Add(fileLogListener);

            // SMA periods
            var periods = new[]
            {
                new Tuple <int, int, Color>(80, 10, Colors.DarkGreen),
                new Tuple <int, int, Color>(70, 8, Colors.Red),
                new Tuple <int, int, Color>(60, 6, Colors.DarkBlue)
            };

            // storage to historical data
            var storageRegistry = new StorageRegistry
            {
                // set historical path
                DefaultDrive = new LocalMarketDataDrive(HistoryPath.Text)
            };

            var timeFrame = TimeSpan.FromMinutes(5);

            // create test security
            var security = new Security
            {
                Id    = "RIZ2@FORTS",              // sec id has the same name as folder with historical data
                Code  = "RIZ2",
                Name  = "RTS-12.12",
                Board = ExchangeBoard.Forts,
            };

            var startTime = new DateTime(2012, 10, 1);
            var stopTime  = new DateTime(2012, 10, 31);

            var level1Info = new Level1ChangeMessage
            {
                SecurityId = security.ToSecurityId(),
                ServerTime = startTime,
            }
            .TryAdd(Level1Fields.PriceStep, 10m)
            .TryAdd(Level1Fields.StepPrice, 6m)
            .TryAdd(Level1Fields.MinPrice, 10m)
            .TryAdd(Level1Fields.MaxPrice, 1000000m)
            .TryAdd(Level1Fields.MarginBuy, 10000m)
            .TryAdd(Level1Fields.MarginSell, 10000m);

            // test portfolio
            var portfolio = new Portfolio
            {
                Name       = "test account",
                BeginValue = 1000000,
            };

            // create backtesting connector
            var batchEmulation = new BatchEmulation(new[] { security }, new[] { portfolio }, storageRegistry)
            {
                EmulationSettings =
                {
                    MarketTimeChangedInterval = timeFrame,
                    StartTime = startTime,
                    StopTime  = stopTime,

                    // count of parallel testing strategies
                    BatchSize                 = periods.Length,
                }
            };

            // handle historical time for update ProgressBar
            batchEmulation.ProgressChanged += (curr, total) => this.GuiAsync(() => TestingProcess.Value = total);

            batchEmulation.StateChanged += (oldState, newState) =>
            {
                if (batchEmulation.State != EmulationStates.Stopped)
                {
                    return;
                }

                this.GuiAsync(() =>
                {
                    if (batchEmulation.IsFinished)
                    {
                        TestingProcess.Value = TestingProcess.Maximum;
                        MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime));
                    }
                    else
                    {
                        MessageBox.Show(this, LocalizedStrings.cancelled);
                    }
                });
            };

            // get emulation connector
            var connector = batchEmulation.EmulationConnector;

            logManager.Sources.Add(connector);

            connector.NewSecurities += securities =>
            {
                if (securities.All(s => s != security))
                {
                    return;
                }

                // fill level1 values
                connector.SendInMessage(level1Info);

                connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security))
                {
                    // order book freq refresh is 1 sec
                    Interval = TimeSpan.FromSeconds(1),
                });
            };

            TestingProcess.Maximum = 100;
            TestingProcess.Value   = 0;

            _startEmulationTime = DateTime.Now;

            var strategies = periods
                             .Select(period =>
            {
                var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);

                // create strategy based SMA
                var strategy = new SmaStrategy(series, new SimpleMovingAverage {
                    Length = period.Item1
                }, new SimpleMovingAverage {
                    Length = period.Item2
                })
                {
                    Volume    = 1,
                    Security  = security,
                    Portfolio = portfolio,
                    Connector = connector,

                    // by default interval is 1 min,
                    // it is excessively for time range with several months
                    UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>()
                };

                strategy.SetCandleManager(new CandleManager(connector));

                var curveItems       = Curve.CreateCurve(LocalizedStrings.Str3026Params.Put(period.Item1, period.Item2), period.Item3);
                strategy.PnLChanged += () =>
                {
                    var data = new EquityData
                    {
                        Time  = strategy.CurrentTime,
                        Value = strategy.PnL,
                    };

                    this.GuiAsync(() => curveItems.Add(data));
                };

                Stat.AddStrategies(new[] { strategy });

                return(strategy);
            })
                             .ToEx(periods.Length);

            // start emulation
            batchEmulation.Start(strategies);
        }
Esempio n. 12
0
        protected override async void OnStartup(StartupEventArgs e)
        {
            var languageService = ServiceLocator.Default.ResolveType <ILanguageService>();

            languageService.PreferredCulture = new CultureInfo("en-US");

            languageService.FallbackCulture = new CultureInfo("en-US");

#if DEBUG
            _debugListener = LogManager.AddDebugListener(true);
#endif
            var fileLogListener = new FileLogListener
            {
                IgnoreCatelLogging = true,
                FilePath           = FileLocations.LogFile,
                TimeDisplay        = TimeDisplay.DateTime
            };
            LogManager.IgnoreDuplicateExceptionLogging = false;
            LogManager.AddListener(fileLogListener);
            LogManager.GetCurrentClassLogger().Debug($"Started with command line {Environment.CommandLine}");

            var serviceLocator = ServiceLocator.Default;
            var updateService  = serviceLocator.ResolveType <IUpdateService>();
            updateService.Initialize(Settings.Application.AutomaticUpdates.AvailableChannels,
                                     Settings.Application.AutomaticUpdates.DefaultChannel,
                                     Settings.Application.AutomaticUpdates.CheckForUpdatesDefaultValue);

            if (updateService.IsUpdateSystemAvailable)
            {
                LogManager.GetCurrentClassLogger().Debug("Update system available, processing squirrel events");
                using (var mgr = new UpdateManager(updateService.CurrentChannel.DefaultUrl))
                {
                    // Note, in most of these scenarios, the app exits after this method
                    // completes!
                    SquirrelAwareApp.HandleEvents(
                        onInitialInstall: v =>
                    {
                        LogManager.GetCurrentClassLogger().Debug("Installing shortcuts");
                        mgr.CreateShortcutForThisExe();
                        Environment.Exit(0);
                    },
                        onAppUpdate: v =>
                    {
                        LogManager.GetCurrentClassLogger().Debug("Update: Installing shortcuts");
                        mgr.CreateShortcutForThisExe();
                        Environment.Exit(0);
                    },
                        onAppUninstall: v =>
                    {
                        mgr.RemoveShortcutForThisExe();
                        Environment.Exit(0);
                    });
                }
            }


            LogManager.GetCurrentClassLogger().Debug("Startup");

            try
            {
                RotateLogFile(fileLogListener.FilePath);
            }
            catch (Exception exception)
            {
                LogManager.GetCurrentClassLogger().Error("Tried to rotate the log file, but it failed.");
                LogManager.GetCurrentClassLogger().Error(exception);
                MessageBox.Show(
                    $"Unable to rotate the log file {fileLogListener.FilePath}. Please verify that you have access to that file. " +
                    $"We will continue, but no logging will be available. Additional information: {Environment.NewLine}{Environment.NewLine}{exception}",
                    "Log File Error",
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
            }

            // Clean up old RemoteVstHost logs
            VstUtils.CleanupVstWorkerLogDirectory();

            await StartShell();
        }
Esempio n. 13
0
        private void StartBtnClick(object sender, RoutedEventArgs e)
        {
            if (HistoryPath.Text.IsEmpty() || !Directory.Exists(HistoryPath.Text))
            {
                MessageBox.Show(this, LocalizedStrings.Str3014);
                return;
            }

            if (Math.Abs(TestingProcess.Value - 0) > double.Epsilon)
            {
                MessageBox.Show(this, LocalizedStrings.Str3015);
                return;
            }

            var logManager      = new LogManager();
            var fileLogListener = new FileLogListener("sample.log");

            logManager.Listeners.Add(fileLogListener);

            // создаем длины скользящих средник
            var periods = new[]
            {
                new Tuple <int, int, Color>(80, 10, Colors.DarkGreen),
                new Tuple <int, int, Color>(70, 8, Colors.Red),
                new Tuple <int, int, Color>(60, 6, Colors.DarkBlue)
            };

            // хранилище, через которое будет производиться доступ к тиковой и котировочной базе
            var storageRegistry = new StorageRegistry
            {
                // изменяем путь, используемый по умолчанию
                DefaultDrive = new LocalMarketDataDrive(HistoryPath.Text)
            };

            var timeFrame = TimeSpan.FromMinutes(5);

            // создаем тестовый инструмент, на котором будет производится тестирование
            var security = new Security
            {
                Id    = "RIZ2@FORTS",              // по идентификатору инструмента будет искаться папка с историческими маркет данными
                Code  = "RIZ2",
                Name  = "RTS-12.12",
                Board = ExchangeBoard.Forts,
            };

            var startTime = new DateTime(2012, 10, 1);
            var stopTime  = new DateTime(2012, 10, 31);

            var level1Info = new Level1ChangeMessage
            {
                SecurityId = security.ToSecurityId(),
                ServerTime = startTime,
            }
            .TryAdd(Level1Fields.PriceStep, 10m)
            .TryAdd(Level1Fields.StepPrice, 6m)
            .TryAdd(Level1Fields.MinPrice, 10m)
            .TryAdd(Level1Fields.MaxPrice, 1000000m)
            .TryAdd(Level1Fields.MarginBuy, 10000m)
            .TryAdd(Level1Fields.MarginSell, 10000m);

            // тестовый портфель
            var portfolio = new Portfolio
            {
                Name       = "test account",
                BeginValue = 1000000,
            };

            // создаем подключение для эмуляции
            var batchEmulation = new BatchEmulation(new[] { security }, new[] { portfolio }, storageRegistry)
            {
                // инициализируем настройки (инструмент в истории обновляется раз в секунду)
                EmulationSettings =
                {
                    MarketTimeChangedInterval = timeFrame,
                    StartTime = startTime,
                    StopTime  = stopTime,

                    // кол-во одновременно тестируемых стратегий
                    BatchSize                 = periods.Length,
                }
            };

            // и подписываемся на событие изменения прогресса тестирования, чтобы обновить ProgressBar
            batchEmulation.ProgressChanged += (curr, total) => this.GuiAsync(() => TestingProcess.Value = total);

            batchEmulation.StateChanged += (oldState, newState) =>
            {
                if (batchEmulation.State != EmulationStates.Stopped)
                {
                    return;
                }

                this.GuiAsync(() =>
                {
                    if (batchEmulation.IsFinished)
                    {
                        TestingProcess.Value = TestingProcess.Maximum;
                        MessageBox.Show(LocalizedStrings.Str3024 + (DateTime.Now - _startEmulationTime));
                    }
                    else
                    {
                        MessageBox.Show(LocalizedStrings.cancelled);
                    }
                });
            };

            // получаем подключение для эмуляции
            var connector = batchEmulation.EmulationConnector;

            logManager.Sources.Add(connector);

            // подписываемся на получение данных после получения инструмента
            connector.NewSecurities += securities =>
            {
                if (securities.All(s => s != security))
                {
                    return;
                }

                // отправляем данные Level1 для инструмента
                connector.MarketDataAdapter.SendOutMessage(level1Info);

                connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security))
                {
                    // стакан для инструмента в истории обновляется раз в секунду
                    Interval = TimeSpan.FromSeconds(1),
                });
            };

            TestingProcess.Maximum = 100;
            TestingProcess.Value   = 0;

            _startEmulationTime = DateTime.Now;

            var strategies = periods
                             .Select(period =>
            {
                var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);

                // создаем торговую стратегию
                var strategy = new SmaStrategy(series, new SimpleMovingAverage {
                    Length = period.Item1
                }, new SimpleMovingAverage {
                    Length = period.Item2
                })
                {
                    Volume    = 1,
                    Security  = security,
                    Portfolio = portfolio,
                    Connector = connector,

                    // по-умолчанию интервал равен 1 минут,
                    // что для истории в диапазон от нескольких месяцев излишне
                    UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>()
                };

                strategy.SetCandleManager(new CandleManager(connector));

                var curveItems       = Curve.CreateCurve(LocalizedStrings.Str3026Params.Put(period.Item1, period.Item2), period.Item3);
                strategy.PnLChanged += () =>
                {
                    var data = new EquityData
                    {
                        Time  = strategy.CurrentTime,
                        Value = strategy.PnL,
                    };

                    this.GuiAsync(() => curveItems.Add(data));
                };

                Stat.AddStrategies(new[] { strategy });

                return(strategy);
            })
                             .ToEx(periods.Length);

            // запускаем эмуляцию
            batchEmulation.Start(strategies);
        }
Esempio n. 14
0
        private void StartBtnClick(object sender, RoutedEventArgs e)
        {
            if (_batchEmulation != null)
            {
                _batchEmulation.Resume();
                return;
            }

            if (HistoryPath.Folder.IsEmpty() || !Directory.Exists(HistoryPath.Folder))
            {
                MessageBox.Show(this, LocalizedStrings.Str3014);
                return;
            }

            TestingProcess.Value = 0;
            Curve.Clear();
            Stat.Clear();

            var logManager      = new LogManager();
            var fileLogListener = new FileLogListener("sample.log");

            logManager.Listeners.Add(fileLogListener);

            // SMA periods
            var periods = new List <(int longMa, int shortMa, Color color)>();

            for (var l = 100; l >= 50; l -= 10)
            {
                for (var s = 10; s >= 5; s -= 1)
                {
                    periods.Add((l, s, Color.FromRgb((byte)RandomGen.GetInt(255), (byte)RandomGen.GetInt(255), (byte)RandomGen.GetInt(255))));
                }
            }

            // storage to historical data
            var storageRegistry = new StorageRegistry
            {
                // set historical path
                DefaultDrive = new LocalMarketDataDrive(HistoryPath.Folder)
            };

            var timeFrame = TimeSpan.FromMinutes(1);

            // create test security
            var security = new Security
            {
                Id    = "SBER@TQBR",              // sec id has the same name as folder with historical data
                Code  = "SBER",
                Name  = "SBER",
                Board = ExchangeBoard.Micex,
            };

            var startTime = new DateTime(2020, 4, 1);
            var stopTime  = new DateTime(2020, 4, 20);

            var level1Info = new Level1ChangeMessage
            {
                SecurityId = security.ToSecurityId(),
                ServerTime = startTime,
            }
            .TryAdd(Level1Fields.PriceStep, 0.01m)
            .TryAdd(Level1Fields.StepPrice, 0.01m)
            .TryAdd(Level1Fields.MinPrice, 0.01m)
            .TryAdd(Level1Fields.MaxPrice, 1000000m)
            .TryAdd(Level1Fields.MarginBuy, 10000m)
            .TryAdd(Level1Fields.MarginSell, 10000m);

            // test portfolio
            var portfolio = Portfolio.CreateSimulator();

            // create backtesting connector
            _batchEmulation = new BatchEmulation(new[] { security }, new[] { portfolio }, storageRegistry)
            {
                EmulationSettings =
                {
                    MarketTimeChangedInterval = timeFrame,
                    StartTime = startTime,
                    StopTime  = stopTime,

                    // count of parallel testing strategies
                    // if not set, then CPU count * 2
                    //BatchSize = 3,
                }
            };

            // handle historical time for update ProgressBar
            _batchEmulation.TotalProgressChanged += (currBatch, total) => this.GuiAsync(() => TestingProcess.Value = total);

            _batchEmulation.StateChanged += (oldState, newState) =>
            {
                var isFinished = _batchEmulation.IsFinished;

                if (_batchEmulation.State == ChannelStates.Stopped)
                {
                    _batchEmulation = null;
                }

                this.GuiAsync(() =>
                {
                    switch (newState)
                    {
                    case ChannelStates.Stopping:
                    case ChannelStates.Starting:
                    case ChannelStates.Suspending:
                        SetIsEnabled(false, false, false);
                        break;

                    case ChannelStates.Stopped:
                        SetIsEnabled(true, false, false);

                        if (isFinished)
                        {
                            TestingProcess.Value = TestingProcess.Maximum;
                            MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime));
                        }
                        else
                        {
                            MessageBox.Show(this, LocalizedStrings.cancelled);
                        }

                        break;

                    case ChannelStates.Started:
                        SetIsEnabled(false, true, true);
                        break;

                    case ChannelStates.Suspended:
                        SetIsEnabled(true, false, true);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException(newState.ToString());
                    }
                });
            };

            _startEmulationTime = DateTime.Now;

            var strategies = periods
                             .Select(period =>
            {
                var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);

                // create strategy based SMA
                var strategy = new SampleHistoryTesting.SmaStrategy(series)
                {
                    ShortSma = { Length = period.shortMa },
                    LongSma  = { Length = period.longMa },

                    Volume    = 1,
                    Security  = security,
                    Portfolio = portfolio,
                    //Connector = connector,

                    // by default interval is 1 min,
                    // it is excessively for time range with several months
                    UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>()
                };

                this.GuiSync(() =>
                {
                    var curveElem = Curve.CreateCurve(LocalizedStrings.Str3026Params.Put(period.Item1, period.Item2), period.Item3, ChartIndicatorDrawStyles.Line);

                    strategy.PnLChanged += () =>
                    {
                        var data = new ChartDrawData();

                        data
                        .Group(strategy.CurrentTime)
                        .Add(curveElem, strategy.PnL);

                        Curve.Draw(data);
                    };

                    Stat.AddStrategies(new[] { strategy });
                });

                return(strategy);
            });

            // start emulation
            _batchEmulation.Start(strategies, periods.Count);
        }
Esempio n. 15
0
        public static int Link(Context context)
        {
            int?exitCode = null;

            var stopWatch = new Stopwatch();

            stopWatch.Start();

            context.ValidateContext();

            if (!string.IsNullOrEmpty(context.LogFile))
            {
                var fileLogListener = new FileLogListener(context.LogFile, 25 * 1024);
                fileLogListener.IsDebugEnabled = context.IsDebug;

                fileLogListener.IgnoreCatelLogging = true;
                LogManager.AddListener(fileLogListener);
            }

            if (!PdbStrHelper.IsPdbStrAvailable())
            {
                Log.Error("PdbStr is not found on the computer, please install 'Debugging Tools for Windows'");
                return(-1);
            }

            try
            {
                var      projects = new List <Project>();
                string[] solutionFiles;
                if (string.IsNullOrEmpty(context.SolutionFile))
                {
                    solutionFiles = Directory.GetFiles(context.SolutionDirectory, "*.sln", SearchOption.AllDirectories);
                }
                else
                {
                    var pathToSolutionFile = Path.Combine(context.SolutionDirectory, context.SolutionFile);
                    if (!File.Exists(pathToSolutionFile))
                    {
                        Log.Error("Could not find solution file: " + pathToSolutionFile);
                        return(-1);
                    }

                    solutionFiles = new[] { pathToSolutionFile };
                }

                foreach (var solutionFile in solutionFiles)
                {
                    var solutionProjects = ProjectHelper.GetProjects(solutionFile, context.ConfigurationName, context.PlatformName);
                    projects.AddRange(solutionProjects);
                }

                var provider = context.Provider;
                if (provider == null)
                {
                    Log.ErrorAndThrowException <GitLinkException>("Cannot find a matching provider for '{0}'", context.TargetUrl);
                }

                Log.Info("Using provider '{0}'", provider.GetType().Name);

                var shaHash = context.Provider.GetShaHashOfCurrentBranch(context);

                Log.Info("Using commit sha '{0}' as version stamp", shaHash);

                var projectCount   = projects.Count();
                var failedProjects = new List <Project>();
                Log.Info("Found '{0}' project(s)", projectCount);
                Log.Info(string.Empty);

                foreach (var project in projects)
                {
                    try
                    {
                        if (project.ShouldBeIgnored(context.IgnoredProjects))
                        {
                            Log.Info("Ignoring '{0}'", project.GetProjectName());
                            Log.Info(string.Empty);
                            continue;
                        }

                        if (context.IsDebug)
                        {
                            project.DumpProperties();
                        }

                        if (!LinkProject(context, project, shaHash))
                        {
                            failedProjects.Add(project);
                        }
                    }
                    catch (Exception)
                    {
                        failedProjects.Add(project);
                    }
                }

                Log.Info("All projects are done. {0} of {1} succeeded", projectCount - failedProjects.Count, projectCount);

                if (failedProjects.Count > 0)
                {
                    Log.Info(string.Empty);
                    Log.Info("The following projects have failed:");
                    Log.Indent();

                    foreach (var failedProject in failedProjects)
                    {
                        Log.Info("* {0}", context.GetRelativePath(failedProject.GetProjectName()));
                    }

                    Log.Unindent();
                }

                exitCode = (failedProjects.Count == 0) ? 0 : -1;
            }
            catch (GitLinkException ex)
            {
                Log.Error(ex, "An error occurred");
            }
            catch (Exception ex)
            {
                Log.Error(ex, "An unexpected error occurred");
            }

            stopWatch.Stop();

            Log.Info(string.Empty);
            Log.Info("Completed in '{0}'", stopWatch.Elapsed);

            return(exitCode ?? -1);
        }
Esempio n. 16
0
        public static int Link(Context context)
        {
            int?exitCode = null;

            var stopWatch = new Stopwatch();

            stopWatch.Start();

            context.ValidateContext();

            if (!string.IsNullOrEmpty(context.LogFile))
            {
                var fileLogListener = new FileLogListener(context.LogFile, 25 * 1024);
                fileLogListener.IsDebugEnabled = context.IsDebug;

                fileLogListener.IgnoreCatelLogging = true;
                LogManager.AddListener(fileLogListener);
            }

            using (var temporaryFilesContext = new TemporaryFilesContext())
            {
                Log.Info("Extracting embedded pdbstr.exe");

                var pdbStrFile = temporaryFilesContext.GetFile("pdbstr.exe");
                ResourceHelper.ExtractEmbeddedResource("GitLink.Resources.Files.pdbstr.exe", pdbStrFile);

                try
                {
                    var      projects = new List <Project>();
                    string[] solutionFiles;
                    if (string.IsNullOrEmpty(context.SolutionFile))
                    {
                        solutionFiles = Directory.GetFiles(context.SolutionDirectory, "*.sln", SearchOption.AllDirectories);
                    }
                    else
                    {
                        var pathToSolutionFile = Path.Combine(context.SolutionDirectory, context.SolutionFile);
                        if (!File.Exists(pathToSolutionFile))
                        {
                            Log.Error("Could not find solution file: {0}", pathToSolutionFile);
                            return(-1);
                        }

                        solutionFiles = new[] { pathToSolutionFile };
                    }

                    foreach (var solutionFile in solutionFiles)
                    {
                        var solutionProjects = ProjectHelper.GetProjects(solutionFile, context.ConfigurationName, context.PlatformName);
                        projects.AddRange(solutionProjects);
                    }

                    var provider = context.Provider;
                    if (provider == null)
                    {
                        throw Log.ErrorAndCreateException <GitLinkException>("Cannot find a matching provider for '{0}'", context.TargetUrl);
                    }

                    Log.Info("Using provider '{0}'", provider.GetType().Name);

                    var shaHash = context.Provider.GetShaHashOfCurrentBranch(context, temporaryFilesContext);

                    Log.Info("Using commit sha '{0}' as version stamp", shaHash);

                    var projectCount   = projects.Count();
                    var failedProjects = new List <Project>();
                    Log.Info("Found '{0}' project(s)", projectCount);
                    Log.Info(string.Empty);

                    foreach (var project in projects)
                    {
                        try
                        {
                            var projectName = project.GetProjectName();
                            if (ProjectHelper.ShouldBeIgnored(projectName, context.IncludedProjects, context.IgnoredProjects))
                            {
                                Log.Info("Ignoring '{0}'", project.GetProjectName());
                                Log.Info(string.Empty);
                                continue;
                            }

                            if (context.IsDebug)
                            {
                                project.DumpProperties();
                            }

                            if (!LinkProject(context, project, pdbStrFile, shaHash, context.PdbFilesDirectory))
                            {
                                failedProjects.Add(project);
                            }
                        }
                        catch (Exception)
                        {
                            failedProjects.Add(project);
                        }
                    }

                    Log.Info("All projects are done. {0} of {1} succeeded", projectCount - failedProjects.Count, projectCount);

                    if (failedProjects.Count > 0)
                    {
                        Log.Info(string.Empty);
                        Log.Info("The following projects have failed:");
                        Log.Indent();

                        foreach (var failedProject in failedProjects)
                        {
                            Log.Info("* {0}", context.GetRelativePath(failedProject.GetProjectName()));
                        }

                        Log.Unindent();
                    }

                    exitCode = (failedProjects.Count == 0) ? 0 : -1;
                }
                catch (GitLinkException ex)
                {
                    Log.Error(ex, "An error occurred");
                }
                catch (Exception ex)
                {
                    Log.Error(ex, "An unexpected error occurred");
                }

                stopWatch.Stop();
            }

            Log.Info(string.Empty);
            Log.Info("Completed in '{0}'", stopWatch.Elapsed);

            exitCode = exitCode ?? -1;

            if (context.ErrorsAsWarnings && exitCode != 0)
            {
                Log.Info("One or more errors occurred, but treating it as warning instead");

                exitCode = 0;
            }

            return(exitCode.Value);
        }
Esempio n. 17
0
        private void StartBtnClick(object sender, RoutedEventArgs e)
        {
            InitChart();

            if (HistoryPath.Text.IsEmpty() || !Directory.Exists(HistoryPath.Text))
            {
                MessageBox.Show(this, LocalizedStrings.Str3014);
                return;
            }

            if (_connectors.Any(t => t.State != EmulationStates.Stopped))
            {
                MessageBox.Show(this, LocalizedStrings.Str3015);
                return;
            }

            var secIdParts = SecId.Text.Split('@');

            if (secIdParts.Length != 2)
            {
                MessageBox.Show(this, LocalizedStrings.Str3016);
                return;
            }

            var timeFrame = TimeSpan.FromMinutes(5);

            // создаем настройки для тестирования
            var settings = new[]
            {
                Tuple.Create(
                    TicksCheckBox,
                    TicksTestingProcess,
                    TicksParameterGrid,
                    // тест только на тиках
                    new EmulationInfo {
                    CurveColor = Colors.DarkGreen, StrategyName = LocalizedStrings.Str3017
                }),

                Tuple.Create(
                    TicksAndDepthsCheckBox,
                    TicksAndDepthsTestingProcess,
                    TicksAndDepthsParameterGrid,
                    // тест на тиках + стаканы
                    new EmulationInfo {
                    UseMarketDepth = true, CurveColor = Colors.Red, StrategyName = LocalizedStrings.Str3018
                }),

                Tuple.Create(
                    CandlesCheckBox,
                    CandlesTestingProcess,
                    CandlesParameterGrid,
                    // тест на свечах
                    new EmulationInfo {
                    UseCandleTimeFrame = timeFrame, CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.Str3019
                }),

                Tuple.Create(
                    CandlesAndDepthsCheckBox,
                    CandlesAndDepthsTestingProcess,
                    CandlesAndDepthsParameterGrid,
                    // тест на свечах + стаканы
                    new EmulationInfo {
                    UseMarketDepth = true, UseCandleTimeFrame = timeFrame, CurveColor = Colors.Cyan, StrategyName = LocalizedStrings.Str3020
                }),

                Tuple.Create(
                    OrderLogCheckBox,
                    OrderLogTestingProcess,
                    OrderLogParameterGrid,
                    // тест на логе заявок
                    new EmulationInfo {
                    UseOrderLog = true, CurveColor = Colors.CornflowerBlue, StrategyName = LocalizedStrings.Str3021
                })
            };

            // хранилище, через которое будет производиться доступ к тиковой и котировочной базе
            var storageRegistry = new StorageRegistry
            {
                // изменяем путь, используемый по умолчанию
                DefaultDrive = new LocalMarketDataDrive(HistoryPath.Text)
            };

            var startTime = (DateTime)From.Value;
            var stopTime  = (DateTime)To.Value;

            // ОЛ необходимо загружать с 18.45 пред дня, чтобы стаканы строились правильно
            if (OrderLogCheckBox.IsChecked == true)
            {
                startTime = startTime.Subtract(TimeSpan.FromDays(1)).AddHours(18).AddMinutes(45).AddTicks(1);
            }

            // задаем шаг ProgressBar
            var progressStep = ((stopTime - startTime).Ticks / 100).To <TimeSpan>();

            // в реальности период может быть другим, и это зависит от объема данных,
            // хранящихся по пути HistoryPath,
            TicksTestingProcess.Maximum = TicksAndDepthsTestingProcess.Maximum = CandlesTestingProcess.Maximum = 100;
            TicksTestingProcess.Value   = TicksAndDepthsTestingProcess.Value = CandlesTestingProcess.Value = 0;

            var logManager      = new LogManager();
            var fileLogListener = new FileLogListener("sample.log");

            logManager.Listeners.Add(fileLogListener);
            //logManager.Listeners.Add(new DebugLogListener());	// чтобы смотреть логи в отладчике - работает медленно.

            var generateDepths = GenDepthsCheckBox.IsChecked == true;
            var maxDepth       = MaxDepth.Text.To <int>();
            var maxVolume      = MaxVolume.Text.To <int>();

            var secCode = secIdParts[0];
            var board   = ExchangeBoard.GetOrCreateBoard(secIdParts[1]);

            foreach (var set in settings)
            {
                if (set.Item1.IsChecked == false)
                {
                    continue;
                }

                var progressBar   = set.Item2;
                var statistic     = set.Item3;
                var emulationInfo = set.Item4;

                // создаем тестовый инструмент, на котором будет производится тестирование
                var security = new Security
                {
                    Id    = SecId.Text,                  // по идентификатору инструмента будет искаться папка с историческими маркет данными
                    Code  = secCode,
                    Board = board,
                };

                var level1Info = new Level1ChangeMessage
                {
                    SecurityId = security.ToSecurityId(),
                    ServerTime = startTime,
                }
                .TryAdd(Level1Fields.PriceStep, 10m)
                .TryAdd(Level1Fields.StepPrice, 6m)
                .TryAdd(Level1Fields.MinPrice, 10m)
                .TryAdd(Level1Fields.MaxPrice, 1000000m)
                .TryAdd(Level1Fields.MarginBuy, 10000m)
                .TryAdd(Level1Fields.MarginSell, 10000m);

                // тестовый портфель
                var portfolio = new Portfolio
                {
                    Name       = "test account",
                    BeginValue = 1000000,
                };

                // создаем подключение для эмуляции
                // инициализируем настройки (инструмент в истории обновляется раз в секунду)
                var connector = new HistoryEmulationConnector(
                    new[] { security },
                    new[] { portfolio })
                {
                    StorageRegistry = storageRegistry,

                    MarketEmulator =
                    {
                        Settings                =
                        {
                            // использовать свечи
                            UseCandlesTimeFrame = emulationInfo.UseCandleTimeFrame,

                            // сведение сделки в эмуляторе если цена коснулась нашей лимитной заявки.
                            // Если выключено - требуется "прохождение цены сквозь уровень"
                            // (более "суровый" режим тестирования.)
                            MatchOnTouch        = false,
                        }
                    },

                    //UseExternalCandleSource = true,
                    CreateDepthFromOrdersLog  = emulationInfo.UseOrderLog,
                    CreateTradesFromOrdersLog = emulationInfo.UseOrderLog,
                };

                connector.MarketDataAdapter.SessionHolder.MarketTimeChangedInterval = timeFrame;

                ((ILogSource)connector).LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info;

                logManager.Sources.Add(connector);

                connector.NewSecurities += securities =>
                {
                    //подписываемся на получение данных после получения инструмента

                    if (securities.All(s => s != security))
                    {
                        return;
                    }

                    // отправляем данные Level1 для инструмента
                    connector.MarketDataAdapter.SendOutMessage(level1Info);

                    // тест подразумевает наличие стаканов
                    if (emulationInfo.UseMarketDepth)
                    {
                        connector.RegisterMarketDepth(security);

                        if (
                            // если выбрана генерация стаканов вместо реальных стаканов
                            generateDepths ||
                            // для свечей генерируем стаканы всегда
                            emulationInfo.UseCandleTimeFrame != TimeSpan.Zero
                            )
                        {
                            // если история по стаканам отсутствует, но стаканы необходимы для стратегии,
                            // то их можно сгенерировать на основании цен последних сделок или свечек.
                            connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security))
                            {
                                Interval           = TimeSpan.FromSeconds(1),                       // стакан для инструмента в истории обновляется раз в секунду
                                MaxAsksDepth       = maxDepth,
                                MaxBidsDepth       = maxDepth,
                                UseTradeVolume     = true,
                                MaxVolume          = maxVolume,
                                MinSpreadStepCount = 2,                                 // минимальный генерируемый спред - 2 минимальных шага цены
                                MaxSpreadStepCount = 5,                                 // не генерировать спрэд между лучшим бид и аск больше чем 5 минимальных шагов цены - нужно чтобы при генерации из свечей не получалось слишком широкого спреда.
                                MaxPriceStepCount  = 3                                  // максимальное количество шагов между ценами,
                            });
                        }
                    }
                    else if (emulationInfo.UseOrderLog)
                    {
                        connector.RegisterOrderLog(security);
                    }
                };

                // соединяемся с трейдером и запускаем экспорт,
                // чтобы инициализировать переданными инструментами и портфелями необходимые свойства EmulationTrader
                connector.Connect();
                connector.StartExport();

                var candleManager = new CandleManager(connector);
                var series        = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);

                _shortMa = new SimpleMovingAverage {
                    Length = 10
                };
                _shortElem = new ChartIndicatorElement
                {
                    Color          = Colors.Coral,
                    ShowAxisMarker = false,
                    FullTitle      = _shortMa.ToString()
                };
                _bufferedChart.AddElement(_area, _shortElem);

                _longMa = new SimpleMovingAverage {
                    Length = 80
                };
                _longElem = new ChartIndicatorElement
                {
                    ShowAxisMarker = false,
                    FullTitle      = _longMa.ToString()
                };
                _bufferedChart.AddElement(_area, _longElem);

                // создаем торговую стратегию, скользящие средние на 80 5-минуток и 10 5-минуток
                var strategy = new SmaStrategy(_bufferedChart, _candlesElem, _tradesElem, _shortMa, _shortElem, _longMa, _longElem, series)
                {
                    Volume    = 1,
                    Portfolio = portfolio,
                    Security  = security,
                    Connector = connector,
                    LogLevel  = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info,

                    // по-умолчанию интервал равен 1 минут,
                    // что для истории в диапазон от нескольких месяцев излишне
                    UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>()
                };

                // комиссия в 1 копейку за сделку
                connector.MarketEmulator.SendInMessage(new CommissionRuleMessage
                {
                    Rule = new CommissionPerTradeRule {
                        Value = 0.01m
                    }
                });

                logManager.Sources.Add(strategy);

                // копируем параметры на визуальную панель
                statistic.Parameters.Clear();
                statistic.Parameters.AddRange(strategy.StatisticManager.Parameters);

                var pnlCurve           = Curve.CreateCurve("P&L " + emulationInfo.StrategyName, emulationInfo.CurveColor, EquityCurveChartStyles.Area);
                var unrealizedPnLCurve = Curve.CreateCurve(LocalizedStrings.PnLUnreal + emulationInfo.StrategyName, Colors.Black);
                var commissionCurve    = Curve.CreateCurve(LocalizedStrings.Str159 + " " + emulationInfo.StrategyName, Colors.Red, EquityCurveChartStyles.DashedLine);
                var posItems           = PositionCurve.CreateCurve(emulationInfo.StrategyName, emulationInfo.CurveColor);
                strategy.PnLChanged += () =>
                {
                    var pnl = new EquityData
                    {
                        Time  = strategy.CurrentTime,
                        Value = strategy.PnL - strategy.Commission ?? 0
                    };

                    var unrealizedPnL = new EquityData
                    {
                        Time  = strategy.CurrentTime,
                        Value = strategy.PnLManager.UnrealizedPnL
                    };

                    var commission = new EquityData
                    {
                        Time  = strategy.CurrentTime,
                        Value = strategy.Commission ?? 0
                    };

                    pnlCurve.Add(pnl);
                    unrealizedPnLCurve.Add(unrealizedPnL);
                    commissionCurve.Add(commission);
                };

                strategy.PositionChanged += () => posItems.Add(new EquityData {
                    Time = strategy.CurrentTime, Value = strategy.Position
                });

                var nextTime = startTime + progressStep;

                // и подписываемся на событие изменения времени, чтобы обновить ProgressBar
                connector.MarketTimeChanged += d =>
                {
                    if (connector.CurrentTime < nextTime && connector.CurrentTime < stopTime)
                    {
                        return;
                    }

                    var steps = (connector.CurrentTime - startTime).Ticks / progressStep.Ticks + 1;
                    nextTime = startTime + (steps * progressStep.Ticks).To <TimeSpan>();
                    this.GuiAsync(() => progressBar.Value = steps);
                };

                connector.StateChanged += () =>
                {
                    if (connector.State == EmulationStates.Stopped)
                    {
                        candleManager.Stop(series);
                        strategy.Stop();

                        logManager.Dispose();
                        _connectors.Clear();

                        SetIsEnabled(false);

                        this.GuiAsync(() =>
                        {
                            if (connector.IsFinished)
                            {
                                progressBar.Value = progressBar.Maximum;
                                MessageBox.Show(LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime));
                            }
                            else
                            {
                                MessageBox.Show(LocalizedStrings.cancelled);
                            }
                        });
                    }
                    else if (connector.State == EmulationStates.Started)
                    {
                        SetIsEnabled(true);

                        // запускаем стратегию когда эмулятор запустился
                        strategy.Start();
                        candleManager.Start(series);
                    }
                };

                if (ShowDepth.IsChecked == true)
                {
                    MarketDepth.UpdateFormat(security);

                    connector.NewMessage += (message, dir) =>
                    {
                        var quoteMsg = message as QuoteChangeMessage;

                        if (quoteMsg != null)
                        {
                            MarketDepth.UpdateDepth(quoteMsg);
                        }
                    };
                }

                _connectors.Add(connector);
            }

            _startEmulationTime = DateTime.Now;

            // запускаем эмуляцию
            foreach (var connector in _connectors)
            {
                // указываем даты начала и конца тестирования
                connector.Start(startTime, stopTime);
            }

            TabControl.Items.Cast <TabItem>().First(i => i.Visibility == Visibility.Visible).IsSelected = true;
        }
Esempio n. 18
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ShellWindow"/> class.
        /// </summary>
        /// <remarks>This method is required for design time support.</remarks>
        public ShellWindow()
            : base(DataWindowMode.Custom, setOwnerAndFocus: false)
        {
            var currentLogFileName = TaskRunnerEnvironment.CurrentLogFileName;

            if (File.Exists(currentLogFileName))
            {
                File.Delete(currentLogFileName);
            }

            var fileLogListener = new FileLogListener(currentLogFileName, 25 * 1000)
            {
                IgnoreCatelLogging = true,
                IsDebugEnabled     = false
            };

            LogManager.AddListener(fileLogListener);

            var serviceLocator      = this.GetServiceLocator();
            var taskRunnerService   = serviceLocator.ResolveType <ITaskRunnerService>();
            var commandManager      = serviceLocator.ResolveType <ICommandManager>();
            var uiVisualizerService = serviceLocator.ResolveType <IUIVisualizerService>();

            if (taskRunnerService.ShowCustomizeShortcutsButton)
            {
                AddCustomButton(DataWindowButton.FromAsync("Keyboard shortcuts", () => uiVisualizerService.ShowDialogAsync <KeyboardMappingsOverviewViewModel>(), null));
            }

            serviceLocator.RegisterInstance <IAboutInfoService>(taskRunnerService);

            if (taskRunnerService.GetAboutInfo() != null)
            {
                var aboutService = serviceLocator.ResolveType <IAboutService>();
#pragma warning disable AvoidAsyncVoid // Avoid async void
                commandManager.RegisterAction("Help.About", async() => await aboutService.ShowAboutAsync());
#pragma warning restore AvoidAsyncVoid // Avoid async void

                AddCustomButton(new DataWindowButton("About", commandManager.GetCommand("Help.About")));
            }

            ThemeHelper.EnsureApplicationThemes(GetType().Assembly, true);

            InitializeComponent();
            serviceLocator.RegisterInstance <ILogControlService>(new LogControlService(traceOutputControl));

            ConfigurationContext = taskRunnerService.GetViewDataContext();

            var startupSize = taskRunnerService.GetInitialWindowSize();
            if (startupSize != null && !startupSize.IsEmpty)
            {
                var setWidth  = startupSize.Width > 0d;
                var setHeight = startupSize.Height > 0d;

                if (setHeight && setWidth)
                {
                    SetCurrentValue(SizeToContentProperty, SizeToContent.Manual);
                }
                else if (setHeight)
                {
                    SetCurrentValue(SizeToContentProperty, SizeToContent.Width);
                }
                else if (setWidth)
                {
                    SetCurrentValue(SizeToContentProperty, SizeToContent.Height);
                }
                else
                {
                    SetCurrentValue(SizeToContentProperty, SizeToContent.WidthAndHeight);
                }

                if (setWidth)
                {
                    SetCurrentValue(MinWidthProperty, startupSize.Width);
                    SetCurrentValue(WidthProperty, startupSize.Width);
                }

                if (setHeight)
                {
                    SetCurrentValue(MinHeightProperty, startupSize.Height);
                    SetCurrentValue(HeightProperty, startupSize.Height);
                }
            }

            var view = taskRunnerService.GetView();

            contentControl.Content = view;
        }
Esempio n. 19
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ShellWindow"/> class.
        /// </summary>
        /// <remarks>This method is required for design time support.</remarks>
        public ShellWindow()
            : base(DataWindowMode.Custom, setOwnerAndFocus: false)
        {
            var currentLogFileName = TaskRunnerEnvironment.CurrentLogFileName;

            if (File.Exists(currentLogFileName))
            {
                File.Delete(currentLogFileName);
            }

            var fileLogListener = new FileLogListener(currentLogFileName, 25 * 1000)
            {
                IgnoreCatelLogging = true,
                IsDebugEnabled     = false
            };

            LogManager.AddListener(fileLogListener);

            var serviceLocator      = this.GetServiceLocator();
            var processService      = serviceLocator.ResolveType <IProcessService>();
            var taskRunnerService   = serviceLocator.ResolveType <ITaskRunnerService>();
            var commandManager      = serviceLocator.ResolveType <ICommandManager>();
            var uiVisualizerService = serviceLocator.ResolveType <IUIVisualizerService>();

            AddCustomButton(new DataWindowButton("Open log...", () =>
            {
                LogManager.FlushAll();

                processService.StartProcess(currentLogFileName);
            }));

            if (taskRunnerService.ShowCustomizeShortcutsButton)
            {
                AddCustomButton(new DataWindowButton("Keyboard shortcuts", () => uiVisualizerService.ShowDialog <KeyboardMappingsOverviewViewModel>()));
            }

            serviceLocator.RegisterInstance <IAboutInfoService>(taskRunnerService);

            if (taskRunnerService.GetAboutInfo() != null)
            {
                var aboutService = serviceLocator.ResolveType <IAboutService>();
                commandManager.RegisterAction("Help.About", aboutService.ShowAbout);

                AddCustomButton(new DataWindowButton("About", commandManager.GetCommand("Help.About")));
            }

            ThemeHelper.EnsureApplicationThemes(GetType().Assembly, true);

            InitializeComponent();

            serviceLocator.RegisterInstance <ILogControlService>(new LogControlService(traceOutputControl));

            var task = taskRunnerService.GetViewDataContext();

            task.Wait();
            ConfigurationContext = task.Result;

            var startupSize = taskRunnerService.GetInitialWindowSize();

            if (startupSize != null && !startupSize.IsEmpty)
            {
                bool setWidth  = startupSize.Width > 0d;
                bool setHeight = startupSize.Height > 0d;

                if (setHeight && setWidth)
                {
                    SizeToContent = SizeToContent.Manual;
                }
                else if (setHeight)
                {
                    SizeToContent = SizeToContent.Width;
                }
                else if (setWidth)
                {
                    SizeToContent = SizeToContent.Height;
                }
                else
                {
                    SizeToContent = SizeToContent.WidthAndHeight;
                }

                if (setWidth)
                {
                    MinWidth = startupSize.Width;
                    Width    = startupSize.Width;
                }

                if (setHeight)
                {
                    MinHeight = startupSize.Height;
                    Height    = startupSize.Height;
                }
            }

            var view = taskRunnerService.GetView();

            contentControl.Content = view;
        }
Esempio n. 20
0
        private void StartBtnClick(object sender, RoutedEventArgs e)
        {
            InitChart();

            if (HistoryPath.Text.IsEmpty() || !Directory.Exists(HistoryPath.Text))
            {
                MessageBox.Show(this, LocalizedStrings.Str3014);
                return;
            }

            if (_connectors.Any(t => t.State != EmulationStates.Stopped))
            {
                MessageBox.Show(this, LocalizedStrings.Str3015);
                return;
            }

            var secIdParts = SecId.Text.Split('@');

            if (secIdParts.Length != 2)
            {
                MessageBox.Show(this, LocalizedStrings.Str3016);
                return;
            }

            var timeFrame = TimeSpan.FromMinutes(5);

            // create backtesting modes
            var settings = new[]
            {
                Tuple.Create(
                    TicksCheckBox,
                    TicksTestingProcess,
                    TicksParameterGrid,
                    // ticks
                    new EmulationInfo {
                    UseTicks = true, CurveColor = Colors.DarkGreen, StrategyName = LocalizedStrings.Str3017
                }),

                Tuple.Create(
                    TicksAndDepthsCheckBox,
                    TicksAndDepthsTestingProcess,
                    TicksAndDepthsParameterGrid,
                    // ticks + order book
                    new EmulationInfo {
                    UseTicks = true, UseMarketDepth = true, CurveColor = Colors.Red, StrategyName = LocalizedStrings.Str3018
                }),

                Tuple.Create(
                    CandlesCheckBox,
                    CandlesTestingProcess,
                    CandlesParameterGrid,
                    // candles
                    new EmulationInfo {
                    UseCandleTimeFrame = timeFrame, CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.Str3019
                }),

                Tuple.Create(
                    CandlesAndDepthsCheckBox,
                    CandlesAndDepthsTestingProcess,
                    CandlesAndDepthsParameterGrid,
                    // candles + orderbook
                    new EmulationInfo {
                    UseMarketDepth = true, UseCandleTimeFrame = timeFrame, CurveColor = Colors.Cyan, StrategyName = LocalizedStrings.Str3020
                }),

                Tuple.Create(
                    OrderLogCheckBox,
                    OrderLogTestingProcess,
                    OrderLogParameterGrid,
                    // order log
                    new EmulationInfo {
                    UseOrderLog = true, CurveColor = Colors.CornflowerBlue, StrategyName = LocalizedStrings.Str3021
                })
            };

            // storage to historical data
            var storageRegistry = new StorageRegistry
            {
                // set historical path
                DefaultDrive = new LocalMarketDataDrive(HistoryPath.Text)
            };

            var startTime = (DateTime)From.Value;
            var stopTime  = (DateTime)To.Value;

            // ОЛ необходимо загружать с 18.45 пред дня, чтобы стаканы строились правильно
            if (OrderLogCheckBox.IsChecked == true)
            {
                startTime = startTime.Subtract(TimeSpan.FromDays(1)).AddHours(18).AddMinutes(45).AddTicks(1);
            }

            // ProgressBar refresh step
            var progressStep = ((stopTime - startTime).Ticks / 100).To <TimeSpan>();

            // set ProgressBar bounds
            TicksTestingProcess.Maximum = TicksAndDepthsTestingProcess.Maximum = CandlesTestingProcess.Maximum = 100;
            TicksTestingProcess.Value   = TicksAndDepthsTestingProcess.Value = CandlesTestingProcess.Value = 0;

            var logManager      = new LogManager();
            var fileLogListener = new FileLogListener("sample.log");

            logManager.Listeners.Add(fileLogListener);
            //logManager.Listeners.Add(new DebugLogListener());	// for track logs in output window in Vusial Studio (poor performance).

            var generateDepths = GenDepthsCheckBox.IsChecked == true;
            var maxDepth       = MaxDepth.Text.To <int>();
            var maxVolume      = MaxVolume.Text.To <int>();

            var secCode = secIdParts[0];
            var board   = ExchangeBoard.GetOrCreateBoard(secIdParts[1]);

            foreach (var set in settings)
            {
                if (set.Item1.IsChecked == false)
                {
                    continue;
                }

                var progressBar   = set.Item2;
                var statistic     = set.Item3;
                var emulationInfo = set.Item4;

                // create test security
                var security = new Security
                {
                    Id    = SecId.Text,                  // sec id has the same name as folder with historical data
                    Code  = secCode,
                    Board = board,
                };

                var level1Info = new Level1ChangeMessage
                {
                    SecurityId = security.ToSecurityId(),
                    ServerTime = startTime,
                }
                .TryAdd(Level1Fields.PriceStep, 10m)
                .TryAdd(Level1Fields.StepPrice, 6m)
                .TryAdd(Level1Fields.MinPrice, 10m)
                .TryAdd(Level1Fields.MaxPrice, 1000000m)
                .TryAdd(Level1Fields.MarginBuy, 10000m)
                .TryAdd(Level1Fields.MarginSell, 10000m);

                // test portfolio
                var portfolio = new Portfolio
                {
                    Name       = "test account",
                    BeginValue = 1000000,
                };

                // create backtesting connector
                var connector = new HistoryEmulationConnector(
                    new[] { security },
                    new[] { portfolio })
                {
                    StorageRegistry = storageRegistry,

                    MarketEmulator =
                    {
                        Settings                =
                        {
                            // set time frame is backtesting on candles
                            UseCandlesTimeFrame = emulationInfo.UseCandleTimeFrame,

                            // match order if historical price touched our limit order price.
                            // It is terned off, and price should go through limit order price level
                            // (more "severe" test mode)
                            MatchOnTouch        = false,
                        }
                    },

                    //UseExternalCandleSource = true,
                    CreateDepthFromOrdersLog  = emulationInfo.UseOrderLog,
                    CreateTradesFromOrdersLog = emulationInfo.UseOrderLog,
                };

                connector.StartDate = startTime;
                connector.StopDate  = stopTime;

                connector.MarketTimeChangedInterval = timeFrame;

                ((ILogSource)connector).LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info;

                logManager.Sources.Add(connector);

                connector.NewSecurities += securities =>
                {
                    if (securities.All(s => s != security))
                    {
                        return;
                    }

                    // fill level1 values
                    connector.SendOutMessage(level1Info);

                    if (emulationInfo.UseMarketDepth)
                    {
                        connector.RegisterMarketDepth(security);

                        if (
                            // if order book will be generated
                            generateDepths ||
                            // of backtesting will be on candles
                            emulationInfo.UseCandleTimeFrame != TimeSpan.Zero
                            )
                        {
                            // if no have order book historical data, but strategy is required,
                            // use generator based on last prices
                            connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security))
                            {
                                Interval           = TimeSpan.FromSeconds(1),                       // order book freq refresh is 1 sec
                                MaxAsksDepth       = maxDepth,
                                MaxBidsDepth       = maxDepth,
                                UseTradeVolume     = true,
                                MaxVolume          = maxVolume,
                                MinSpreadStepCount = 2,                                 // min spread generation is 2 pips
                                MaxSpreadStepCount = 5,                                 // max spread generation size (prevent extremely size)
                                MaxPriceStepCount  = 3                                  // pips size,
                            });
                        }
                    }

                    if (emulationInfo.UseOrderLog)
                    {
                        connector.RegisterOrderLog(security);
                    }

                    if (emulationInfo.UseTicks)
                    {
                        connector.RegisterTrades(security);
                    }

                    // start historical data loading when connection established successfully and all data subscribed
                    connector.Start();
                };

                var candleManager = new CandleManager(connector);
                var series        = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);

                _shortMa = new SimpleMovingAverage {
                    Length = 10
                };
                _shortElem = new ChartIndicatorElement
                {
                    Color          = Colors.Coral,
                    ShowAxisMarker = false,
                    FullTitle      = _shortMa.ToString()
                };
                _bufferedChart.AddElement(_area, _shortElem);

                _longMa = new SimpleMovingAverage {
                    Length = 80
                };
                _longElem = new ChartIndicatorElement
                {
                    ShowAxisMarker = false,
                    FullTitle      = _longMa.ToString()
                };
                _bufferedChart.AddElement(_area, _longElem);

                // create strategy based on 80 5-min и 10 5-min
                var strategy = new SmaStrategy(_bufferedChart, _candlesElem, _tradesElem, _shortMa, _shortElem, _longMa, _longElem, series)
                {
                    Volume    = 1,
                    Portfolio = portfolio,
                    Security  = security,
                    Connector = connector,
                    LogLevel  = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info,

                    // by default interval is 1 min,
                    // it is excessively for time range with several months
                    UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>()
                };

                logManager.Sources.Add(strategy);

                // fill parameters panel
                statistic.Parameters.Clear();
                statistic.Parameters.AddRange(strategy.StatisticManager.Parameters);

                var pnlCurve           = Curve.CreateCurve("P&L " + emulationInfo.StrategyName, emulationInfo.CurveColor, EquityCurveChartStyles.Area);
                var unrealizedPnLCurve = Curve.CreateCurve(LocalizedStrings.PnLUnreal + emulationInfo.StrategyName, Colors.Black);
                var commissionCurve    = Curve.CreateCurve(LocalizedStrings.Str159 + " " + emulationInfo.StrategyName, Colors.Red, EquityCurveChartStyles.DashedLine);
                var posItems           = PositionCurve.CreateCurve(emulationInfo.StrategyName, emulationInfo.CurveColor);
                strategy.PnLChanged += () =>
                {
                    var pnl = new EquityData
                    {
                        Time  = strategy.CurrentTime,
                        Value = strategy.PnL - strategy.Commission ?? 0
                    };

                    var unrealizedPnL = new EquityData
                    {
                        Time  = strategy.CurrentTime,
                        Value = strategy.PnLManager.UnrealizedPnL
                    };

                    var commission = new EquityData
                    {
                        Time  = strategy.CurrentTime,
                        Value = strategy.Commission ?? 0
                    };

                    pnlCurve.Add(pnl);
                    unrealizedPnLCurve.Add(unrealizedPnL);
                    commissionCurve.Add(commission);
                };

                strategy.PositionChanged += () => posItems.Add(new EquityData {
                    Time = strategy.CurrentTime, Value = strategy.Position
                });

                var nextTime = startTime + progressStep;

                // handle historical time for update ProgressBar
                connector.MarketTimeChanged += d =>
                {
                    if (connector.CurrentTime < nextTime && connector.CurrentTime < stopTime)
                    {
                        return;
                    }

                    var steps = (connector.CurrentTime - startTime).Ticks / progressStep.Ticks + 1;
                    nextTime = startTime + (steps * progressStep.Ticks).To <TimeSpan>();
                    this.GuiAsync(() => progressBar.Value = steps);
                };

                connector.StateChanged += () =>
                {
                    if (connector.State == EmulationStates.Stopped)
                    {
                        candleManager.Stop(series);
                        strategy.Stop();

                        logManager.Dispose();
                        _connectors.Clear();

                        SetIsEnabled(false);

                        this.GuiAsync(() =>
                        {
                            if (connector.IsFinished)
                            {
                                progressBar.Value = progressBar.Maximum;
                                MessageBox.Show(LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime));
                            }
                            else
                            {
                                MessageBox.Show(LocalizedStrings.cancelled);
                            }
                        });
                    }
                    else if (connector.State == EmulationStates.Started)
                    {
                        SetIsEnabled(true);

                        // start strategy when emulation started
                        strategy.Start();
                        candleManager.Start(series);
                    }
                };

                if (ShowDepth.IsChecked == true)
                {
                    MarketDepth.UpdateFormat(security);

                    connector.NewMessage += (message, dir) =>
                    {
                        var quoteMsg = message as QuoteChangeMessage;

                        if (quoteMsg != null)
                        {
                            MarketDepth.UpdateDepth(quoteMsg);
                        }
                    };
                }

                _connectors.Add(connector);
            }

            _startEmulationTime = DateTime.Now;

            // start emulation
            foreach (var connector in _connectors)
            {
                // raise NewSecurities and NewPortfolio for full fill strategy properties
                connector.Connect();

                // 1 cent commission for trade
                connector.SendInMessage(new CommissionRuleMessage
                {
                    Rule = new CommissionPerTradeRule {
                        Value = 0.01m
                    }
                });
            }

            TabControl.Items.Cast <TabItem>().First(i => i.Visibility == Visibility.Visible).IsSelected = true;
        }
Esempio n. 21
0
 public DynamicPluginClient()
 {
     FileLogListener.AddFileLogListener(this);
 }