17 using System.Collections;
18 using System.Collections.Generic;
37 private Cash _baseCurrencyCash;
38 private bool _setCashWasCalled;
39 private decimal _totalPortfolioValue;
40 private bool _isTotalPortfolioValueValid;
41 private object _totalPortfolioValueLock =
new();
42 private bool _setAccountCurrencyWasCalled;
43 private decimal _freePortfolioValue;
90 _algorithmSettings = algorithmSettings;
107 var cash = args.Cash;
108 var unsettledCash =
new Cash(cash.Symbol, 0m, cash.ConversionRate);
109 unsettledCash.CurrencyConversion = cash.CurrencyConversion;
111 cash.CurrencyConversionUpdated += (sender, args) =>
125 #region IDictionary Implementation
183 public bool Contains(KeyValuePair<Symbol, SecurityHolding> pair)
218 public void CopyTo(KeyValuePair<Symbol, SecurityHolding>[] array,
int index)
226 array[i] =
new KeyValuePair<Symbol, SecurityHolding>(asset.Symbol, asset.Holdings);
246 protected override IEnumerable<SecurityHolding>
GetValues =>
Securities.Select(pair => pair.Value.Holdings);
252 public ICollection<Symbol>
Keys
264 public ICollection<SecurityHolding>
Values
283 holding = success ? security.Holdings :
null;
292 IEnumerator<KeyValuePair<Symbol, SecurityHolding>> IEnumerable<KeyValuePair<Symbol, SecurityHolding>>.GetEnumerator()
294 return Securities.Select(x =>
new KeyValuePair<Symbol, SecurityHolding>(x.Key, x.Value.Holdings)).GetEnumerator();
302 IEnumerator IEnumerable.GetEnumerator()
304 return Securities.Select(x =>
new KeyValuePair<Symbol, SecurityHolding>(x.Key, x.Value.Holdings)).GetEnumerator();
341 return Securities.
Values.Sum(security => security.Holdings.UnleveredAbsoluteHoldingsCost);
353 return Securities.
Values.Sum(security => security.Holdings.AbsoluteHoldingsCost);
365 return Securities.
Values.Sum(security => security.Holdings.AbsoluteHoldingsValue);
380 if (security.HoldStock)
402 return Securities.
Values.Sum(security => security.Holdings.UnrealizedProfit);
426 lock (_totalPortfolioValueLock)
428 if (!_isTotalPortfolioValueValid)
430 decimal totalHoldingsValueWithoutForexCryptoFutureCfd = 0;
431 decimal totalFuturesAndCfdHoldingsValue = 0;
432 foreach (var security
in Securities.
Values.Where((x) => x.Holdings.Invested))
434 var position = security;
435 var securityType = position.Type;
444 totalHoldingsValueWithoutForexCryptoFutureCfd += position.Holdings.HoldingsValue;
451 totalFuturesAndCfdHoldingsValue += position.Holdings.UnrealizedProfit;
457 totalFuturesAndCfdHoldingsValue += futureHoldings.UnsettledProfit;
463 totalHoldingsValueWithoutForexCryptoFutureCfd +
464 totalFuturesAndCfdHoldingsValue;
466 _isTotalPortfolioValueValid =
true;
470 return _totalPortfolioValue;
504 _isTotalPortfolioValueValid =
false;
547 return Securities.
Total.Sum(security => security.Holdings.TotalSaleVolume);
561 sum += group.BuyingPowerModel.GetReservedBuyingPowerForPositionGroup(
this, group);
614 accountCurrency = accountCurrency.LazyToUpper();
618 if (_setAccountCurrencyWasCalled)
622 Log.
Trace(
"SecurityPortfolioManager.SetAccountCurrency(): " +
627 _setAccountCurrencyWasCalled =
true;
631 throw new InvalidOperationException(
"SecurityPortfolioManager.SetAccountCurrency(): " +
635 if (_setCashWasCalled)
637 throw new InvalidOperationException(
"SecurityPortfolioManager.SetAccountCurrency(): " +
641 Log.
Trace(
"SecurityPortfolioManager.SetAccountCurrency(): " +
647 _baseCurrencyCash =
CashBook[accountCurrency];
649 if (startingCash !=
null)
651 SetCash((decimal)startingCash);
661 _setCashWasCalled =
true;
671 public void SetCash(
string symbol, decimal cash, decimal conversionRate)
673 _setCashWasCalled =
true;
675 symbol = symbol.LazyToUpper();
679 item.ConversionRate = conversionRate;
702 var positionGroupOrderDirection = direction;
703 if (security.Holdings.IsShort)
709 return positionGroup.BuyingPowerModel.GetPositionGroupBuyingPower(parameters);
734 lock (_totalPortfolioValueLock)
736 for (var i = 0; i < fills.Count; i++)
740 security.PortfolioModel.ProcessFill(
this, security, fill);
769 var total = security.Holdings.Quantity * dividend.
Distribution * security.QuoteCurrency.ConversionRate;
773 security.Holdings.AddNewDividend(total);
803 var leftOver = quantity - (int)quantity;
819 security.ApplySplit(split);
821 _baseCurrencyCash.
AddAmount(leftOver * next.Price);
866 if (orderSubmitRequest !=
null)
869 var security =
Securities[orderSubmitRequest.Symbol];
876 var marginRemaining = positionGroup.BuyingPowerModel.GetPositionGroupBuyingPower(
877 this, positionGroup, direction
914 for (var i = 0; i < orders.Count; i++)
916 var order = orders[i];
918 var result = security.BuyingPowerModel.HasSufficientBuyingPowerForOrder(
this, security, order);
919 if (!result.IsSufficient)