/********************************************************
        * CLASS PROPERTIES
        *********************************************************/
        /********************************************************
        * CLASS METHODS
        *********************************************************/
        /// <summary>
        /// Perform neccessary check to see if the model has been filled, appoximate the best we can.
        /// </summary>
        /// <param name="vehicle">Asset we're working with</param>
        /// <param name="order">Order class to check if filled.</param>
        public virtual OrderEvent Fill(Security vehicle, Order order)
        {
            //Default order event to return.
            var fill = new OrderEvent(order);

            try
            {
                switch (order.Type)
                {
                    case OrderType.Limit:
                        fill = LimitFill(vehicle, order);
                        break;
                    case OrderType.StopMarket:
                        fill = StopFill(vehicle, order);
                        break;
                    case OrderType.Market:
                        fill = MarketFill(vehicle, order);
                        break;
                }
            } catch (Exception err) {
                Log.Error("SecurityTransactionModel.TransOrderDirection.Fill(): " + err.Message);
            }

            return fill;
        }
        /// <summary>
        /// Gets the order fee associated with the specified order. This returns the cost
        /// of the transaction in the account currency
        /// </summary>
        /// <param name="security">The security matching the order</param>
        /// <param name="order">The order to compute fees for</param>
        /// <returns>The cost of the order in units of the account currency</returns>
        public decimal GetOrderFee(Security security, Order order)
        {
            switch (security.Type)
            {
                case SecurityType.Forex:
                    // get the total order value in the account currency
                    var totalOrderValue = order.GetValue(security);
                    var fee = Math.Abs(_forexCommissionRate*totalOrderValue);
                    return Math.Max(_forexMinimumOrderFee, fee);

                case SecurityType.Equity:
                    var tradeValue = Math.Abs(order.GetValue(security));

                    //Per share fees
                    var tradeFee = 0.005m * order.AbsoluteQuantity;

                    //Maximum Per Order: 0.5%
                    //Minimum per order. $1.0
                    var maximumPerOrder = 0.005m * tradeValue;
                    if (tradeFee < 1)
                    {
                        tradeFee = 1;
                    }
                    else if (tradeFee > maximumPerOrder)
                    {
                        tradeFee = maximumPerOrder;
                    }

                    //Always return a positive fee.
                    return Math.Abs(tradeFee);
            }

            // all other types default to zero fees
            return 0m;
        }
Exemple #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="StreamStore"/> class
 /// </summary>
 /// <param name="config">The subscripton's configuration</param>
 /// <param name="security">The security object, used for exchange hours</param>
 public StreamStore(SubscriptionDataConfig config, Security security)
 {
     _security = security;
     _config = config;
     _increment = config.Increment;
     _queue = new ConcurrentQueue<BaseData>();
 }
Exemple #4
0
        /// <summary>
        /// Returns true if the brokerage could accept this order. This takes into account
        /// order type, security type, and order size limits.
        /// </summary>
        /// <remarks>
        /// For example, a brokerage may have no connectivity at certain times, or an order rate/size limit
        /// </remarks>
        /// <param name="security"></param>
        /// <param name="order">The order to be processed</param>
        /// <param name="message">If this function returns false, a brokerage message detailing why the order may not be submitted</param>
        /// <returns>True if the brokerage could process the order, false otherwise</returns>
        public override bool CanSubmitOrder(Security security, Order order, out BrokerageMessageEvent message)
        {
            message = null;

            // validate security type
            if (security.Type != SecurityType.Forex && security.Type != SecurityType.Cfd)
            {
                message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
                    "This model does not support " + security.Type + " security type."
                    );

                return false;
            }

            // validate order type
            if (order.Type != OrderType.Limit && order.Type != OrderType.Market && order.Type != OrderType.StopMarket)
            {
                message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
                    "This model does not support " + order.Type + " order type."
                    );

                return false;
            }

            return true;
        }
Exemple #5
0
        /// <summary>
        /// Slippage Model. Return a decimal cash slippage approximation on the order.
        /// </summary>
        public override decimal GetSlippageApproximation(Security asset, Order order)
        {
            var lastData = asset.GetLastData();
            if (lastData == null) return 0;

            return lastData.Value*_slippagePercent;
        }
        /// <summary>
        /// Get the slippage approximation for this order
        /// </summary>
        /// <returns>Decimal value of the slippage approximation</returns>
        /// <seealso cref="Order"/>
        public override decimal GetSlippageApproximation(Security security, Order order)
        {
            //Return 0 by default
            decimal slippage = 0;
            //For FOREX, the slippage is the Bid/Ask Spread for Tick, and an approximation for TradeBars
            switch (security.Resolution)
            {
                case Resolution.Minute:
                case Resolution.Second:
                    //Get the last data packet:
                    //Assume slippage is 1/10,000th of the price
                    slippage = security.GetLastData().Value * 0.0001m;
                    break;

                case Resolution.Tick:
                    var lastTick = (Tick)security.GetLastData();
                    switch (order.Direction)
                    {
                        case OrderDirection.Buy:
                            //We're buying, assume slip to Asking Price.
                            slippage = Math.Abs(order.Price - lastTick.AskPrice);
                            break;

                        case OrderDirection.Sell:
                            //We're selling, assume slip to the bid price.
                            slippage = Math.Abs(order.Price - lastTick.BidPrice);
                            break;
                    }
                    break;
            }
            return slippage;
        }
