コード例 #1
0
        public void GtdSameDayTimeInForceCryptoOrderExpiresAtMidnightUtc()
        {
            var utcTime = new DateTime(2018, 4, 27, 10, 0, 0);

            var security = new Crypto(
                SecurityExchangeHours.AlwaysOpen(TimeZones.Utc),
                new Cash(Currencies.USD, 0, 1m),
                new SubscriptionDataConfig(
                    typeof(QuoteBar),
                    Symbols.BTCUSD,
                    Resolution.Minute,
                    TimeZones.Utc,
                    TimeZones.Utc,
                    true,
                    true,
                    true
                    ),
                SymbolProperties.GetDefault(Currencies.USD),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );
            var localTimeKeeper = new LocalTimeKeeper(utcTime, TimeZones.Utc);

            security.SetLocalTimeKeeper(localTimeKeeper);

            var timeInForce     = TimeInForce.GoodTilDate(new DateTime(2018, 4, 27));
            var orderProperties = new OrderProperties {
                TimeInForce = timeInForce
            };
            var order = new LimitOrder(Symbols.BTCUSD, 10, 100, utcTime, "", orderProperties);

            Assert.IsFalse(timeInForce.IsOrderExpired(security, order));

            var fill1 = new OrderEvent(order.Id, order.Symbol, utcTime, OrderStatus.PartiallyFilled, OrderDirection.Buy, order.LimitPrice, 3, OrderFee.Zero);

            Assert.IsTrue(timeInForce.IsFillValid(security, order, fill1));

            var fill2 = new OrderEvent(order.Id, order.Symbol, utcTime, OrderStatus.Filled, OrderDirection.Buy, order.LimitPrice, 7, OrderFee.Zero);

            Assert.IsTrue(timeInForce.IsFillValid(security, order, fill2));

            localTimeKeeper.UpdateTime(utcTime.AddHours(14).AddSeconds(-1));
            Assert.IsFalse(timeInForce.IsOrderExpired(security, order));

            localTimeKeeper.UpdateTime(utcTime.AddHours(14));
            Assert.IsTrue(timeInForce.IsOrderExpired(security, order));

            Assert.IsTrue(timeInForce.IsFillValid(security, order, fill1));
            Assert.IsTrue(timeInForce.IsFillValid(security, order, fill2));
        }
コード例 #2
0
        /// <summary>
        /// Sends a new Limit Order Request to 'Order Execution Server'
        /// </summary>
        /// <param name="orderDetails">Contains limit order information</param>
        public void LimitOrderRequest(OrderDetails orderDetails)
        {
            // Get new Order ID
            orderDetails.ID = _orderExecutionService.GetOrderId();

            // Create Limit Order object to be sent to 'Order Execution Service'
            LimitOrder limitOrder = OrderMessage.GenerateLimitOrder(orderDetails.ID, orderDetails.Security, orderDetails.Side,
                                                                    orderDetails.Quantity, orderDetails.Price, orderDetails.Provider);

            limitOrder.OrderTif = OrderTif.GTC;

            // Send Reques to Server
            _orderExecutionService.SendOrder(limitOrder);
        }
コード例 #3
0
        public async Task RegisterLinkedLimitOrders(LimitOrder order1, LimitOrder order2)
        {
            await HandleCommonStuff(order1);
            await HandleCommonStuff(order2);

            order2.LinkedLimitOrder = order1.Id;
            order1.LinkedLimitOrder = order2.Id;

            await _ordersRepository.RegisterOrderAsync(order1);

            await _ordersRepository.RegisterOrderAsync(order2);

            await _orderExecuter.Execute();
        }
コード例 #4
0
        public ActionResult BuyLimitOrder(string currencyname, string buyamount, string buyatprice)
        {
            var userId = User.Identity.GetUserId();
            var db     = new SiteDbContext();
            var user   = db.Users.Find(userId);

            decimal BuyAmount  = decimal.Parse(buyamount, CultureInfo.InvariantCulture);
            decimal BuyAtPrice = decimal.Parse(buyatprice, CultureInfo.InvariantCulture);

            if (BuyAmount == 0 || BuyAtPrice == 0 || BuyAtPrice < 0 || BuyAmount < 0)
            {
                return(View("Index"));
            }

            var TotalOrderBtcCost = BuyAmount * BuyAtPrice;

            var Coins = CoinValues.GetValues().ToList();

            if (Coins.Where(c => c.Name.Contains(currencyname)).Count() == 0)
            {
                return(View("TradePage"));
            }
            if (TotalOrderBtcCost > user.Balance)
            {
                return(View("TradePage"));
            }

            LimitOrder order = new LimitOrder()
            {
                User      = user,
                Amount    = BuyAmount,
                Currency  = currencyname,
                AtPrice   = BuyAtPrice,
                OrderType = "Buy",
                OrderDate = DateTime.Now
            };

            db.LimitOrders.Add(order);
            user.Balance -= TotalOrderBtcCost;

            db.SaveChanges();

            var Data = Newtonsoft.Json.JsonConvert.SerializeObject(new
            {
                UserBtc = user.Balance,
                UserUsd = user.Balance * CoinValues.GetBtcValue().Price
            });

            return(Json(Data, JsonRequestBehavior.AllowGet));
        }
