예제 #1
0
        public static BROKER_ORDER UndecorateBrokerOrder(BrokerOrder ord)
        {
            var order = new BROKER_ORDER
            {
                RequestID         = ord.RequestId,
                ID                = ord.Id,
                Ticker            = ord.Ticker,
                Instrument        = (int)ord.Instrument,
                Volume            = ord.Volume,
                Side              = ord.Side,
                OrderPricing      = (int)ord.OrderPricing,
                RequestedPrice    = ord.RequestedPrice,
                Slippage          = ord.Slippage,
                Dealer            = ord.DealerCode,
                AccountID         = ord.AccountID,
                ClosingPositionID = ord.ClosingPositionID,
                TimeCreated       = ord.TimeCreated,
                Magic             = ord.Magic,
                Comment           = ord.Comment,
                ExpertComment     = ord.ExpertComment,
                Markup            = ord.MarkupAbs
            };

            return(order);
        }
예제 #2
0
        public async Task HandlerShouldAddOrder()
        {
            // Arrange
            var expectedPlayer = new BrokerPlayer {
                PlayerId = Guid.NewGuid()
            };
            var expectedOrder = new BrokerOrder
            {
                OrderId = Guid.NewGuid(),
                ItemId  = Guid.NewGuid().ToString(),
            };

            _state.Players.Add(expectedPlayer.PlayerId, expectedPlayer);

            // Act
            await _handler.Handle(new OrderCreatedEvent(expectedOrder.OrderId, expectedPlayer)
            {
                ItemId = expectedOrder.ItemId,
            });

            // Assert
            Assert.Equal(expectedOrder.OrderId, _state.Orders.Values.Single().OrderId);
            Assert.Equal(expectedOrder.ItemId, _state.Orders.Values.Single().ItemId);
            Assert.Equal(OrderState.Active, _state.Orders.Values.Single().State);
            Assert.Same(expectedPlayer, _state.Orders.Values.Single().Owner);
        }
예제 #3
0
        private BrokerOrder vHxhvWlydv(BinaryReader obj0)
        {
            BrokerOrder brokerOrder = new BrokerOrder();

            brokerOrder.Currency         = obj0.ReadString();
            brokerOrder.OrderID          = obj0.ReadString();
            brokerOrder.OrderQty         = obj0.ReadDouble();
            brokerOrder.OrdStatus        = obj0.ReadChar();
            brokerOrder.OrdType          = obj0.ReadChar();
            brokerOrder.Price            = obj0.ReadDouble();
            brokerOrder.SecurityExchange = obj0.ReadString();
            brokerOrder.SecurityType     = obj0.ReadString();
            brokerOrder.Side             = obj0.ReadChar();
            brokerOrder.StopPx           = obj0.ReadDouble();
            brokerOrder.Symbol           = obj0.ReadString();
            int num = obj0.ReadInt32();

            for (int index = 0; index < num; ++index)
            {
                string name = obj0.ReadString();
                string str  = obj0.ReadString();
                brokerOrder.AddCustomField(name, str);
            }
            return(brokerOrder);
        }
예제 #4
0
파일: Broker.cs 프로젝트: eoliveros/acuerdo
        bool DepositAndCreateTrade(ApplicationUser brokerUser, BrokerOrder order)
        {
            // check broker exchange id
            if (brokerUser.Exchange == null)
            {
                _logger.LogError("Failed to get broker exchange id");
                return(false);
            }
            // create and test backend connection
            var via = new ViaJsonRpc(_settings.AccessHttpUrl); //TODO: move this to a ViaRpcProvider in /Services (like IWalletProvider)

            via.BalanceQuery(1);
            // register new deposit with the exchange backend
            var amount = order.AmountSend.ToString();
            var source = new Dictionary <string, object>();

            source["BrokerOrderToken"] = order.Token;
            var businessId = order.Id;

            try
            {
                via.BalanceUpdateQuery(brokerUser.Exchange.Id, order.AssetSend, "deposit", businessId, amount, source);
            }
            catch (ViaJsonException ex)
            {
                if (ex.Err == ViaError.BALANCE_UPDATE__REPEAT_UPDATE)
                {
                    _logger.LogError(ex, $"broker already made this exchange update - exch id: {brokerUser.Exchange.Id}, business id: {businessId}");
                }
                else
                {
                    throw;
                }
            }
            // make trade
            string tradeAmount;

            if (order.Side == OrderSide.Bid)
            {
                tradeAmount = order.AmountReceive.ToString();
            }
            else if (order.Side == OrderSide.Ask)
            {
                tradeAmount = order.AmountSend.ToString();
            }
            else
            {
                throw new Exception("invalid order side");
            }
            if (!_settings.MarketOrderBidAmountMoney)
            {
                via.OrderMarketQuery(brokerUser.Exchange.Id, order.Market, order.Side, tradeAmount, "0", _apiSettings.Broker.BrokerTag, _settings.MarketOrderBidAmountMoney);
            }
            else
            {
                via.OrderMarketQuery(brokerUser.Exchange.Id, order.Market, order.Side, tradeAmount, "0", _apiSettings.Broker.BrokerTag);
            }
            return(true);
        }
 public void SaveProviderMessage(BrokerOrder msg)
 {
     using (var ctx = DatabaseContext.Instance.Make())
     {
         var brokOrder = LinqToEntity.UndecorateBrokerOrder(msg);
         ctx.BROKER_ORDER.Add(brokOrder);
         ctx.SaveChanges();
     }
 }
예제 #6
0
 public MarketOrder(int id, string ticker, Instrument instrument, int volume, int side,
                    OrderPricing orderPricing, string accountGroupCode)
 {
     AccountGroupCode = accountGroupCode;
     brokerOrder      = new BrokerOrder
     {
         Id           = id,
         Ticker       = ticker,
         Instrument   = instrument,
         Volume       = volume,
         Side         = side,
         OrderPricing = orderPricing
     };
 }