Exemple #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LiveSubscription"/> class
 /// </summary>
 /// <param name="security">The security this subscription is for</param>
 /// <param name="enumerator">The subscription's data source</param>
 /// <param name="utcStartTime">The start time of the subscription</param>
 /// <param name="utcEndTime">The end time of the subscription</param>
 /// <param name="isUserDefined">True if the user explicitly defined this subscription, false otherwise</param>
 public LiveSubscription(Security security, IEnumerator<BaseData> enumerator, DateTime utcStartTime, DateTime utcEndTime, bool isUserDefined)
     : base(security, enumerator, utcStartTime, utcEndTime, isUserDefined)
 {
     NeedsMoveNext = true;
     IsCustomData = security.SubscriptionDataConfig.IsCustomData;
     StreamStore = new StreamStore(Configuration, security);
 }
Exemple #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LiveSubscription"/> class
 /// </summary>
 /// <param name="universe">The universe of the subscription</param>
 /// <param name="security">The security this subscription is for</param>
 /// <param name="enumerator">The subscription's data source</param>
 /// <param name="utcStartTime">The start time of the subscription</param>
 /// <param name="utcEndTime">The end time of the subscription</param>
 public LiveSubscription(IUniverse universe, Security security, IEnumerator<BaseData> enumerator, DateTime utcStartTime, DateTime utcEndTime)
     : base(universe, security, enumerator, utcStartTime, utcEndTime)
 {
     NeedsMoveNext = true;
     IsCustomData = security.SubscriptionDataConfig.IsCustomData;
     StreamStore = new StreamStore(Configuration, security);
 }
        public void UpdatesAfterCorrectPeriodElapses()
        {
            const int periods = 3;
            var periodSpan = Time.OneMinute;
            var reference = new DateTime(2016, 04, 06, 12, 0, 0);
            var referenceUtc = reference.ConvertToUtc(TimeZones.NewYork);
            var timeKeeper = new TimeKeeper(referenceUtc);
            var config = new SubscriptionDataConfig(typeof (TradeBar), Symbols.SPY, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, true, false, false);
            var security = new Security(SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), config, new Cash("USD", 0, 0), SymbolProperties.GetDefault("USD"));
            security.SetLocalTimeKeeper(timeKeeper.GetLocalTimeKeeper(TimeZones.NewYork));

            var model = new RelativeStandardDeviationVolatilityModel(periodSpan, periods);
            security.VolatilityModel = model;

            var first = new IndicatorDataPoint(reference, 1);
            security.SetMarketPrice(first);

            Assert.AreEqual(0m, model.Volatility);

            const decimal value = 0.471404520791032M; // std of 1,2 is ~0.707 over a mean of 1.5
            var second = new IndicatorDataPoint(reference.AddMinutes(1), 2);
            security.SetMarketPrice(second);
            Assert.AreEqual(value, model.Volatility);

            // update should not be applied since not enough time has passed
            var third = new IndicatorDataPoint(reference.AddMinutes(1.01), 1000);
            security.SetMarketPrice(third);
            Assert.AreEqual(value, model.Volatility);

            var fourth = new IndicatorDataPoint(reference.AddMinutes(2), 3m);
            security.SetMarketPrice(fourth);
            Assert.AreEqual(0.5m, model.Volatility);
        }
        public void PerformsLimitFillSell()
        {
            var model = new SecurityTransactionModel();
            var order = new LimitOrder(Symbol, -100, 101.5m, 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, 101m));

            var fill = model.LimitFill(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 TradeBar(DateTime.Now, Symbol, 102m, 103m, 101m, 102.3m, 100));

            fill = model.LimitFill(security, order);

            // this fills worst case scenario, so it's at the limit price
            Assert.AreEqual(order.Quantity, fill.FillQuantity);
            Assert.AreEqual(Math.Max(order.LimitPrice, security.Low), fill.FillPrice);
            Assert.AreEqual(OrderStatus.Filled, fill.Status);
            Assert.AreEqual(OrderStatus.Filled, order.Status);
        }