コード例 #5
0
        public void DayTimeInForceEquityOrderExpiresAtMarketClose()
        {
            var utcTime = new DateTime(2018, 4, 27, 10, 0, 0).ConvertToUtc(TimeZones.NewYork);

            var security = new Equity(
                SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(),
                new SubscriptionDataConfig(
                    typeof(TradeBar),
                    Symbols.SPY,
                    Resolution.Minute,
                    TimeZones.NewYork,
                    TimeZones.NewYork,
                    true,
                    true,
                    true
                    ),
                new Cash(Currencies.USD, 0, 1m),
                SymbolProperties.GetDefault(Currencies.USD),
                ErrorCurrencyConverter.Instance,
                RegisteredSecurityDataTypesProvider.Null
                );
            var localTimeKeeper = new LocalTimeKeeper(utcTime, TimeZones.NewYork);

            security.SetLocalTimeKeeper(localTimeKeeper);

            var timeInForce     = TimeInForce.Day;
            var orderProperties = new OrderProperties {
                TimeInForce = timeInForce
            };
            var order = new LimitOrder(Symbols.SPY, 10, 100, utcTime, "", orderProperties);

            Assert.IsFalse(timeInForce.IsOrderExpired(security, order));

            var fill1 = new OrderEvent(order.Id, order.Symbol, utcTime, OrderStatus.PartiallyFilled, OrderDirection.Buy, order.LimitPrice, 3, OrderFee.Zero);

            Assert.IsTrue(timeInForce.IsFillValid(security, order, fill1));

            var fill2 = new OrderEvent(order.Id, order.Symbol, utcTime, OrderStatus.Filled, OrderDirection.Buy, order.LimitPrice, 7, OrderFee.Zero);

            Assert.IsTrue(timeInForce.IsFillValid(security, order, fill2));

            localTimeKeeper.UpdateTime(utcTime.AddHours(6).AddSeconds(-1));
            Assert.IsFalse(timeInForce.IsOrderExpired(security, order));

            localTimeKeeper.UpdateTime(utcTime.AddHours(6));
            Assert.IsTrue(timeInForce.IsOrderExpired(security, order));

            Assert.IsTrue(timeInForce.IsFillValid(security, order, fill1));
            Assert.IsTrue(timeInForce.IsFillValid(security, order, fill2));
        }
コード例 #6
0
        public void LimitSellOrderRequiresBaseCurrencyInPortfolio()
        {
            _portfolio.SetCash(0);
            _portfolio.CashBook["BTC"].SetAmount(0.5m);

            // 0.5 BTC in portfolio, can sell 0.5 BTC at any price
            var order = new LimitOrder(_btcusd.Symbol, -0.5m, 10000m, DateTime.UtcNow);

            Assert.IsTrue(_buyingPowerModel.HasSufficientBuyingPowerForOrder(_portfolio, _btcusd, order).IsSufficient);

            // 0.5 BTC in portfolio, cannot sell 0.6 BTC at any price
            order = new LimitOrder(_btcusd.Symbol, -0.6m, 10000m, DateTime.UtcNow);
            Assert.IsFalse(_buyingPowerModel.HasSufficientBuyingPowerForOrder(_portfolio, _btcusd, order).IsSufficient);
        }
        private void CreateLimitOrder(Trade trade)
        {
            var newLimitOrder = new LimitOrder(trade);

            if (_limitOrderList == null)
            {
                _limitOrderList = new List <LimitOrder>();
            }

            _limitOrderList.Add(newLimitOrder);

            //Send updated List<LimitOrder> to listeners in MainViewModel
            Messenger.Default.Send <LimitOrderMessage>(new LimitOrderMessage(_limitOrderList, false));
        }
コード例 #8
0
        private void testBinanceFuture()
        {
            /* web de referencia:
             * https://github.com/fman42/FutureBinanceAPI
             * */

            var Api_Clave   = "e3a7d6025708b6c3008c2cb56b209d9a4a180d8af9869533c0fe55719b88da5b";
            var API_secreta = "8c6e0568ab0a2d3a9340486b602c87805ccdd1863bee0c4e8060f6959a35e85e";

            AuthClient authClient = new AuthClient(Api_Clave, API_secreta, true); // el parametro True indica que usa la testnet.

            TickerEndPoint Ticker = new TickerEndPoint(authClient);

            var GetPrice = Task.Run(async() => await Ticker.GetPriceTickerAsync(TraidingPair.BTCUSDT));

            GetPrice.Wait();

            /* OBTIENE EL PRECIO */
            OrderEndPoint order = new OrderEndPoint(authClient); // Create an order endpoint

            decimal Precio   = decimal.Round(GetPrice.Result.Price * Convert.ToDecimal("0,98"), 2);
            decimal Cantidad = Convert.ToDecimal("0,001");

            /* ESTABLE EL APALANCAMIENTO */
            TradeEndPoint trade = new TradeEndPoint(authClient);                                           // Create a trade endpoint

            var setLeverage = Task.Run(async() => await trade.SetLeverageAsync(TraidingPair.BTCUSDT, 25)); // Set 25 leverage for BTCUSDT

            setLeverage.Wait();

            var setMargin = Task.Run(async() => await trade.SetMarginTypeAsync(TraidingPair.BTCUSDT, MarginType.CROSSED));

            setMargin.Wait();


            /* GENERA LA ORDEN */
            LimitOrder limitOrder       = new LimitOrder(TraidingPair.BTCUSDT, Side.SELL, Cantidad, Precio, TimeInForceType.GTC);
            var        limitOrderResult = Task.Run(async() => await order.SetAsync(limitOrder));

            limitOrderResult.Wait();

            /* CANCELA LA ORDEN */
            var cancelOrderResult = Task.Run(async() => await order.CancelAsync(TraidingPair.BTCUSDT, limitOrderResult.Result.OrderId));

            cancelOrderResult.Wait();

            var aaa = 1;

            aaa = aaa + 2;
        }
コード例 #9
0
ファイル: Client.cs プロジェクト: Casimir666/CryptoExchange
        public async Task <OrderResponse> PutLimitOrder(SideType side, ProductType productType, decimal price, decimal size, Guid?clientId, bool?postOnly)
        {
            var order = new LimitOrder
            {
                Side        = side,
                Price       = price,
                Size        = size,
                ProductType = productType.EnumToString(),
                ClientGuid  = clientId,
                PostOnly    = postOnly
            };

            return(await SendPostRequest <OrderResponse>(Constants.RestUrl.Orders, order));
        }
コード例 #10
0
 /// <summary>
 /// Publishes limit order message
 /// </summary>
 public void PublishLimitOrder(LimitOrder limitOrder)
 {
     try
     {
         // Message to be published
         IMessage <LimitOrder> message = new Message <LimitOrder>(limitOrder);
         // Publish message
         _easyNetQBus.Publish(_easyNetQExchange, _limitOrderQueueRoutingKey, true, false, message);
     }
     catch (Exception exception)
     {
         Logger.Error(exception, _type.FullName, "PublishLimitOrder");
     }
 }
