Beispiel #1
0
        private async Task UpdateTrades()
        {
            List <Trade> newTrades = new List <Trade>();

            if (Trades.Count == 0)
            {
                Trades.Add(new Trade {
                    Status = TradeStatus.Empty
                });
            }
            foreach (var trade in Trades.Where(t => t.Status != TradeStatus.Completed))
            {
                var newTrade = await UpdateTrade(trade);

                if (newTrade != Trade.Empty)
                {
                    newTrades.Add(newTrade);
                }
            }

            if (newTrades.Count > 0)
            {
                Trades.AddRange(newTrades);
            }

            var canceledTrades = Trades.Where(t => t.Status == TradeStatus.Canceled).ToList();

            foreach (var canceledTrade in canceledTrades)
            {
                Trades.Remove(canceledTrade);
            }
        }
Beispiel #2
0
 public override void Initialize()
 {
     Trades.AddRange(new[]
     {
         new TradeEvent {
             InstrumentKey = "72990", Quantity = 10000, EventTime = DateTime.MinValue, Comment = "Initial"
         },
         new TradeEvent {
             InstrumentKey = "39988", Quantity = 10000, EventTime = DateTime.MinValue, Comment = "Initial"
         },
         new TradeEvent {
             InstrumentKey = "46244", Quantity = 10000, EventTime = DateTime.MinValue, Comment = "Initial"
         },
     });
 }
Beispiel #3
0
        public void SetTrades(List <Trade> trades, ITradeDetailsAutoCalculatorService tradeCalculateService, IBroker broker)
        {
            AccountLastUpdated = DateTime.UtcNow;

            foreach (var t in Trades)
            {
                tradeCalculateService.RemoveTrade(t);
            }

            Trades.Clear();
            Trades.AddRange(trades);

            Log.Debug($"Completed updating {broker.Name} trades");
            _brokerAccountUpdatedSubject.OnNext(new BrokerAccountUpdated(this));
        }
Beispiel #4
0
 private void FirstTrades()
 {
     Trades.AddRange(new List <Trade> {
         new Trade {
             Value = 2000000, ClientSector = "Private"
         },
         new Trade {
             Value = 400000, ClientSector = "Public"
         },
         new Trade {
             Value = 500000, ClientSector = "Public"
         },
         new Trade {
             Value = 3000000, ClientSector = "Public"
         }
     });
     BindGrid();
 }
Beispiel #5
0
        public (bool, Book) ProcessOffer(Domain.Offer of)
        {
            var transact     = TransactManager;
            var dic          = Dictionary;
            var result       = false;
            var offers       = new List <Offer>();
            var trades       = new List <Trade>();
            var resultOffers = new List <Offer>();
            var resultTrades = new List <Trade>();

            if (!dic.ContainsKey(of.Asset))
            {
                dic = dic.Add(of.Asset, new OfferBook(of.Asset));
            }


            var sourceQuantity = of.Quantity;
            var asset          = of.Asset;

            if (of.Type == OfferType.Bid)
            {
                sourceQuantity = of.Quantity * of.Price;
                asset          = "BIZ";
            }

            if (transact.HasBalance(of.Wallet, asset, sourceQuantity))
            {
                transact = transact.ChangeBalance(of.Wallet, asset, -sourceQuantity);
                var book = dic[of.Asset];

                if (of.Type == OfferType.Bid)
                {
                    (book, resultTrades, resultOffers) = book.AddBid(of);
                }
                else
                {
                    (book, resultTrades, resultOffers) = book.AddAsk(of);
                }

                dic = dic.SetItem(of.Asset, book);
                offers.AddRange(resultOffers);
                trades.AddRange(resultTrades);

                result = true;
                foreach (var trade in resultTrades)
                {
                    transact = transact.ChangeBalance(trade.BuyerWallet, trade.Asset, trade.Quantity);
                    transact = transact.ChangeBalance(trade.SellerWallet, "BIZ", trade.Quantity * trade.Price);
                }
            }
            else
            {
                Log.Error("Wallet has no balance to send offer.");
            }

            if (result)
            {
                return(true, new Book(this, transact, dic, ProcessedOffers.AddRange(offers), Trades.AddRange(trades)));
            }
            else
            {
                return(false, this);
            }
        }
