public void Optimise(DateTime fromDate, DateTime toDate) { _stakingService.Evaluate(fromDate, toDate); Dictionary <int, List <int> > histogram = new(); var history = _marketDataCache.TakeUntil(toDate).ToArray(); for (var i = 1; i < history.Length; i++) { var previousPrice = Convert.ToInt32(history[i - 1].DeltaPercent); var currentPrice = Convert.ToInt32(history[i].DeltaPercent); if (!histogram.ContainsKey(previousPrice)) { histogram[previousPrice] = new List <int>(); } histogram[previousPrice].Add(currentPrice); } var parameters = Enumerable.Range(1, 100) .Select(x => new ProbabilityParameters { Threshold = -x, Histogram = histogram }); var optimal = _searcher.Maximum(parameters, fromDate, toDate); _parameters = (ProbabilityParameters)optimal; }
public IEnumerable <SimulationState> Evaluate( IStrategy strategy, Investor investor, DateTime?endDate = null, ProgressBar _ = null) { var state = new SimulationState(); foreach (var data in _dataCache.TakeUntil(endDate)) { var shouldBuy = _simulationCache.GetOrCreate((strategy, data.Date), () => ShouldBuy(strategy, data)); state = state.UpdateState(data, shouldBuy); state.AddFunds(investor.DailyFunds); state.ExecuteOrders(); if (state.ShouldBuy) { var funds = strategy.GetStake(data.Date, state.TotalFunds); state.AddBuyOrder(investor.OrderBrokerage, investor.OrderDelayDays, funds); } yield return(state); } }
public void RateMarketData(DateTime?toDate = null) { var buyDates = _marketDataCache .TakeUntil(toDate) .Skip(_marketDataCache.BacktestingIndex) .Select(x => x.Date) .ToDictionary(k => k, _ => true); using var progressBar = ProgressBarProvider.Create(_marketDataCache.BacktestingIndex, "Initialising..."); _marketAverage = SimulateBuyDates(buyDates); _marketMaximum = GetMarketMaximum(buyDates, progressBar); }
public bool ShouldBuy(MarketData data) { var batch = _marketDataCache.TakeUntil(data.Date).ToList().Last(_parameters.Window); if (batch.Length < 2) { return(false); } var xData = batch.Select(x => (double)x.Price).ToArray(); var yData = Enumerable.Range(0, batch.Length).Select(x => (double)x).ToArray(); var(intercept, gradient) = Fit.Line(xData, yData); return(gradient < (double)_parameters.Threshold); }
public void Optimise(DateTime fromDate, DateTime toDate) { _stakingService.Evaluate(fromDate, toDate); var history = _marketDataCache.TakeUntil(toDate).ToArray(); // Build 2d array where each cell is sized to has equal data points and probability var xData = history.Select(_xSelector).ToArray(); var yData = history.Select(_ySelector).ToArray(); var grid = new Grid <List <decimal> >(xData, yData, _parameters.Partitions); // Place each data point in appropriate cell var marketDataValues = _ratingService.CalculateMarketDataValues(history); foreach (var data in history) { var x = _xSelector(data); var y = _ySelector(data); var cell = grid[x, y]; marketDataValues.TryGetValue(data.Date, out var value); cell.Add(value); } // Determine the average value of each cell var averages = grid .Where(x => x.Any()) .Select(GetAverage) .Distinct() .ToArray(); var minValue = Convert.ToInt32(Math.Round(averages.Min(), MidpointRounding.ToNegativeInfinity)); var maxValue = Convert.ToInt32(Math.Round(averages.Max(), MidpointRounding.ToPositiveInfinity)); var range = maxValue - minValue; // Search for optimal buy threshold var potentials = Enumerable.Range(minValue, range) .SelectMany(t => Enumerable.Range(2, 8) .Select(p => new ClusteringParameters { Partitions = p, Threshold = -t, Grid = grid })); var optimal = _searcher.Maximum(potentials, fromDate, toDate); _parameters = (ClusteringParameters)optimal; }