Пример #1
0
        /// <summary>Attempt to make a trade on 'pair' for the given 'price' and base 'amount'</summary>
        private void TryFillOrder(TradePair pair, Fund fund, long order_id, ETradeType tt, EOrderType ot, Unit <decimal> amount_in, Unit <decimal> amount_out, Unit <decimal> remaining_in, out Order ord, out OrderCompleted his)
        {
            // The order can be filled immediately, filled partially, or not filled and remain as an 'Order'.
            // Also, exchanges use the base currency as the amount to fill, so for Q2B trades it's possible
            // that 'amount_in' is less than the trade asked for.
            var market = m_depth[pair];

            // Consume orders
            var price_q2b   = tt.PriceQ2B(amount_out / amount_in);
            var amount_base = tt.AmountBase(price_q2b, amount_in: remaining_in);
            var filled      = market.Consume(pair, tt, ot, price_q2b, amount_base, out var remaining_base);

            // The order is partially or completely filled...
            Debug.Assert(Misc.EqlAmount(amount_base, filled.Sum(x => x.AmountBase) + remaining_base));
            ord = remaining_base != 0 ? new Order(order_id, fund, pair, ot, tt, amount_in, amount_out, tt.AmountIn(remaining_base, price_q2b), Model.UtcNow, Model.UtcNow) : null;
            his = remaining_base != amount_base ? new OrderCompleted(order_id, fund, pair, tt) : null;

            // Add 'TradeCompleted' entries for each order book offer that was filled
            foreach (var fill in filled)
            {
                his.Trades.AddOrUpdate(new TradeCompleted(his.OrderId, ++m_history_id, pair, tt, fill.AmountIn(tt), fill.AmountOut(tt), Exchange.Fee * fill.AmountOut(tt), tt.CoinOut(pair), Model.UtcNow, Model.UtcNow));
            }
        }
Пример #2
0
 /// <summary>The 'In' side of the offer</summary>
 public Unit <decimal> AmountIn(ETradeType tt) => tt.AmountIn(AmountBase, PriceQ2B);