コード例 #11
0
        /// <summary>
        /// Send a limit order to the transaction handler:
        /// </summary>
        /// <param name="symbol">String symbol for the asset</param>
        /// <param name="quantity">Quantity of shares for limit order</param>
        /// <param name="limitPrice">Limit price to fill this order</param>
        /// <param name="tag">String tag for the order (optional)</param>
        /// <returns>Order id</returns>
        public int LimitOrder(string symbol, int quantity, decimal limitPrice, string tag = "")
        {
            var error = PreOrderChecks(symbol, quantity, OrderType.Limit);

            if (error < 0)
            {
                return(error);
            }

            var order = new LimitOrder(symbol, quantity, limitPrice, Time, tag, Securities[symbol].Type);

            //Add the order and create a new order Id.
            return(Transactions.AddOrder(order));
        }
コード例 #12
0
        /// <summary>
        /// Handles New Limit Order Request messages from Applications
        /// </summary>
        /// <param name="limitOrder">TradeHub Limit Order</param>
        /// <param name="appId">Unique Application ID</param>
        public void LimitOrderRequestReceived(LimitOrder limitOrder, string appId)
        {
            try
            {
                if (Logger.IsDebugEnabled)
                {
                    Logger.Debug(
                        "New Limit Order request received from: " + appId + limitOrder.OrderID + " for: " +
                        limitOrder.OrderExecutionProvider,
                        _type.FullName, "LimitOrderRequestReceived");
                }

                IOrderExecutionProvider orderExecutionProvider;
                if (_providersMap.TryGetValue(limitOrder.OrderExecutionProvider, out orderExecutionProvider))
                {
                    ILimitOrderProvider limitOrderProvider = orderExecutionProvider as ILimitOrderProvider;
                    if (limitOrderProvider != null)
                    {
                        // Modify Order ID by appending Application ID in the front
                        limitOrder.OrderID = appId + "|" + limitOrder.OrderID;

                        // Register Market Order Events
                        RegisterLimitOrderEvents(limitOrderProvider);

                        // Send Limit Order to Execution Provider
                        limitOrderProvider.SendLimitOrder(limitOrder);
                    }
                    else
                    {
                        if (Logger.IsInfoEnabled)
                        {
                            Logger.Info("Requested provider doesn't support Limit Orders", _type.FullName, "LimitOrderRequestReceived");
                        }
                    }
                }
                else
                {
                    if (Logger.IsInfoEnabled)
                    {
                        Logger.Info(
                            "Order Execution Provider module not available for: " + limitOrder.OrderExecutionProvider,
                            _type.FullName, "LimitOrderRequestReceived");
                    }
                }
            }
            catch (Exception exception)
            {
                Logger.Error(exception, _type.FullName, "LimitOrderRequestReceived");
            }
        }