Exemple #11
0
        public void HoldingsTests()
        {
            var security = new Security(SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork), CreateTradeBarConfig());
            
            // Long 100 stocks test
            security.Holdings.SetHoldings(100m, 100);
            
            Assert.AreEqual(100m, security.Holdings.AveragePrice);
            Assert.AreEqual(100, security.Holdings.Quantity);
            Assert.IsTrue(security.HoldStock);
            Assert.IsTrue(security.Invested);
            Assert.IsTrue(security.Holdings.IsLong);
            Assert.IsFalse(security.Holdings.IsShort);

            // Short 100 stocks test
            security.Holdings.SetHoldings(100m, -100);

            Assert.AreEqual(100m, security.Holdings.AveragePrice);
            Assert.AreEqual(-100, security.Holdings.Quantity);
            Assert.IsTrue(security.HoldStock);
            Assert.IsTrue(security.Invested);
            Assert.IsFalse(security.Holdings.IsLong);
            Assert.IsTrue(security.Holdings.IsShort);

            // Flat test
            security.Holdings.SetHoldings(100m, 0);

            Assert.AreEqual(100m, security.Holdings.AveragePrice);
            Assert.AreEqual(0, security.Holdings.Quantity);
            Assert.IsFalse(security.HoldStock);
            Assert.IsFalse(security.Invested);
            Assert.IsFalse(security.Holdings.IsLong);
            Assert.IsFalse(security.Holdings.IsShort);

        }
            public override OrderEvent MarketFill(Security asset, MarketOrder order)
            {
                // this model randomly fills market orders

                decimal absoluteRemaining;
                if (!_absoluteRemainingByOrderId.TryGetValue(order.Id, out absoluteRemaining))
                {
                    absoluteRemaining = order.AbsoluteQuantity;
                    _absoluteRemainingByOrderId.Add(order.Id, order.AbsoluteQuantity);
                }

                var fill = base.MarketFill(asset, order);
                var absoluteFillQuantity = (int) (Math.Min(absoluteRemaining, _random.Next(0, 2*(int)order.AbsoluteQuantity)));
                fill.FillQuantity = Math.Sign(order.Quantity) * absoluteFillQuantity;

                if (absoluteRemaining == absoluteFillQuantity)
                {
                    fill.Status = OrderStatus.Filled;
                    _absoluteRemainingByOrderId.Remove(order.Id);
                }
                else
                {
                    absoluteRemaining = absoluteRemaining - absoluteFillQuantity;
                    _absoluteRemainingByOrderId[order.Id] = absoluteRemaining;
                    fill.Status = OrderStatus.PartiallyFilled;
                }

                _algorithm.Log("CustomFillModel: " + fill);

                return fill;
            }
        public void PerformsLimitFillSell()
        {
            var model = new SecurityTransactionModel();
            var order = new LimitOrder(Symbol, -100, 101.5m, Noon, type: SecurityType.Equity);
            var config = CreateTradeBarConfig(Symbol);
            var security = new Security(SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, 1);
            security.SetMarketPrice(Noon, new IndicatorDataPoint(Symbol, Noon, 101m));

            var fill = model.LimitFill(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 TradeBar(Noon, Symbol, 102m, 103m, 101m, 102.3m, 100));

            fill = model.LimitFill(security, order);

            // this fills worst case scenario, so it's at the limit price
            Assert.AreEqual(order.Quantity, fill.FillQuantity);
            Assert.AreEqual(Math.Max(order.LimitPrice, security.Low), fill.FillPrice);
            Assert.AreEqual(OrderStatus.Filled, fill.Status);
            Assert.AreEqual(OrderStatus.Filled, order.Status);
        }
        public void FundsAreSettledImmediately()
        {
            var securities = new SecurityManager(TimeKeeper);
            var transactions = new SecurityTransactionManager(securities);
            var portfolio = new SecurityPortfolioManager(securities, transactions);
            var model = new ImmediateSettlementModel();
            var config = CreateTradeBarConfig();
            var security = new Security(SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config);

            portfolio.SetCash(1000);
            Assert.AreEqual(1000, portfolio.Cash);
            Assert.AreEqual(0, portfolio.UnsettledCash);

            var timeUtc = Noon.ConvertToUtc(TimeZones.NewYork);
            model.ApplyFunds(portfolio, security, timeUtc, "USD", 1000);

            Assert.AreEqual(2000, portfolio.Cash);
            Assert.AreEqual(0, portfolio.UnsettledCash);

            model.ApplyFunds(portfolio, security, timeUtc, "USD", -500);

            Assert.AreEqual(1500, portfolio.Cash);
            Assert.AreEqual(0, portfolio.UnsettledCash);

            model.ApplyFunds(portfolio, security, timeUtc, "USD", 1000);

            Assert.AreEqual(2500, portfolio.Cash);
            Assert.AreEqual(0, portfolio.UnsettledCash);
        }
Exemple #15
0
 /// <summary>
 /// Create a new holding class instance setting the initial properties to $0.
 /// </summary>
 /// <param name="security">The security being held</param>
 public SecurityHolding(Security security)
 {
     _security = security;
     //Total Sales Volume for the day
     _totalSaleVolume = 0;
     _lastTradeProfit = 0;
 }
