Beispiel #1
0
        /// <summary>
        /// To get the storage for <paramref name="path"/>.
        /// </summary>
        /// <param name="path">Path.</param>
        /// <returns>Market data storage.</returns>
        public IMarketDataDrive GetDrive(string path)
        {
            if (path.IsEmpty() || Guid.TryParse(path, out _) /* TODO remove few versions later 2019-08-06 */)
            {
                return(DefaultDrive);
            }

            var pair = CreatePair(path);

            return(_drives.SafeAdd(pair, key =>
            {
                IMarketDataDrive drive;

                if (pair.Item2 == null)
                {
                    drive = new LocalMarketDataDrive(path);
                }
                else
                {
                    drive = new RemoteMarketDataDrive(new RemoteStorageClient(new Uri(pair.Item2.To <string>())));
                }

                NewDriveCreated?.Invoke(drive);

                return drive;
            }));
        }
Beispiel #2
0
		static void Main()
		{
			// creating AAPL security
			var security = new Security
			{
				Id = "AAPL@NASDAQ",
				PriceStep = 0.1m,
				Decimals = 1,
			};

			var trades = new List<Trade>();

			// generation 1000 random ticks
			//

			for (var i = 0; i < 1000; i++)
			{
				var t = new Trade
				{
					Time = DateTime.Today + TimeSpan.FromMinutes(i),
					Id = i + 1,
					Security = security,
					Volume = RandomGen.GetInt(1, 10),
					Price = RandomGen.GetInt(1, 100) * security.PriceStep ?? 1m + 99
				};

				trades.Add(t);
			}

			using (var drive = new LocalMarketDataDrive())
			{
				// get AAPL storage
				var aaplStorage = drive.GetSecurityDrive(security);

				// get tick storage
				var tradeStorage = (IMarketDataStorage<Trade>)aaplStorage.GetTickStorage(new CsvMarketDataSerializer<ExecutionMessage>());

				// saving ticks
				tradeStorage.Save(trades);

				// loading ticks
				var loadedTrades = tradeStorage.Load(DateTime.Today, DateTime.Today + TimeSpan.FromMinutes(1000));

				foreach (var trade in loadedTrades)
				{
					Console.WriteLine(LocalizedStrings.Str2968Params, trade.Id, trade);
				}

				Console.ReadLine();

				// deleting ticks (and removing file)
				tradeStorage.Delete(DateTime.Today, DateTime.Today + TimeSpan.FromMinutes(1000));	
			}
		}
        private void Download_OnClick(object sender, RoutedEventArgs e)
        {
            var year = SelectedYear;
            var from = From.Value ?? year.Days.First();
            var to = (To.Value ?? year.Days.Last()).EndOfDay();
            var trader = SelectedTrader;
            var tf = SelectedTimeFrame;

            var seriesSet = _securityCtrls
                .Where(pair => pair.Key.SelectedSecurity != null)
                .Select(pair => Tuple.Create(new CandleSeries(typeof(TimeFrameCandle), pair.Key.SelectedSecurity, tf), pair.Value))
                .ToArray();

            BusyIndicator.BusyContent = "Подготовка данных...";
            BusyIndicator.IsBusy = true;

            _candles.Clear();

            var trades = new Dictionary<Security, Dictionary<DateTimeOffset, Tuple<MyTrade[], MyTrade>>>();

            var worker = new BackgroundWorker { WorkerReportsProgress = true };

            worker.DoWork += (o, ea) =>
            {
                foreach (var series in seriesSet)
                {
                    var security = series.Item1.Security;
                    var candleStorage = _dataRegistry.GetCandleStorage(series.Item1, format: StorageFormats.Csv);
                    var secCandles = _candles.SafeAdd(security);

                    secCandles.Clear();
                    secCandles.AddRange(candleStorage.Load(from, to));

                    var candlesDatesCache = _candlesDates.SafeAdd(Tuple.Create(security, tf), k => new DatesCache(Path.Combine(((LocalMarketDataDrive)candleStorage.Drive.Drive).GetSecurityPath(security.ToSecurityId()), "{0}min_date.bin".Put((int)tf.TotalMinutes))));

                    var minCandleDate = candlesDatesCache.MinValue;
                    var maxCandleDate = candlesDatesCache.MaxValue;

                    if (from >= minCandleDate && to <= maxCandleDate)
                        continue;

                    var finamFrom = from;
                    var finamTo = to;

                    if (maxCandleDate != null && finamFrom >= minCandleDate && finamFrom <= maxCandleDate)
                        finamFrom = maxCandleDate.Value + TimeSpan.FromDays(1);

                    if (minCandleDate != null && finamTo >= minCandleDate && finamTo <= maxCandleDate)
                        finamTo = minCandleDate.Value - TimeSpan.FromDays(1);

                    if (finamTo <= finamFrom)
                        continue;

                    worker.ReportProgress(1, Tuple.Create(security, finamFrom, finamTo));

                    var newCandles = (tf.Ticks == 1
                        ? finamFrom.Range(finamTo, TimeSpan.FromDays(1)).SelectMany(day => _finamHistorySource.GetTrades(security, day, day)).ToEx().ToCandles<TimeFrameCandle>(tf)
                        : _finamHistorySource.GetCandles(security, tf, finamFrom, finamTo)
                        ).ToArray();

                    candleStorage.Save(newCandles);

                    foreach (var date in newCandles.Select(c => c.OpenTime.Date).Distinct())
                        candlesDatesCache.Add(date);

                    candlesDatesCache.Save();

                    // TODO
                    secCandles.AddRange(newCandles);
                }

                var traderDrive = new LocalMarketDataDrive(trader);
                var traderStorage = _traderStorages.SafeAdd(trader, key => new StorageRegistry { DefaultDrive = traderDrive });

                foreach (var series in seriesSet)
                {
                    var security = series.Item1.Security;

                    var olStorage = traderStorage.GetOrderLogStorage(security, format: StorageFormats.Csv);
                    var tradeDatesCache = _tradesDates.SafeAdd(trader, k => new DatesCache(Path.Combine(traderDrive.Path, "dates.bin")));

                    var secTrades = from
                        .Range(to, TimeSpan.FromDays(1))
                        .Intersect(year.Days)
                        .SelectMany(date =>
                        {
                            if (olStorage.Dates.Contains(date))
                                return olStorage.Load(date);

                            if (tradeDatesCache.Contains(date))
                                return Enumerable.Empty<OrderLogItem>();

                            worker.ReportProgress(2, date);

                            var loadedTrades = year.GetTrades(_securityStorage, trader, date);

                            var dateTrades = Enumerable.Empty<OrderLogItem>();

                            foreach (var group in loadedTrades.GroupBy(t => t.Order.Security))
                            {
                                var sec = group.Key;

                                traderStorage
                                    .GetOrderLogStorage(sec, format: StorageFormats.Csv)
                                    .Save(group.OrderBy(i => i.Order.Time));

                                if (group.Key == security)
                                    dateTrades = group;
                            }

                            tradeDatesCache.Add(date);
                            tradeDatesCache.Save();

                            return dateTrades;
                        })
                        .GroupBy(ol =>
                        {
                            var time = ol.Order.Time;

                            var period = security.Board.WorkingTime.GetPeriod(time.ToLocalTime(security.Board.Exchange.TimeZoneInfo));
                            if (period != null && period.Times.Length > 0)
                            {
                                var last = period.Times.Last().Max;

                                if (time.TimeOfDay >= last)
                                    time = time.AddTicks(-1);
                            }

                            return time.Truncate(tf);
                        })
                        .ToDictionary(g => g.Key, g =>
                        {
                            var candleTrades = g.Select(ol => new MyTrade
                            {
                                Order = ol.Order,
                                Trade = ol.Trade
                            })
                            .ToArray();

                            if (candleTrades.Length == 0)
                                return null;

                            var order = candleTrades[0].Order;
                            var volume = candleTrades.Sum(t1 => t1.Trade.Volume * (t1.Order.Direction == Sides.Buy ? 1 : -1));

                            if (volume == 0)
                                return Tuple.Create(candleTrades, (MyTrade)null);

                            var side = volume > 0 ? Sides.Buy : Sides.Sell;

                            volume = volume.Abs();

                            var availableVolume = volume;
                            var avgPrice = 0m;

                            foreach (var trade in candleTrades.Where(t1 => t1.Order.Direction == side))
                            {
                                var tradeVol = trade.Trade.Volume.Min(availableVolume);
                                avgPrice += trade.Trade.Price * tradeVol;

                                availableVolume -= tradeVol;

                                if (availableVolume <= 0)
                                    break;
                            }

                            avgPrice = avgPrice / volume;

                            return Tuple.Create(candleTrades, new MyTrade
                            {
                                Order = new Order
                                {
                                    Security = order.Security,
                                    Direction = side,
                                    Time = g.Key,
                                    Portfolio = order.Portfolio,
                                    Price = avgPrice,
                                    Volume = volume,
                                },
                                Trade = new Trade
                                {
                                    Security = order.Security,
                                    Time = g.Key,
                                    Volume = volume,
                                    Price = avgPrice
                                }
                            });
                        });

                    trades.Add(security, secTrades);
                }
            };

            worker.ProgressChanged += (o, ea) =>
            {
                switch (ea.ProgressPercentage)
                {
                    case 1:
                        BusyIndicator.BusyContent = "Скачивание {Item1.Id} свечей с {Item2:yyyy-MM-dd} по {Item3:yyyy-MM-dd}...".PutEx(ea.UserState);
                        break;

                    default:
                        BusyIndicator.BusyContent = "Скачивание сделок за {0:yyyy-MM-dd}...".Put(ea.UserState);
                        break;
                }
            };

            worker.RunWorkerCompleted += (o, ea) =>
            {
                BusyIndicator.IsBusy = false;

                if (ea.Error == null)
                {
                    Chart.ClearAreas();

                    _statisticManager.Reset();

                    var candlesArea = new ChartArea();
                    Chart.AddArea(candlesArea);

                    var positionArea = new ChartArea { Height = 200 };
                    Chart.AddArea(positionArea);
                    positionArea.YAxises.Clear();

                    const string equityYAxis = "Equity";

                    candlesArea.YAxises.Clear();
                    candlesArea.YAxises.Add(new ChartAxis
                    {
                        Id = equityYAxis,
                        AutoRange = true,
                        AxisType = ChartAxisType.Numeric,
                        AxisAlignment = ChartAxisAlignment.Left,
                    });
                    var equityElem = new ChartIndicatorElement
                    {
                        YAxisId = equityYAxis,
                        FullTitle = LocalizedStrings.PnL,
                        IndicatorPainter = new PnlPainter()
                    };
                    var equityInd = new SimpleMovingAverage { Length = 1 };
                    Chart.AddElement(candlesArea, equityElem);

                    var chartValues = new SortedDictionary<DateTimeOffset, IDictionary<IChartElement, object>>();
                    var pnlValues = new Dictionary<DateTimeOffset, decimal>();

                    foreach (var series in seriesSet)
                    {
                        var security = series.Item1.Security;

                        var candleYAxis = "Candles_Y_" + security.Id;

                        candlesArea.YAxises.Add(new ChartAxis
                        {
                            Id = candleYAxis,
                            AutoRange = true,
                            AxisType = ChartAxisType.Numeric,
                            AxisAlignment = ChartAxisAlignment.Right,
                        });

                        var candlesElem = new ChartCandleElement
                        {
                            ShowAxisMarker = false,
                            YAxisId = candleYAxis,
                        };
                        Chart.AddElement(candlesArea, candlesElem, series.Item1);

                        var tradesElem = new ChartTradeElement
                        {
                            BuyStrokeColor = Colors.Black,
                            SellStrokeColor = Colors.Black,
                            BuyColor = series.Item2.Buy,
                            SellColor = series.Item2.Sell,
                            FullTitle = LocalizedStrings.Str985 + " " + security.Id,
                            YAxisId = candleYAxis,
                        };
                        Chart.AddElement(candlesArea, tradesElem);

                        var posYAxis = "Pos_Y_" + security.Id;
                        positionArea.YAxises.Add(new ChartAxis
                        {
                            Id = posYAxis,
                            AutoRange = true,
                            AxisType = ChartAxisType.Numeric,
                            AxisAlignment = ChartAxisAlignment.Right,
                        });
                        var positionElem = new ChartIndicatorElement
                        {
                            FullTitle = LocalizedStrings.Str862 + " " + security.Id,
                            YAxisId = posYAxis,
                            Color = series.Item2.Position
                        };
                        var positionInd = new SimpleMovingAverage { Length = 1 };
                        Chart.AddElement(positionArea, positionElem);

                        var pnlQueue = new PnLQueue(security.ToSecurityId());
                        //var level1Info = new Level1ChangeMessage
                        //{
                        //	SecurityId = pnlQueue.SecurityId,
                        //}
                        //.TryAdd(Level1Fields.PriceStep, security.PriceStep)
                        //.TryAdd(Level1Fields.StepPrice, security.StepPrice);

                        //pnlQueue.ProcessLevel1(level1Info);

                        var pos = 0m;

                        var secTrades = trades[security];

                        var secValues = _candles[security]
                            .Select(c =>
                            {
                                if (c.State != CandleStates.Finished)
                                    c.State = CandleStates.Finished;

                                pnlQueue.ProcessLevel1(new Level1ChangeMessage
                                {
                                    SecurityId = security.ToSecurityId(),
                                }.TryAdd(Level1Fields.LastTradePrice, c.ClosePrice));

                                var values = new Dictionary<IChartElement, object>
                                {
                                    { candlesElem, c },
                                };

                                var candleTrade = secTrades.TryGetValue(c.OpenTime);

                                if (candleTrade != null)
                                {
                                    if (candleTrade.Item2 != null)
                                        values.Add(tradesElem, candleTrade.Item2);

                                    foreach (var myTrade in candleTrade.Item1)
                                    {
                                        pos += myTrade.Order.Direction == Sides.Buy ? myTrade.Trade.Volume : -myTrade.Trade.Volume;
                                        var pnl = pnlQueue.Process(myTrade.ToMessage());

                                        _statisticManager.AddMyTrade(pnl);
                                    }

                                    _statisticManager.AddPosition(c.OpenTime, pos);
                                    _statisticManager.AddPnL(c.OpenTime, pnlQueue.RealizedPnL + pnlQueue.UnrealizedPnL);
                                }

                                pnlValues[c.OpenTime] = pnlValues.TryGetValue(c.OpenTime) + (pnlQueue.RealizedPnL + pnlQueue.UnrealizedPnL);
                                values.Add(positionElem, positionInd.Process(pos));

                                return new RefPair<DateTimeOffset, IDictionary<IChartElement, object>>
                                {
                                    First = c.OpenTime,
                                    Second = values
                                };
                            })
                            .ToArray();

                        foreach (var pair in secValues)
                        {
                            var dict = chartValues.SafeAdd(pair.First, key => new Dictionary<IChartElement, object>());

                            foreach (var pair2 in pair.Second)
                            {
                                dict[pair2.Key] = pair2.Value;
                            }
                        }
                    }

                    foreach (var pair in pnlValues)
                    {
                        chartValues[pair.Key].Add(equityElem, equityInd.Process(pair.Value));
                    }

                    Chart.IsAutoRange = true;

                    try
                    {
                        Chart.Draw(chartValues.Select(p => RefTuple.Create(p.Key, p.Value)));
                    }
                    finally
                    {
                        Chart.IsAutoRange = false;
                    }
                }
                else
                {
                    new MessageBoxBuilder()
                        .Error()
                        .Owner(this)
                        .Text(ea.Error.ToString())
                        .Show();
                }
            };

            worker.RunWorkerAsync();
        }
