Exemplo n.º 1
0
        /// <summary>
        /// Получить хранилище маркет-данных.
        /// </summary>
        /// <param name="path">Путь к данным.</param>
        /// <returns>Хранилище маркет-данных.</returns>
        public IMarketDataDrive GetDrive(string path)
        {
            if (path.IsEmpty())
            {
                return(DefaultDrive);
            }

            return(_drives.SafeAdd(path ?? string.Empty, key =>
            {
                IMarketDataDrive drive;

                try
                {
                    var addr = path.To <EndPoint>();
                    drive = new RemoteMarketDataDrive(new RemoteStorageClient(new Uri(addr.To <string>())));
                }
                catch
                {
                    drive = new LocalMarketDataDrive(path);
                }

                NewDriveCreated.SafeInvoke(drive);

                return drive;
            }));
        }
Exemplo n.º 2
0
        private void HistoryPath_OnFolderChanged(string path)
        {
            var secs = LocalMarketDataDrive.GetAvailableSecurities(path).ToArray();

            Securities.ItemsSource = secs;

            if (secs.Length > 0)
            {
                Securities.SelectedIndex = 0;
            }
        }
Exemplo n.º 3
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));
            }
        }
Exemplo n.º 4
0
 public void InitDl()
 {
     dlDates  = new double[0];
     dlInfo   = new double[0, 0];
     SecList  = new List <string>();
     SecArray = new string[0];
     //SStor = new SimStorage();
     str              = new StorageRegistry();
     lmd              = new LocalMarketDataDrive();
     lmd.Path         = Path;
     str.DefaultDrive = lmd; //
 }
Exemplo n.º 5
0
        static void Main(string[] args)
        {
            var security = new Security()
            {
                Id = "RIH7@FORTS", Board = ExchangeBoard.Forts
            };
            StorageRegistry storage = new StorageRegistry();

            string path = @"../../../Data/Quik";

            //Для работы будем использовать готовое локальное файловое хранилище, в которое данные были предварительно записаны при помощи Гидры.
            //Создаем экземпляр LocalMarketDataDrive.
            LocalMarketDataDrive drive = new LocalMarketDataDrive()
            {
                Path = path
            };

            //Передаем в StorageRegistry ссылку на локальное файловое хранилище
            storage.DefaultDrive = drive;

            DateTime from = new DateTime(2017, 02, 14, 10, 0, 0);
            DateTime to   = new DateTime(2017, 02, 15, 23, 50, 0);

            // Получаем хранилище сделок для RIH7
            IMarketDataStorage <Trade> tradeStorage = storage.GetTradeStorage(security);

            // Загружаем сделки из хранилища
            var trades = tradeStorage.Load(from, to);

            // Отображаем в окне вывода информацию
            foreach (var trade in trades)
            {
                Debug.WriteLine("{0} {1}", trade, trade.OpenInterest);
            }

            Console.Read();
        }
Exemplo n.º 6
0
 public StudioDrive()
 {
     _localDrive  = new LocalMarketDataDrive();
     _remoteDrive = new RemoteMarketDataDrive();
     _cacheDrive  = new LocalMarketDataDrive(Path.Combine(BaseApplication.AppDataPath, "Cache"));
 }