예제 #7
0
        public async Task HandlerShouldCancelOrder()
        {
            // Arrange
            var initialOrder = new BrokerOrder
            {
                OrderId = Guid.NewGuid(),
                State   = OrderState.Active,
            };

            _state.Orders.Add(initialOrder.OrderId, initialOrder);

            // Act
            await _handler.Handle(new OrderCancelledEvent(initialOrder.OrderId, null));

            // Assert
            Assert.Equal(OrderState.Cancelled, _state.Orders.Values.Single().State);
        }
예제 #8
0
 public MarketOrder(int id, string ticker, Instrument instrument, int volume, int side,
                    OrderPricing orderPricing, decimal?requestedPrice, decimal?enabledAbsoluteSlippage,
                    string accountGroupCode)
 {
     AccountGroupCode = accountGroupCode;
     brokerOrder      = new BrokerOrder
     {
         Id             = id,
         Ticker         = ticker,
         Instrument     = instrument,
         Volume         = volume,
         Side           = side,
         OrderPricing   = orderPricing,
         RequestedPrice = requestedPrice,
         Slippage       = enabledAbsoluteSlippage
     };
 }
예제 #9
0
        public Task Handle(OrderCreatedEvent evnt)
        {
            var player = _state.Players[evnt.OwnerId];
            var order  = new BrokerOrder
            {
                OrderId   = evnt.EntityId,
                OwnerId   = evnt.OwnerId,
                ItemId    = evnt.ItemId,
                Quantity  = evnt.Quantity,
                Price     = evnt.Price,
                OrderType = evnt.OrderType,
                State     = OrderState.Active,
                Owner     = player,
            };

            _state.Orders.Add(evnt.EntityId, order);
            return(Task.CompletedTask);
        }
예제 #10
0
 private void RoYu8jI0tu(BinaryWriter obj0, BrokerOrder obj1)
 {
     obj0.Write(obj1.Currency);
     obj0.Write(obj1.OrderID);
     obj0.Write(obj1.OrderQty);
     obj0.Write(obj1.OrdStatus);
     obj0.Write(obj1.OrdType);
     obj0.Write(obj1.Price);
     obj0.Write(obj1.SecurityExchange);
     obj0.Write(obj1.SecurityType);
     obj0.Write(obj1.Side);
     obj0.Write(obj1.StopPx);
     obj0.Write(obj1.Symbol);
     BrokerOrderField[] customFields = obj1.GetCustomFields();
     obj0.Write(customFields.Length);
     foreach (BrokerOrderField brokerOrderField in customFields)
     {
         obj0.Write(brokerOrderField.Name);
         obj0.Write(brokerOrderField.Value);
     }
 }
예제 #11
0
        static void AddPendingOrder(LiveOpenPositionsEditor openPositionData, Symbol symbol, string orderId, long size, DateTime submittedTime,
            OrderType orderType, TransactionType transactionType, double price, string customString)
        {
            if (openPositionData.PortfolioXml.PendingOrders.Any(o => o.OrderId == orderId))
            {
                //  Order already tracked
                return;
            }

            PositionType positionType = (transactionType == TransactionType.Buy || transactionType == TransactionType.Sell) ? PositionType.Long : PositionType.Short;

            //  This assumes there is just one position per symbol.  If this isn't the case then you will need to find a way of figuring out which
            //  position a pending order corresponds to.
            PositionDataXml position = openPositionData.PortfolioXml.Positions.FirstOrDefault(pos => pos.Symbol.Equals(symbol) && pos.PositionType == positionType);

            if (position == null)
            {
                //  No existing position, so create a new one
                position = openPositionData.AddPosition(symbol, positionType);
                position.CustomString = customString;
            }

            BrokerOrder brokerOrder = new BrokerOrder();
            if (orderType == OrderType.Limit || orderType == OrderType.LimitOnClose)
            {
                brokerOrder.LimitPrice = price;
            }
            else if (orderType == OrderType.Stop || orderType == OrderType.TrailingStop)
            {
                brokerOrder.StopPrice = price;
            }
            brokerOrder.CustomString = customString;

            TradeOrderXml tradeOrder = openPositionData.AddPendingOrder(position, brokerOrder, orderId, size, submittedTime, orderType, transactionType);
        }
예제 #12
0
 public MarketOrder(BrokerOrder brokerOrder)
 {
     this.brokerOrder = brokerOrder;
 }
