Exemplo n.º 1
0
        /// <summary>
        /// Creates a deep-copy clone of this order
        /// </summary>
        /// <returns>A copy of this order</returns>
        public override Order Clone()
        {
            var order = new StopLimitOrder {
                StopPrice = StopPrice, LimitPrice = LimitPrice
            };

            CopyTo(order);
            return(order);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates an order of the correct type
        /// </summary>
        private static Order CreateOrder(OrderType orderType, JObject jObject)
        {
            Order order;

            switch (orderType)
            {
            case OrderType.Market:
                order = new MarketOrder();
                break;

            case OrderType.Limit:
                order = new LimitOrder {
                    LimitPrice = jObject["LimitPrice"] == null ? default(decimal) : jObject["LimitPrice"].Value <decimal>()
                };
                break;

            case OrderType.StopMarket:
                order = new StopMarketOrder
                {
                    StopPrice = jObject["StopPrice"] == null ? default(decimal) : jObject["StopPrice"].Value <decimal>()
                };
                break;

            case OrderType.StopLimit:
                order = new StopLimitOrder
                {
                    LimitPrice = jObject["LimitPrice"] == null ? default(decimal) : jObject["LimitPrice"].Value <decimal>(),
                    StopPrice  = jObject["StopPrice"] == null ? default(decimal) : jObject["StopPrice"].Value <decimal>()
                };
                break;

            case OrderType.LimitIfTouched:
                order = new LimitIfTouchedOrder
                {
                    LimitPrice   = jObject["LimitPrice"] == null ? default(decimal) : jObject["LimitPrice"].Value <decimal>(),
                    TriggerPrice = jObject["TriggerPrice"] == null ? default(decimal) : jObject["TriggerPrice"].Value <decimal>()
                };
                break;

            case OrderType.MarketOnOpen:
                order = new MarketOnOpenOrder();
                break;

            case OrderType.MarketOnClose:
                order = new MarketOnCloseOrder();
                break;

            case OrderType.OptionExercise:
                order = new OptionExerciseOrder();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            return(order);
        }
Exemplo n.º 3
0
        private static Order CreateOrder(int orderId, OrderType type, Symbol symbol, decimal quantity, DateTime time,
                                         string tag, IOrderProperties properties, decimal limitPrice, decimal stopPrice, decimal triggerPrice)
        {
            Order order;

            switch (type)
            {
            case OrderType.Market:
                order = new MarketOrder(symbol, quantity, time, tag, properties);
                break;

            case OrderType.Limit:
                order = new LimitOrder(symbol, quantity, limitPrice, time, tag, properties);
                break;

            case OrderType.StopMarket:
                order = new StopMarketOrder(symbol, quantity, stopPrice, time, tag, properties);
                break;

            case OrderType.StopLimit:
                order = new StopLimitOrder(symbol, quantity, stopPrice, limitPrice, time, tag, properties);
                break;

            case OrderType.LimitIfTouched:
                order = new LimitIfTouchedOrder(symbol, quantity, triggerPrice, limitPrice, time, tag, properties);
                break;

            case OrderType.MarketOnOpen:
                order = new MarketOnOpenOrder(symbol, quantity, time, tag, properties);
                break;

            case OrderType.MarketOnClose:
                order = new MarketOnCloseOrder(symbol, quantity, time, tag, properties);
                break;

            case OrderType.OptionExercise:
                order = new OptionExerciseOrder(symbol, quantity, time, tag, properties);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            order.Status = OrderStatus.New;
            order.Id     = orderId;
            return(order);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Creates an <see cref="Order"/> to match the specified <paramref name="request"/>
        /// </summary>
        /// <param name="request">The <see cref="SubmitOrderRequest"/> to create an order for</param>
        /// <returns>The <see cref="Order"/> that matches the request</returns>
        public static Order CreateOrder(SubmitOrderRequest request)
        {
            Order order;

            switch (request.OrderType)
            {
            case OrderType.Market:
                order = new MarketOrder(request.Symbol, request.Quantity, request.Time, request.Tag, request.OrderProperties);
                break;

            case OrderType.Limit:
                order = new LimitOrder(request.Symbol, request.Quantity, request.LimitPrice, request.Time, request.Tag, request.OrderProperties);
                break;

            case OrderType.StopMarket:
                order = new StopMarketOrder(request.Symbol, request.Quantity, request.StopPrice, request.Time, request.Tag, request.OrderProperties);
                break;

            case OrderType.StopLimit:
                order = new StopLimitOrder(request.Symbol, request.Quantity, request.StopPrice, request.LimitPrice, request.Time, request.Tag, request.OrderProperties);
                break;

            case OrderType.MarketOnOpen:
                order = new MarketOnOpenOrder(request.Symbol, request.Quantity, request.Time, request.Tag, request.OrderProperties);
                break;

            case OrderType.MarketOnClose:
                order = new MarketOnCloseOrder(request.Symbol, request.Quantity, request.Time, request.Tag, request.OrderProperties);
                break;

            case OrderType.OptionExercise:
                order = new OptionExerciseOrder(request.Symbol, request.Quantity, request.Time, request.Tag, request.OrderProperties);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            order.Status = OrderStatus.New;
            order.Id     = request.OrderId;
            if (request.Tag != null)
            {
                order.Tag = request.Tag;
            }
            return(order);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Creates an <see cref="Order"/> to match the specified <paramref name="request"/>
 /// </summary>
 /// <param name="request">The <see cref="SubmitOrderRequest"/> to create an order for</param>
 /// <returns>The <see cref="Order"/> that matches the request</returns>
 public static Order CreateOrder(SubmitOrderRequest request)
 {
     Order order;
     switch (request.OrderType)
     {
         case OrderType.Market:
             order =  new MarketOrder(request.Symbol, request.Quantity, request.Time, request.Tag, request.SecurityType);
             break;
         case OrderType.Limit:
             order =  new LimitOrder(request.Symbol, request.Quantity, request.LimitPrice, request.Time, request.Tag, request.SecurityType);
             break;
         case OrderType.StopMarket:
             order =  new StopMarketOrder(request.Symbol, request.Quantity, request.StopPrice, request.Time, request.Tag, request.SecurityType);
             break;
         case OrderType.StopLimit:
             order =  new StopLimitOrder(request.Symbol, request.Quantity, request.StopPrice, request.LimitPrice, request.Time, request.Tag, request.SecurityType);
             break;
         case OrderType.MarketOnOpen:
             order =  new MarketOnOpenOrder(request.Symbol, request.SecurityType, request.Quantity, request.Time, request.Tag);
             break;
         case OrderType.MarketOnClose:
             order =  new MarketOnCloseOrder(request.Symbol, request.SecurityType, request.Quantity, request.Time, request.Tag);
             break;
         default:
             throw new ArgumentOutOfRangeException();
     }
     order.Status = OrderStatus.New;
     order.Id = request.OrderId;
     if (request.Tag != null)
     {
         order.Tag = request.Tag;
     }
     return order;
 }
Exemplo n.º 6
0
        public void PerformsStopLimitFillSell()
        {
            var model = new ForexTransactionModel();
            var security = CreateSecurity();
            var order = new StopLimitOrder(Symbol, -100, 101.75m, 101.50m, DateTime.Now, type: SecurityType.Forex);
            security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork));
            security.SetMarketPrice(new IndicatorDataPoint(Symbol, DateTime.Now, 102m));

            var fill = model.StopLimitFill(security, order);

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

            security.SetMarketPrice(new IndicatorDataPoint(Symbol, DateTime.Now, 101m));

            fill = model.StopLimitFill(security, order);

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

            security.SetMarketPrice(new IndicatorDataPoint(Symbol, DateTime.Now, 101.66m));

            fill = model.StopLimitFill(security, order);

            // this fills worst case scenario, so it's at the limit price
            Assert.AreEqual(order.Quantity, fill.FillQuantity);
            Assert.AreEqual(order.LimitPrice, fill.FillPrice);
            Assert.AreEqual(OrderStatus.Filled, fill.Status);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Creates an order of the correct type
        /// </summary>
        private static Order CreateOrder(OrderType orderType, JObject jObject)
        {
            Order order;
            switch (orderType)
            {
                case OrderType.Market:
                    order = new MarketOrder();
                    break;

                case OrderType.Limit:
                    order = new LimitOrder {LimitPrice = jObject["LimitPrice"].Value<decimal>()};
                    break;

                case OrderType.StopMarket:
                    order = new StopMarketOrder
                    {
                        StopPrice = jObject["StopPrice"].Value<decimal>()
                    };
                    break;

                case OrderType.StopLimit:
                    order = new StopLimitOrder
                    {
                        LimitPrice = jObject["LimitPrice"].Value<decimal>(),
                        StopPrice = jObject["StopPrice"].Value<decimal>()
                    };
                    break;

                case OrderType.MarketOnOpen:
                    order = new MarketOnOpenOrder();
                    break;

                case OrderType.MarketOnClose:
                    order = new MarketOnCloseOrder();
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
            }
            return order;
        }
        public void PerformsStopLimitFillSell()
        {
            var model = new SecurityTransactionModel();
            var order = new StopLimitOrder(Symbol, -100, 101.75m, 101.50m, Noon, type: SecurityType.Equity);
            var config = CreateTradeBarConfig(Symbol);
            var security = new Security(SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, 1);
            security.SetMarketPrice(Noon, new IndicatorDataPoint(Symbol, Noon, 102m));

            var fill = model.StopLimitFill(security, order);

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

            security.SetMarketPrice(Noon, new IndicatorDataPoint(Symbol, Noon, 101m));

            fill = model.StopLimitFill(security, order);

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

            security.SetMarketPrice(Noon, new IndicatorDataPoint(Symbol, Noon, 101.66m));

            fill = model.StopLimitFill(security, order);

            // this fills worst case scenario, so it's at the limit price
            Assert.AreEqual(order.Quantity, fill.FillQuantity);
            Assert.AreEqual(order.LimitPrice, fill.FillPrice);
            Assert.AreEqual(OrderStatus.Filled, fill.Status);
            Assert.AreEqual(OrderStatus.Filled, order.Status);
        }
Exemplo n.º 9
0
        public void ValidateStopLimitOrders()
        {
            var oanda = (OandaBrokerage) Brokerage;
            var symbol = Symbol;
            var quotes = oanda.GetRates(new List<string> {new OandaSymbolMapper().GetBrokerageSymbol(symbol)});

            // Buy StopLimit order below market (Oanda accepts this order but cancels it immediately)
            var stopPrice = Convert.ToDecimal(quotes[0].bid - 0.5);
            var limitPrice = stopPrice + 0.0005m;
            var order = new StopLimitOrder(symbol, 1, stopPrice, limitPrice, DateTime.Now);
            Assert.IsTrue(oanda.PlaceOrder(order));

            // Buy StopLimit order above market
            stopPrice = Convert.ToDecimal(quotes[0].ask + 0.5);
            limitPrice = stopPrice + 0.0005m;
            order = new StopLimitOrder(symbol, 1, stopPrice, limitPrice, DateTime.Now);
            Assert.IsTrue(oanda.PlaceOrder(order));

            // Sell StopLimit order below market
            stopPrice = Convert.ToDecimal(quotes[0].bid - 0.5);
            limitPrice = stopPrice - 0.0005m;
            order = new StopLimitOrder(symbol, -1, stopPrice, limitPrice, DateTime.Now);
            Assert.IsTrue(oanda.PlaceOrder(order));

            // Sell StopLimit order above market (Oanda accepts this order but cancels it immediately)
            stopPrice = Convert.ToDecimal(quotes[0].ask + 0.5);
            limitPrice = stopPrice - 0.0005m;
            order = new StopLimitOrder(symbol, -1, stopPrice, limitPrice, DateTime.Now);
            Assert.IsTrue(oanda.PlaceOrder(order));
        }
        public void PerformsStopLimitFillSell()
        {
            var model = new SecurityTransactionModel();
            var order = new StopLimitOrder(Symbols.SPY, -100, 101.75m, 101.50m, Noon);
            var config = CreateTradeBarConfig(Symbols.SPY);
            var security = new Security(SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency));
            security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork));
            security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 102m));

            var fill = model.StopLimitFill(security, order);

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

            security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 101m));

            fill = model.StopLimitFill(security, order);

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

            security.SetMarketPrice(new IndicatorDataPoint(Symbols.SPY, Noon, 101.66m));

            fill = model.StopLimitFill(security, order);

            // this fills worst case scenario, so it's at the limit price
            Assert.AreEqual(order.Quantity, fill.FillQuantity);
            Assert.AreEqual(order.LimitPrice, fill.FillPrice);
            Assert.AreEqual(OrderStatus.Filled, fill.Status);
        }