コード例 #13
0
        /*
         * private bool IsUnknownOrderID(KeyValuePair<long, TradierOrder> x)
         * {
         *  // we don't have it in our local cache
         *  return !_cachedOpenOrdersByTradierOrderID.ContainsKey(x.Key)
         *      // the transaction happened after we initialized, make sure they're in the same time zone
         *      && x.Value.TransactionDate.ToUniversalTime() > _initializationDateTime.ToUniversalTime()
         *      // we don't have a record of it in our last 10k filled orders
         *      && !_filledTradierOrderIDs.Contains(x.Key);
         * }
         *
         * private void ProcessPotentiallyUpdatedOrder(TradierCachedOpenOrder cachedOrder, TradierOrder updatedOrder)
         * {
         *  // check for fills or status changes, for either fire a fill event
         *  if (updatedOrder.RemainingQuantity != cachedOrder.Order.RemainingQuantity
         || ConvertStatus(updatedOrder.Status) != ConvertStatus(cachedOrder.Order.Status))
         || {
         ||     var qcOrder = _orderProvider.GetOrderByBrokerageId(updatedOrder.Id);
         ||     qcOrder.PriceCurrency = "USD";
         ||     const int orderFee = 0;
         ||     var fill = new OrderEvent(qcOrder, DateTime.UtcNow, orderFee, "Tradier Fill Event")
         ||     {
         ||         Status = ConvertStatus(updatedOrder.Status),
         ||         // this is guaranteed to be wrong in the event we have multiple fills within our polling interval,
         ||         // we're able to partially cope with the fill quantity by diffing the previous info vs current info
         ||         // but the fill price will always be the most recent fill, so if we have two fills with 1/10 of a second
         ||         // we'll get the latter fill price, so for large orders this can lead to inconsistent state
         ||         FillPrice = updatedOrder.LastFillPrice,
         ||         FillQuantity = (int)(updatedOrder.QuantityExecuted - cachedOrder.Order.QuantityExecuted)
         ||     };
         ||
         ||     // flip the quantity on sell actions
         ||     if (IsShort(updatedOrder.Direction))
         ||     {
         ||         fill.FillQuantity *= -1;
         ||     }
         ||
         ||     if (!cachedOrder.EmittedOrderFee)
         ||     {
         ||         cachedOrder.EmittedOrderFee = true;
         ||         var security = _securityProvider.GetSecurity(qcOrder.Symbol);
         ||         fill.OrderFee = security.FeeModel.GetOrderFee(security, qcOrder);
         ||     }
         ||
         ||     // if we filled the order and have another contingent order waiting, submit it
         ||     ContingentOrderQueue contingent;
         ||     if (fill.Status == OrderStatus.Filled && _contingentOrdersByQCOrderID.TryGetValue(qcOrder.Id, out contingent))
         ||     {
         ||         // prevent submitting the contingent order multiple times
         ||         if (_contingentReentranceGuardByQCOrderID.Add(qcOrder.Id))
         ||         {
         ||             var order = contingent.Next();
         ||             if (order == null || contingent.Contingents.Count == 0)
         ||             {
         ||                 // we've finished with this contingent order
         ||                 _contingentOrdersByQCOrderID.TryRemove(qcOrder.Id, out contingent);
         ||             }
         ||             // fire this off in a task so we don't block this thread
         ||             if (order != null)
         ||             {
         ||                 // if we have a contingent that needs to be submitted then we can't respect the 'Filled' state from the order
         ||                 // because the QC order hasn't been technically filled yet, so mark it as 'PartiallyFilled'
         ||                 fill.Status = OrderStatus.PartiallyFilled;
         ||
         ||                 Task.Run(() =>
         ||                 {
         ||                     try
         ||                     {
         ||                         Log.Trace("TradierBrokerage.SubmitContingentOrder(): Submitting contingent order for QC id: " + qcOrder.Id);
         ||
         ||                         var response = TradierPlaceOrder(order);
         ||                         if (response.Errors.Errors.IsNullOrEmpty())
         ||                         {
         ||                             // add the new brokerage id for retrieval later
         ||                             qcOrder.BrokerId.Add(response.Order.Id.ToString());
         ||                         }
         ||                         else
         ||                         {
         ||                             // if we failed to place this order I don't know what to do, we've filled the first part
         ||                             // and failed to place the second... strange. Should we invalidate the rest of the order??
         ||                             Log.Error("TradierBrokerage.SubmitContingentOrder(): Failed to submit contingent order.");
         ||                             var message = string.Format("{0} Failed submitting contingent order for QC id: {1} Filled Tradier Order id: {2}", qcOrder.Symbol, qcOrder.Id, updatedOrder.Id);
         ||                             OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, "ContingentOrderFailed", message));
         ||                             OnOrderEvent(new OrderEvent(qcOrder, DateTime.UtcNow, orderFee) { Status = OrderStatus.Canceled });
         ||                         }
         ||                     }
         ||                     catch (Exception err)
         ||                     {
         ||                         Log.Error(err);
         ||                         OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, "ContingentOrderError", "An error ocurred while trying to submit an Tradier contingent order: " + err));
         ||                         OnOrderEvent(new OrderEvent(qcOrder, DateTime.UtcNow, orderFee) { Status = OrderStatus.Canceled });
         ||                     }
         ||                     finally
         ||                     {
         ||                         _contingentReentranceGuardByQCOrderID.Remove(qcOrder.Id);
         ||                     }
         ||                 });
         ||             }
         ||         }
         ||     }
         ||
         ||     OnOrderEvent(fill);
         || }
         ||
         || // remove from open orders since it's now closed
         || if (OrderIsClosed(updatedOrder))
         || {
         ||     _filledTradierOrderIDs.Add(updatedOrder.Id);
         ||     _cachedOpenOrdersByTradierOrderID.TryRemove(updatedOrder.Id, out cachedOrder);
         || }
         ||}
         ||
         ||private void UpdateCachedOpenOrder(long key, TradierOrder updatedOrder)
         ||{
         || TradierCachedOpenOrder cachedOpenOrder;
         || if (_cachedOpenOrdersByTradierOrderID.TryGetValue(key, out cachedOpenOrder))
         || {
         ||     cachedOpenOrder.Order = updatedOrder;
         || }
         || else
         || {
         ||     _cachedOpenOrdersByTradierOrderID[key] = new TradierCachedOpenOrder(updatedOrder);
         || }
         ||}
         */

        #endregion

        #region Conversion routines

        /// <summary>
        /// Converts the specified tradier order into a qc order.
        /// The 'task' will have a value if we needed to issue a rest call for the stop price, otherwise it will be null
        /// </summary>
        protected Order ConvertOrder(Anonymous8 order)
        {
            Order qcOrder;

            qcOrder = new LimitOrder()
            {
                LimitPrice = (decimal)order.LimitPrice
            };
            //TODO

            /*
             * switch (order.OrderType)
             * {
             *  case Type2
             *      qcOrder = new LimitOrder { LimitPrice = order.Price };
             *      break;
             *  case TradierOrderType.Market:
             *      qcOrder = new MarketOrder();
             *      break;
             *  case TradierOrderType.StopMarket:
             *      qcOrder = new StopMarketOrder { StopPrice = GetOrder(order.Id).StopPrice };
             *      break;
             *  case TradierOrderType.StopLimit:
             *      qcOrder = new StopLimitOrder { LimitPrice = order.Price, StopPrice = GetOrder(order.Id).StopPrice };
             *      break;
             *
             *  //case TradierOrderType.Credit:
             *  //case TradierOrderType.Debit:
             *  //case TradierOrderType.Even:
             *  default:
             *      throw new NotImplementedException("The Tradier order type " + order.Type + " is not implemented.");
             * }
             */
            qcOrder.Symbol   = _symbolMapper.GetLeanSymbol(order.Symbol, order.AssetType);// Symbol.Create(order.Symbol, SecurityType.Equity, Market.USA);
            qcOrder.Quantity = ConvertQuantity(order);
            qcOrder.Status   = ConvertStatus(order.Status);
            qcOrder.Id       = Int32.Parse(order.OrderID.ToString());
            //qcOrder.BrokerId.Add(order.OrderID.ToString());
            //qcOrder.ContingentId =
            qcOrder.Properties.TimeInForce = ConvertDuration(order.Duration);

            /*var orderByBrokerageId = _orderProvider.GetOrderByBrokerageId(order.OrderID.ToString());
             * if (orderByBrokerageId != null)
             * {
             *  qcOrder.Id = orderByBrokerageId.Id;
             * }
             */
            qcOrder.Time = DateTime.Parse(order.TimeStamp); //TransactionDate;
            return(qcOrder);
        }
コード例 #14
0
        public async Task PlaceLimitOrderAsync(LimitOrder limitOrder)
        {
            var model = new LimitOrderModel
            {
                AssetPairId          = limitOrder.AssetPairId,
                CancelPreviousOrders = false,
                ClientId             = _walletId,
                Id          = Guid.NewGuid().ToString(),
                OrderAction = limitOrder.TradeType.ToOrderAction(),
                Price       = (double)limitOrder.Price,
                Volume      = (double)limitOrder.Volume,
            };

            limitOrder.ExternalId = model.Id;

            MeResponseModel response;

            try
            {
                response = await _matchingEngineClient.PlaceLimitOrderAsync(model,
                                                                            new CancellationTokenSource(Consts.MatchingEngineTimeout).Token);
            }
            catch (Exception exception)
            {
                _log.Error(exception, "An error occurred during creating limit orders",
                           new { request = $"data: {model.ToJson()}" });

                throw;
            }

            if (response == null)
            {
                throw new Exception("ME response is null");
            }

            if (response.Status == MeStatusCodes.Ok)
            {
                _log.Info("ME place limit order response", new { response = $"data: {response.ToJson()}" });

                limitOrder.Error = LimitOrderError.None;
            }
            else
            {
                _log.Warning("ME place limit order response unsuccessful code.", context: new { response = $"data: {response.ToJson()}" });
                limitOrder.Error        = response.Status.ToOrderError();
                limitOrder.ErrorMessage = limitOrder.Error != LimitOrderError.Unknown
                    ? response.Message
                    : !string.IsNullOrEmpty(response.Message) ? response.Message : "Unknown error";
            }
        }
