예제 #1
0
        public InstrumentModel GetInstrument(string epic)
        {
            var market = Instruments.FirstOrDefault(m => m.Epic == epic);

            if (market == null)
            {
                var detail = GetMarketDetails(epic);

                market = new InstrumentModel();

                market.DealingRuleData = detail.dealingRules;
                market.InstrumentData  = detail.instrument;
                market.SnapshotData    = detail.snapshot;

                market.Epic           = epic;
                market.InstrumentName = market.InstrumentData.name;

                market.Offer = market.SnapshotData.offer;
                market.Bid   = market.SnapshotData.bid;
                market.High  = market.SnapshotData.high;
                market.Low   = market.SnapshotData.low;

                Instruments.Add(market);

                SubscribeL1WatchlistPrices();
            }

            return(market);
        }
예제 #2
0
        private void Client_ExecutionsError(object sender, InstrumentIdErrorEventArgs e)
        {
            var i = Instruments.FirstOrDefault(m => m.Id == e.InstrumentId);

            if (i != null)
            {
                i.LastError = (e.Exception.GetBaseException() ?? e.Exception).Message;
            }
        }
예제 #3
0
        private void StartLoad()
        {
            try
            {
                IsConnected = _bitmexApiSocketService.Connect();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            if (IsConnected)
            {
                _bitmexApiSocketService.Subscribe(BitmexApiSubscriptionInfo <IEnumerable <InstrumentDto> > .Create(SubscriptionType.instrument,
                                                                                                                   dtos =>
                {
                    foreach (var instrumentDto in dtos)
                    {
                        lock (_syncObj)
                        {
                            var existing = Instruments.FirstOrDefault(a => a.Symbol == instrumentDto.Symbol);
                            if (existing != null)
                            {
                                Mapper.Map <InstrumentDto, InstrumentModel>(instrumentDto, existing);
                            }
                            else
                            {
                                Instruments.Add(Mapper.Map <InstrumentDto, InstrumentModel>(instrumentDto));
                            }
                        }
                    }
                }));

                _bitmexApiSocketService.Subscribe(BitmexApiSubscriptionInfo <IEnumerable <OrderDto> > .Create(SubscriptionType.order,
                                                                                                              dtos =>
                {
                    foreach (var order in dtos)
                    {
                        lock (_syncObjOrders)
                        {
                            var existing = OrderUpdates.FirstOrDefault(a => a.OrderId == order.OrderId);
                            if (existing != null)
                            {
                                Mapper.Map <OrderDto, OrderUpdateModel>(order, existing);
                            }
                            else
                            {
                                OrderUpdates.Add(Mapper.Map <OrderDto, OrderUpdateModel>(order));
                            }
                        }

                        OnPropertyChanged(nameof(OrderUpdates));
                    }
                }));
            }
        }
        private void Client_PositionsReceived(object sender, CollectionReceivedEventArgs <Position> e)
        {
            var i = Instruments.FirstOrDefault(m => m.Id == e.Data[0].InstrumentId);

            if (i != null)
            {
                i.LastError = null;

                lock (Positions)
                {
                    foreach (var m in e.Data)
                    {
                        Positions.Add(new PositionEntry(e.Action, i, m));
                    }

                    const int MAX = 100;
                    while (Positions.Count > 100)
                    {
                        Positions.RemoveAt(Positions.Count - 1 - MAX);
                    }
                }

                lock (ActivePositions)
                {
                    // 対象のInstrumentのポジションのみを対象に副作用を与える
                    var activePositions = ActivePositions.Where(p => p.Instrument.Id.Equals(i.Id)).ToList();
                    if (e.Action == NotifyCollectionChangedAction.Add ||
                        e.Action == NotifyCollectionChangedAction.Replace)
                    {
                        // Add,Replace が来たらスナップショット受信とみなして入れ替える
                        foreach (var ap in activePositions)
                        {
                            ActivePositions.Remove(ap);
                        }
                        foreach (var m in e.Data)
                        {
                            ActivePositions.Add(new PositionEntry(e.Action, i, m));
                        }
                    }
                    else if (e.Action == NotifyCollectionChangedAction.Remove ||
                             e.Action == NotifyCollectionChangedAction.Reset)
                    {
                        // Remove,Reset が来たらポジションが全て決済されたとみなして削除する
                        foreach (var ap in activePositions)
                        {
                            ActivePositions.Remove(ap);
                        }
                    }
                    else if (e.Action == NotifyCollectionChangedAction.Move)
                    {
                    }
                }
            }
        }
예제 #5
0
        // TODO: wamp sends strange tickprices with ask=bid, temporary switch to direct rabbitmq connection
//        private void StartWampConnection()
//        {
//            var wampSettings = new WampSubscriberSettings()
//            {
//                Address = Config.WampEndpoint.Url,
//                Realm = Config.WampEndpoint.PricesRealm,
//                Topics = Instruments.SelectMany(i => new string[] {
//                    String.Format(Config.WampEndpoint.PricesTopic, i.Name.ToLowerInvariant(), "ask", "sec"),
//                    String.Format(Config.WampEndpoint.PricesTopic, i.Name.ToLowerInvariant(), "bid", "sec") }).ToArray()
//            };
//
//            this.wampSubscriber = new WampSubscriber<Candle>(wampSettings, this.LykkeLog)
//                .Subscribe(HandlePrice);
//
//            this.wampSubscriber.Start();
//        }

        /// <summary>
        /// Called on incoming prices
        /// </summary>
        /// <param name="candle">Incoming candlestick</param>
        /// <remarks>Can be called simultaneously from multiple threads</remarks>
        private async Task HandlePrice(Candle candle)
        {
            var instrument = Instruments.FirstOrDefault(i => string.Equals(i.Name, candle.Asset, StringComparison.InvariantCultureIgnoreCase));

            if (instrument != null)
            {
                var tickPrice = new TickPrice(
                    instrument,
                    candle.Timestamp,
                    ask: candle.L,
                    bid: candle.H);

                await _tickPriceHandler.Handle(tickPrice);
            }
        }
예제 #6
0
        private void PopulateJobs()
        {
            var dataUpdateJobKeys = _scheduler.GetJobKeys(GroupMatcher <JobKey> .AnyGroup());

            foreach (JobKey job in dataUpdateJobKeys)
            {
                IJobDetail jobDetails = _scheduler.GetJobDetail(job);

                if (job.Group == JobTypes.DataUpdate)
                {
                    try
                    {
                        var jd = JsonConvert.DeserializeObject <DataUpdateJobSettings>((string)jobDetails.JobDataMap["settings"]);
                        if (jd.InstrumentID.HasValue)
                        {
                            jd.Instrument = Instruments.FirstOrDefault(x => x.ID == jd.InstrumentID.Value);
                        }
                        if (jd.TagID.HasValue)
                        {
                            jd.Tag = Tags.FirstOrDefault(x => x.ID == jd.TagID.Value);
                        }

                        Jobs.Add(new DataUpdateJobViewModel(jd, _scheduler));
                    }
                    catch (Exception e)
                    {
                        _logger.Error(e, "Failed to deserialize data update job");
                    }
                }
                else if (job.Group == JobTypes.EconomicRelease)
                {
                    try
                    {
                        var jd = JsonConvert.DeserializeObject <EconomicReleaseUpdateJobSettings>((string)jobDetails.JobDataMap["settings"]);

                        Jobs.Add(new EconomicReleaseUpdateJobViewModel(jd, _scheduler));
                    }
                    catch (Exception e)
                    {
                        _logger.Error(e, "Failed to deserialize economic release update job");
                    }
                }
            }
        }
예제 #7
0
        private void Client_ExecutionsReceived(object sender, CollectionReceivedEventArgs <Execution> e)
        {
            var i = Instruments.FirstOrDefault(m => m.Id == e.Data[0].InstrumentId);

            if (i != null)
            {
                i.LastError = null;

                lock (Executions)
                {
                    foreach (var m in e.Data)
                    {
                        Executions.Add(new ExecutionEntry(e.Action, i, m));
                    }

                    const int MAX = 100;
                    while (Executions.Count > 100)
                    {
                        Executions.RemoveAt(Executions.Count - 1 - MAX);
                    }
                }
            }
        }
        private void BitFlyer_ChildOrdersReceived(object sender, CollectionReceivedEventArgs <BitFlyerChildOrder> e)
        {
            var i = Instruments.FirstOrDefault(m => m.Id == e.Data[0].InstrumentId);

            if (i != null)
            {
                i.LastError = null;

                lock (ChildOrders)
                {
                    foreach (var m in e.Data)
                    {
                        ChildOrders.Add(new ChildOrderEntry(e.Action, i, m));
                    }

                    const int MAX = 100;
                    while (ChildOrders.Count > 100)
                    {
                        ChildOrders.RemoveAt(ChildOrders.Count - 1 - MAX);
                    }
                }
            }
        }
예제 #9
0
        private async Task HandleOrderBook(OrderBook orderBook)
        {
            var instrument = Instruments.FirstOrDefault(x => string.Compare(x.Name, orderBook.AssetPair, StringComparison.InvariantCultureIgnoreCase) == 0);

            if (instrument == null && Config.UseSupportedCurrencySymbolsAsFilter == false)
            {
                instrument = new Instrument(Name, orderBook.AssetPair);
            }

            if (instrument != null)
            {
                if (orderBook.Prices.Any())
                {
                    decimal bestBid = 0;
                    decimal bestAsk = 0;

                    if (orderBook.IsBuy)
                    {
                        _lastBids[instrument.Name] = bestBid = orderBook.Prices.Select(x => x.Price).OrderByDescending(x => x).First();
                        bestAsk = _lastAsks.ContainsKey(instrument.Name) ? _lastAsks[instrument.Name] : 0;
                    }
                    else
                    {
                        _lastAsks[instrument.Name] = bestAsk = orderBook.Prices.Select(x => x.Price).OrderBy(x => x).First();
                        bestBid = _lastBids.ContainsKey(instrument.Name) ? _lastBids[instrument.Name] : 0;
                    }

                    if (bestBid > 0 && bestAsk > 0)
                    {
                        var tickPrice = new TickPrice(instrument, orderBook.Timestamp, bestAsk, bestBid);
                        await _tickPriceHandler.Handle(tickPrice);

                        await _orderBookHandler.Handle(orderBook);
                    }
                }
            }
        }
예제 #10
0
        private void StartLoad()
        {
            try
            {
                IsConnected = _bitmexApiSocketService.Connect();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            if (IsConnected)
            {
                _bitmexApiSocketService.Subscribe(BitmetSocketSubscriptions.CreateInstrumentSubsription(
                                                      message =>
                {
                    foreach (var instrumentDto in message.Data)
                    {
                        lock (_syncObj)
                        {
                            var existing = Instruments.FirstOrDefault(a => a.Symbol == instrumentDto.Symbol);
                            if (existing != null && message.Action == BitmexActions.Update)
                            {
                                Mapper.Map <InstrumentDto, InstrumentModel>(instrumentDto, existing);
                            }
                            else if (message.Action != BitmexActions.Partial && message.Action != BitmexActions.Delete)
                            {
                                Instruments.Add(Mapper.Map <InstrumentDto, InstrumentModel>(instrumentDto));
                            }
                        }
                    }
                }));

                _bitmexApiSocketService.Subscribe(BitmetSocketSubscriptions.CreateOrderSubsription(
                                                      message =>
                {
                    foreach (var order in message.Data)
                    {
                        lock (_syncObjOrders)
                        {
                            var existing = OrderUpdates.FirstOrDefault(a => a.OrderId == order.OrderId);
                            if (existing != null && message.Action == BitmexActions.Update)
                            {
                                Mapper.Map <OrderDto, OrderUpdateModel>(order, existing);
                            }
                            else if (message.Action != BitmexActions.Partial && message.Action != BitmexActions.Delete)
                            {
                                OrderUpdates.Add(Mapper.Map <OrderDto, OrderUpdateModel>(order));
                            }
                        }

                        OnPropertyChanged(nameof(OrderUpdates));
                    }
                }));

                _bitmexApiSocketService.Subscribe(BitmetSocketSubscriptions.CreateOrderBook10Subsription(
                                                      message =>
                {
                    foreach (var dto in message.Data)
                    {
                        if (dto.Symbol != "XBTUSD")
                        {
                            continue;
                        }

                        lock (_syncObjOrderBook10)
                        {
                            OrderBook10 = dto.Asks.Select(a =>
                                                          new OrderBookModel {
                                Direction = "Sell", Price = a[0], Size = a[1]
                            })
                                          .Union(dto.Asks.Select(a =>
                                                                 new OrderBookModel {
                                Direction = "Buy", Price = a[0], Size = a[1]
                            })).ToList();
                        }

                        OnPropertyChanged(nameof(OrderBook10));
                    }
                }));

                _bitmexApiSocketService.Subscribe(BitmetSocketSubscriptions.CreateOrderBookL2Subsription(
                                                      message =>
                {
                    foreach (var dto in message.Data)
                    {
                        if (dto.Symbol != "XBTUSD")
                        {
                            continue;
                        }

                        lock (_syncObjOrderBookL2)
                        {
                            if (message.Action == BitmexActions.Insert || message.Action == BitmexActions.Partial)
                            {
                                OrderBookL2.Add(Mapper.Map <OrderBookDto, OrderBookModel>(dto));
                            }
                            if (message.Action == BitmexActions.Delete)
                            {
                                var existing = OrderBookL2.FirstOrDefault(a => a.Id == dto.Id);
                                if (existing != null)
                                {
                                    OrderBookL2.Remove(existing);
                                }
                            }

                            if (message.Action == BitmexActions.Update)
                            {
                                var existing = OrderBookL2.FirstOrDefault(a => a.Id == dto.Id);
                                if (existing == null)
                                {
                                    OrderBookL2.Add(Mapper.Map <OrderBookDto, OrderBookModel>(dto));
                                }
                                else
                                {
                                    Mapper.Map <OrderBookDto, OrderBookModel>(dto, existing);
                                }
                            }
                        }

                        OnPropertyChanged(nameof(OrderBook10));
                    }
                }));
            }
        }