예제 #13
0
        private IEnumerable <IEvent> EvaluateBuyOrder(
            BrokerOrder buyOrder,
            BrokerOrder sellOrder,
            long quantityToSell,
            State state)
        {
            // The quantity one order can buy will be the least of either:
            // 1. As much as the buyer can buy (credits)
            // 2. As much as the seller can sell (inventory/order size)
            // 3. As much as the buyer wants to buy (order size)
            if (sellOrder.Price == 0)
            {
                yield break;
            }
            var affordableQuantity = buyOrder.Owner.Credits / sellOrder.Price;
            var quantityToBuy      = Math.Min(affordableQuantity, quantityToSell); // Case 1 & 2

            if (buyOrder.Quantity != -1)                                           // Case 3
            {
                quantityToBuy = Math.Min(quantityToBuy, buyOrder.Quantity - buyOrder.QuantityFulfilled);
            }

            var evnt = new OrderTransactionEvent(Guid.NewGuid(), _initiator)
            {
                FromPlayer    = sellOrder.Owner.PlayerId,
                ToPlayer      = buyOrder.Owner.PlayerId,
                FromSellOrder = sellOrder.OrderId,
                ToBuyOrder    = buyOrder.OrderId,
                ItemId        = sellOrder.ItemId,
                Quantity      = quantityToBuy,
                Price         = quantityToBuy * sellOrder.Price,
            };

            buyOrder.Owner.Credits  -= evnt.Price;
            sellOrder.Owner.Credits += evnt.Price;

            buyOrder.QuantityFulfilled  += evnt.Quantity;
            sellOrder.QuantityFulfilled += evnt.Quantity;

            UpdatePlayerInventory(buyOrder.Owner, evnt.ItemId, evnt.Quantity);
            UpdatePlayerInventory(sellOrder.Owner, evnt.ItemId, -evnt.Quantity);

            state.HandledTransactions.Enqueue(evnt.EntityId);
            yield return(evnt);

            yield return(new OrderPartiallyFulfilledEvent(buyOrder.OrderId, _initiator)
            {
                TransactionId = evnt.EntityId,
                Price = evnt.Price,
                QuantityFulfilled = evnt.Quantity,
            });

            yield return(new OrderPartiallyFulfilledEvent(sellOrder.OrderId, _initiator)
            {
                TransactionId = evnt.EntityId,
                Price = evnt.Price,
                QuantityFulfilled = evnt.Quantity,
            });

            yield return(new PlayerBalanceChangedEvent(buyOrder.Owner.PlayerId, _initiator)
            {
                TransactionId = evnt.EntityId,
                BalanceChange = -evnt.Price,
            });

            yield return(new PlayerBalanceChangedEvent(sellOrder.Owner.PlayerId, _initiator)
            {
                TransactionId = evnt.EntityId,
                BalanceChange = evnt.Price,
            });

            yield return(new PlayerInventoryChangedEvent(buyOrder.Owner.PlayerId, _initiator)
            {
                TransactionId = evnt.EntityId,
                InventoryChange = new[]
                {
                    new LuaItemStack
                    {
                        Name = evnt.ItemId,
                        Count = evnt.Quantity,
                    },
                },
            });

            yield return(new PlayerInventoryChangedEvent(sellOrder.Owner.PlayerId, _initiator)
            {
                TransactionId = evnt.EntityId,
                InventoryChange = new[]
                {
                    new LuaItemStack
                    {
                        Name = evnt.ItemId,
                        Count = -evnt.Quantity,
                    },
                },
            });

            if (buyOrder.Quantity != -1 && buyOrder.QuantityFulfilled >= buyOrder.Quantity)
            {
                yield return(new OrderFulfilledEvent(buyOrder.OrderId, _initiator));

                buyOrder.State = OrderState.Fulfilled;
                _logger.Information($"Buy order ${buyOrder.OrderId} completely fulfilled!");
            }
        }
예제 #14
0
파일: Broker.cs 프로젝트: eoliveros/acuerdo
        void ProcessOrderChain(BrokerOrder order)
        {
            // check wallet has been updated
            var time = _walletProvider.LastBlockchainWalletUpdate(order.AssetSend);

            if (time < DateTimeOffset.Now.AddMinutes(-(_apiSettings.Broker.TimeLimitGracePeriod / 2)))
            {
                _logger.LogWarning($"Not processing broker order ({order.Token}) as the wallet ({order.AssetSend}) was not updated since {time}");
                return;
            }

            // get broker user
            var brokerUser = _userManager.FindByNameAsync(_apiSettings.Broker.BrokerTag).GetAwaiter().GetResult();

            if (brokerUser == null)
            {
                _logger.LogError("Failed to find broker user");
                return;
            }

            // get order user
            var user = _userManager.FindByIdAsync(order.ApplicationUserId).GetAwaiter().GetResult();

            if (user == null)
            {
                _logger.LogError($"Failed to find order user ('{order.ApplicationUserId}')");
                return;
            }

            if (order.Status == BrokerOrderStatus.Ready.ToString() || order.Status == BrokerOrderStatus.Incomming.ToString())
            {
                CheckTxs(brokerUser, user, order);
            }
            else if (order.Status == BrokerOrderStatus.Confirmed.ToString())
            {
                if (FiatWithdrawToCustomer(brokerUser, order))
                {
                    order.Status = BrokerOrderStatus.PayoutWait.ToString();
                    _context.BrokerOrders.Update(order);
                    _logger.LogError($"Sent fiat for order ('{order.Token}')");
                }
                else
                {
                    _logger.LogError($"failed to send fiat for order ({order.Token})");
                }
            }
            else if (order.Status == BrokerOrderStatus.PayoutWait.ToString())
            {
                var bow = _context.BrokerOrderFiatWithdrawals.SingleOrDefault(o => o.BrokerOrderId == order.Id);
                if (bow == null)
                {
                    _logger.LogWarning($"broker order withdrawal not found ({order.Token})");
                    return;
                }

                // check fiat withdrawal is completed
                var wallet = _walletProvider.GetFiat(order.AssetReceive);
                var fiatTx = wallet.GetTx(bow.DepositCode);
                if (fiatTx != null && fiatTx.BankTx != null)
                {
                    order.Status = BrokerOrderStatus.Sent.ToString();
                    _context.BrokerOrders.Update(order);
                    _logger.LogInformation($"Payout confirmed for order {order.Token}");

                    // send email
                    var sendWallet    = _walletProvider.GetChain(order.AssetSend);
                    var receiveWallet = _walletProvider.GetFiat(order.AssetReceive);
                    _emailSender.SendEmailBrokerSentOutgoingFunds(user.Email, order.AssetSend, sendWallet.AmountToString(order.AmountSend), order.AssetReceive,
                                                                  receiveWallet.AmountToString(order.AmountReceive), order.InvoiceId).GetAwaiter().GetResult();
                    _logger.LogInformation($"Sent email to {user.Email}");
                }
            }
        }