コード例 #15
0
        public void LimitOrderDoesNotFillUsingDataBeforeSubmitTime(decimal orderQuantity, decimal limitPrice)
        {
            var time       = new DateTime(2018, 9, 24, 9, 30, 0);
            var timeKeeper = new TimeKeeper(time.ConvertToUtc(TimeZones.NewYork), TimeZones.NewYork);
            var symbol     = Symbol.Create("SPY", SecurityType.Equity, Market.USA);

            var config   = new SubscriptionDataConfig(typeof(TradeBar), symbol, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, true, false);
            var security = new Security(
                SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(),
                config,
                new Cash(CashBook.AccountCurrency, 0, 1m),
                SymbolProperties.GetDefault(CashBook.AccountCurrency),
                ErrorCurrencyConverter.Instance
                );

            security.SetLocalTimeKeeper(timeKeeper.GetLocalTimeKeeper(TimeZones.NewYork));

            var tradeBar = new TradeBar(time, symbol, 290m, 292m, 289m, 291m, 12345);

            security.SetMarketPrice(tradeBar);

            time += TimeSpan.FromMinutes(1);
            timeKeeper.SetUtcDateTime(time.ConvertToUtc(TimeZones.NewYork));

            var fillForwardBar = (TradeBar)tradeBar.Clone(true);

            security.SetMarketPrice(fillForwardBar);

            var fillModel = new ImmediateFillModel();
            var order     = new LimitOrder(symbol, orderQuantity, limitPrice, time.ConvertToUtc(TimeZones.NewYork));

            var fill = fillModel.LimitFill(security, order);

            Assert.AreEqual(0, fill.FillQuantity);
            Assert.AreEqual(0, fill.FillPrice);
            Assert.AreEqual(OrderStatus.None, fill.Status);

            time += TimeSpan.FromMinutes(1);
            timeKeeper.SetUtcDateTime(time.ConvertToUtc(TimeZones.NewYork));

            tradeBar = new TradeBar(time, symbol, 290m, 292m, 289m, 291m, 12345);
            security.SetMarketPrice(tradeBar);

            fill = fillModel.LimitFill(security, order);

            Assert.AreEqual(orderQuantity, fill.FillQuantity);
            Assert.AreEqual(limitPrice, fill.FillPrice);
            Assert.AreEqual(OrderStatus.Filled, fill.Status);
            Assert.AreEqual(0, fill.OrderFee);
        }
コード例 #16
0
        public async Task OnlyBelowMinimumLimitOrdersAreReplacedWhenMixedWithAboveMinimumOrders(string marketId, long selectionId, Side side, double size, double price)
        {
            var limitOrder    = new LimitOrder(selectionId, side, price, size);
            var aboveMinOrder = new LimitOrder(1, Side.Back, 2, 10);
            await _orderService.Place(marketId, new List <LimitOrder> {
                limitOrder, aboveMinOrder
            });

            var cancelInstruction  = $"{{\"marketId\":\"{marketId}\",\"instructions\":[{limitOrder.ToBelowMinimumCancelInstruction()}]}}";
            var replaceInstruction = $"{{\"marketId\":\"{marketId}\",\"instructions\":[{limitOrder.ToBelowMinimumReplaceInstruction()}]}}";

            Assert.Equal(cancelInstruction, _exchange.SentParameters["cancelOrders"]);
            Assert.Equal(replaceInstruction, _exchange.SentParameters["replaceOrders"]);
        }
コード例 #17
0
        public void LimitOrderTestCase()
        {
            bool isConnected      = false;
            bool newArrived       = false;
            bool executionArrived = false;

            var manualLogonEvent     = new ManualResetEvent(false);
            var manualNewEvent       = new ManualResetEvent(false);
            var manualExecutionEvent = new ManualResetEvent(false);

            LimitOrder limitOrder = new LimitOrder(Constants.OrderExecutionProvider.Simulated);

            limitOrder.OrderID = "AA";

            _orderExecutionProvider.LogonArrived +=
                delegate(string obj)
            {
                isConnected = true;
                Console.WriteLine("Logon Received");
                _orderExecutionProvider.SendLimitOrder(limitOrder);
                manualLogonEvent.Set();
            };

            _orderExecutionProvider.NewArrived +=
                delegate(Order obj)
            {
                newArrived = true;
                Console.WriteLine("New Received");
                manualNewEvent.Set();
            };

            _orderExecutionProvider.ExecutionArrived +=
                delegate(Execution obj)
            {
                executionArrived = true;
                Console.WriteLine("Execution Received");
                manualExecutionEvent.Set();
            };

            _orderExecutionProvider.Start();

            manualLogonEvent.WaitOne(30000, false);
            manualNewEvent.WaitOne(300000, false);
            manualExecutionEvent.WaitOne(300000, false);

            Assert.AreEqual(true, isConnected, "Is Execution Order Provider connected");
            Assert.AreEqual(true, newArrived, "New arrived");
            Assert.AreEqual(true, executionArrived, "Execution arrived");
        }
