using System;
using System.Windows;
using System.Windows.Media;
using Ecng.Collections;
using Ecng.Common;
using StockSharp.Algo;
using StockSharp.Algo.Candles;
using StockSharp.Algo.Commissions;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Storages;
using StockSharp.Algo.Strategies;
using StockSharp.Algo.Testing;
using StockSharp.BusinessEntities;
using StockSharp.Logging;
using StockSharp.Messages;
using StockSharp.Configuration;
using StockSharp.Xaml;
using StockSharp.Xaml.Charting;
using StockSharp.Xaml.Charting.IndicatorPainters;
namespace _02_bolinger_band_strategy
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow 
    {
        private HistoryEmulationConnector _connector;
        private ChartCandleElement _candleElement;
        private ChartTradeElement _tradesElem;
        private ChartIndicatorElement _bollingerElem;
        private BollingerBands _bollingerBands;
        private CandleSeries _candleSeries;
        private Security _security;
        private Portfolio _portfolio;
        private readonly LogManager _logManager;
        private Strategy _strategy;
        private readonly string _pathHistory = @"..\..\..\..\..\\History".ToFullPath();
        private ChartBandElement _pnl;
        private ChartBandElement _unrealizedPnL;
        private ChartBandElement _commissionCurve;
        public MainWindow()
        {
            InitializeComponent();
            _logManager = new LogManager();
            _logManager.Listeners.Add(new FileLogListener("log.txt"));
            _logManager.Listeners.Add(new GuiLogListener(Monitor));
            DatePickerBegin.SelectedDate = new DateTime(2021, 02, 09);
            DatePickerEnd.SelectedDate = new DateTime(2021, 02, 11);
            CandleSettingsEditor.Settings = new CandleSeries
            {
                CandleType = typeof(TimeFrameCandle),
                Arg = TimeSpan.FromMinutes(1),
            };
        }
		private void Start_Click(object sender, RoutedEventArgs e)
		{
			_security = new Security
			{
				Id = "ETHUSD_1@FINAM",
				Code = "ETHUSD_1",
				PriceStep = 0.0001m,
				Board = ExchangeBoard.Cryptopia
			};
			_portfolio = new Portfolio { Name = "test account", BeginValue = 1 };
			var storageRegistry = new StorageRegistry
			{
				DefaultDrive = new LocalMarketDataDrive(_pathHistory),
			};
			_connector = new HistoryEmulationConnector(new[] { _security }, new[] { _portfolio })
			{
				HistoryMessageAdapter =
				{
					StorageRegistry = storageRegistry,
					StorageFormat = StorageFormats.Binary,
					StartDate = DatePickerBegin.SelectedDate.Value.ChangeKind(DateTimeKind.Utc),
					StopDate = DatePickerEnd.SelectedDate.Value.ChangeKind(DateTimeKind.Utc),
				},
				LogLevel = LogLevels.Info,
			};
			_logManager.Sources.Add(_connector);
			_candleSeries = new CandleSeries(CandleSettingsEditor.Settings.CandleType, _security,
				CandleSettingsEditor.Settings.Arg)
			{
				//BuildCandlesMode = MarketDataBuildModes.Build,
				BuildCandlesFrom2 = DataType.CandleTimeFrame,
			};
			InitChart();
			_connector.CandleSeriesProcessing += Connector_CandleSeriesProcessing;
			//-------------------------------------------------
			_connector.NewSecurity += Connector_NewSecurity;
			_connector.NewOrder += OrderGrid.Orders.Add;
			_connector.OrderRegisterFailed += OrderGrid.AddRegistrationFail;
			_bollingerBands = new BollingerBands();
			_strategy = new BoligerStrategy_001(_candleSeries)
			{
				Security = _security,
				Connector = _connector,
				Portfolio = _portfolio,
				BollingerBands = new BollingerBands()
			};
			_logManager.Sources.Add(_strategy);
			_strategy.NewMyTrade += MyTradeGrid.Trades.Add;
			_strategy.NewMyTrade += FirstStrategy_NewMyTrade;
			_strategy.PnLChanged += Strategy_PnLChanged;
			CollectionHelper.AddRange(StatisticParameterGrid.Parameters, _strategy.StatisticManager.Parameters);
			_connector.Connect();
			_connector.SendInMessage(new CommissionRuleMessage
			{
				Rule = new CommissionPerTradeRule { Value = 0.01m }
			});
		}
		private void InitChart()
		{
			//-----------------Chart--------------------------------
			Chart.ClearAreas();
			var area = new ChartArea();
			Chart.AddArea(area);
			_candleElement = new ChartCandleElement();
			Chart.AddElement(area, _candleElement);
			_bollingerElem = new ChartIndicatorElement()
			{
				IndicatorPainter = new BollingerBandsPainter()
			};
			Chart.AddElement(area, _bollingerElem);
			_tradesElem = new ChartTradeElement { FullTitle = "Trade" };
			Chart.AddElement(area, _tradesElem);
			_pnl = EquityCurveChart.CreateCurve("PNL", Colors.Green, ChartIndicatorDrawStyles.Area);
			_unrealizedPnL = EquityCurveChart.CreateCurve("unrealizedPnL", Colors.Black, ChartIndicatorDrawStyles.Line);
			_commissionCurve = EquityCurveChart.CreateCurve("commissionCurve", Colors.Red, ChartIndicatorDrawStyles.Line);
		}
		private void Connector_NewSecurity(Security security)
		{
			//_connector.RegisterTrades(security); // - out of date
			_connector.SubscribeTrades(security);
			_strategy.Start();
			_connector.Start();
		}
		private void Strategy_PnLChanged()
		{
			var data = new ChartDrawData();
			data.Group(_strategy.CurrentTime)
				.Add(_pnl, _strategy.PnL)
				.Add(_unrealizedPnL, _strategy.PnLManager.UnrealizedPnL ?? 0)
				.Add(_commissionCurve, _strategy.Commission ?? 0);
			EquityCurveChart.Draw(data);
		}
		private void FirstStrategy_NewMyTrade(MyTrade myTrade)
		{
			var data = new ChartDrawData();
			data.Group(myTrade.Trade.Time)
				.Add(_tradesElem, myTrade);
			Chart.Draw(data);
		}
		private void Connector_CandleSeriesProcessing(CandleSeries candleSeries, Candle candle)
		{
			if (candle.State != CandleStates.Finished) return;
			var s = _bollingerBands.Process(candle);
			var data = new ChartDrawData();
			data.Group(candle.OpenTime)
				.Add(_candleElement, candle)
				.Add(_bollingerElem, s);
			Chart.Draw(data);
		}
	}
}