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);
            }
        }
示例#3
0
        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;
        }