Exemplo n.º 7
0
        protected override TimeSpan OnProcess()
        {
            IBackupService service;

            switch (_settings.Service)
            {
            case BackupServices.AwsS3:
                service = new AmazonS3Service(AmazonExtensions.GetEndpoint(_settings.Address), _settings.ServiceRepo, _settings.Login, _settings.Password.To <string>());
                break;

            case BackupServices.AwsGlacier:
                service = new AmazonGlacierService(AmazonExtensions.GetEndpoint(_settings.Address), _settings.ServiceRepo, _settings.Login, _settings.Password.To <string>());
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            var hasSecurities = false;

            this.AddInfoLog(LocalizedStrings.Str2306Params.Put(_settings.StartFrom));

            var startDate = _settings.StartFrom;
            var endDate   = DateTime.Today - TimeSpan.FromDays(_settings.Offset);

            var allDates = startDate.Range(endDate, TimeSpan.FromDays(1)).ToArray();

            var pathEntry = ToEntry(new DirectoryInfo(_settings.Drive.Path));

            var workingSecurities = GetWorkingSecurities().ToArray();

            foreach (var date in allDates)
            {
                foreach (var security in workingSecurities)
                {
                    hasSecurities = true;

                    if (!CanProcess())
                    {
                        break;
                    }

                    var dateEntry = new BackupEntry
                    {
                        Name   = date.ToString("yyyy_MM_dd"),
                        Parent = new BackupEntry
                        {
                            Parent = new BackupEntry
                            {
                                Name   = security.Security.Id.Substring(0, 1),
                                Parent = pathEntry
                            },
                            Name = security.Security.Id,
                        }
                    };

                    var dataTypes = _settings.Drive.GetAvailableDataTypes(security.Security.ToSecurityId(), _settings.StorageFormat);

                    foreach (var dataType in dataTypes)
                    {
                        var storage = StorageRegistry.GetStorage(security.Security, dataType.MessageType, dataType.Arg, _settings.Drive, _settings.StorageFormat);

                        var drive = storage.Drive;

                        var stream = drive.LoadStream(date);

                        if (stream == Stream.Null)
                        {
                            continue;
                        }

                        var entry = new BackupEntry
                        {
                            Name   = LocalMarketDataDrive.GetFileName(dataType.MessageType, dataType.Arg) + LocalMarketDataDrive.GetExtension(StorageFormats.Binary),
                            Parent = dateEntry,
                        };

                        service.Upload(entry, stream, p => { });

                        this.AddInfoLog(LocalizedStrings.Str1580Params, GetPath(entry));
                    }
                }

                if (CanProcess())
                {
                    _settings.StartFrom += TimeSpan.FromDays(1);
                    SaveSettings();
                }
            }

            if (!hasSecurities)
            {
                this.AddWarningLog(LocalizedStrings.Str2292);
                return(TimeSpan.MaxValue);
            }

            if (CanProcess())
            {
                this.AddInfoLog(LocalizedStrings.Str2300);
            }

            return(base.OnProcess());
        }
Exemplo n.º 8
0
        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 security = SelectedSecurity;
            var tf       = SelectedTimeFrame;
            var series   = new CandleSeries(typeof(TimeFrameCandle), security, tf);

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

            Dictionary <DateTimeOffset, Tuple <MyTrade[], MyTrade> > trades = null;

            var worker = new BackgroundWorker {
                WorkerReportsProgress = true
            };

            worker.DoWork += (o, ea) =>
            {
                var candleStorage = _dataRegistry.GetCandleStorage(series, format: StorageFormats.Csv);

                _candles = 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)
                {
                    var finamFrom = from;
                    var finamTo   = to;

                    if (maxCandleDate != default(DateTime) && finamFrom >= minCandleDate && finamFrom <= maxCandleDate)
                    {
                        finamFrom = maxCandleDate + TimeSpan.FromDays(1);
                    }

                    if (minCandleDate != default(DateTime) && finamTo >= minCandleDate && finamTo <= maxCandleDate)
                    {
                        finamTo = minCandleDate - TimeSpan.FromDays(1);
                    }

                    if (finamTo > finamFrom)
                    {
                        worker.ReportProgress(1);

                        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();

                        _candles = _candles.Concat(newCandles);
                    }
                }

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

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

                trades = 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 secTrades = 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)
                        {
                            secTrades = group;
                        }
                    }

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

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

                    var period = security.Board.WorkingTime.GetPeriod(time.DateTime);
                    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(order => new MyTrade
                    {
                        Order = order.Order,
                        Trade = order.Trade
                    })
                                       .ToArray();

                    if (candleTrades.Length > 0)
                    {
                        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
                            }
                        }));
                    }

                    return(null);
                });
            };

            worker.ProgressChanged += (o, ea) =>
            {
                switch (ea.ProgressPercentage)
                {
                case 1:
                    BusyIndicator.BusyContent = "Скачивание свечей...";
                    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 area = new ChartArea();
                    area.YAxises.Add(new ChartAxis
                    {
                        Id            = "equity",
                        AutoRange     = true,
                        AxisType      = ChartAxisType.Numeric,
                        AxisAlignment = ChartAxisAlignment.Left,
                    });
                    Chart.AddArea(area);

                    var candlesElem = new ChartCandleElement {
                        ShowAxisMarker = false
                    };
                    Chart.AddElement(area, candlesElem, series);

                    var tradesElem = new ChartTradeElement
                    {
                        BuyStrokeColor  = Colors.Black,
                        SellStrokeColor = Colors.Black,
                        FullTitle       = "trades",
                    };
                    Chart.AddElement(area, tradesElem);

                    var equityElem = new ChartIndicatorElement {
                        YAxisId = "equity", FullTitle = "equity", IndicatorPainter = new PnlPainter()
                    };
                    var equityInd = new SimpleMovingAverage {
                        Length = 1
                    };
                    Chart.AddElement(area, equityElem);

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

                    var positionElem = new ChartIndicatorElement {
                        FullTitle = "position"
                    };
                    var positionInd = new SimpleMovingAverage {
                        Length = 1
                    };
                    Chart.AddElement(positionArea, positionElem);

                    Chart.IsAutoRange = true;

                    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 chartValues = _candles
                                      .Select(c =>
                    {
                        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 = trades.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);
                        }

                        values.Add(equityElem, equityInd.Process(pnlQueue.RealizedPnL + pnlQueue.UnrealizedPnL));
                        values.Add(positionElem, positionInd.Process(pos));

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

                    Chart.Draw(chartValues);

                    Chart.IsAutoRange = false;
                }
                else
                {
                    new MessageBoxBuilder()
                    .Error()
                    .Owner(this)
                    .Text(ea.Error.ToString())
                    .Show();
                }
            };

            worker.RunWorkerAsync();
        }