コード例 #18
0
        /// <summary>
        /// Adds new LimitOrder to list
        /// If validation of order is successful it sends NewArrived Message.
        /// In case of failure it sends sends rejection.
        /// </summary>
        public void NewLimitOrderArrived(LimitOrder limitOrder)
        {
            try
            {
                if (ValidateMarketOrder(limitOrder))
                {
                    var order = new Order(limitOrder.OrderID,
                                          limitOrder.OrderSide,
                                          limitOrder.OrderSize,
                                          limitOrder.OrderTif,
                                          limitOrder.OrderCurrency,
                                          limitOrder.Security,
                                          limitOrder.OrderExecutionProvider);
                    if (Logger.IsInfoEnabled)
                    {
                        Logger.Info("New Arrived :" + order, _type.FullName, "NewLimitOrderArrived");
                    }
                    if (NewArrived != null)
                    {
                        NewArrived.Invoke(order);
                    }

                    // Execute Limit Order
                    ExecuteLimitOrder(limitOrder);

                    //// Add to List
                    //_limitOrders.Add(limitOrder);
                }
                else
                {
                    Rejection rejection = new Rejection(limitOrder.Security, OrderExecutionProvider.SimulatedExchange)
                    {
                        OrderId = limitOrder.OrderID, DateTime = DateTime.Now, RejectioReason = "Invaild Price Or Size"
                    };
                    if (Logger.IsInfoEnabled)
                    {
                        Logger.Info("Rejection :" + rejection, _type.FullName, "NewLimitOrderArrived");
                    }
                    if (LimitOrderRejection != null)
                    {
                        LimitOrderRejection.Invoke(rejection);
                    }
                }
            }
            catch (Exception exception)
            {
                Logger.Error(exception, _type.FullName, "NewLimitOrderArrived");
            }
        }
コード例 #19
0
ファイル: TestBroker.cs プロジェクト: michaelwills/tradelink
        public void Fill_RegularLiquidity()
        {
            Broker       broker    = new Broker();
            const string s         = "SPY";
            OrderImpl    limitBuy  = new LimitOrder(s, true, 1, 133m);
            OrderImpl    limitSell = new LimitOrder(s, false, 2, 133.5m);
            OrderImpl    stopBuy   = new StopOrder(s, true, 3, 135.70m);
            OrderImpl    stopSell  = new StopOrder(s, false, 4, 135.75m);

            broker.SendOrderStatus(limitBuy);
            broker.SendOrderStatus(limitSell);
            broker.SendOrderStatus(stopBuy);
            broker.SendOrderStatus(stopSell);

            // OHLC for 6/21/2012 on SPY
            TickImpl openingTick  = TickImpl.NewTrade(s, Util.ToTLDate(DateTime.Now), Util.TL2FT(9, 30, 00), 135.67m, 10670270, "NYS");
            TickImpl endMornTick  = TickImpl.NewTrade(s, Util.ToTLDate(DateTime.Now), Util.TL2FT(12, 00, 00), 135.78m, 10670270, "NYS");
            TickImpl endLunchTick = TickImpl.NewTrade(s, Util.ToTLDate(DateTime.Now), Util.TL2FT(14, 15, 00), 132.33m, 10670270, "NYS");
            TickImpl closingTick  = TickImpl.NewTrade(s, Util.ToTLDate(DateTime.Now), Util.TL2FT(16, 00, 00), 132.44m, 10670270, "NYS");

            broker.Execute(openingTick);
            broker.Execute(endMornTick);
            broker.Execute(endLunchTick);
            broker.Execute(closingTick);

            List <Trade> trades = broker.GetTradeList();

            Assert.IsTrue(trades.Count == 4);

            foreach (Trade trade in trades)
            {
                if (trade.xsize == 1)
                {
                    Assert.AreEqual(132.33m, trade.xprice);
                }
                else if (trade.xsize == 2)
                {
                    Assert.AreEqual(132.33m, trade.xprice);
                }
                else if (trade.xsize == 3)
                {
                    Assert.AreEqual(135.78m, trade.xprice);
                }
                else if (trade.xsize == 4)
                {
                    Assert.AreEqual(135.78m, trade.xprice);
                }
            }
        }
コード例 #20
0
        private static void MakerOnly_orders_of_same_side_never_match(Side side)
        {
            var quantity            = 1;
            var price               = 10000;
            var secondAndThirdPrice = price + 1;
            var market              = new Market(Currency.BTC, Currency.USD);

            foreach (var exchange in BasicTests.CreateExchangesOfDifferentTypes())
            {
                var orderBook = exchange[market];

                var firstLimitOrder =
                    new LimitOrder(new OrderInfo(Guid.NewGuid(), side, quantity), price);
                SendOrder(exchange, firstLimitOrder, market);

                var secondLimitOrder =
                    new LimitOrder(new OrderInfo(Guid.NewGuid(), side, quantity), secondAndThirdPrice);
                SendOrder(exchange, secondLimitOrder, market);

                var thirdLimitOrder =
                    new LimitOrder(new OrderInfo(Guid.NewGuid(), side, quantity), secondAndThirdPrice);
                SendOrder(exchange, thirdLimitOrder, market);

                var allLimitOrdersSent = new List <LimitOrder> {
                    firstLimitOrder, secondLimitOrder, thirdLimitOrder
                };

                var orderBookAgain = exchange[market];

                Assert.That(orderBookAgain[side.Other()].Count(), Is.EqualTo(0));
                var ourSide           = new List <LimitOrder>();
                var orderBookThisSide = orderBookAgain[side];
                while (true)
                {
                    try
                    {
                        var tip = orderBookThisSide.Tip.Value;
                        ourSide.Add(tip);
                        orderBookThisSide = orderBookThisSide.Tail.Value;
                    }
                    catch
                    {
                        break;
                    }
                }
                LimitOrders.AssertAreSameOrdersRegardlessOfOrder(allLimitOrdersSent,
                                                                 ourSide);
            }
        }
コード例 #21
0
        public void CreateLimitOrder_IfAllParametersAreOk_VerifyLimitOrderIsCreated()
        {
            LimitOrder limitOrder = OrderMessage.GenerateLimitOrder(new Security()
            {
                Symbol = "AAPL"
            }, OrderSide.BUY, 10, 100,
                                                                    OrderExecutionProvider.SimulatedExchange);

            Assert.NotNull(limitOrder);
            Assert.IsNotNullOrEmpty(limitOrder.OrderID);
            Assert.AreEqual(limitOrder.OrderSide, OrderSide.BUY);
            Assert.AreEqual(limitOrder.OrderSize, 10);
            Assert.AreEqual(limitOrder.LimitPrice, 100);
            Assert.AreEqual(limitOrder.OrderExecutionProvider, OrderExecutionProvider.SimulatedExchange);
        }
