예제 #1
0
        private void EmitFillOrder(TradeExecutionUpdate update)
        {
            try
            {
                var brokerId = update.OrderId.ToStringInvariant();

                var order = CachedOrderIDs
                            .FirstOrDefault(o => o.Value.BrokerId.Contains(brokerId))
                            .Value;

                if (order == null)
                {
                    order = _algorithm.Transactions.GetOrderByBrokerageId(brokerId);
                    if (order == null)
                    {
                        Log.Error($"EmitFillOrder(): order not found: BrokerId: {brokerId}");
                        return;
                    }
                }

                var symbol       = _symbolMapper.GetLeanSymbol(update.Symbol, SecurityType.Crypto, Market.Bitfinex);
                var fillPrice    = update.ExecPrice;
                var fillQuantity = update.ExecAmount;
                var direction    = fillQuantity < 0 ? OrderDirection.Sell : OrderDirection.Buy;
                var updTime      = Time.UnixMillisecondTimeStampToDateTime(update.MtsCreate);
                var orderFee     = new OrderFee(new CashAmount(Math.Abs(update.Fee), GetLeanCurrency(update.FeeCurrency)));

                var status = OrderStatus.Filled;
                if (fillQuantity != order.Quantity)
                {
                    decimal totalFillQuantity;
                    _fills.TryGetValue(order.Id, out totalFillQuantity);
                    totalFillQuantity += fillQuantity;
                    _fills[order.Id]   = totalFillQuantity;

                    status = totalFillQuantity == order.Quantity
                        ? OrderStatus.Filled
                        : OrderStatus.PartiallyFilled;
                }

                if (_algorithm.BrokerageModel.AccountType == AccountType.Cash &&
                    order.Direction == OrderDirection.Buy)
                {
                    // fees are debited in the base currency, so we have to subtract them from the filled quantity
                    fillQuantity -= orderFee.Value.Amount;

                    orderFee = new ModifiedFillQuantityOrderFee(orderFee.Value);
                }

                var orderEvent = new OrderEvent
                                 (
                    order.Id, symbol, updTime, status,
                    direction, fillPrice, fillQuantity,
                    orderFee, $"Bitfinex Order Event {direction}"
                                 );

                // if the order is closed, we no longer need it in the active order list
                if (status == OrderStatus.Filled)
                {
                    Order outOrder;
                    CachedOrderIDs.TryRemove(order.Id, out outOrder);

                    decimal ignored;
                    _fills.TryRemove(order.Id, out ignored);

                    var clientOrderId = _orderMap.FirstOrDefault(x => x.Value.BrokerId.Contains(brokerId)).Key;
                    if (clientOrderId > 0)
                    {
                        _orderMap.TryRemove(clientOrderId, out outOrder);
                    }
                }

                OnOrderEvent(orderEvent);
            }
            catch (Exception e)
            {
                Log.Error(e);
                throw;
            }
        }
예제 #2
0
        private void EmitFillOrder(TradeExecutionUpdate update)
        {
            try
            {
                var brokerId = update.OrderId.ToStringInvariant();

                var order = CachedOrderIDs
                            .FirstOrDefault(o => o.Value.BrokerId.Contains(brokerId))
                            .Value;

                if (order == null)
                {
                    order = _algorithm.Transactions.GetOrderByBrokerageId(brokerId);
                    if (order == null)
                    {
                        Log.Error($"BitfinexBrokerage.EmitFillOrder(): order not found: BrokerId: {brokerId}");
                        return;
                    }
                }

                var symbol       = _symbolMapper.GetLeanSymbol(update.Symbol, SecurityType.Crypto, Market.Bitfinex);
                var fillPrice    = update.ExecPrice;
                var fillQuantity = update.ExecAmount;
                var direction    = fillQuantity < 0 ? OrderDirection.Sell : OrderDirection.Buy;
                var updTime      = Time.UnixMillisecondTimeStampToDateTime(update.MtsCreate);
                var orderFee     = new OrderFee(new CashAmount(Math.Abs(update.Fee), GetLeanCurrency(update.FeeCurrency)));

                var status = OrderStatus.Filled;
                if (fillQuantity != order.Quantity)
                {
                    decimal totalFillQuantity;
                    _fills.TryGetValue(order.Id, out totalFillQuantity);
                    totalFillQuantity += fillQuantity;
                    _fills[order.Id]   = totalFillQuantity;

                    status = totalFillQuantity == order.Quantity
                        ? OrderStatus.Filled
                        : OrderStatus.PartiallyFilled;
                }

                if (_algorithm.BrokerageModel.AccountType == AccountType.Cash &&
                    order.Direction == OrderDirection.Buy)
                {
                    var symbolProperties = _symbolPropertiesDatabase.GetSymbolProperties(symbol.ID.Market,
                                                                                         symbol,
                                                                                         symbol.SecurityType,
                                                                                         AccountBaseCurrency);
                    Crypto.DecomposeCurrencyPair(symbol, symbolProperties, out var baseCurrency, out var _);

                    if (orderFee.Value.Currency != baseCurrency)
                    {
                        OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Error, "UnexpectedFeeCurrency", $"Unexpected fee currency {orderFee.Value.Currency} for symbol {symbol}. OrderId {order.Id}. BrokerageOrderId {brokerId}. " +
                                                            "This error can happen because your account is Margin type and Lean is configured to be Cash type or while using Cash type the Bitfinex account fee settings are set to 'Asset Trading Fee' and should be set to 'Currency Exchange Fee'."));
                    }
                    else
                    {
                        // fees are debited in the base currency, so we have to subtract them from the filled quantity
                        fillQuantity -= orderFee.Value.Amount;

                        orderFee = new ModifiedFillQuantityOrderFee(orderFee.Value);
                    }
                }

                var orderEvent = new OrderEvent
                                 (
                    order.Id, symbol, updTime, status,
                    direction, fillPrice, fillQuantity,
                    orderFee, $"Bitfinex Order Event {direction}"
                                 );

                // if the order is closed, we no longer need it in the active order list
                if (status == OrderStatus.Filled)
                {
                    Order outOrder;
                    CachedOrderIDs.TryRemove(order.Id, out outOrder);

                    decimal ignored;
                    _fills.TryRemove(order.Id, out ignored);

                    var clientOrderId = _orderMap.FirstOrDefault(x => x.Value.BrokerId.Contains(brokerId)).Key;
                    if (clientOrderId > 0)
                    {
                        _orderMap.TryRemove(clientOrderId, out outOrder);
                    }
                }

                OnOrderEvent(orderEvent);
            }
            catch (Exception e)
            {
                Log.Error(e);
                throw;
            }
        }