Beispiel #4
0
            //private static readonly Version _dateVersion = new Version(1, 0);

            public LocalMarketDataStorageDrive(Type dataType, object arg, string path, StorageFormats format, LocalMarketDataDrive drive)
            {
                var fileName = GetFileName(dataType, arg);

                if (path.IsEmpty())
                {
                    throw new ArgumentNullException(nameof(path));
                }

                _path  = path;
                _drive = drive ?? throw new ArgumentNullException(nameof(drive));
                _fileNameWithExtension = fileName + GetExtension(format);
                _datesPath             = IOPath.Combine(_path, fileName + format + "Dates.txt");

                _dataType = DataType.Create(dataType, arg);

                _datesDict = new Lazy <CachedSynchronizedOrderedDictionary <DateTime, DateTime> >(() =>
                {
                    var retVal = new CachedSynchronizedOrderedDictionary <DateTime, DateTime>();

                    if (File.Exists(_datesPath))
                    {
                        foreach (var date in LoadDates())
                        {
                            retVal.Add(date, date);
                        }
                    }
                    else
                    {
                        var dates = InteropHelper
                                    .GetDirectories(_path)
                                    .Where(dir => File.Exists(IOPath.Combine(dir, _fileNameWithExtension)))
                                    .Select(dir => GetDate(IOPath.GetFileName(dir)));

                        foreach (var date in dates)
                        {
                            retVal.Add(date, date);
                        }

                        SaveDates(retVal.CachedValues);
                    }

                    return(retVal);
                }).Track();
            }
