/// <summary>Set the total balance attributed to the fund 'fund_id'</summary> public void AssignFundBalance(Fund fund, Unit <decimal> total, bool notify = true) { // Notes: // - Don't throw if the nett total becomes negative, that probably just means a fund // has been assigned too much. Allow the user to reduce the allocations. // Get the balance info for 'fund_id', create if necessary var balance = (Balance)Funds.FirstOrDefault(x => x.Fund == fund) ?? m_funds.Add2(new Balance(this, fund)); balance.Total = total; // The main fund changes with each update. Other funds don't. // Notify *after* 'LastUpdated' and 'CheckHolds' have been set if (notify) { Invalidate(); } }
/// <summary>Add or subtract an amount from a fund</summary> public void ChangeFundBalance(Fund fund, Unit <decimal> change_amount, bool notify = true) { // Get the balance info for 'fund_id', create if necessary var balance = (Balance)Funds.FirstOrDefault(x => x.Fund == fund); // ?? m_funds.Add2(new Balance(this, fund)); if (balance == null) { return; } // Apply the balance change to the total balance.Total += change_amount; // Changing the total for a fund effects the balance of the main fund. if (notify) { Invalidate(); } }
/// <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)); } }
public bool Equals(Fund rhs) { return(this == rhs);; }
/// <summary>Access balances associated with the given fund. Unknown fund ids return an empty balance</summary> public IBalance this[Fund fund] => Funds.FirstOrDefault(x => x.Fund == fund) ?? new Balance(this, fund);
public FundHoldContainer(Fund fund) { Fund = fund; m_holds = new List <FundHold>(); m_dispatcher = Dispatcher.CurrentDispatcher; }