コード例 #22
0
 /// <summary>
 /// Methord Fired when Limit Order Arrived.
 /// </summary>
 /// <param name="obj"></param>
 private void LimitOrderArrived(LimitOrder obj)
 {
     try
     {
         if (Logger.IsInfoEnabled)
         {
             Logger.Info(obj.ToString(), _type.FullName, "LimitOrderArrived");
         }
         _simulateLimitOrder.NewLimitOrderArrived(obj);
     }
     catch (Exception exception)
     {
         Logger.Error(exception, _type.FullName, "LimitOrderArrived");
     }
 }
コード例 #23
0
        /// <summary>
        /// Creates new Limit Order including unique OrderID
        /// </summary>
        /// <param name="security">Contains symbol info on which to trade</param>
        /// <param name="orderSide">Order side</param>
        /// <param name="orderSize">Size of the given order</param>
        /// <param name="limitPrice">Limit price for the given order</param>
        /// <param name="orderExecutionProvider">Name of the ordeer execution provider</param>
        /// <returns>TradeHub LimitOrder Object</returns>
        public static LimitOrder GenerateLimitOrder(Security security, string orderSide, int orderSize, decimal limitPrice, string orderExecutionProvider)
        {
            ValidateBasicOrderParameters(security, orderSide, orderSize, orderExecutionProvider);
            ValidateLimitOrderPrice(limitPrice);
            LimitOrder limitOrder = new LimitOrder(orderExecutionProvider)
            {
                OrderID    = Guid.NewGuid().ToString(),
                Security   = security,
                OrderSize  = orderSize,
                OrderSide  = orderSide,
                LimitPrice = limitPrice
            };

            return(limitOrder);
        }
コード例 #24
0
        public async Task BelowMinimumLimitOrdersArePlacedWithReference(string marketId, long selectionId, Side side, double size, double price, string reference)
        {
            var limitOrder = new LimitOrder(selectionId, side, price, size);
            await _orderService.Place(marketId, new List <LimitOrder> {
                limitOrder
            }, reference);

            var placeInstruction   = $"{{\"marketId\":\"{marketId}\",\"customerStrategyRef\":\"{reference}\",\"instructions\":[{limitOrder.ToInstruction()}]}}";
            var cancelInstruction  = $"{{\"marketId\":\"{marketId}\",\"instructions\":[{limitOrder.ToBelowMinimumCancelInstruction()}]}}";
            var replaceInstruction = $"{{\"marketId\":\"{marketId}\",\"customerStrategyRef\":\"{reference}\",\"instructions\":[{limitOrder.ToBelowMinimumReplaceInstruction()}]}}";

            Assert.Equal(placeInstruction, _exchange.SentParameters["placeOrders"]);
            Assert.Equal(cancelInstruction, _exchange.SentParameters["cancelOrders"]);
            Assert.Equal(replaceInstruction, _exchange.SentParameters["replaceOrders"]);
        }
コード例 #25
0
        public async Task DoNotPlaceOrdersOfZeroSize()
        {
            var validOrder = new LimitOrder(1, Side.Lay, 2.5, 9.99);
            var orders     = new List <LimitOrder>
            {
                validOrder,
                new LimitOrder(2, Side.Back, 2.5, 0),
            };

            await _orderService.Place("1.2345", orders);

            var expected = $"{{\"marketId\":\"1.2345\",\"instructions\":[{validOrder.ToInstruction()}]}}";

            Assert.Equal(expected, _exchange.SentParameters["placeOrders"]);
        }
コード例 #26
0
        /// <summary>
        /// Sends Limit Order on the given Order Execution Provider
        /// </summary>
        /// <param name="limitOrder">TradeHub LimitOrder</param>
        public void SendLimitOrder(LimitOrder limitOrder)
        {
            try
            {
                if (Logger.IsInfoEnabled)
                {
                    Logger.Info("Sending Limit Order on Blackwood." + limitOrder, _type.FullName, "SendLimitOrder");
                }

                OrderSide tempSide    = BlackwoodTypeConvertor.OrderSideConvertor.GetBlackwoodOrderSide(limitOrder.OrderSide);
                TIMEOUT   tempTimeout = BlackwoodTypeConvertor.OrderTifConvertor.GetBlackwoodOrderTif(limitOrder.OrderTif);

                if (tempSide.Equals(ORDER_SIDE.NONE))
                {
                    Logger.Info("Invalid Order Side", _type.FullName, "SendLimitOrder");
                    return;
                }

                // NOTE: FFED_ID is fixed to ARCA according to StockTrader code
                // Create Blackwood Order
                //BWOrder bwOrder = new BWOrder(_session, limitOrder.Security.Symbol, tempSide,
                //                              (uint)limitOrder.OrderSize, (double)limitOrder.LimitPrice, 0,
                //                              ORDER_TYPE.LIMIT, (int)tempTimeout, FEED_ID.ARCA, false,
                //                              (uint)limitOrder.OrderSize);
                BWOrder bwOrder = new BWOrder(_session, limitOrder.Security.Symbol, tempSide,
                                              (uint)limitOrder.OrderSize, (double)limitOrder.LimitPrice, 0, OrderType.LIMIT, (int)tempTimeout,
                                              FeedId.ARCA, false, (uint)limitOrder.OrderSize);

                // Send Order to gateway
                bwOrder.Send();

                // Update Local IDs Map
                _localToBlackwoodIdsMap.TryAdd(limitOrder.OrderID, bwOrder.ClientOrderID.ToString());

                // Update BW-Orders Map
                _bwOrders.TryAdd(bwOrder.ClientOrderID.ToString(), bwOrder);

                if (Logger.IsDebugEnabled)
                {
                    Logger.Debug("BW-Order ID: " + bwOrder.OrderID + " | BW-ClientOrder ID: " + bwOrder.ClientOrderID,
                                 _type.FullName, "SendLimitOrder");
                }
            }
            catch (Exception exception)
            {
                Logger.Error(exception, _type.FullName, "SendLimitOrder");
            }
        }
