Ejemplo n.º 1
0
        public void ValidateLimitOrders()
        {
            var orderEventTracker = new ConcurrentBag <OrderEvent>();
            var alpaca            = (AlpacaBrokerage)Brokerage;
            var symbol            = Symbol;
            var lastPrice         = GetLastPrice(symbol.Value);
            EventHandler <OrderEvent> orderStatusChangedCallback = (s, e) =>
            {
                orderEventTracker.Add(e);
            };

            alpaca.OrderStatusChanged += orderStatusChangedCallback;

            // Buy Limit order above market - should be filled immediately
            var limitPrice = lastPrice + 0.5m;
            var order      = new LimitOrder(symbol, 1, limitPrice, DateTime.UtcNow);

            OrderProvider.Add(order);
            Assert.IsTrue(alpaca.PlaceOrder(order));

            Thread.Sleep(10000);

            alpaca.OrderStatusChanged -= orderStatusChangedCallback;
            Assert.AreEqual(orderEventTracker.Count(x => x.Status == OrderStatus.Submitted), 1);
            Assert.AreEqual(orderEventTracker.Count(x => x.Status == OrderStatus.Filled), 1);
        }
Ejemplo n.º 2
0
        public void ValidateMarketOrders()
        {
            var orderEventTracker = new ConcurrentBag <OrderEvent>();
            var oanda             = (OandaBrokerage)Brokerage;
            var symbol            = Symbol;
            EventHandler <OrderEvent> orderStatusChangedCallback = (s, e) => {
                orderEventTracker.Add(e);
            };

            oanda.OrderStatusChanged += orderStatusChangedCallback;
            const int numberOfOrders = 100;

            Parallel.For(0, numberOfOrders, (i) =>
            {
                var order = new MarketOrder(symbol, 100, DateTime.Now);
                OrderProvider.Add(order);
                Assert.IsTrue(oanda.PlaceOrder(order));
                Assert.IsTrue(order.Status == OrderStatus.Filled || order.Status == OrderStatus.PartiallyFilled);
                var orderr = new MarketOrder(symbol, -100, DateTime.UtcNow);
                OrderProvider.Add(orderr);
                Assert.IsTrue(oanda.PlaceOrder(orderr));
                Assert.IsTrue(orderr.Status == OrderStatus.Filled || orderr.Status == OrderStatus.PartiallyFilled);
            });
            // We want to verify the number of order events with OrderStatus.Filled sent
            Thread.Sleep(4000);
            oanda.OrderStatusChanged -= orderStatusChangedCallback;
            Assert.AreEqual(orderEventTracker.Count(x => x.Status == OrderStatus.Submitted), numberOfOrders * 2);
            Assert.AreEqual(orderEventTracker.Count(x => x.Status == OrderStatus.Filled), numberOfOrders * 2);
        }
Ejemplo n.º 3
0
        public void ValidateMarketOrders()
        {
            var orderEventTracker = new ConcurrentBag <OrderEvent>();
            var alpaca            = (AlpacaBrokerage)Brokerage;
            var symbol            = Symbol;
            EventHandler <OrderEvent> orderStatusChangedCallback = (s, e) =>
            {
                orderEventTracker.Add(e);
            };

            alpaca.OrderStatusChanged += orderStatusChangedCallback;
            const int numberOfOrders = 2;

            for (var i = 0; i < numberOfOrders; i++)
            {
                var order = new MarketOrder(symbol, 10, DateTime.UtcNow);
                OrderProvider.Add(order);
                Console.WriteLine("Buy Order");
                alpaca.PlaceOrder(order);

                var orderr = new MarketOrder(symbol, -10, DateTime.UtcNow);
                OrderProvider.Add(orderr);
                Console.WriteLine("Sell Order");
                alpaca.PlaceOrder(orderr);
            }

            // We want to verify the number of order events with OrderStatus.Filled sent
            Thread.Sleep(14000);
            alpaca.OrderStatusChanged -= orderStatusChangedCallback;
            Assert.AreEqual(orderEventTracker.Count(x => x.Status == OrderStatus.Submitted), numberOfOrders * 2);
            Assert.AreEqual(orderEventTracker.Count(x => x.Status == OrderStatus.Filled), numberOfOrders * 2);
        }