Beispiel #6
0
        /// <summary>Refresh the set of trades</summary>
        private void UpdateTrades()
        {
            m_trades_invalidated = false;
            if (Model == null)
            {
                return;
            }

            // Create lists of trades per instrument.
            // Once complete, go through existing trades looking for matches.
            // Remove any trades not in 'trades', and any trades not in 'Trades'.
            var trades_map = new Dictionary <Instrument, List <Trade> >();

            // Remove orders from trades that are no longer in 'Orders'
            foreach (var trade in Trades)
            {
                trade.Orders.RemoveIf(x => !OrderLookup.ContainsKey(x.Id));
            }

            // Remove trades that contain no orders
            Trades.RemoveIf(x => x.Orders.Count == 0);

            // Group the orders into instruments
            foreach (var order_grp in Orders.GroupBy(x => x.Instrument))
            {
                // Create an ordered list of trades based on non-overlapping time ranges
                var instr  = order_grp.Key;
                var trades = trades_map.GetOrAdd(instr, k => new List <Trade>());
                foreach (var order in order_grp)
                {
                    // Look for a trade in the list that intersects the time range
                    var idx = trades.BinarySearch(r =>
                                                  order.ExitTimeUTC <r.EntryTimeUTC ? -1 :
                                                                     order.EntryTimeUTC> r.ExitTimeUTC  ? +1 : 0);

                    // If index is positive, then it's the index of a trade that intersects the time range.
                    // If not, then there is no trade yet that covers this order so create one.
                    var trade = (idx >= 0) ? trades[idx] : trades.Insert2(idx = ~idx, new Trade(Model, instr));
                    trade.Orders.Add(order);

                    // Sanity check that the trade time range overlaps the order time range
                    Debug.Assert(
                        order.EntryTimeUTC >= trade.EntryTimeUTC &&
                        order.ExitTimeUTC <= trade.ExitTimeUTC &&
                        trade.Orders.Count(x => x == order) == 1);

                    // Merge adjacent trades if their time ranges overlap
                    for (int i = idx; i-- != 0 && trades[i].ExitTimeUTC >= trades[idx].ExitTimeUTC;)
                    {
                        // Trade automatically updates its Entry/Exit time when its 'Orders' collection is changed
                        trades[i].Orders.AddRange(trades[idx].Orders);
                        trades[idx].Dispose();
                        trades.RemoveAt(idx);
                        idx = i;
                    }
                    for (int i = idx; ++i != trades.Count && trades[idx].ExitTimeUTC >= trades[i].EntryTimeUTC;)
                    {
                        // Trade automatically updates its Entry/Exit time when its 'Orders' collection is changed
                        trades[idx].Orders.AddRange(trades[i].Orders);
                        trades[i].Dispose();
                        trades.RemoveAt(i);
                        i = idx;
                    }
                }

                // Check the ranges are non-overlapping
                                #if DEBUG
                for (int i = 0; i != trades.Count; ++i)
                {
                    Debug.Assert(trades[i].EntryTimeUTC <= trades[i].ExitTimeUTC);
                    Debug.Assert(i == 0 || trades[i - 1].EntryTimeUTC < trades[i].EntryTimeUTC);
                    Debug.Assert(i == 0 || trades[i - 1].ExitTimeUTC < trades[i].EntryTimeUTC);
                }
                                #endif
            }

            // Remove trades from the trades map that match existing trades.
            // Want to avoid deleting existing trades where possible.
            foreach (var existing in Trades)
            {
                // There shouldn't be any existing trades for instruments that aren't in 'trades_map'
                var trades = trades_map[existing.Instrument];

                // Try to find a match in trades for 'existing'
                var idx = trades.IndexOf(trade => trade.Orders.SequenceEqualUnordered(existing.Orders));

                // Matching existing trade found, remove from trades list in the map
                if (idx != -1)
                {
                    trades[idx].Dispose();
                    trades.RemoveAt(idx);
                }

                // No more trades for this instrument? Remove the entry from the map
                if (trades.Count == 0)
                {
                    trades_map.Remove(existing.Instrument);
                }
            }

            // Add all trades left in the trades map to the current trades list
            foreach (var trades in trades_map.Values)
            {
                Trades.AddRange(trades);
            }
        }