Knocks/BackEnd/Knoks.Core/Logic/Managers/KnokPriceManager.cs

97 lines
4.4 KiB
C#

using Knoks.Core.Data.Interfaces;
using Knoks.Core.Entities;
using Knoks.Core.Entities.Args;
using Knoks.Core.Logic.Interfaces;
using Microsoft.Extensions.Logging;
using System.Linq;
using System.Threading.Tasks;
namespace Knoks.Core.Logic.Managers
{
public class KnokPriceManager : IKnokPricelManager
{
private readonly ILogger<KnokPriceManager> _logger;
private readonly IUserDao _userDao;
private readonly IKnokDao _knokDao;
private readonly IKnokPriceDao _knokPriceDao;
private readonly IKnokPriceLogic _knokPriceLogic;
private readonly IKnokSettings _settings;
//TODO - move this to settings
private const decimal _objectiveWeight = 0.75m;
private const decimal _analysisMultiplier = 0.33m;
private const decimal _potenialProfitMultiplier = 10m;
private const decimal _profitTimeRatioMultiplier = 100m;
private const decimal _profitLossRatioMultiplier = 100m;
public KnokPriceManager(ILogger<KnokPriceManager> logger, IKnokDao knokDao, IUserDao userDao, IKnokPriceLogic knokPriceLogic, IKnokPriceDao knokPriceDao, IKnokSettings settings)
{
_logger = logger;
_userDao = userDao;
_knokDao = knokDao;
_knokPriceLogic = knokPriceLogic;
_knokPriceDao = knokPriceDao;
_settings = settings;
}
private async Task<decimal> GetExpectancy(long userId)
{
var probabilityOfWinning = await _knokPriceDao.GetProbabilityOfWinning(userId);
var winPayoff = await _knokPriceDao.GetWinPayoff(userId);
var lossPayoff = await _knokPriceDao.GetLossPayoff(userId);
return _knokPriceLogic.CalculateExpectancy(probabilityOfWinning, winPayoff, lossPayoff);
}
private decimal GetPaidPercent(UserRank userRank)
{
var userRankValue = (UserRankValues)userRank;
return ((int)userRankValue) / 100;
}
private async Task<decimal> GetObjectivePrice(long userId, UserRank userRank)
{
var expectancy = await GetExpectancy(userId);
var paidPercent = GetPaidPercent(userRank);
return _knokPriceLogic.CalculateObjectivePrice(expectancy, paidPercent, _objectiveWeight, _settings.Multiplier);
}
private decimal GetSubjectivePrice(CreateKnokArgs knok)
{
var faPrice = knok.Fundamental != null ?
_knokPriceLogic.CalcAnalysisPrice(knok.Fundamental.Header, knok.Fundamental.Description, knok.Fundamental.Tags, _analysisMultiplier) : 0m;
var taPrice = knok.Technical != null ?
_knokPriceLogic.CalcAnalysisPrice(knok.Technical.Header, knok.Technical.Description, knok.Technical.Tags, _analysisMultiplier) : 0m;
var potentialProfitPrice = _knokPriceLogic.CalculatePotentialProfitPrice(knok.PotentialProfitValue, _potenialProfitMultiplier);//a
var profitTimeRatioPrice = _knokPriceLogic.CalculateProfitTimeRatioPrice(knok.PotentialProfitValue,knok.Duration,_profitTimeRatioMultiplier);//b
var profitLossRatioPrice = _knokPriceLogic.CalculateProfitLossRatioPrice(knok.PotentialProfitValue, knok.EntryPriceFrom, knok.EntryPriceTo, knok.StopLoss, _profitLossRatioMultiplier);//c
return _knokPriceLogic.CalculateSubjectivePrice(faPrice, taPrice, potentialProfitPrice, profitTimeRatioPrice, profitLossRatioPrice);
}
private decimal GetNetContribution(CreateKnokArgs knok)
{
var subjectivePrice = GetSubjectivePrice(knok);
return subjectivePrice * (1 - _objectiveWeight);
}
public async Task<decimal> TotalPrice(CreateKnokArgs knok, long userId)
{
var users = await _userDao.GetUsers(userId: userId);
var userTypeId = users.First().UserTypeId;
var userRank = (UserRank)userTypeId;
knok.PotentialProfitValue = _knokPriceLogic.CalculatePotentialProfit(knok.EntryPriceFrom, knok.EntryPriceTo, knok.ExitPriceFrom, knok.ExitPriceTo);
var objectivePrice = await GetObjectivePrice(userId, userRank);
var netContribution = GetNetContribution(knok);
var rankPayoff = _knokPriceLogic.RankPayoff(userRank);
var rankWeighted = rankPayoff / 100m * netContribution;
return objectivePrice + rankWeighted;
}
}
}