Ejemplo n.º 4
0
        public void ValidateLimitOrders()
        {
            var orderEventTracker = new ConcurrentBag <OrderEvent>();
            var oanda             = (OandaBrokerage)Brokerage;
            var symbol            = Symbol;
            var quote             = oanda.GetRates(new OandaSymbolMapper().GetBrokerageSymbol(symbol));
            EventHandler <OrderEvent> orderStatusChangedCallback = (s, e) => {
                orderEventTracker.Add(e);
            };

            oanda.OrderStatusChanged += orderStatusChangedCallback;

            // Buy Limit order below market
            var limitPrice = quote.BidPrice - 0.5m;
            var order      = new LimitOrder(symbol, 1, limitPrice, DateTime.Now);

            OrderProvider.Add(order);
            Assert.IsTrue(oanda.PlaceOrder(order));

            // update Buy Limit order with no changes
            Assert.IsTrue(oanda.UpdateOrder(order));

            // move Buy Limit order above market
            order.LimitPrice = quote.AskPrice + 0.5m;
            Assert.IsTrue(oanda.UpdateOrder(order));
            oanda.OrderStatusChanged -= orderStatusChangedCallback;
            Assert.AreEqual(orderEventTracker.Count(x => x.Status == OrderStatus.Submitted), 1);
            Assert.AreEqual(orderEventTracker.Count(x => x.Status == OrderStatus.Filled), 1);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Places the specified order with the brokerage and wait until we get the <paramref name="expectedStatus"/> back via an OrderStatusChanged event.
        /// This function handles adding the order to the <see cref="IOrderProvider"/> instance as well as incrementing the order ID.
        /// </summary>
        /// <param name="order">The order to be submitted</param>
        /// <param name="expectedStatus">The status to wait for</param>
        /// <param name="secondsTimeout">Maximum amount of time to wait for <paramref name="expectedStatus"/></param>
        /// <param name="allowFailedSubmission">Allow failed order submission</param>
        /// <returns>The same order that was submitted.</returns>
        protected Order PlaceZerodhaOrderWaitForStatus(Order order, OrderStatus expectedStatus = OrderStatus.Filled,
                                                       double secondsTimeout = 10.0, bool allowFailedSubmission = false)
        {
            var requiredStatusEvent = new ManualResetEvent(false);
            var desiredStatusEvent  = new ManualResetEvent(false);
            EventHandler <OrderEvent> brokerageOnOrderStatusChanged = (sender, args) =>
            {
                // no matter what, every order should fire at least one of these
                if (args.Status == OrderStatus.Submitted || args.Status == OrderStatus.Invalid)
                {
                    Log.Trace("");
                    Log.Trace("SUBMITTED: " + args);
                    Log.Trace("");
                    requiredStatusEvent.Set();
                }
                // make sure we fire the status we're expecting
                if (args.Status == expectedStatus)
                {
                    Log.Trace("");
                    Log.Trace("EXPECTED: " + args);
                    Log.Trace("");
                    desiredStatusEvent.Set();
                }
            };

            Brokerage.OrderStatusChanged += brokerageOnOrderStatusChanged;

            OrderProvider.Add(order);
            if (!Brokerage.PlaceOrder(order) && !allowFailedSubmission)
            {
                Assert.Fail("Brokerage failed to place the order: " + order);
            }


            requiredStatusEvent.WaitOneAssertFail((int)(1000 * secondsTimeout), "Expected every order to fire a submitted or invalid status event");
            desiredStatusEvent.WaitOneAssertFail((int)(1000 * secondsTimeout), "OrderStatus " + expectedStatus + " was not encountered within the timeout. Order Id:" + order.Id);


            Brokerage.OrderStatusChanged -= brokerageOnOrderStatusChanged;

            return(order);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// This is used to ensure each test starts with a clean, known state.
        /// </summary>
        protected void LiquidateZerodhaHoldings()
        {
            Log.Trace("");
            Log.Trace("LIQUIDATE HOLDINGS");
            Log.Trace("");

            var holdings = Brokerage.GetAccountHoldings();

            foreach (var holding in holdings)
            {
                if (holding.Quantity == 0)
                {
                    continue;
                }
                Log.Trace("Liquidating: " + holding);
                var order = new MarketOrder(holding.Symbol, -holding.Quantity, DateTime.UtcNow, properties: orderProperties);
                _orderProvider.Add(order);
                PlaceZerodhaOrderWaitForStatus(order, OrderStatus.Filled);
            }
        }
Ejemplo n.º 7
0
        public void PartialFills()
        {
            var manualResetEvent = new ManualResetEvent(false);

            var qty       = 1000000m;
            var remaining = qty;
            var sync      = new object();

            Brokerage.OrderStatusChanged += (sender, orderEvent) =>
            {
                lock (sync)
                {
                    remaining -= orderEvent.FillQuantity;
                    Console.WriteLine("Remaining: " + remaining + " FillQuantity: " + orderEvent.FillQuantity);
                    if (orderEvent.Status == OrderStatus.Filled)
                    {
                        manualResetEvent.Set();
                    }
                }
            };

            // pick a security with low, but some, volume
            var symbol = Symbols.EURUSD;
            var order  = new MarketOrder(symbol, qty, DateTime.UtcNow)
            {
                Id = 1
            };

            OrderProvider.Add(order);
            Brokerage.PlaceOrder(order);

            // pause for a while to wait for fills to come in
            manualResetEvent.WaitOne(2500);
            manualResetEvent.WaitOne(2500);
            manualResetEvent.WaitOne(2500);

            Console.WriteLine("Remaining: " + remaining);
            Assert.AreEqual(0, remaining);
        }
Ejemplo n.º 8
0
        private IBrokerage InitializeBrokerage()
        {
            Log.Trace("");
            Log.Trace("- INITIALIZING BROKERAGE -");
            Log.Trace("");

            var brokerage = CreateBrokerage(OrderProvider, SecurityProvider);

            brokerage.Connect();

            if (!brokerage.IsConnected)
            {
                Assert.Fail("Failed to connect to brokerage");
            }

            Log.Trace("");
            Log.Trace("GET OPEN ORDERS");
            Log.Trace("");
            foreach (var openOrder in brokerage.GetOpenOrders())
            {
                OrderProvider.Add(openOrder);
            }

            Log.Trace("");
            Log.Trace("GET ACCOUNT HOLDINGS");
            Log.Trace("");
            foreach (var accountHolding in brokerage.GetAccountHoldings())
            {
                // these securities don't need to be real, just used for the ISecurityProvider impl, required
                // by brokerages to track holdings
                SecurityProvider[accountHolding.Symbol] = CreateSecurity(accountHolding.Symbol);
            }
            brokerage.OrderStatusChanged += (sender, args) =>
            {
                Log.Trace("");
                Log.Trace("ORDER STATUS CHANGED: " + args);
                Log.Trace("");

                // we need to keep this maintained properly
                if (args.Status == OrderStatus.Filled || args.Status == OrderStatus.PartiallyFilled)
                {
                    Log.Trace("FILL EVENT: " + args.FillQuantity + " units of " + args.Symbol.ToString());

                    Security security;
                    if (_securityProvider.TryGetValue(args.Symbol, out security))
                    {
                        var holding = _securityProvider[args.Symbol].Holdings;
                        holding.SetHoldings(args.FillPrice, holding.Quantity + args.FillQuantity);
                    }
                    else
                    {
                        _securityProvider[args.Symbol] = CreateSecurity(args.Symbol);
                        _securityProvider[args.Symbol].Holdings.SetHoldings(args.FillPrice, args.FillQuantity);
                    }

                    Log.Trace("--HOLDINGS: " + _securityProvider[args.Symbol]);

                    // update order mapping
                    var order = _orderProvider.GetOrderById(args.OrderId);
                    order.Status = args.Status;
                }
            };
            return(brokerage);
        }