コード例 #27
0
ファイル: OrderBookTests.cs プロジェクト: dirkju/MemExchange
        public void BookShouldRemoveSlotWhenOrderIsFilled()
        {
            var orderBookBestBidAsk = new OrderBookBestBidAsk("ABC");
            var book = new OrderBook("ABC", limitOrderMatchingAlgorithmMock.Object, marketOrderMatchingAlgorithmMock.Object, orderBookBestBidAsk);

            var buyOrder = new LimitOrder("ABC", 10, 90, WayEnum.Buy, 9);

            book.AddLimitOrder(buyOrder);

            Assert.IsTrue(book.PriceSlots.ContainsKey(90));
            Assert.AreEqual(buyOrder, book.PriceSlots[90].BuyOrders[0]);

            buyOrder.Modify(0);

            Assert.IsFalse(book.PriceSlots.ContainsKey(90));
        }
コード例 #28
0
        public void DeserializesLimitOrder(Symbols.SymbolsKey key)
        {
            var expected = new LimitOrder(Symbols.Lookup(key), 100, 210.10m, new DateTime(2015, 11, 23, 17, 15, 37), "now")
            {
                Id           = 12345,
                Price        = 209.03m,
                ContingentId = 123456,
                BrokerId     = new List <string> {
                    "727", "54970"
                }
            };

            var actual = TestOrderType(expected);

            Assert.AreEqual(expected.LimitPrice, actual.LimitPrice);
        }
コード例 #29
0
        public void ShouldRegisterModifyEventHandlerAndReceiveModifyEvent()
        {
            var newOrder = new LimitOrder("ABC", 10, 99.22d, WayEnum.Buy, 3);

            newOrder.RegisterModifyNotificationHandler((order, oldQuantity, oldPrice) =>
            {
                Assert.AreEqual(newOrder, order);
                Assert.AreEqual(11, order.Quantity);
                Assert.AreEqual(88.44d, order.Price);

                Assert.AreEqual(10, oldQuantity);
                Assert.AreEqual(99.22d, oldPrice);
            });

            newOrder.Modify(11, 88.44d);
        }
コード例 #30
0
        public void LimitBuyOrderIncludesFees()
        {
            _portfolio.SetCash(20000);
            _btcusd.FeeModel = new ConstantFeeModel(50);

            // Available cash = 20000, cannot buy 2 BTC at 10000 because of order fee
            var order = new LimitOrder(_btcusd.Symbol, 2m, 10000m, DateTime.UtcNow);

            Assert.IsFalse(_buyingPowerModel.HasSufficientBuyingPowerForOrder(_portfolio, _btcusd, order));

            // deposit another 50 USD
            _portfolio.CashBook["USD"].AddAmount(50);

            // now the order is allowed
            Assert.IsTrue(_buyingPowerModel.HasSufficientBuyingPowerForOrder(_portfolio, _btcusd, order));
        }
コード例 #31
0
ファイル: Strategy.cs プロジェクト: houzhongxu/OpenQuant.API
		public Order SellLimitOrder(double qty, double limitPrice, string text)
		{
			SingleOrder singleOrder = new LimitOrder(this.sq_Instrument, Side.Sell, qty, limitPrice, text);
			singleOrder.Strategy = this.strategyName;
			Order order = new Order(singleOrder);
			order.Portfolio = this.portfolio;
			Map.OQ_SQ_Order[order] = singleOrder;
			Map.SQ_OQ_Order[singleOrder] = order;
			return order;
		}
コード例 #32
0
ファイル: Strategy.cs プロジェクト: houzhongxu/OpenQuant.API
		public Order LimitOrder(Instrument instrument, OrderSide side, double qty, double limitPrice, string text)
		{
			SingleOrder singleOrder;
			if (side == OrderSide.Buy)
			{
				singleOrder = new LimitOrder(instrument.instrument, Side.Buy, qty, limitPrice, text);
			}
			else
			{
				singleOrder = new LimitOrder(instrument.instrument, Side.Sell, qty, limitPrice, text);
			}
			singleOrder.Strategy = this.strategyName;
			Order order = new Order(singleOrder);
			order.Portfolio = this.portfolio;
			Map.OQ_SQ_Order[order] = singleOrder;
			Map.SQ_OQ_Order[singleOrder] = order;
			return order;
		}
コード例 #33
0
        /// <summary>
        /// Default limit order fill model in the base security class.
        /// </summary>
        /// <param name="asset">Security asset we're filling</param>
        /// <param name="order">Order packet to model</param>
        /// <returns>Order fill information detailing the average price and quantity filled.</returns>
        /// <seealso cref="StopMarketFill(Security, StopMarketOrder)"/>
        /// <seealso cref="MarketFill(Security, MarketOrder)"/>
        public virtual OrderEvent LimitFill(Security asset, LimitOrder order)
        {
            //Initialise;
            var utcTime = asset.LocalTime.ConvertToUtc(asset.Exchange.TimeZone);
            var fill = new OrderEvent(order, utcTime, 0);

            //If its cancelled don't need anymore checks:
            if (order.Status == OrderStatus.Canceled) return fill;

            //Get the range of prices in the last bar:
            decimal minimumPrice;
            decimal maximumPrice;
            DataMinMaxPrices(asset, out minimumPrice, out maximumPrice, order.Direction);

            //-> Valid Live/Model Order: 
            switch (order.Direction)
            {
                case OrderDirection.Buy:
                    //Buy limit seeks lowest price
                    if (minimumPrice < order.LimitPrice)
                    {
                        //Set order fill:
                        fill.Status = OrderStatus.Filled;
                        // fill at the worse price this bar or the limit price, this allows far out of the money limits
                        // to be executed properly
                        fill.FillPrice = Math.Min(maximumPrice, order.LimitPrice);
                    }
                    break;
                case OrderDirection.Sell:
                    //Sell limit seeks highest price possible
                    if (maximumPrice > order.LimitPrice)
                    {
                        fill.Status = OrderStatus.Filled;
                        // fill at the worse price this bar or the limit price, this allows far out of the money limits
                        // to be executed properly
                        fill.FillPrice = Math.Max(minimumPrice, order.LimitPrice);
                    }
                    break;
            }

            // assume the order completely filled
            if (fill.Status == OrderStatus.Filled)
            {
                fill.FillQuantity = order.Quantity;
                fill.OrderFee = asset.FeeModel.GetOrderFee(asset, order);
            }

            return fill;
        }