private AdvisorRankingAndProfitData GetAdvisorRankingAndProfitData(DateTime now, List <Order> advisorClosedOpenAndRunningOrders, Dictionary <int, double> assetsBidValues, Dictionary <int, double> assetsAskValues) { var result = new AdvisorRankingAndProfitData(); var advisorClosedOrders = advisorClosedOpenAndRunningOrders.Where(c => c.OrderStatusType == OrderStatusType.Close); foreach (var order in advisorClosedOrders) { var tradeMinutes = Convert.ToInt32(Math.Round(order.StatusDate.Subtract(order.OpenDate.Value).TotalMinutes, 0)); SetAdvisorRankingAndProfitData(ref result, order.OrderStatusType, order.OrderType, order.AssetId, order.Profit.Value, order.Quantity, GetExpectedCloseValue(order) - order.Fee.Value, now, order.StatusDate, tradeMinutes, order.TotalTradeFee); } var advisorOpenOrders = advisorClosedOpenAndRunningOrders.Where(c => c.OrderStatusType == OrderStatusType.Open); foreach (var order in advisorOpenOrders) { SetAdvisorRankingAndProfitData(ref result, order.OrderStatusType, order.OrderType, order.AssetId, 0, order.Quantity, order.Price * order.Quantity, now, order.StatusDate, null, order.Fee); } var advisorRunningOrders = advisorClosedOpenAndRunningOrders.Where(c => c.OrderStatusType == OrderStatusType.Executed && c.AssetId != AssetUSDId); if (advisorRunningOrders.Any()) { var assetsAvgPrice = advisorRunningOrders.GroupBy(c => new { c.AssetId, c.Type }).Select(c => new { AssetId = c.Key.AssetId, OrderType = OrderType.Get(c.Key.Type), TotalUSD = c.Sum(s => s.RemainingQuantity * s.Price), TotalQuantity = c.Sum(s => s.RemainingQuantity), TotalFee = c.Sum(s => s.Fee ?? 0) }); foreach (var avgPrice in assetsAvgPrice) { var price = (avgPrice.TotalUSD / avgPrice.TotalQuantity); var dictionaryPrice = avgPrice.OrderType == OrderType.Buy ? assetsBidValues : assetsAskValues; var currentValue = dictionaryPrice.ContainsKey(avgPrice.AssetId) ? dictionaryPrice[avgPrice.AssetId] : price; var expectedCloseValue = OrderBusiness.GetExpectedCloseValue(avgPrice.OrderType, price, currentValue, avgPrice.TotalQuantity); var closedFee = expectedCloseValue * OrderFee; var totalDollar = expectedCloseValue - closedFee; var feePercentage = avgPrice.TotalFee / (price * avgPrice.TotalQuantity + avgPrice.TotalFee); var profit = OrderBusiness.GetProfitValue(totalDollar, price, avgPrice.TotalQuantity, feePercentage); SetAdvisorRankingAndProfitData(ref result, OrderStatusType.Executed, avgPrice.OrderType, avgPrice.AssetId, profit, avgPrice.TotalQuantity, totalDollar, now, now, null, avgPrice.TotalFee); } } return(result); }
private void SetAdvisorRankingAndProfitData(ref AdvisorRankingAndProfitData advisorRankingAndProfitData, OrderStatusType statusType, OrderType orderType, int assetId, double profit, double quantity, double totalUSD, DateTime now, DateTime closeDate, int?tradeMinutes, double?fee) { var investedDollar = profit != -1 ? (totalUSD / (1 + profit)) : totalUSD; if (statusType != OrderStatusType.Open) { var days = now.Subtract(closeDate).TotalDays; var weight = (days <= 30 ? 1.0 : Math.Max((Math.Log(days) / -2.5100067169575757) + 2.3550550915595987, 0.0)) * investedDollar; advisorRankingAndProfitData.RankingWeight += weight; advisorRankingAndProfitData.RankingWeightedProfit += profit * weight; if (weight > 0) { ++advisorRankingAndProfitData.OrderCount; } } if (!advisorRankingAndProfitData.AssetProfitData.ContainsKey(assetId)) { advisorRankingAndProfitData.AssetProfitData[assetId] = new Dictionary <OrderStatusType, Dictionary <OrderType, AdvisorRankingAndProfitData.ProfitData> >(); } if (!advisorRankingAndProfitData.AssetProfitData[assetId].ContainsKey(statusType)) { advisorRankingAndProfitData.AssetProfitData[assetId][statusType] = new Dictionary <OrderType, AdvisorRankingAndProfitData.ProfitData>(); } if (!advisorRankingAndProfitData.AssetProfitData[assetId][statusType].ContainsKey(orderType)) { advisorRankingAndProfitData.AssetProfitData[assetId][statusType][orderType] = new AdvisorRankingAndProfitData.ProfitData(); } advisorRankingAndProfitData.AssetProfitData[assetId][statusType][orderType].SummedProfitPercentage += profit; advisorRankingAndProfitData.AssetProfitData[assetId][statusType][orderType].TotalDollar += totalUSD; advisorRankingAndProfitData.AssetProfitData[assetId][statusType][orderType].TotalQuantity += quantity; advisorRankingAndProfitData.AssetProfitData[assetId][statusType][orderType].SummedProfitDollar += totalUSD - investedDollar; ++advisorRankingAndProfitData.AssetProfitData[assetId][statusType][orderType].OrderCount; if (profit > 0) { ++advisorRankingAndProfitData.AssetProfitData[assetId][statusType][orderType].SuccessCount; } if (tradeMinutes.HasValue) { if (advisorRankingAndProfitData.AssetProfitData[assetId][statusType][orderType].SummedTradeMinutes.HasValue) { advisorRankingAndProfitData.AssetProfitData[assetId][statusType][orderType].SummedTradeMinutes += tradeMinutes.Value; } else { advisorRankingAndProfitData.AssetProfitData[assetId][statusType][orderType].SummedTradeMinutes = tradeMinutes.Value; } } if (fee.HasValue) { if (advisorRankingAndProfitData.AssetProfitData[assetId][statusType][orderType].TotalFee.HasValue) { advisorRankingAndProfitData.AssetProfitData[assetId][statusType][orderType].TotalFee += fee.Value; } else { advisorRankingAndProfitData.AssetProfitData[assetId][statusType][orderType].TotalFee = fee.Value; } } }