Exemplo n.º 11
0
        public void PerformsStopLimitFillSell()
        {
            var model = new SecurityTransactionModel();
            var order = new StopLimitOrder(Symbol, -100, 101.75m, 101.50m, DateTime.Now, type: SecurityType.Equity);
            var config = new SubscriptionDataConfig(typeof(TradeBar), SecurityType.Equity, Symbol, Resolution.Minute, true, true, true, true, false, 0);
            var security = new Security(config, 1);
            security.SetMarketPrice(DateTime.Now, new IndicatorDataPoint(Symbol, DateTime.Now, 102m));

            var fill = model.StopLimitFill(security, order);

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

            security.SetMarketPrice(DateTime.Now, new IndicatorDataPoint(Symbol, DateTime.Now, 101m));

            fill = model.StopLimitFill(security, order);

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

            security.SetMarketPrice(DateTime.Now, new IndicatorDataPoint(Symbol, DateTime.Now, 101.66m));

            fill = model.StopLimitFill(security, order);

            // this fills worst case scenario, so it's at the limit price
            Assert.AreEqual(order.Quantity, fill.FillQuantity);
            Assert.AreEqual(order.LimitPrice, fill.FillPrice);
            Assert.AreEqual(OrderStatus.Filled, fill.Status);
            Assert.AreEqual(OrderStatus.Filled, order.Status);
        }