Exemple #16
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LiveSubscription"/> class
 /// </summary>
 /// <param name="security">The security this subscription is for</param>
 /// <param name="enumerator">The subscription's data source</param>
 /// <param name="utcStartTime">The start time of the subscription</param>
 /// <param name="utcEndTime">The end time of the subscription</param>
 /// <param name="isUserDefined">True if the user explicitly defined this subscription, false otherwise</param>
 /// <param name="isFundamentalSubscription">True if this subscription is used to define the times to perform universe selection
 /// for a specific market, false for all other subscriptions</param>
 public LiveSubscription(Security security, IEnumerator<BaseData> enumerator, DateTime utcStartTime, DateTime utcEndTime, bool isUserDefined, bool isFundamentalSubscription)
     : base(security, enumerator, utcStartTime, utcEndTime, isUserDefined, isFundamentalSubscription)
 {
     NeedsMoveNext = true;
     IsCustomData = security.IsDynamicallyLoadedData;
     StreamStore = new StreamStore(Configuration, security);
 }
        public void PerformsLimitFillSell()
        {
            var model = new ForexTransactionModel();
            var order = new LimitOrder(Symbol, -100, 101.5m, DateTime.Now, type: SecurityType.Forex);
            var config = CreateTradeBarDataConfig(SecurityType.Forex, Symbol);
            var security = new Security(SecurityExchangeHours.AlwaysOpen, config, 1);
            security.SetLocalTimeKeeper(TimeKeeper.GetLocalTimeKeeper(TimeZones.NewYork));
            security.SetMarketPrice(new IndicatorDataPoint(Symbol, DateTime.Now, 101m));

            var fill = model.LimitFill(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(new TradeBar(DateTime.Now, Symbol, 102m, 103m, 101m, 102.3m, 100));

            fill = model.LimitFill(security, order);

            // this fills worst case scenario, so it's at the limit price
            Assert.AreEqual(order.Quantity, fill.FillQuantity);
            Assert.AreEqual(Math.Max(order.LimitPrice, security.Low), fill.FillPrice);
            Assert.AreEqual(OrderStatus.Filled, fill.Status);
            Assert.AreEqual(OrderStatus.Filled, order.Status);
        }
Exemple #18
0
        /// <summary>
        /// Applies cash settlement rules
        /// </summary>
        /// <param name="portfolio">The algorithm's portfolio</param>
        /// <param name="security">The fill's security</param>
        /// <param name="applicationTimeUtc">The fill time (in UTC)</param>
        /// <param name="currency">The currency symbol</param>
        /// <param name="amount">The amount of cash to apply</param>
        public void ApplyFunds(SecurityPortfolioManager portfolio, Security security, DateTime applicationTimeUtc, string currency, decimal amount)
        {
            if (amount > 0)
            {
                // positive amount: sell order filled

                portfolio.UnsettledCashBook[currency].AddAmount(amount);

                // find the correct settlement date (usually T+3 or T+1)
                var settlementDate = applicationTimeUtc.ConvertFromUtc(security.Exchange.TimeZone).Date;
                for (var i = 0; i < _numberOfDays; i++)
                {
                    settlementDate = settlementDate.AddDays(1);

                    // only count days when market is open
                    if (!security.Exchange.Hours.IsDateOpen(settlementDate))
                        i--;
                }

                // use correct settlement time
                var settlementTimeUtc = settlementDate.Add(_timeOfDay).ConvertToUtc(security.Exchange.Hours.TimeZone);

                portfolio.AddUnsettledCashAmount(new UnsettledCashAmount(settlementTimeUtc, currency, amount));
            }
            else
            {
                // negative amount: buy order filled

                portfolio.CashBook[currency].AddAmount(amount);
            }
        }
        /// <summary>
        /// Returns true if the brokerage could accept this order. This takes into account
        /// order type, security type, and order size limits.
        /// </summary>
        /// <remarks>
        /// For example, a brokerage may have no connectivity at certain times, or an order rate/size limit
        /// </remarks>
        /// <param name="security">The security of the order</param>
        /// <param name="order">The order to be processed</param>
        /// <param name="message">If this function returns false, a brokerage message detailing why the order may not be submitted</param>
        /// <returns>True if the brokerage could process the order, false otherwise</returns>
        public override bool CanSubmitOrder(Security security, Order order, out BrokerageMessageEvent message)
        {
            message = null;

            var securityType = order.SecurityType;
            if (securityType != SecurityType.Equity)
            {
                message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
                    "This model only supports equities."
                    );
                
                return false;
            }

            if (order.Type == OrderType.MarketOnOpen || order.Type == OrderType.MarketOnClose)
            {
                message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
                    "Tradier brokerage only supports Market orders. MarketOnOpen and MarketOnClose orders not supported."
                    );

                return false;
            }

            if (!CanExecuteOrder(security, order))
            {
                message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "ExtendedMarket",
                    "Tradier does not support extended market hours trading.  Your order will be processed at market open."
                    );
            }

            // tradier order limits
            return true;
        }
            /// <summary>
            /// Initializes the specified security by setting up the models
            /// </summary>
            /// <param name="security">The security to be initialized</param>
            public override void Initialize(Security security)
            {
                // first call the default implementation
                base.Initialize(security);

                // now apply our data normalization mode
                security.SetDataNormalizationMode(_dataNormalizationMode);
            }
 /// <summary>
 /// Initializes the specified security by setting up the models
 /// </summary>
 /// <param name="security">The security to be initialized</param>
 public virtual void Initialize(Security security)
 {
     // set leverage and models
     security.SetLeverage(_brokerageModel.GetLeverage(security));
     security.FillModel = _brokerageModel.GetFillModel(security);
     security.FeeModel = _brokerageModel.GetFeeModel(security);
     security.SlippageModel = _brokerageModel.GetSlippageModel(security);
     security.SettlementModel = _brokerageModel.GetSettlementModel(security, _brokerageModel.AccountType);
 }
        public void SellOnThursdaySettleOnTuesday()
        {
            var securities = new SecurityManager(TimeKeeper);
            var transactions = new SecurityTransactionManager(securities);
            var portfolio = new SecurityPortfolioManager(securities, transactions);
            // settlement at T+3, 8:00 AM
            var model = new DelayedSettlementModel(3, TimeSpan.FromHours(8));
            var config = CreateTradeBarConfig(Symbols.SPY);
            var security = new Security(SecurityExchangeHoursTests.CreateUsEquitySecurityExchangeHours(), config, new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency));

            portfolio.SetCash(3000);
            Assert.AreEqual(3000, portfolio.Cash);
            Assert.AreEqual(0, portfolio.UnsettledCash);

            // Sell on Thursday
            var timeUtc = Noon.AddDays(3).ConvertToUtc(TimeZones.NewYork);
            model.ApplyFunds(portfolio, security, timeUtc, "USD", 1000);
            portfolio.ScanForCashSettlement(timeUtc);
            Assert.AreEqual(3000, portfolio.Cash);
            Assert.AreEqual(1000, portfolio.UnsettledCash);

            // Friday, still unsettled
            timeUtc = timeUtc.AddDays(1);
            portfolio.ScanForCashSettlement(timeUtc);
            Assert.AreEqual(3000, portfolio.Cash);
            Assert.AreEqual(1000, portfolio.UnsettledCash);

            // Saturday, still unsettled
            timeUtc = timeUtc.AddDays(1);
            portfolio.ScanForCashSettlement(timeUtc);
            Assert.AreEqual(3000, portfolio.Cash);
            Assert.AreEqual(1000, portfolio.UnsettledCash);

            // Sunday, still unsettled
            timeUtc = timeUtc.AddDays(1);
            portfolio.ScanForCashSettlement(timeUtc);
            Assert.AreEqual(3000, portfolio.Cash);
            Assert.AreEqual(1000, portfolio.UnsettledCash);

            // Monday, still unsettled
            timeUtc = timeUtc.AddDays(1);
            portfolio.ScanForCashSettlement(timeUtc);
            Assert.AreEqual(3000, portfolio.Cash);
            Assert.AreEqual(1000, portfolio.UnsettledCash);

            // Tuesday at 7:55 AM, still unsettled
            timeUtc = timeUtc.AddDays(1).AddHours(-4).AddMinutes(-5);
            portfolio.ScanForCashSettlement(timeUtc);
            Assert.AreEqual(3000, portfolio.Cash);
            Assert.AreEqual(1000, portfolio.UnsettledCash);

            // Tuesday at 8 AM, now settled
            timeUtc = timeUtc.AddMinutes(5);
            portfolio.ScanForCashSettlement(timeUtc);
            Assert.AreEqual(4000, portfolio.Cash);
            Assert.AreEqual(0, portfolio.UnsettledCash);
        }
        /// <summary>
        /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
        /// </summary>
        public override void Initialize()
        {
            SetStartDate(2013, 10, 07);  //Set Start Date
            SetEndDate(2013, 10, 11);    //Set End Date
            SetCash(100000);             //Set Strategy Cash
            // Find more symbols here: http://quantconnect.com/data
            AddSecurity(SecurityType.Equity, "SPY", Resolution.Second, fillDataForward: true, extendedMarketHours: true);

            security = Securities["SPY"];
        }
 /// <summary>
 /// Returns true if the brokerage would be able to execute this order at this time assuming
 /// market prices are sufficient for the fill to take place. This is used to emulate the 
 /// brokerage fills in backtesting and paper trading. For example some brokerages may not perform
 /// executions during extended market hours. This is not intended to be checking whether or not
 /// the exchange is open, that is handled in the Security.Exchange property.
 /// </summary>
 /// <param name="security">The security being ordered</param>
 /// <param name="order">The order to test for execution</param>
 /// <returns>True if the brokerage would be able to perform the execution, false otherwise</returns>
 public bool CanExecuteOrder(Security security, Order order)
 {
     // tradier doesn't support after hours trading
     var timeOfDay = security.Time.TimeOfDay;
     if (timeOfDay < EquityExchange.MarketOpen || timeOfDay > EquityExchange.MarketClose)
     {
         return false;
     }
     return true;
 }
