using StockSharp.Algo.Indicators;
using StockSharp.Algo.Indicators.Misc;
using System;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using System.Collections.Generic;
using Ecng.Xaml;
using Ecng.Collections;
using StockSharp.Algo;
using StockSharp.Algo.Candles;
using StockSharp.Algo.Storages;
using StockSharp.Algo.Testing;
using StockSharp.Algo.Indicators.Trend;
using StockSharp.BusinessEntities;
using StockSharp.Xaml.Charting;
using StockSharp.Xaml.Charting.IndicatorPainters;
namespace SampleHistoryTesting
{
    public partial class MainWindow
    {
        private ChartCandleElement _candlesElem;
        private ChartTradeElement _tradeElement;    
        private ChartIndicatorElement _volumeElement;
        private ChartIndicatorElement el; 
        private readonly ChartArea main;
        private DateTime _startEmulationTime;
        public MainWindow()
        {
            InitializeComponent();
            main = new ChartArea()
            {
                YAxises =
                {
                    new ChartAxis
                    {
                        Id = "Y2",
                        AxisType = ChartAxisType.Numeric,
                        AxisAlignment = ChartAxisAlignment.Left,
                        Group = "G1",
                        AutoRange = true,
                    }
                },
                XAxises =
                {
                    new ChartAxis
                    {
                        Id = "X2",
                        Group = "G1",
                        AutoRange = true,
                        AxisType = ChartAxisType.Numeric,
                        AxisAlignment = ChartAxisAlignment.Top,
                        FlipCoordinates = true,
                        DrawMajorGridLines = false,
                        DrawMajorTicks = false,
                        DrawMinorGridLines = false,
                        DrawMinorTicks = false,
                        DrwaLables = false
                    }
                },
                
            };
            CandleChart.Areas.Add(main);
            _candlesElem = new ChartCandleElement();
            _tradeElement = new ChartTradeElement();
            _volumeElement = new ChartIndicatorElement
            {
                Color = Colors.DarkRed,
                IsLegend = true,
                Indicator = new VolumeIndicator(),
                Title = "Volume",
                YAxisId = "Y2",
            };
            el = new ChartIndicatorElement
            {
                Color = Colors.Red,
                IsLegend = true,
                Indicator = new VolumeProfileIndicator {UseTotalVolume = true, Step = 5, },
                Title = "VolumeProfile",
                DrawStyle = ChartIndicatorDrawStyles.StackedBar,
                StrokeThickness = 3,
                IndicatorPainter = new VolumeProfilePainter(),
                YAxisId = "Y2",
                XAxisId = "X2",
            };
            CandleChart.IsAutoScroll = true;
            main.XAxises[0].AutoRange = true;
            main.Elements.Add(_candlesElem);
            main.Elements.Add(_tradeElement);
            main.Elements.Add(_volumeElement);
            main.Elements.Add(el);
        }
        private void StartBtnClick(object sender, RoutedEventArgs e)
        {
            var path = @"f:\History\";
            var timeFrame = TimeSpan.FromMinutes(5);
            var security = new Security
            {
                //Id = "RIZ2@FORTS", // по идентификатору инструмента будет искаться папка с историческими маркет данными
                //Code = "RIZ2",
                Name = "RTS-12.12",
                Id = "SPFB.RTS@FORTS",
                Code = "SPFB.RTS",
                Class = "SPFB",
                
                MinStepSize = 10,
                MinStepPrice = 2,
                MinPrice = 10,
                MaxPrice = 1000000,
                MarginBuy = 10000, // задаем ГО
                MarginSell = 10000,
                ExchangeBoard = ExchangeBoard.Forts,
            };
            // тестовый портфель
            var portfolio = new Portfolio
            {
                Name = "test account",
                BeginValue = 1000000,
            };
            // хранилище, через которое будет производиться доступ к тиковой и котировочной базе
            /*-------------- Хранилище-------------------------------------*/
            var storageRegistry = new StorageRegistry();
                // Добавление в источник свечек TimeFrameCandleBuilder источник данных в виде файлов гидры 
            ((LocalMarketDataDrive) storageRegistry.DefaultDrive).Path = path;
            var startTime = new DateTime(2013, 1, 1);
            var stopTime = new DateTime(2013, 1, 30);
            // создаем шлюз для эмуляции
            // инициализируем настройки (инструмент в истории обновляется раз в секунду)
            var trader = new HistoryEmulationTrader(new[] {security}, new[] {portfolio})
            {
                StorageRegistry = storageRegistry,
                MarketEmulator =
                {
                    Settings =
                    {
                        // использовать стаканы
                        UseMarketDepth = true,
                        // использовать свечки
                        UseCandlesTimeFrame = TimeSpan.FromMinutes(5),
                        // проверка что стаканы соответствуют сделкам. Улучшает реалистичность тестирования.
                        SyncDepthToTrades = true,
                        // сведение сделки в эмуляторе если цена коснулась нашей лимитной заявки. 
                        // Если выключено - требуется "прохождение цены сквозь уровень"
                        // (более "суровый" режим тестирования.)
                        FillOnTouch = false,
                    }
                }
            };
            ((MessageAdapter) trader.MarketDataAdapter).MarketTimeChangedInterval = timeFrame;
            trader.RegisterMarketDepth(new TrendMarketDepthGenerator(trader.GetSecurityId(security)));
            trader.Connect();
            trader.StartExport();
            var candleManager = new CandleManager(trader);
            var series = new CandleSeries(typeof (TimeFrameCandle), security, timeFrame);
            // создаем торговую стратегию, скользящие средние на 80 5-минуток и 10 5-минуток
            var strategy = new SmaStrategy(series, new SimpleMovingAverage {Length = 80},
                new SimpleMovingAverage {Length = 10})
            {
                Volume = 1,
                Portfolio = portfolio,
                Security = security,
                Trader = trader,
            };
            // копируем параметры на визуальную панель
            ParameterGrid.Parameters.Clear();
            ParameterGrid.Parameters.AddRange(strategy.StatisticManager.Parameters);
            // и подписываемся на событие изменения времени, чтобы обновить ProgressBar
            trader.MarketTimeChanged += a =>
            {
                var aa = a;
            };
            trader.NewMyTrades += (trade) =>
            {
                var t = timeFrame.GetCandleBounds(trade.Last().Trade.Time).Min;
                this.GuiAsync(() =>CandleChart.ProcessValues(t,new Dictionary<IChartElement, object>{{_tradeElement, trade.Last()},}));
            };
            candleManager.Processing += (send, candle) =>
            {
                var vol1 = new ChartIndicatorValue(_volumeElement.Indicator, candle.TotalVolume) { IsFormed = true };
                var vol2 = new VolumeProfileIndicatorValue();
                if (candle.State == CandleStates.Finished)
                {
                    this.GuiAsync(() => CandleChart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
                    {
                        {_candlesElem, candle},
                        {_volumeElement, vol1},
                       // {el,vol2}
                    }));
                }
            };
            candleManager.ProcessDataError += (a) =>
            {
                var aa = a;
            };
            candleManager.Stopped += (a) =>
            {
                var aa = a;
            };
            candleManager.Log += (a) =>
            {
                var aa = a;
            };
            trader.StateChanged += (oldState, newState) =>
            {
                if (trader.State == EmulationStates.Started)
                {
                    // запускаем стратегию когда эмулятор запустился
                    strategy.Start();
                    candleManager.Start(series);
                }
            };
            trader.ExportStarted += () =>
            {
               // strategy.Start();
               // candleManager.Start(series);
            };
            // запускаем эмуляцию
            // указываем даты начала и конца тестирования
            trader.Start(startTime, stopTime);
        }
    }
}