Exemplo n.º 12
0
        public void PerformsStopLimitFillBuy()
        {
            var model = new ForexTransactionModel();
            var order = new StopLimitOrder(Symbol, 100, 101.5m, 101.75m, DateTime.Now, type: SecurityType.Forex);
            var config = CreateTradeBarDataConfig(SecurityType.Forex, Symbol);
            var security = new Security(SecurityExchangeHours.AlwaysOpen, config, 1);
            security.SetMarketPrice(DateTime.Now, new IndicatorDataPoint(Symbol, DateTime.Now, 100m));

            var fill = model.StopLimitFill(security, order);

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

            security.SetMarketPrice(DateTime.Now, new IndicatorDataPoint(Symbol, DateTime.Now, 102m));

            fill = model.StopLimitFill(security, order);

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

            security.SetMarketPrice(DateTime.Now, new IndicatorDataPoint(Symbol, DateTime.Now, 101.66m));

            fill = model.StopLimitFill(security, order);

            // this fills worst case scenario, so it's at the limit price
            Assert.AreEqual(order.Quantity, fill.FillQuantity);
            Assert.AreEqual(order.LimitPrice, fill.FillPrice);
            Assert.AreEqual(OrderStatus.Filled, fill.Status);
            Assert.AreEqual(OrderStatus.Filled, order.Status);
        }