예제 #15
0
파일: Broker.cs 프로젝트: eoliveros/acuerdo
        void ProcessOrderFiat(BrokerOrder order)
        {
            if (!_fiatSettings.PaymentsEnabled)
            {
                _logger.LogError("receiving fiat not enabled");
                return;
            }
            if (!_fiatSettings.PaymentsAssets.Contains(order.AssetSend))
            {
                _logger.LogError($"receiving fiat currency '${order.AssetSend}' not supported");
                return;
            }
            // get broker user
            var brokerUser = _userManager.FindByNameAsync(_apiSettings.Broker.BrokerTag).GetAwaiter().GetResult();

            if (brokerUser == null)
            {
                _logger.LogError("Failed to find broker user");
                return;
            }

            // get order user
            var user = _userManager.FindByIdAsync(order.ApplicationUserId).GetAwaiter().GetResult();

            if (user == null)
            {
                _logger.LogError($"Failed to find order user ('{order.ApplicationUserId}')");
                return;
            }

            var paymentReq = RestUtils.GetFiatPaymentRequest(_fiatSettings, order.Token);

            if (paymentReq == null)
            {
                _logger.LogError($"Failed to get fiat payment request (token: {order.Token})");
                return;
            }
            if (order.Status == BrokerOrderStatus.Ready.ToString() || order.Status == BrokerOrderStatus.Incomming.ToString())
            {
                // bingo!
                if (paymentReq.Status.ToLower() == viafront3.Models.ApiViewModels.ApiRequestStatus.Completed.ToString().ToLower())
                {
                    order.Status = BrokerOrderStatus.Confirmed.ToString();
                    _context.BrokerOrders.Update(order);
                    _logger.LogInformation($"Payment confirmed for order {order.Token}");
                    DepositAndCreateTrade(brokerUser, order);

                    // send email
                    var wallet = _walletProvider.GetFiat(order.AssetSend);
                    if (wallet == null)
                    {
                        _logger.LogError($"Failed to get fiat wallet for order (token: {order.Token})");
                        return;
                    }
                    _emailSender.SendEmailBrokerSeenIncomingFunds(user.Email, order.AssetSend, wallet.AmountToString(order.AmountSend), order.InvoiceId).GetAwaiter().GetResult();
                    _logger.LogInformation($"Sent email to {user.Email}");
                }
            }
            else if (order.Status == BrokerOrderStatus.Confirmed.ToString())
            {
                if (ChainWithdrawToCustomer(brokerUser, order))
                {
                    order.Status = BrokerOrderStatus.PayoutWait.ToString();
                    _context.BrokerOrders.Update(order);
                    _logger.LogInformation($"Sent funds for order {order.Token}");
                }
                else
                {
                    _logger.LogError($"failed to send funds for order ({order.Token})");
                }
            }
            else if (order.Status == BrokerOrderStatus.PayoutWait.ToString())
            {
                var bow = _context.BrokerOrderChainWithdrawals.SingleOrDefault(o => o.BrokerOrderId == order.Id);
                if (bow == null)
                {
                    _logger.LogWarning($"broker order withdrawal not found ({order.Token})");
                    return;
                }

                var asset  = order.AssetReceive;
                var wallet = _walletProvider.GetChain(asset);
                if (wallet == null)
                {
                    _logger.LogError($"No chain wallet for {asset}");
                    return;
                }

                var spend = wallet.PendingSpendsGet().SingleOrDefault(s => s.SpendCode == bow.SpendCode);
                if (spend == null)
                {
                    _logger.LogError($"No pending spend for broker {bow.SpendCode}");
                    return;
                }

                if (spend.State == PendingSpendState.Complete)
                {
                    order.Status        = BrokerOrderStatus.Sent.ToString();
                    order.TxIdRecipient = spend.TxIds;
                    _context.BrokerOrders.Update(order);
                    _logger.LogInformation($"Payout confirmed for order {order.Token}");

                    // send email
                    var sendWallet    = _walletProvider.GetFiat(order.AssetSend);
                    var receiveWallet = _walletProvider.GetChain(order.AssetReceive);
                    _emailSender.SendEmailBrokerSentOutgoingFunds(user.Email, order.AssetSend, sendWallet.AmountToString(order.AmountSend), order.AssetReceive,
                                                                  receiveWallet.AmountToString(order.AmountReceive), order.InvoiceId).GetAwaiter().GetResult();
                    _logger.LogInformation($"Sent email to {user.Email}");
                }
            }
        }
예제 #16
0
		private void OnOrderUpdated(BrokerOrder order, Fill fill, string information)
		{
			OrderUpdatedDelegate del = _orderUpdated;
			if (del != null)
			{
				del(order, fill, information);
			}
		}
