/// <summary> /// Executes market orders if the standard deviation of price is more than the configured number of deviations /// in the favorable direction. /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="targets">The portfolio targets</param> public override void Execute(QCAlgorithmFramework algorithm, IPortfolioTarget[] 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 STD/SMA indicators 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 (data.STD.IsReady && PriceIsFavorable(data, unorderedQuantity)) { // get the maximum order size based on total order value var maxOrderSize = OrderSizing.Value(data.Security, MaximumOrderValue); 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(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> /// Executes market orders if the standard deviation of price is more than the configured number of deviations /// in the favorable direction. /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="targets">The portfolio targets</param> public override void Execute(QCAlgorithm algorithm, IPortfolioTarget[] 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 STD/SMA indicators SymbolData data; if (!_symbolData.TryGetValue(symbol, out data)) { continue; } // check order entry conditions if (data.STD.IsReady && PriceIsFavorable(data, unorderedQuantity)) { // get the maximum order size based on total order value var maxOrderSize = OrderSizing.Value(data.Security, MaximumOrderValue); 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(symbol, Math.Sign(unorderedQuantity) * orderSize); } } } _targetsCollection.ClearFulfilled(algorithm); } }