Exemple #25
0
        /// <summary>
        /// Returns true if the brokerage could accept this order. This takes into account
        /// order type, security type, and order size limits.
        /// </summary>
        /// <remarks>
        /// For example, a brokerage may have no connectivity at certain times, or an order rate/size limit
        /// </remarks>
        /// <param name="security"></param>
        /// <param name="order">The order to be processed</param>
        /// <param name="message">If this function returns false, a brokerage message detailing why the order may not be submitted</param>
        /// <returns>True if the brokerage could process the order, false otherwise</returns>
        public override bool CanSubmitOrder(Security security, Order order, out BrokerageMessageEvent message)
        {
            message = null;

            // validate security type
            if (security.Type != SecurityType.Forex && security.Type != SecurityType.Cfd)
            {
                message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
                    "This model does not support " + security.Type + " security type."
                    );

                return false;
            }

            // validate order type
            if (order.Type != OrderType.Limit && order.Type != OrderType.Market && order.Type != OrderType.StopMarket)
            {
                message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
                    "This model does not support " + order.Type + " order type."
                    );

                return false;
            }

            // validate order quantity
            if (order.Quantity % 1000 != 0)
            {
                message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
                    "The order quantity must be a multiple of 1000."
                    );

                return false;
            }

            // validate stop/limit orders= prices
            var limit = order as LimitOrder;
            if (limit != null)
            {
                return IsValidOrderPrices(security, OrderType.Limit, limit.Direction, security.Price, limit.LimitPrice, ref message);
            }

            var stopMarket = order as StopMarketOrder;
            if (stopMarket != null)
            {
                return IsValidOrderPrices(security, OrderType.StopMarket, stopMarket.Direction, stopMarket.StopPrice, security.Price, ref message);
            }

            var stopLimit = order as StopLimitOrder;
            if (stopLimit != null)
            {
                return IsValidOrderPrices(security, OrderType.StopLimit, stopLimit.Direction, stopLimit.StopPrice, stopLimit.LimitPrice, ref message);
            }

            return true;
        }
        /// <summary>
        /// Sets the leverage for the applicable securities, i.e, equities
        /// </summary>
        /// <remarks>
        /// This is added to maintain backwards compatibility with the old margin/leverage system
        /// </remarks>
        /// <param name="security"></param>
        /// <param name="leverage">The new leverage</param>
        public virtual void SetLeverage(Security security, decimal leverage)
        {
            if (leverage < 1)
            {
                throw new ArgumentException("Leverage must be greater than or equal to 1.");
            }

            decimal margin = 1/leverage;
            _initialMarginRequirement = margin;
            _maintenanceMarginRequirement = margin;
        }
