private void ProcessPortfolioLookup(PortfolioLookupMessage message)
        {
            if (message != null)
            {
                if (!message.IsSubscribe)
                {
                    return;
                }
            }

            var transactionId = message?.TransactionId ?? 0;

            var pfName = PortfolioName;

            SendOutMessage(new PortfolioMessage
            {
                PortfolioName         = pfName,
                BoardCode             = Extensions.BitStampBoard,
                OriginalTransactionId = transactionId,
            });

            if (message != null)
            {
                SendSubscriptionResult(message);
            }

            var tuple = _httpClient.GetBalances();

            foreach (var pair in tuple.Item1)
            {
                var currValue  = pair.Value.First;
                var currPrice  = pair.Value.Second;
                var blockValue = pair.Value.Third;

                if (currValue == null && currPrice == null && blockValue == null)
                {
                    continue;
                }

                var msg = this.CreatePositionChangeMessage(pfName, pair.Key.ToUpperInvariant().ToStockSharp(false));

                msg.TryAdd(PositionChangeTypes.CurrentValue, currValue, true);
                msg.TryAdd(PositionChangeTypes.CurrentPrice, currPrice, true);
                msg.TryAdd(PositionChangeTypes.BlockedValue, blockValue, true);

                SendOutMessage(msg);
            }

            foreach (var pair in tuple.Item2)
            {
                SendOutMessage(new Level1ChangeMessage
                {
                    SecurityId = pair.Key.ToStockSharp(),
                    ServerTime = CurrentTime.ConvertToUtc()
                }.TryAdd(Level1Fields.CommissionTaker, pair.Value));
            }

            _lastTimeBalanceCheck = CurrentTime;
        }
        private void ProcessOrderRegister(OrderRegisterMessage regMsg)
        {
            var condition = (BitStampOrderCondition)regMsg.Condition;

            switch (regMsg.OrderType)
            {
            case null:
            case OrderTypes.Limit:
            case OrderTypes.Market:
                break;

            case OrderTypes.Conditional:
            {
                if (!condition.IsWithdraw)
                {
                    break;
                }

                var withdrawId = _httpClient.Withdraw(regMsg.SecurityId.SecurityCode, regMsg.Volume, condition.WithdrawInfo);

                SendOutMessage(new ExecutionMessage
                    {
                        ExecutionType         = ExecutionTypes.Transaction,
                        OrderId               = withdrawId,
                        ServerTime            = CurrentTime.ConvertToUtc(),
                        OriginalTransactionId = regMsg.TransactionId,
                        OrderState            = OrderStates.Done,
                        HasOrderInfo          = true,
                    });

                ProcessPortfolioLookup(null);
                return;
            }

            default:
                throw new NotSupportedException(LocalizedStrings.Str1601Params.Put(regMsg.OrderType, regMsg.TransactionId));
            }

            var price = regMsg.OrderType == OrderTypes.Market ? (decimal?)null : regMsg.Price;

            var result = _httpClient.RegisterOrder(regMsg.SecurityId.ToCurrency(), regMsg.Side.ToString().ToLowerInvariant(), price, regMsg.Volume, condition?.StopPrice, regMsg.TillDate == DateTime.Today, regMsg.TimeInForce == TimeInForce.CancelBalance);

            _orderInfo.Add(result.Id, RefTuple.Create(regMsg.TransactionId, regMsg.Volume));

            SendOutMessage(new ExecutionMessage
            {
                ExecutionType         = ExecutionTypes.Transaction,
                OrderId               = result.Id,
                ServerTime            = result.Time,
                OriginalTransactionId = regMsg.TransactionId,
                OrderState            = OrderStates.Active,
                HasOrderInfo          = true,
            });
        }
        private void ProcessOrderGroupCancel(OrderGroupCancelMessage cancelMsg)
        {
            _httpClient.CancelAllOrders();

            SendOutMessage(new ExecutionMessage
            {
                ServerTime            = CurrentTime.ConvertToUtc(),
                ExecutionType         = ExecutionTypes.Transaction,
                OriginalTransactionId = cancelMsg.TransactionId,
                HasOrderInfo          = true,
            });

            ProcessOrderStatus(null);
            ProcessPortfolioLookup(null);
        }
 private void ProcessOrder(UserOrder order, decimal balance, long transId, long origTransId)
 {
     SendOutMessage(new ExecutionMessage
     {
         ExecutionType         = ExecutionTypes.Transaction,
         OrderId               = order.Id,
         TransactionId         = transId,
         OriginalTransactionId = origTransId,
         OrderPrice            = (decimal)order.Price,
         Balance               = balance,
         OrderVolume           = (decimal)order.Amount,
         Side          = order.Type.ToSide(),
         SecurityId    = order.CurrencyPair.ToStockSharp(),
         ServerTime    = transId != 0 ? order.Time : CurrentTime.ConvertToUtc(),
         PortfolioName = PortfolioName,
         OrderState    = OrderStates.Active,
         HasOrderInfo  = true,
     });
 }
        private void ProcessOrderStatus(OrderStatusMessage message)
        {
            if (message == null)
            {
                var portfolioRefresh = false;

                var orders = _httpClient.RequestOpenOrders();

                var ids = _orderInfo.Keys.ToHashSet();

                foreach (var order in orders)
                {
                    ids.Remove(order.Id);

                    var info = _orderInfo.TryGetValue(order.Id);

                    if (info == null)
                    {
                        info = RefTuple.Create(TransactionIdGenerator.GetNextId(), (decimal)order.Amount);

                        _orderInfo.Add(order.Id, info);

                        ProcessOrder(order, (decimal)order.Amount, info.First, 0);

                        portfolioRefresh = true;
                    }
                    else
                    {
                        // balance existing orders tracked by trades
                    }
                }

                var trades = GetTrades();

                foreach (var trade in trades)
                {
                    ProcessTrade(trade);
                }

                foreach (var id in ids)
                {
                    // can be removed from ProcessTrade
                    if (!_orderInfo.TryGetAndRemove(id, out var info))
                    {
                        return;
                    }

                    SendOutMessage(new ExecutionMessage
                    {
                        ExecutionType         = ExecutionTypes.Transaction,
                        HasOrderInfo          = true,
                        OrderId               = id,
                        OriginalTransactionId = info.First,
                        ServerTime            = CurrentTime.ConvertToUtc(),
                        OrderState            = OrderStates.Done,
                    });

                    portfolioRefresh = true;
                }

                if (portfolioRefresh)
                {
                    ProcessPortfolioLookup(null);
                }
            }
            else
            {
                if (!message.IsSubscribe)
                {
                    return;
                }

                var orders = _httpClient.RequestOpenOrders().ToArray();

                foreach (var order in orders)
                {
                    var info = RefTuple.Create(TransactionIdGenerator.GetNextId(), (decimal)order.Amount);

                    _orderInfo.Add(order.Id, info);

                    ProcessOrder(order, (decimal)order.Amount, info.First, message.TransactionId);
                }

                var trades = GetTrades();

                foreach (var trade in trades)
                {
                    ProcessTrade(trade);
                }

                SendSubscriptionResult(message);
            }
        }