Beispiel #5
0
            public LocalMarketDataStorageDrive(LocalMarketDataDrive parent, SecurityId securityId, string fileName, StorageFormats format, IMarketDataDrive drive)
            {
                if (parent == null)
                {
                    throw new ArgumentNullException("parent");
                }

                if (securityId.IsDefault())
                {
                    throw new ArgumentNullException("securityId");
                }

                if (drive == null)
                {
                    throw new ArgumentNullException("drive");
                }

                if (fileName.IsEmpty())
                {
                    throw new ArgumentNullException("fileName");
                }

                _parent                = parent;
                _securityId            = securityId;
                _fileName              = fileName;
                _format                = format;
                _drive                 = drive;
                _fileNameWithExtension = _fileName + GetExtension(_format);

                _datesDict = new Lazy <CachedSynchronizedOrderedDictionary <DateTime, DateTime> >(() =>
                {
                    var retVal = new CachedSynchronizedOrderedDictionary <DateTime, DateTime>();

                    var datesPath = GetDatesCachePath();

                    if (File.Exists(datesPath))
                    {
                        foreach (var date in LoadDates())
                        {
                            retVal.Add(date, date);
                        }
                    }
                    else
                    {
                        var rootDir = Path;

                        var dates = InteropHelper
                                    .GetDirectories(rootDir)
                                    .Where(dir => File.Exists(IOPath.Combine(dir, _fileNameWithExtension)))
                                    .Select(dir => IOPath.GetFileName(dir).ToDateTime(_dateFormat));

                        foreach (var date in dates)
                        {
                            retVal.Add(date, date);
                        }

                        SaveDates(retVal.CachedValues);
                    }

                    return(retVal);
                }).Track();
            }
			public StudioDrive()
			{
				_localDrive = new LocalMarketDataDrive();
				_remoteDrive = new RemoteMarketDataDrive();
				_cacheDrive = new LocalMarketDataDrive(Path.Combine(BaseApplication.AppDataPath, "Cache"));
			}