/// <summary> /// Manages the algorithm's risk at each time step /// </summary> /// <param name="algorithm">The algorithm instance</param> public void ManageRisk(QCAlgorithmFramework algorithm) { foreach (var security in algorithm.Securities.Values) { if (!security.Invested) { continue; } var pnl = security.Holdings.UnrealizedProfitPercent; if (pnl < _maximumDrawdownPercent) { algorithm.Liquidate(security.Symbol); } } }
/// <summary> /// Immediately submits orders for the specified portfolio targets. /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="targets">The portfolio targets to be ordered</param> public override void Execute(QCAlgorithmFramework algorithm, IPortfolioTarget[] targets) { _targetsCollection.AddRange(targets); foreach (var target in _targetsCollection.OrderByMarginImpact(algorithm)) { var openQuantity = algorithm.Transactions.GetOpenOrders(target.Symbol) .Sum(x => x.Quantity); var existing = algorithm.Securities[target.Symbol].Holdings.Quantity + openQuantity; var quantity = target.Quantity - existing; // Liquidate positions in Crude Oil ETF that is no longer part of the highest-correlation pair if (_previousSymbol != null && target.Symbol != _previousSymbol) { algorithm.Liquidate(_previousSymbol); } if (quantity != 0) { algorithm.MarketOrder(target.Symbol, quantity); _previousSymbol = target.Symbol; } } _targetsCollection.ClearFulfilled(algorithm); }