/// <summary> /// Submit orders for the specified portolio targets. /// This model is free to delay or spread out these orders as it sees fit /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="targets">The portfolio targets to be ordered</param> public void Execute(QCAlgorithmFramework algorithm, IEnumerable <IPortfolioTarget> targets) { // update the complete set of portfolio targets with the new targets _targetsCollection.AddRange(targets); foreach (var target in _targetsCollection) { var symbol = target.Symbol; // calculate remaining quantity to be ordered var unorderedQuantity = OrderSizing.GetUnorderedQuantity(algorithm, target); // fetch our symbol data containing our VWAP indicator SymbolData data; if (!_symbolData.TryGetValue(symbol, out data)) { continue; } // ensure we're receiving price data before submitting orders if (data.Security.Price == 0m) { continue; } // check order entry conditions if (PriceIsFavorable(data, unorderedQuantity)) { // get the maximum order size based on a percentage of current volume var maxOrderSize = OrderSizing.PercentVolume(data.Security, MaximumOrderQuantityPercentVolume); var orderSize = Math.Min(maxOrderSize, Math.Abs(unorderedQuantity)); // round down to even lot size orderSize -= orderSize % data.Security.SymbolProperties.LotSize; if (orderSize != 0) { algorithm.MarketOrder(data.Security.Symbol, Math.Sign(unorderedQuantity) * orderSize); } } // check to see if we're done with this target unorderedQuantity = OrderSizing.GetUnorderedQuantity(algorithm, target); if (unorderedQuantity == 0m) { _targetsCollection.Remove(target.Symbol); } } }
/// <summary> /// Submit orders for the specified portolio targets. /// This model is free to delay or spread out these orders as it sees fit /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="targets">The portfolio targets to be ordered</param> public override void Execute(QCAlgorithm algorithm, IPortfolioTarget[] targets) { // update the complete set of portfolio targets with the new targets _targetsCollection.AddRange(targets); // for performance we check count value, OrderByMarginImpact and ClearFulfilled are expensive to call if (_targetsCollection.Count > 0) { foreach (var target in _targetsCollection.OrderByMarginImpact(algorithm)) { var symbol = target.Symbol; // calculate remaining quantity to be ordered var unorderedQuantity = OrderSizing.GetUnorderedQuantity(algorithm, target); // fetch our symbol data containing our VWAP indicator SymbolData data; if (!_symbolData.TryGetValue(symbol, out data)) { continue; } // check order entry conditions if (PriceIsFavorable(data, unorderedQuantity)) { // get the maximum order size based on a percentage of current volume var maxOrderSize = OrderSizing.PercentVolume(data.Security, MaximumOrderQuantityPercentVolume); var orderSize = Math.Min(maxOrderSize, Math.Abs(unorderedQuantity)); // round down to even lot size orderSize -= orderSize % data.Security.SymbolProperties.LotSize; if (orderSize != 0) { algorithm.MarketOrder(data.Security.Symbol, Math.Sign(unorderedQuantity) * orderSize); } } } _targetsCollection.ClearFulfilled(algorithm); } }