21 using System.Collections.Generic;
42 private List<ISignalExportTarget> _signalExports;
52 private bool _isLiveWarningModeLog;
67 _algorithm = algorithm;
68 _isLiveWarningModeLog =
false;
77 _signalExports ??= [];
78 _signalExports.Add(signalExport);
109 using var _ = Py.GIL();
110 if (!signalExports.IsIterable())
143 var totalPortfolioValue = _algorithm.Portfolio.TotalPortfolioValue;
144 if (totalPortfolioValue <= 0)
146 _algorithm.Error(
"Total portfolio value was less than or equal to 0");
163 if (!_algorithm.LiveMode)
165 if (!_isLiveWarningModeLog)
167 _algorithm.Debug(
"Portfolio targets are only sent in live mode");
168 _isLiveWarningModeLog =
true;
174 if (_signalExports.IsNullOrEmpty())
179 if (portfolioTargets ==
null || portfolioTargets.Length == 0)
181 _algorithm.Debug(
"No portfolio target given");
185 var targets =
new List<PortfolioTarget>(portfolioTargets);
189 Algorithm = _algorithm
193 foreach (var signalExport
in _signalExports)
195 result &= signalExport.Send(signalExportTargetParameters);
203 foreach (var holding
in _algorithm.Portfolio.Values)
205 var security = _algorithm.Securities[holding.Symbol];
210 if (!security.IsTradable && !security.Symbol.IsCanonical())
216 var adjustedPercent = Math.Abs(security.BuyingPowerModel.GetInitialMarginRequirement(marginParameters) / totalPortfolioValue);
220 var holdingPercent = adjustedPercent * security.BuyingPowerModel.GetLeverage(security);
224 var adjustedHoldingPercent = (holdingPercent * totalPortfolioValue) / _algorithm.Portfolio.TotalPortfolioValueLessFreeBuffer;
225 if (holding.Quantity < 0)
227 adjustedHoldingPercent *= -1;
230 yield
return new PortfolioTarget(holding.Symbol, adjustedHoldingPercent);
242 _initialOrderEventTimeUtc =
new(orderEvent.
UtcTime);
250 public void Flush(DateTime currentTimeUtc)
252 var initialOrderEventTimeUtc = _initialOrderEventTimeUtc.
Value;
267 catch (Exception exception)
271 _algorithm.Error($
"Failed to send portfolio target(s). Reason: {exception.Message}.{Environment.NewLine}{exception.StackTrace}");