Exemplo n.º 13
0
 /// <summary>
 /// Creates a deep-copy clone of this order
 /// </summary>
 /// <returns>A copy of this order</returns>
 public override Order Clone()
 {
     var order = new StopLimitOrder {StopPrice = StopPrice, LimitPrice = LimitPrice};
     CopyTo(order);
     return order;
 }
        /// <summary>
        /// Default stop limit fill model implementation in base class security. (Stop Limit Order Type)
        /// </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="LimitFill(Security, LimitOrder)"/>
        /// <remarks>
        ///     There is no good way to model limit orders with OHLC because we never know whether the market has 
        ///     gapped past our fill price. We have to make the assumption of a fluid, high volume market.
        /// 
        ///     Stop limit orders we also can't be sure of the order of the H - L values for the limit fill. The assumption
        ///     was made the limit fill will be done with closing price of the bar after the stop has been triggered..
        /// </remarks>
        public virtual OrderEvent StopLimitFill(Security asset, StopLimitOrder order)
        {
            //Default order event to return.
            var utcTime = asset.LocalTime.ConvertToUtc(asset.Exchange.TimeZone);
            var orderFee = GetOrderFee(asset, order);
            var fill = new OrderEvent(order, utcTime, orderFee);

            try
            {
                //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);

                //Check if the Stop Order was filled: opposite to a limit order
                switch (order.Direction)
                {
                    case OrderDirection.Buy:
                        //-> 1.2 Buy Stop: If Price Above Setpoint, Buy:
                        if (maximumPrice > order.StopPrice || order.StopTriggered)
                        {
                            order.StopTriggered = true;

                            // Fill the limit order, using closing price of bar:
                            // Note > Can't use minimum price, because no way to be sure minimum wasn't before the stop triggered.
                            if (asset.Price < order.LimitPrice)
                            {
                                fill.Status = OrderStatus.Filled;
                                fill.FillPrice = order.LimitPrice;
                            }
                        }
                        break;

                    case OrderDirection.Sell:
                        //-> 1.1 Sell Stop: If Price below setpoint, Sell:
                        if (minimumPrice < order.StopPrice || order.StopTriggered)
                        {
                            order.StopTriggered = true;

                            // Fill the limit order, using minimum price of the bar
                            // Note > Can't use minimum price, because no way to be sure minimum wasn't before the stop triggered.
                            if (asset.Price > order.LimitPrice)
                            {
                                fill.Status = OrderStatus.Filled;
                                fill.FillPrice = order.LimitPrice; // Fill at limit price not asset price.
                            }
                        }
                        break;
                }

                // assume the order completely filled
                if (fill.Status == OrderStatus.Filled) fill.FillQuantity = order.Quantity;
            }
            catch (Exception err)
            {
                Log.Error("SecurityTransactionModel.StopLimitFill(): " + err.Message);
            }

            return fill;
        }