예제 #17
0
파일: Broker.cs 프로젝트: eoliveros/acuerdo
        public bool FiatWithdrawToCustomer(ApplicationUser brokerUser, BrokerOrder order)
        {
            var asset  = order.AssetReceive;
            var amount = order.AmountReceive;

            var wallet = _walletProvider.GetFiat(asset);

            if (wallet == null)
            {
                _logger.LogError($"No fiat wallet for {asset}");
                return(false);
            }

            var via     = new ViaJsonRpc(_settings.AccessHttpUrl);
            var balance = via.BalanceQuery(brokerUser.Exchange.Id, asset);

            // validate amount
            var amountInt    = wallet.AmountToLong(amount);
            var availableInt = wallet.StringToAmount(balance.Available);

            if (amountInt > availableInt)
            {
                _logger.LogError("broker available balance is too small");
                return(false);
            }
            if (amountInt <= 0)
            {
                _logger.LogError("amount must be greather then or equal to 0");
                return(false);
            }

            using (var dbtx = wallet.BeginDbTransaction())
            {
                // register withdrawal with wallet
                var acct = new BankAccount {
                    AccountNumber = order.Recipient
                };
                var tx = wallet.RegisterPendingWithdrawal(brokerUser.Id, amountInt, acct);
                if (tx == null)
                {
                    _logger.LogError($"Failed to create fiat withdrawal ('{order.Token}')");
                    return(false);
                }
                wallet.Save();
                var businessId = tx.Id;

                try
                {
                    // link pending withdrawal to broker order
                    var bow = new BrokerOrderFiatWithdrawal {
                        BrokerOrderId = order.Id, DepositCode = tx.DepositCode
                    };
                    _context.BrokerOrderFiatWithdrawals.Add(bow);
                    // we save changes here so that we a broker order cannot be processed twice(BrokerOrderChainWithdrawal.BrokerOrderId is unique)
                    _context.SaveChanges();
                }
                catch
                {
                    _logger.LogError($"unable to create BrokerOrderChainWithdrawal object ({order.Id}, {tx.DepositCode}");
                    throw;
                }

                // register withdrawal with the exchange backend
                var negativeAmount = -amount;
                try
                {
                    via.BalanceUpdateQuery(brokerUser.Exchange.Id, asset, "withdraw", businessId, negativeAmount.ToString(), null);
                }
                catch (ViaJsonException ex)
                {
                    _logger.LogError(ex, "Failed to update (withdraw) user balance (xch id: {0}, asset: {1}, businessId: {2}, amount {3}",
                                     brokerUser.Exchange.Id, asset, businessId, negativeAmount);
                    if (ex.Err == ViaError.BALANCE_UPDATE__BALANCE_NOT_ENOUGH)
                    {
                        dbtx.Rollback();
                        _logger.LogError("balance not enough");
                        return(false);
                    }
                    throw;
                }

                dbtx.Commit();
            }

            return(true);
        }
        //Xem bang này có bảng lịch sử clone từ bảng này ra hay không?
        public static string GetEntityNameHist(string entityName)
        {
            if (entityName == ApprovalAccount.EntityName())
            {
                return(ApprovalAccountHist.EntityName());
            }
            if (entityName == ApprovalDealing.EntityName())
            {
                return(ApprovalDealingHist.EntityName());
            }
            if (entityName == ApprovalMember.EntityName())
            {
                return(ApprovalMemberHist.EntityName());
            }
            if (entityName == ApprovalOrder.EntityName())
            {
                return(ApprovalOrderHist.EntityName());
            }
            if (entityName == ApprovalPreRisk.EntityName())
            {
                return(ApprovalPreRiskHist.EntityName());
            }
            if (entityName == ApprovalSystem.EntityName())
            {
                return(ApprovalSystemHist.EntityName());
            }

            if (entityName == AccountTransaction.EntityName())
            {
                return(AccountTransactionHist.EntityName());
            }
            if (entityName == BrokerOrder.EntityName())
            {
                return(BrokerOrderHist.EntityName());
            }
            if (entityName == ExecutionReport.EntityName())
            {
                return(ExecutionReportHist.EntityName());
            }

            if (entityName == OpenPositionDetail.EntityName())
            {
                return(OpenPositionDetailHist.EntityName());
            }
            if (entityName == OpenPosition.EntityName())
            {
                return(OpenPositionHist.EntityName());
            }
            if (entityName == OrderTransaction.EntityName())
            {
                return(OrderTransactionHist.EntityName());
            }
            if (entityName == SpecAccounting.EntityName())
            {
                return(SpecAccountingHist.EntityName());
            }
            if (entityName == SymbolSettlementPrice.EntityName())
            {
                return(SymbolSettlementPriceDaily.EntityName());
            }
            if (entityName == TradingDeal.EntityName())
            {
                return(TradingDealHist.EntityName());
            }

            return(null);
        }