Exemplo n.º 9
0
        protected override TimeSpan OnProcess()
        {
            IBackupService service;

            switch (_settings.Service)
            {
            case BackupServices.AwsS3:
                service = new AmazonS3Service(AmazonExtensions.GetEndpoint(_settings.Address), _settings.ServiceRepo, _settings.Login, _settings.Password.To <string>());
                break;

            case BackupServices.AwsGlacier:
                service = new AmazonGlacierService(AmazonExtensions.GetEndpoint(_settings.Address), _settings.ServiceRepo, _settings.Login, _settings.Password.To <string>());
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            var hasSecurities = false;

            this.AddInfoLog(LocalizedStrings.Str2306Params.Put(_settings.StartFrom));

            var startDate = _settings.StartFrom;
            var endDate   = DateTime.Today - TimeSpan.FromDays(_settings.Offset);

            var allDates = startDate.Range(endDate, TimeSpan.FromDays(1)).ToArray();

            var pathEntry = ToEntry(new DirectoryInfo(_settings.Drive.Path));

            IEnumerable <Tuple <Type, object> > dataTypes = new[]
            {
                Tuple.Create(typeof(ExecutionMessage), (object)ExecutionTypes.Tick),
                Tuple.Create(typeof(ExecutionMessage), (object)ExecutionTypes.OrderLog),
                Tuple.Create(typeof(ExecutionMessage), (object)ExecutionTypes.Order),
                Tuple.Create(typeof(ExecutionMessage), (object)ExecutionTypes.Trade),
                Tuple.Create(typeof(QuoteChangeMessage), (object)null),
                Tuple.Create(typeof(Level1ChangeMessage), (object)null),
                Tuple.Create(typeof(NewsMessage), (object)null)
            };

            var workingSecurities = GetWorkingSecurities().ToArray();

            foreach (var date in allDates)
            {
                foreach (var security in workingSecurities)
                {
                    hasSecurities = true;

                    if (!CanProcess())
                    {
                        break;
                    }

                    var dateEntry = new BackupEntry
                    {
                        Name   = date.ToString("yyyy_MM_dd"),
                        Parent = new BackupEntry
                        {
                            Parent = new BackupEntry
                            {
                                Name   = security.Security.Id.Substring(0, 1),
                                Parent = pathEntry
                            },
                            Name = security.Security.Id,
                        }
                    };

                    var candleTypes = _settings.Drive.GetCandleTypes(security.Security.ToSecurityId(), _settings.StorageFormat);

                    var secDataTypes = dataTypes.Concat(candleTypes.SelectMany(t => t.Item2.Select(a => Tuple.Create(t.Item1, a))));

                    foreach (var tuple in secDataTypes)
                    {
                        var storage = StorageRegistry.GetStorage(security.Security, tuple.Item1, tuple.Item2, _settings.Drive, _settings.StorageFormat);

                        var drive = storage.Drive;

                        var stream = drive.LoadStream(date);

                        if (stream == Stream.Null)
                        {
                            continue;
                        }

                        var entry = new BackupEntry
                        {
                            Name   = LocalMarketDataDrive.CreateFileName(tuple.Item1, tuple.Item2) + LocalMarketDataDrive.GetExtension(StorageFormats.Binary),
                            Parent = dateEntry,
                        };

                        service.Upload(entry, stream, p => { });

                        this.AddInfoLog(LocalizedStrings.Str1580Params, GetPath(entry));
                    }
                }

                if (CanProcess())
                {
                    _settings.StartFrom += TimeSpan.FromDays(1);
                    SaveSettings();
                }
            }

            if (!hasSecurities)
            {
                this.AddWarningLog(LocalizedStrings.Str2292);
                return(TimeSpan.MaxValue);
            }

            if (CanProcess())
            {
                this.AddInfoLog(LocalizedStrings.Str2300);
            }

            return(base.OnProcess());
        }
Exemplo n.º 10
0
        public void Start(IMarketDataDrive destDrive, DateTime?startDate, DateTime?endDate, Security security, IMarketDataDrive sourceDrive, StorageFormats format, Type dataType, object arg)
        {
            CreateWorker(0, null);

            _worker.DoWork += (s, e) =>
            {
                var storageRegistry = ConfigManager.GetService <IStorageRegistry>();
                var storage         = storageRegistry.GetStorage(security, dataType, arg, sourceDrive, format);

                try
                {
                    var dates = storage.Dates.ToArray();

                    if (dates.IsEmpty())
                    {
                        return;
                    }

                    var allDates = (startDate ?? dates.First()).Range((endDate ?? dates.Last()), TimeSpan.FromDays(1));

                    var datesToExport = storage.Dates
                                        .Intersect(allDates)
                                        .Select(d =>
                    {
                        int count;

                        if (dataType == typeof(ExecutionMessage))
                        {
                            count = ((IMarketDataStorage <ExecutionMessage>)storage).Load(d).Count;
                        }
                        else if (dataType == typeof(QuoteChangeMessage))
                        {
                            count = ((IMarketDataStorage <QuoteChangeMessage>)storage).Load(d).Count;
                        }
                        else if (dataType == typeof(Level1ChangeMessage))
                        {
                            count = ((IMarketDataStorage <Level1ChangeMessage>)storage).Load(d).Count;
                        }
                        else if (dataType.IsSubclassOf(typeof(CandleMessage)))
                        {
                            count = ((IMarketDataStorage <CandleMessage>)storage).Load(d).Count;
                        }
                        else
                        {
                            throw new NotSupportedException(LocalizedStrings.Str2872Params.Put(dataType.Name));
                        }

                        return(Tuple.Create(d, count));
                    })
                                        .ToArray();

                    _worker.ReportProgress(0);

                    var currentValuesCount = 0;
                    var totalValuesCount   = datesToExport.Select(d => d.Item2).Sum();

                    if (!Directory.Exists(destDrive.Path))
                    {
                        Directory.CreateDirectory(destDrive.Path);
                    }

                    var dataPath = ((LocalMarketDataDrive)sourceDrive).GetSecurityPath(security.ToSecurityId());
                    var fileName = LocalMarketDataDrive.CreateFileName(dataType, arg) + LocalMarketDataDrive.GetExtension(StorageFormats.Binary);

                    foreach (var date in datesToExport)
                    {
                        var d    = date.Item1.ToString("yyyy_MM_dd");
                        var file = Path.Combine(dataPath, d, fileName);

                        if (File.Exists(file))
                        {
                            if (!Directory.Exists(Path.Combine(destDrive.Path, d)))
                            {
                                Directory.CreateDirectory(Path.Combine(destDrive.Path, d));
                            }

                            File.Copy(file, Path.Combine(destDrive.Path, d, Path.GetFileName(file)), true);
                        }

                        if (date.Item2 == 0)
                        {
                            continue;
                        }

                        currentValuesCount += date.Item2;
                        _worker.ReportProgress((int)Math.Round(currentValuesCount * 100m / totalValuesCount));
                        this.GuiAsync(() => UpdateCount(currentValuesCount));
                    }
                }
                finally
                {
                    _worker.ReportProgress(100);
                    Thread.Sleep(500);
                    _worker.ReportProgress(0);
                }
            };

            _worker.RunWorkerAsync();
        }
Exemplo n.º 11
0
        static void Main(string[] args)
        {
            var security = new Security()
            {
                Id = "RIH7@FORTS", Board = ExchangeBoard.Forts
            };
            StorageRegistry storage = new StorageRegistry();

            string path = @"../../../Data/Quik";

            //Для работы будем использовать готовое локальное файловое хранилище, в которое данные были предварительно записаны при помощи Гидры.
            //Создаем экземпляр LocalMarketDataDrive.
            LocalMarketDataDrive drive = new LocalMarketDataDrive()
            {
                Path = path
            };

            //Передаем в StorageRegistry ссылку на локальное файловое хранилище
            storage.DefaultDrive = drive;

            DateTime from = new DateTime(2017, 02, 14, 10, 0, 0);
            DateTime to   = new DateTime(2017, 02, 15, 23, 50, 0);

            // Создаем простой индикатор - простая скользяшая средняя. Простой индикатор - индикатор, которые состоит из одного индикатора.
            var ma = new SimpleMovingAverage()
            {
                Length = 11
            };

            // Событие генерируется при изменении текущего значения индикатора.. Событие имеет два параметра: входное и выходное значение.
            ma.Changed += (input, output) =>
            {
                //TODO
            };

            // Создаем комплексный индикатор - полосы Боллинджера. Комплексный индикатор - индикатор, которые состоит из нескольких простых или комплексных
            // индикаторов. В состав полос Боллинджера входят три простых индикатора: верхняя и нижняя полоса BollingerBand, а также простая скользящая средняя.
            var bb = new BollingerBands()
            {
                Length = 11, Width = 1.5m
            };

            // Событие генерируется при изменении текущего значения индикатора.. Событие имеет два параметра: входное и выходное значение.
            bb.Changed += (input, output) =>
            {
                //TODO
            };

            // Создаем кандлеменеджер, который в качестве источника свечек использует сделки из хранилища.
            CandleManager candleManager = new CandleManager(new TradeStorageCandleBuilderSource()
            {
                StorageRegistry = storage
            });

            candleManager.Processing += (series, candle) =>
            {
                if (candle.State != CandleStates.Finished)
                {
                    return;
                }

                // передаем в метод Process значение для обработки...
                // Передаваемый параметр должен реализовывать интерфейс IIndicatorValue.
                // В нашем случае используется метод расширения, который преобразует
                // свечу в класс CandleIndicatorValue, который реализует требуемый интерфейс.
                // Функция возвращается тип, который также реализует интерфейс IIndicatorValue
                // Такой подход обладает следующими преимуществами:
                // 1. IIndicatorValue используется при построении графиков
                // 2. Значение одного индикторы, можно сразу передавать на вход другого индикатра.
                var maValue = ma.Process(candle);


                // Свойство IsFormed становится true, когда текущее значение индикатора становится валидным
                // Наример, в скользящих средних, если число значений поступивших на вход больше или равно
                // периоду индикатора
                if (ma.IsFormed)
                {
                    // Так можно вернуть "нормальное" значение из IIndicatorValue
                    var maCur = ma.GetCurrentValue();

                    // Это другой способ получения "нормальное" текущего значения индикатора
                    maCur = maValue.GetValue <decimal>();
                }


                // Здесь мы используем комплексный индикатор. Также передаем в метод Process значение для обработки...
                // На выходе мы получаем тип ComplexIndicatorValue (тоже реализует IIndicatorValue).
                // Главная особенность типа ComplexIndicatorValue в наличии свойства InnerValues, где
                // хранятся текущие значения всех простых индикаторов, входящих в состав комплексного индикатора.
                var bbValue = (ComplexIndicatorValue)bb.Process(candle);

                if (bb.IsFormed)
                {
                    // Так можно получить значения из InnerValues
                    var upBandValue  = bbValue.InnerValues[bb.UpBand];
                    var lowBandValue = bbValue.InnerValues[bb.LowBand];

                    var upBand  = bb.UpBand.GetCurrentValue();
                    var lowBand = bb.LowBand.GetCurrentValue();

                    upBand  = upBandValue.GetValue <decimal>();
                    lowBand = lowBandValue.GetValue <decimal>();
                }
            };

            var srs = new CandleSeries(typeof(TimeFrameCandle), security, TimeSpan.FromMinutes(1));

            candleManager.Start(srs, from, to);

            Console.Read();

            candleManager.Stop(srs);
        }
Exemplo n.º 12
0
        private void Download_OnClick(object sender, RoutedEventArgs e)
        {
            var settings = new Settings
            {
                Year      = SelectedYear.Year,
                Trader    = Trader.Text,
                From      = From.Value,
                To        = To.Value,
                Security1 = Security1.Text,
                Security2 = Security2.Text,
                Security3 = Security3.Text,
                Security4 = Security4.Text,
                TimeFrame = SelectedTimeFrame,
                Apart     = Apart.IsChecked == true,
            };

            CultureInfo.InvariantCulture.DoInCulture(() => new XmlSerializer <SettingsStorage>().Serialize(settings.Save(), _settingsFile));

            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 apart  = Apart.IsChecked == true;

            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;
                    }

                    TimeFrameCandle[] newCandles;

                    if (tf.Ticks == 1)
                    {
                        newCandles = finamFrom.Range(finamTo, TimeSpan.FromDays(1)).SelectMany(day =>
                        {
                            worker.ReportProgress(1, Tuple.Create(security, day));

                            var candles = _finamHistorySource.GetTrades(security, day, day).ToEx().ToCandles <TimeFrameCandle>(tf).ToArray();
                            candleStorage.Save(candles);
                            candlesDatesCache.Add(day);
                            return(candles);
                        }).ToArray();
                    }
                    else
                    {
                        worker.ReportProgress(1, Tuple.Create(security, finamFrom, finamTo));
                        newCandles = _finamHistorySource.GetCandles(security, tf, finamFrom, finamTo).ToArray();

                        candleStorage.Save(newCandles);
                        candlesDatesCache.Add(newCandles.Select(c => c.OpenTime.Date).Distinct().ToArray());
                    }

                    // TODO
                    secCandles.AddRange(newCandles);
                }

                var traderDrive   = new LocalMarketDataDrive(Path.Combine(_settingsDir, 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.xml")));

                    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);

                        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);
                            }
                        }

                        if (tf == TimeSpan.FromDays(1) && period != null && period.Times.Length > 0)
                        {
                            return(new DateTimeOffset(time.Date + period.Times[0].Min, time.Offset));
                        }

                        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:
                {
                    if (ea.UserState is Tuple <Security, DateTime> )
                    {
                        BusyIndicator.BusyContent = "Скачивание {Item1.Id} тиков за {Item2:yyyy-MM-dd}...".PutEx(ea.UserState);
                    }
                    else
                    {
                        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 equityInd = new SimpleMovingAverage {
                        Length = 1
                    };
                    ChartIndicatorElement equityElem;
                    var candlesAreas = new Dictionary <CandleSeries, ChartArea>();

                    if (apart)
                    {
                        foreach (var series in seriesSet)
                        {
                            var area = new ChartArea {
                                Title = series.Item1.Security.Id
                            };
                            Chart.AddArea(area);
                            area.YAxises.Clear();
                            candlesAreas.Add(series.Item1, area);
                        }

                        var equityArea = new ChartArea {
                            Title = LocalizedStrings.PnL
                        };
                        Chart.AddArea(equityArea);

                        equityElem = new ChartIndicatorElement
                        {
                            FullTitle        = LocalizedStrings.PnL,
                            IndicatorPainter = new PnlPainter()
                        };
                        Chart.AddElement(equityArea, equityElem);
                    }
                    else
                    {
                        var candlesArea = new ChartArea();
                        Chart.AddArea(candlesArea);

                        foreach (var tuple in seriesSet)
                        {
                            candlesAreas.Add(tuple.Item1, candlesArea);
                        }

                        const string equityYAxis = "Equity";

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

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

                    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;

                        var candlesArea = candlesAreas[series.Item1];

                        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();
        }