Exemplo n.º 15
0
        /// <summary>
        /// Send a stop 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="stopPrice">Stop price for this 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 StopLimitOrder(string symbol, int quantity, decimal stopPrice, decimal limitPrice, string tag = "")
        {
            var error = PreOrderChecks(symbol, quantity, OrderType.StopLimit);
            if (error < 0)
            {
                return error;
            }

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

            //Add the order and create a new order Id.
            return Transactions.AddOrder(order);
        }
Exemplo n.º 16
0
        private Order ConvertOrder(IB.Order ibOrder, IB.Contract contract)
        {
            // this function is called by GetOpenOrders which is mainly used by the setup handler to
            // initialize algorithm state.  So the only time we'll be executing this code is when the account
            // has orders sitting and waiting from before algo initialization...
            // because of this we can't get the time accurately

            Order order;
            var mappedSymbol = MapSymbol(contract);
            var orderType = ConvertOrderType(ibOrder);
            switch (orderType)
            {
                case OrderType.Market:
                    order = new MarketOrder(mappedSymbol,
                        ibOrder.TotalQuantity,
                        new DateTime() // not sure how to get this data
                        );
                    break;

                case OrderType.MarketOnOpen:
                    order = new MarketOnOpenOrder(mappedSymbol, 
                        ibOrder.TotalQuantity,
                        new DateTime());
                    break;

                case OrderType.MarketOnClose:
                    order = new MarketOnCloseOrder(mappedSymbol,
                        ibOrder.TotalQuantity,
                        new DateTime()
                        );
                    break;

                case OrderType.Limit:
                    order = new LimitOrder(mappedSymbol,
                        ibOrder.TotalQuantity,
                        ibOrder.LimitPrice,
                        new DateTime()
                        );
                    break;

                case OrderType.StopMarket:
                    order = new StopMarketOrder(mappedSymbol,
                        ibOrder.TotalQuantity,
                        ibOrder.AuxPrice,
                        new DateTime()
                        );
                    break;

                case OrderType.StopLimit:
                    order = new StopLimitOrder(mappedSymbol,
                        ibOrder.TotalQuantity,
                        ibOrder.AuxPrice,
                        ibOrder.LimitPrice,
                        new DateTime()
                        );
                    break;

                default:
                    throw new InvalidEnumArgumentException("orderType", (int) orderType, typeof (OrderType));
            }

            order.BrokerId.Add(ibOrder.OrderId.ToString());

            return order;
        }
Exemplo n.º 17
0
 /// <summary>
 /// Default stop limit fill model implementation in base class security. (Stop Limit Order Type)
 /// </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="LimitFill(Security, LimitOrder)"/>
 /// <remarks>
 ///     There is no good way to model limit orders with OHLC because we never know whether the market has 
 ///     gapped past our fill price. We have to make the assumption of a fluid, high volume market.
 /// 
 ///     Stop limit orders we also can't be sure of the order of the H - L values for the limit fill. The assumption
 ///     was made the limit fill will be done with closing price of the bar after the stop has been triggered..
 /// </remarks>
 public virtual OrderEvent StopLimitFill(Security asset, StopLimitOrder order)
 {
     return _fillModel.StopLimitFill(asset, order);
 }