private static AssetBalanceInventory ComputeAssetDynamics(AssetBalanceInventory startInventory, AssetBalanceInventory endInventory) { if (startInventory == null && endInventory == null) { throw new InvalidOperationException("At least one inventory is required to compute dynamics"); } Dictionary <string, AssetInventory> assetInventories = GroupAndMerge( startInventory?.Inventories, endInventory?.Inventories, o => o.Exchange, ComputeInventoryDynamics); Dictionary <string, AssetBalance> assetBalances = GroupAndMerge( startInventory?.Balances, endInventory?.Balances, o => o.Exchange, ComputeBalanceDynamics); return(new AssetBalanceInventory { AssetId = startInventory?.AssetId ?? endInventory.AssetId, AssetDisplayId = startInventory?.AssetDisplayId ?? endInventory.AssetDisplayId, Inventories = assetInventories.Values.ToList(), Balances = assetBalances.Values.ToList() }); }
private static AssetPnL CalcPnLByAsset(string assetId, string exchange, InventorySnapshot startInventorySnapshot, InventorySnapshot endInventorySnapshot) { AssetBalanceInventory startAssetBalanceInventory = startInventorySnapshot.Assets .SingleOrDefault(a => a.AssetId == assetId); AssetBalanceInventory endAssetBalanceInventory = endInventorySnapshot.Assets .SingleOrDefault(a => a.AssetId == assetId); var startAssetBalance = startAssetBalanceInventory == null ? BalanceOnDate.Empty : new BalanceOnDate(startAssetBalanceInventory.GetBalanceByExchange(exchange)); var endAssetBalance = endAssetBalanceInventory == null ? BalanceOnDate.Empty : new BalanceOnDate(endAssetBalanceInventory.GetBalanceByExchange(exchange)); var startAssetInventory = startAssetBalanceInventory == null ? new AssetInventory { Exchange = exchange } : startAssetBalanceInventory.GetInventoryByExchange(exchange); var endAssetInventory = endAssetBalanceInventory == null ? new AssetInventory { Exchange = exchange } : endAssetBalanceInventory.GetInventoryByExchange(exchange); decimal tradingPnL = endAssetBalance.Price * (endAssetInventory.VolumeInUsd - startAssetInventory.VolumeInUsd); decimal directionalPnL = startAssetBalance.Balance * (endAssetBalance.Price - startAssetBalance.Price); var assetDisplayId = startAssetBalanceInventory?.AssetDisplayId ?? endAssetBalanceInventory?.AssetDisplayId ?? assetId; return(new AssetPnL { Asset = assetDisplayId, Exchange = exchange, Trading = tradingPnL, Directional = directionalPnL, StartBalance = startAssetBalance, EndBalance = endAssetBalance }); }