Exemple #27
0
        /// <summary>
        /// Updates the models for the specified security. If the <see cref="DefaultBrokerageModel"/> is specified,
        /// then no update is performed.
        /// </summary>
        /// <param name="algorithm">The algorithm instance</param>
        /// <param name="model">The brokerage model</param>
        /// <param name="security">The security to be updated</param>
        public static void UpdateModel(this IAlgorithm algorithm, IBrokerageModel model, Security security)
        {
            if (model.GetType() == typeof(DefaultBrokerageModel))
            {
                // if we're using the default don't do anything
                return;
            }

            security.TransactionModel = model.GetTransactionModel(security);
            security.SettlementModel = model.GetSettlementModel(security, algorithm.AccountType);
        }
        /// <summary>
        /// Returns true if the brokerage would allow updating the order as specified by the request
        /// </summary>
        /// <param name="security">The security of the order</param>
        /// <param name="order">The order to be updated</param>
        /// <param name="request">The requested update to be made to the order</param>
        /// <param name="message">If this function returns false, a brokerage message detailing why the order may not be updated</param>
        /// <returns>True if the brokerage would allow updating the order, false otherwise</returns>
        public override bool CanUpdateOrder(Security security, Order order, UpdateOrderRequest request, out BrokerageMessageEvent message)
        {
            message = null;

            if (order.SecurityType == SecurityType.Forex && request.Quantity != null)
            {
                return IsForexWithinOrderSizeLimits(order.Symbol.Value, request.Quantity.Value, out message);
            }

            return true;
        }
        /// <summary>
        /// Default stop fill model implementation in base class security. (Stop Market 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="MarketFill(Security, MarketOrder)"/>
        /// <seealso cref="SecurityTransactionModel.LimitFill"/>
        public virtual OrderEvent StopMarketFill(Security asset, StopMarketOrder order)
        {
            //Default order event to return.
            var utcTime = asset.LocalTime.ConvertToUtc(asset.Exchange.TimeZone);
            var fill = new OrderEvent(order, utcTime, 0);

            // make sure the exchange is open before filling
            if (!IsExchangeOpen(asset)) return fill;

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

            //Calculate the model slippage: e.g. 0.01c
            var slip = asset.SlippageModel.GetSlippageApproximation(asset, order);

            //Check if the Stop Order was filled: opposite to a limit order
            switch (order.Direction)
            {
                case OrderDirection.Sell:
                    //-> 1.1 Sell Stop: If Price below setpoint, Sell:
                    if (minimumPrice < order.StopPrice)
                    {
                        fill.Status = OrderStatus.Filled;
                        // Assuming worse case scenario fill - fill at lowest of the stop & asset price.
                        fill.FillPrice = Math.Min(order.StopPrice, asset.Price - slip); 
                    }
                    break;

                case OrderDirection.Buy:
                    //-> 1.2 Buy Stop: If Price Above Setpoint, Buy:
                    if (maximumPrice > order.StopPrice)
                    {
                        fill.Status = OrderStatus.Filled;
                        // Assuming worse case scenario fill - fill at highest of the stop & asset price.
                        fill.FillPrice = Math.Max(order.StopPrice, asset.Price + slip);
                    }
                    break;
            }

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

            return fill;
        }
        public override void Initialize()
        {
            SetStartDate(2012, 01, 01);
            SetEndDate(2012, 02, 01);
            AddSecurity(SecurityType.Equity, "SPY", Resolution.Hour);

            // set our models
            _security = Securities[_spy];
            _security.FeeModel = new CustomFeeModel(this);
            _security.FillModel = new CustomFillModel(this);
            _security.SlippageModel = new CustomSlippageModel(this);
        }
 /// <summary>
 /// Gets the amount of buying power reserved to maintain the specified position
 /// </summary>
 /// <param name="security">The security for the position</param>
 /// <returns>The reserved buying power in account currency</returns>
 public decimal GetReservedBuyingPowerForPosition(Security security)
 {
     // Always returns 0. Since we're purchasing currencies outright, the position doesn't consume buying power
     return(0);
 }
 /// <summary>
 /// Gets the current leverage of the security
 /// </summary>
 /// <param name="security">The security to get leverage for</param>
 /// <returns>The current leverage in the security</returns>
 public decimal GetLeverage(Security security)
 {
     // Always returns 1. Cash accounts have no leverage.
     return(1m);
 }
 /// <summary>
 /// Sets the leverage for the applicable securities, i.e, equities
 /// </summary>
 /// <remarks>
 /// This is added to maintain backwards compatibility with the old margin/leverage system
 /// </remarks>
 /// <param name="security">The security to set leverage for</param>
 /// <param name="leverage">The new leverage</param>
 public void SetLeverage(Security security, decimal leverage)
 {
     // No action performed. This model always uses a leverage = 1
 }
        /// <summary>
        /// Check if there is sufficient buying power to execute this order.
        /// </summary>
        /// <param name="portfolio">The algorithm's portfolio</param>
        /// <param name="security">The security to be traded</param>
        /// <param name="order">The order to be checked</param>
        /// <returns>Returns true if there is sufficient buying power to execute the order, false otherwise</returns>
        public bool HasSufficientBuyingPowerForOrder(SecurityPortfolioManager portfolio, Security security, Order order)
        {
            var baseCurrency = security as IBaseCurrencySymbol;

            if (baseCurrency == null)
            {
                return(false);
            }

            decimal totalQuantity;
            decimal orderQuantity;

            if (order.Direction == OrderDirection.Buy)
            {
                // quantity available for buying in quote currency
                totalQuantity = portfolio.CashBook[security.QuoteCurrency.Symbol].Amount;
                orderQuantity = order.AbsoluteQuantity * GetOrderPrice(security, order);
            }
            else
            {
                // quantity available for selling in base currency
                totalQuantity = portfolio.CashBook[baseCurrency.BaseCurrencySymbol].Amount;
                orderQuantity = order.AbsoluteQuantity;
            }

            // calculate reserved quantity for open orders (in quote or base currency depending on direction)
            var openOrdersReservedQuantity = GetOpenOrdersReservedQuantity(portfolio, security, order);

            if (order.Direction == OrderDirection.Sell)
            {
                // can sell available and non-reserved quantities
                return(orderQuantity <= totalQuantity - openOrdersReservedQuantity);
            }

            if (order.Type == OrderType.Market)
            {
                // find a target value in account currency for buy market orders
                var targetValue =
                    portfolio.CashBook.ConvertToAccountCurrency(totalQuantity - openOrdersReservedQuantity,
                                                                security.QuoteCurrency.Symbol);

                var maximumQuantity =
                    GetMaximumOrderQuantityForTargetValue(portfolio, security, targetValue) * GetOrderPrice(security, order);

                // include existing holdings
                var holdingsValue =
                    portfolio.CashBook.ConvertToAccountCurrency(
                        portfolio.CashBook[baseCurrency.BaseCurrencySymbol].Amount, baseCurrency.BaseCurrencySymbol);

                return(orderQuantity <= Math.Abs(maximumQuantity) + holdingsValue);
            }

            // for limit orders, add fees to the order cost
            var orderFee = 0m;

            if (order.Type == OrderType.Limit)
            {
                orderFee = security.FeeModel.GetOrderFee(security, order);
                orderFee = portfolio.CashBook.Convert(orderFee, CashBook.AccountCurrency, security.QuoteCurrency.Symbol);
            }

            return(orderQuantity <= totalQuantity - openOrdersReservedQuantity - orderFee);
        }
        /// <summary>
        /// Get the maximum market order quantity to obtain a position with a given value in account currency
        /// </summary>
        /// <param name="portfolio">The algorithm's portfolio</param>
        /// <param name="security">The security to be traded</param>
        /// <param name="targetPortfolioValue">The value in account currency that we want our holding to have</param>
        /// <returns>Returns the maximum allowed market order quantity</returns>
        public decimal GetMaximumOrderQuantityForTargetValue(SecurityPortfolioManager portfolio, Security security, decimal targetPortfolioValue)
        {
            // no shorting allowed
            if (targetPortfolioValue < 0)
            {
                return(0);
            }

            var baseCurrency = security as IBaseCurrencySymbol;

            if (baseCurrency == null)
            {
                return(0);
            }

            // if target value is zero, return amount of base currency available to sell
            if (targetPortfolioValue == 0)
            {
                return(-portfolio.CashBook[baseCurrency.BaseCurrencySymbol].Amount);
            }

            // convert base currency cash to account currency
            var baseCurrencyPosition = portfolio.CashBook.ConvertToAccountCurrency(
                portfolio.CashBook[baseCurrency.BaseCurrencySymbol].Amount,
                baseCurrency.BaseCurrencySymbol);

            // convert quote currency cash to account currency
            var quoteCurrencyPosition = portfolio.CashBook.ConvertToAccountCurrency(
                portfolio.CashBook[security.QuoteCurrency.Symbol].Amount,
                security.QuoteCurrency.Symbol);

            // determine the unit price in terms of the account currency
            var unitPrice = new MarketOrder(security.Symbol, 1, DateTime.UtcNow).GetValue(security);

            if (unitPrice == 0)
            {
                return(0);
            }

            // remove directionality, we'll work in the land of absolutes
            var targetOrderValue = Math.Abs(targetPortfolioValue - baseCurrencyPosition);
            var direction        = targetPortfolioValue > baseCurrencyPosition ? OrderDirection.Buy : OrderDirection.Sell;

            // calculate the total cash available
            var cashRemaining = direction == OrderDirection.Buy ? quoteCurrencyPosition : baseCurrencyPosition;

            if (cashRemaining <= 0)
            {
                return(0);
            }

            // continue iterating while we do not have enough cash for the order
            decimal cashRequired;
            decimal orderValue;
            decimal orderFees;
            var     feeToPriceRatio = 0m;

            // compute the initial order quantity
            var orderQuantity = targetOrderValue / unitPrice;

            // rounding off Order Quantity to the nearest multiple of Lot Size
            orderQuantity -= orderQuantity % security.SymbolProperties.LotSize;

            do
            {
                // reduce order quantity by feeToPriceRatio, since it is faster than by lot size
                // if it becomes nonpositive, return zero
                orderQuantity -= feeToPriceRatio;
                if (orderQuantity <= 0)
                {
                    return(0);
                }

                // generate the order
                var order = new MarketOrder(security.Symbol, orderQuantity, DateTime.UtcNow);
                orderValue = order.GetValue(security);
                orderFees  = security.FeeModel.GetOrderFee(security, order);

                // find an incremental delta value for the next iteration step
                feeToPriceRatio  = orderFees / unitPrice;
                feeToPriceRatio -= feeToPriceRatio % security.SymbolProperties.LotSize;
                if (feeToPriceRatio < security.SymbolProperties.LotSize)
                {
                    feeToPriceRatio = security.SymbolProperties.LotSize;
                }

                // calculate the cash required for the order
                cashRequired = orderValue;
            } while (cashRequired > cashRemaining || orderValue + orderFees > targetOrderValue);

            // add directionality back in
            return((direction == OrderDirection.Sell ? -1 : 1) * orderQuantity);
        }
        private static decimal GetOpenOrdersReservedQuantity(SecurityPortfolioManager portfolio, Security security, Order order)
        {
            var baseCurrency = security as IBaseCurrencySymbol;

            if (baseCurrency == null)
            {
                return(0);
            }

            // find the target currency for the requested direction and the securities potentially involved
            var targetCurrency = order.Direction == OrderDirection.Buy
                ? security.QuoteCurrency.Symbol
                : baseCurrency.BaseCurrencySymbol;

            var symbolDirectionPairs = new Dictionary <Symbol, OrderDirection>();

            foreach (var portfolioSecurity in portfolio.Securities.Values)
            {
                var basePortfolioSecurity = portfolioSecurity as IBaseCurrencySymbol;
                if (basePortfolioSecurity == null)
                {
                    continue;
                }

                if (basePortfolioSecurity.BaseCurrencySymbol == targetCurrency)
                {
                    symbolDirectionPairs.Add(portfolioSecurity.Symbol, OrderDirection.Sell);
                }
                else if (portfolioSecurity.QuoteCurrency.Symbol == targetCurrency)
                {
                    symbolDirectionPairs.Add(portfolioSecurity.Symbol, OrderDirection.Buy);
                }
            }

            // fetch open orders with matching symbol/side
            var openOrders = portfolio.Transactions.GetOpenOrders(x =>
            {
                OrderDirection dir;
                return(symbolDirectionPairs.TryGetValue(x.Symbol, out dir) &&
                       // same direction of our order
                       dir == x.Direction &&
                       // don't count our current order
                       x.Id != order.Id &&
                       // only count working orders
                       (x.Type == OrderType.Limit || x.Type == OrderType.StopMarket));
            }
                                                                  );

            // calculate reserved quantity for selected orders
            var openOrdersReservedQuantity = 0m;

            foreach (var openOrder in openOrders)
            {
                var orderSecurity     = portfolio.Securities[openOrder.Symbol];
                var orderBaseCurrency = orderSecurity as IBaseCurrencySymbol;

                if (orderBaseCurrency != null)
                {
                    // convert order value to target currency
                    var quantityInTargetCurrency = openOrder.AbsoluteQuantity;
                    if (orderSecurity.QuoteCurrency.Symbol == targetCurrency)
                    {
                        quantityInTargetCurrency *= GetOrderPrice(security, openOrder);
                    }

                    openOrdersReservedQuantity += quantityInTargetCurrency;
                }
            }

            return(openOrdersReservedQuantity);
        }