예제 #19
0
		public bool SubmitOrder(BrokerOrder order, out string orderId)
		{
			VerifyConnected();

			order.OrderId = Guid.NewGuid().ToString();
			orderId = order.OrderId;

			//	Make sure this symbol is being watched
			if (!knownSymbols.ContainsKey(order.OrderSymbol))
			{
				//Console.WriteLine("Looking up contract for " + order.OrderSymbol.ToString());
				knownSymbols[order.OrderSymbol] = null;
				StartWatching();

				_pendingOrders.Add(order);
				_openOrderMap[order.OrderId] = order;
				return true;
			}

			ReturnCode ret = InternalSubmitOrder(order);
			if (!ret.Success)
			{
				lastError = ret.Message;
				orderId = null;
				return false;
			}
			_openOrderMap[order.OrderId] = order;
			return true;
		}
        public TradeInfo AddCompletedTradeToPosition(PositionDataXml position, DateTime filledTime, TransactionType transactionType, Price price, long size, string orderID)
        {
            PositionDataXml brokerPos = GetBrokerPosition(position.Symbol, position.PositionType);

            //  Create a PositionInfo object to calculate the PositionStats, which we can use to calculate a new TradeInfo
            PositionInfo brokerPosInfo = GetPositionInfo(brokerPos);

            BrokerOrder order = new BrokerOrder();
            order.OrderId = orderID;
            order.PositionID = position.PosID;
            order.TransactionType = transactionType;
            order.OrderType = OrderType.Market;
            order.OrderSymbol = position.Symbol;

            Fill fill = new Fill();
            fill.FillDateTime = filledTime;
            fill.Price = price;
            fill.Quantity = size;
            fill.Commission = 0;

            var createPositionTradeMethod = typeof(PositionManager).GetMethod("CreatePositionTrade", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
            var argList = new object[]
            {
                position.Symbol,
                brokerPosInfo.CurrentStats,
                new SymbolAccountInfo(position.Symbol),
                order,
                fill,
                TradeType.UserSubmitted,        //  Trade type
                string.Empty                    //  Description
            };

            TradeInfo ret = (TradeInfo)createPositionTradeMethod.Invoke(null, argList);

            if (position.Trades.Any(t => t.FilledTime == filledTime))
            {
                ret.Sequence = position.Trades.Where(t => t.FilledTime == filledTime).Max(t => t.Sequence) + 1;
            }
            else
            {
                ret.Sequence = 0;
            }

            position.Trades.Add(ret);
            brokerPos.Trades.Add(ret);

            PortfolioXml.CurrentPrices[position.Symbol] = price.SymbolPrice;

            position.IsPending = false;
            brokerPos.IsPending = false;

            //  If position size is now zero, remove it from the list of open positions
            if (GetPositionInfo(position).CurrentStats.CurrentSize == 0)
            {
                PortfolioXml.Positions.Remove(position);
            }
            if (GetPositionInfo(brokerPos).CurrentStats.CurrentSize == 0)
            {
                if (brokerPos.PositionType == PositionType.Long)
                {
                    _longBrokerPositions.Remove(brokerPos.Symbol);
                }
                else
                {
                    _shortBrokerPositions.Remove(brokerPos.Symbol);
                }
            }

            return ret;
        }
        public TradeOrderXml AddPendingOrder(PositionDataXml position, BrokerOrder brokerOrder, string orderId, long size, DateTime submittedTime, OrderType orderType, TransactionType transactionType)
        {
            brokerOrder.OrderSymbol = position.Symbol;
            brokerOrder.OrderId = orderId;
            brokerOrder.PositionID = position.PosID;
            brokerOrder.Shares = size;
            brokerOrder.SubmittedDate = submittedTime;
            brokerOrder.OrderType = orderType;
            brokerOrder.TransactionType = transactionType;
            brokerOrder.OrderState = BrokerOrderState.Submitted;

            TradeOrderXml ret = new TradeOrderXml();
            ret.PosID = position.PosID;
            ret.OrderID = orderId;
            ret.TradeType = TradeType.UserSubmitted;
            ret.Description = string.Empty;
            ret.Error = null;
            ret.BarsValid = -1;
            ret.CancelPending = false;

            PortfolioXml.PendingOrders.Add(brokerOrder);
            position.PendingOrders.Add(ret);
            return ret;
        }
예제 #22
0
		private ReturnCode InternalSubmitOrder(BrokerOrder order)
		{
			OEC.API.OrderDraft draft = oecClient.CreateDraft();
			draft.Account = oecClient.Accounts.First;
			if (order.TransactionType == TransactionType.Buy || order.TransactionType == TransactionType.Cover)
			{
				draft.Side = OEC.Data.OrderSide.Buy;
			}
			else if (order.TransactionType == TransactionType.Sell || order.TransactionType == TransactionType.Short)
			{
				draft.Side = OEC.Data.OrderSide.Sell;
			}
			else
			{
				throw new RightEdgeError("Transaction type " + order.TransactionType.ToString() + " not supported by broker.");
			}
			draft.Quantity = (int)order.Shares;
			draft.Contract = GetContractFromSymbol(order.OrderSymbol);
			if (order.OrderType == OrderType.Market)
			{
				draft.Type = OEC.Data.OrderType.Market;
			}
			else if (order.OrderType == OrderType.MarketOnClose)
			{
				draft.Type = OEC.Data.OrderType.MarketOnClose;
			}
			else if (order.OrderType == OrderType.MarketOnOpen)
			{
				draft.Type = OEC.Data.OrderType.MarketOnOpen;
			}
			else if (order.OrderType == OrderType.Limit)
			{
				draft.Type = OEC.Data.OrderType.Limit;
				draft.Price = order.LimitPrice;
			}
			else if (order.OrderType == OrderType.Stop)
			{
				draft.Type = OEC.Data.OrderType.Stop;
				draft.Price = order.StopPrice;
			}
			else if (order.OrderType == OrderType.StopLimit)
			{
				draft.Type = OEC.Data.OrderType.StopLimit;
				draft.Price = order.StopPrice;
				draft.Price2 = order.LimitPrice;
			}
			//else if (order.OrderType == OrderType.TrailingStop)
			//{
			//    draft.Type = OEC.Data.OrderType.TrailingStopLimit;
			//}
			else
			{
				//throw new RightEdgeError("Order type " + order.OrderType.ToString() + " not supported by broker.");
				return ReturnCode.Fail("Order type " + order.OrderType.ToString() + " not supported by broker.");
			}

			if (order.GoodTillCanceled)
			{
				draft.Flags |= OEC.Data.OrderFlags.GTC;
			}

			//draft.Flags |= OEC.Data.OrderFlags.AON;

			OEC.API.OrderParts res = draft.GetInvalidParts();
			if (res != OEC.API.OrderParts.None)
			{
				string msg = "Invalid order: " + res.ToString();
				Trace.WriteLine(msg);
				//orderId = null;
				return ReturnCode.Fail(msg);
			}


			OEC.API.Order oecOrder = oecClient.SendOrder(draft);

			_orderIDMap[oecOrder.ID] = order.OrderId;

			order.OrderState = BrokerOrderState.Submitted;
			order.SubmittedDate = DateTime.Now;

			return ReturnCode.Succeed;
		}
예제 #23
0
        public async Task HandlerShouldHandleTransaction(bool buyerHasExistingInventory)
        {
            // Arrange
            var rng              = new Random();
            var expectedPrice    = rng.Next();
            var expectedQuantity = rng.Next();
            var expectedItem     = Guid.NewGuid().ToString();
            var buyer            = new BrokerPlayer
            {
                PlayerId  = Guid.NewGuid(),
                Inventory = new Dictionary <string, WarehouseInventory>(),
            };

            if (buyerHasExistingInventory)
            {
                buyer.Inventory.Add(expectedItem, new WarehouseInventory());
            }
            var seller = new BrokerPlayer
            {
                PlayerId  = Guid.NewGuid(),
                Inventory = new Dictionary <string, WarehouseInventory>
                {
                    { expectedItem, new WarehouseInventory() }
                }
            };
            var buyOrder = new BrokerOrder
            {
                OrderId   = Guid.NewGuid(),
                OrderType = OrderType.Buy,
                ItemId    = expectedItem,
                Owner     = buyer,
            };
            var sellOrder = new BrokerOrder
            {
                OrderId   = Guid.NewGuid(),
                OrderType = OrderType.Sell,
                ItemId    = expectedItem,
                Owner     = seller,
            };

            _state.Orders.Add(buyOrder.OrderId, buyOrder);
            _state.Orders.Add(sellOrder.OrderId, sellOrder);

            // Act
            await _handler.Handle(new OrderTransactionEvent(Guid.NewGuid(), null)
            {
                FromSellOrder = sellOrder.OrderId,
                ToBuyOrder    = buyOrder.OrderId,
                Quantity      = expectedQuantity,
                Price         = expectedPrice,
                ItemId        = expectedItem,
            });

            // Assert
            Assert.Equal(-expectedPrice, buyer.Credits);
            Assert.Equal(expectedPrice, seller.Credits);
            Assert.Equal(expectedQuantity, buyOrder.QuantityFulfilled);
            Assert.Equal(expectedQuantity, sellOrder.QuantityFulfilled);
            Assert.Equal(expectedQuantity, buyer.Inventory[expectedItem].Quantity);
            Assert.Equal(-expectedQuantity, seller.Inventory[expectedItem].Quantity);
        }
예제 #24
0
파일: Broker.cs 프로젝트: eoliveros/acuerdo
        void CheckTxs(ApplicationUser brokerUser, ApplicationUser user, BrokerOrder order)
        {
            // get wallet and only update from the blockchain one time
            IWallet wallet = _walletProvider.GetChain(order.AssetSend);

            var txs    = wallet.GetAddrUnacknowledgedTransactions(order.PaymentAddress);
            var ackTxs = new List <WalletTx>();

            foreach (var tx in txs)
            {
                // get invoice id
                string invoiceId = null;
                if (tx.ChainTx.Attachment != null)
                {
                    var att = System.Text.Encoding.UTF8.GetString(tx.ChainTx.Attachment.Data);
                    try
                    {
                        var dict = JsonConvert.DeserializeObject <Dictionary <string, string> >(att);
                        invoiceId = dict.FirstOrDefault(x => String.Equals(x.Key, "InvoiceId", StringComparison.OrdinalIgnoreCase)).Value;
                    }
                    catch {}
                }
                // check tx is incomming to our wallet
                if (tx.Direction == WalletDirection.Incomming)
                {
                    // check invoice id matches (if asset uses account model)
                    if (wallet.GetLedgerModel() == xchwallet.LedgerModel.Account && invoiceId == order.InvoiceId ||
                        wallet.GetLedgerModel() == xchwallet.LedgerModel.UTXO)
                    {
                        // check amount matches
                        var amount = wallet.AmountToString(tx.AmountOutputs());
                        if (order.AmountSend <= decimal.Parse(amount))
                        {
                            // bingo!
                            if (order.Status == BrokerOrderStatus.Ready.ToString())
                            {
                                order.Status      = BrokerOrderStatus.Incomming.ToString();
                                order.TxIdPayment = tx.ChainTx.TxId;
                                _context.BrokerOrders.Update(order);
                                _logger.LogInformation($"Payment detected for order {order.Token}, {tx}");

                                // send email
                                _emailSender.SendEmailBrokerSeenIncomingFunds(user.Email, order.AssetSend, wallet.AmountToString(order.AmountSend), order.InvoiceId).GetAwaiter().GetResult();
                                _logger.LogInformation($"Sent email to {user.Email}");
                            }
                            else if (order.Status == BrokerOrderStatus.Incomming.ToString() &&
                                     tx.ChainTx.Confirmations >= _walletProvider.ChainAssetSettings(order.AssetSend).MinConf)
                            {
                                order.Status = BrokerOrderStatus.Confirmed.ToString();
                                _context.BrokerOrders.Update(order);
                                ackTxs.Add(tx);
                                _logger.LogInformation($"Payment confirmed for order {order.Token}, {tx}");
                                DepositAndCreateTrade(brokerUser, order);
                            }
                        }
                    }
                }
            }
            wallet.AcknowledgeTransactions(ackTxs);
            wallet.Save();
        }
예제 #25
0
        /// <summary>
        /// отдельный класс читает очередь сообщений от провайдеров
        /// каждый FIX-дилер получает сообщения своей группы
        /// </summary>
        public void ProcessExecutionReport(BrokerResponse response, BrokerOrder request)
        {
            Logger.InfoFormat("Запрос ({0}), ответ ({1})", request, response);
            requestWatchdog.OnRequestProcessed(response.RequestId);
            // сообщить клиенту об отказе обработать ордер
            // вынимаем ордер из базы
            MarketOrder order;
            int         orderId;

            if (request.ClosingPositionID != null && request.ClosingPositionID > 0)
            {
                orderId = (int)request.ClosingPositionID;
            }
            else
            {
                orderId = request.RequestId;
                Logger.InfoFormat("Запрос GetMarketOrder orderId={0} requestId={1}", orderId, request.RequestId);
            }
            Logger.InfoFormat("Запрос GetMarketOrder accountId={0}, orderId={1}", request.AccountID, orderId);
            var res = ServerInterface.GetMarketOrder(orderId, out order);

            if (res == false)
            {
                errorStorage.AddMessage(new ErrorMessage(DateTime.Now, ErrorMessageType.ОтказСервера,
                                                         string.Format("Дилер {0}: не найдена позиция ID={0} для обработка запроса [{1}]-[счет {2}, пара {3}]",
                                                                       request.RequestId, request.Id, request.AccountID, request.Instrument), null));
                ServerInterface.NotifyClientOnOrderRejected(order, "не найден ордер");
                return;
            }

            if (response.Status == OrderStatus.Отклонен)
            {
                var rejectReasonStr = string.IsNullOrEmpty(response.RejectReasonString)
                                          ? (response.RejectReason ?? OrderRejectReason.None).ToString()
                                          : response.RejectReasonString;
                ServerInterface.NotifyClientOnOrderRejected(order, rejectReasonStr);
                errorStorage.AddMessage(new ErrorMessage(DateTime.Now, ErrorMessageType.ОтказСервера,
                                                         string.Format("Дилер {0}: отказ сервера [{1}] на запрос [{2}]-[счет {3}, пара {4}]",
                                                                       DealerCode, rejectReasonStr, request.Id, request.AccountID, request.Instrument), null));
                return;
            }
            if (!response.Price.HasValue)
            {
                errorStorage.AddMessage(new ErrorMessage(DateTime.Now, ErrorMessageType.ОтказСервера,
                                                         string.Format("Дилер {0}: отказ сервера [нет цены] на запрос [{1}]-[счет {2}, пара {3}]",
                                                                       DealerCode, request.Id, request.AccountID, request.Instrument), null));
                ServerInterface.NotifyClientOnOrderRejected(order, "Нет цены");
                return;
            }
            var deltaMarkup = request.MarkupAbs * order.Side;

            // закрытие позиции - ордер обработан
            if (request.ClosingPositionID.HasValue)
            {
                var reason = exitReasonByOrderId.ReceiveValue(order.ID);
                // закрыть ордер немедленно
                ServerInterface.CloseOrder(order.ID, response.Price.Value - (decimal)deltaMarkup, reason);
                return;
            }

            // открытие позы - обработано
            order.TimeEnter  = response.ValueDate;
            order.PriceEnter = (float)response.Price.Value + deltaMarkup;
            order.State      = PositionState.Opened;
            ServerInterface.ModifyMarketOrder(order);
        }
예제 #26
0
파일: Broker.cs 프로젝트: eoliveros/acuerdo
        bool ChainWithdrawToCustomer(ApplicationUser brokerUser, BrokerOrder order)
        {
            var asset  = order.AssetReceive;
            var amount = order.AmountReceive;

            var wallet = _walletProvider.GetChain(asset);

            if (wallet == null)
            {
                _logger.LogError($"No chain wallet for {asset}");
                return(false);
            }
            var brokerWalletTag = wallet.GetTag(brokerUser.Id);

            if (brokerWalletTag == null)
            {
                _logger.LogError($"No tag for broker {brokerUser.Id}");
                return(false);
            }

            var via     = new ViaJsonRpc(_settings.AccessHttpUrl);
            var balance = via.BalanceQuery(brokerUser.Exchange.Id, asset);

            // validate amount
            var amountInt    = wallet.StringToAmount(amount.ToString());
            var availableInt = wallet.StringToAmount(balance.Available);

            if (amountInt > availableInt)
            {
                _logger.LogError("broker available balance is too small");
                return(false);
            }
            if (amountInt <= 0)
            {
                _logger.LogError("amount must be greather then or equal to 0");
                return(false);
            }

            var consolidatedFundsTag = _walletProvider.ConsolidatedFundsTag();

            using (var dbtx = wallet.BeginDbTransaction())
            {
                // ensure tag exists
                if (!wallet.HasTag(consolidatedFundsTag))
                {
                    wallet.NewTag(consolidatedFundsTag);
                    wallet.Save();
                }

                // register withdrawal with wallet
                var tag = wallet.GetTag(brokerUser.Id);
                if (tag == null)
                {
                    tag = wallet.NewTag(brokerUser.Id);
                }
                var spend = wallet.RegisterPendingSpend(consolidatedFundsTag, consolidatedFundsTag,
                                                        order.Recipient, amountInt, tag);
                wallet.Save();
                var businessId = spend.Id;

                try
                {
                    // link pending withdrawal to broker order
                    var bow = new BrokerOrderChainWithdrawal {
                        BrokerOrderId = order.Id, SpendCode = spend.SpendCode
                    };
                    _context.BrokerOrderChainWithdrawals.Add(bow);
                    // we save changes here so that we a broker order cannot be processed twice(BrokerOrderChainWithdrawal.BrokerOrderId is unique)
                    _context.SaveChanges();
                }
                catch
                {
                    _logger.LogError($"unable to create BrokerOrderChainWithdrawal object ({order.Id}, {spend.SpendCode}");
                    throw;
                }

                // register withdrawal with the exchange backend
                var negativeAmount = -amount;
                try
                {
                    via.BalanceUpdateQuery(brokerUser.Exchange.Id, asset, "withdraw", businessId, negativeAmount.ToString(), null);
                }
                catch (ViaJsonException ex)
                {
                    _logger.LogError(ex, "Failed to update (withdraw) user balance (xch id: {0}, asset: {1}, businessId: {2}, amount {3}",
                                     brokerUser.Exchange.Id, asset, businessId, negativeAmount);
                    if (ex.Err == ViaError.BALANCE_UPDATE__BALANCE_NOT_ENOUGH)
                    {
                        dbtx.Rollback();
                        _logger.LogError("balance not enough");
                        return(false);
                    }
                    throw;
                }

                dbtx.Commit();
            }

            return(true);
        }