예제 #1
0
        /// <summary>
        /// This is used to ensure each test starts with a clean, known state.
        /// </summary>
        protected void LiquidateHoldings()
        {
            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, (int)-holding.Quantity, DateTime.Now, type: holding.Type);
                _orderMapping.Add(order);
                PlaceOrderWaitForStatus(order, OrderStatus.Filled);
            }
        }
예제 #2
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="IOrderMapping"/> 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>
        /// <returns>The same order that was submitted.</returns>
        protected Order PlaceOrderWaitForStatus(Order order, OrderStatus expectedStatus = OrderStatus.Filled, double secondsTimeout = 10.0)
        {
            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;

            OrderMapping.Add(order);
            if (!Brokerage.PlaceOrder(order))
            {
                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.");

            Brokerage.OrderStatusChanged -= brokerageOnOrderStatusChanged;

            return(order);
        }
예제 #3
0
        private IBrokerage InitializeBrokerage()
        {
            Log.Trace("");
            Log.Trace("- INITIALIZING BROKERAGE -");
            Log.Trace("");

            var brokerage = CreateBrokerage(OrderMapping, HoldingsProvider);

            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())
            {
                OrderMapping.Add(openOrder);
            }

            Log.Trace("");
            Log.Trace("GET ACCOUNT HOLDINGS");
            Log.Trace("");
            foreach (var accountHolding in brokerage.GetAccountHoldings())
            {
                HoldingsProvider[accountHolding.Symbol] = accountHolding;
            }
            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);

                    Holding holding;
                    if (_holdingsProvider.TryGetValue(args.Symbol, out holding))
                    {
                        _holdingsProvider[args.Symbol].Quantity += args.FillQuantity;
                    }
                    else
                    {
                        var accountHoldings = brokerage.GetAccountHoldings().ToDictionary(x => x.Symbol);
                        if (accountHoldings.ContainsKey(args.Symbol))
                        {
                            _holdingsProvider[args.Symbol] = accountHoldings[args.Symbol];
                        }
                        else
                        {
                            _holdingsProvider[args.Symbol] = new Holding {
                                Symbol = args.Symbol
                            };
                        }
                    }

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

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