Ejemplo n.º 1
0
        public JsonResult SpotPriceSimulation(
            int[] timeStepsInLevels, double[] priceLevels,
            double timeStep, double reversionRate, double volatility,
            int numberOfSimulations)
        {
            if (timeStepsInLevels.Length != priceLevels.Length)
            {
                throw new Exception("Lengths not consistent");
            }

            //hourly simulation
            var horizon = timeStepsInLevels.Sum() * 24; //

            //TODO: add daily/hourly resolution... if it makes sense... but not really.

            //estimate an hourly ARMA...
            var d = AppData.GetHistoricalSeries(PricesController._timeSeries);

            var data = d
                       .Select(x => x.Value != null ? (double)x.Value : 0) //0 for now, when interpolation is done... etc..
                       .ToArray();

            //just take last 3 years... mhm...
            var threeYears = 24 * 7 * 4 * 12 * 3;

            if (data.Length > threeYears)
            {
                data = data.Skip(data.Length - threeYears).Take(threeYears).ToArray();
            }
            //detrend to make stationary
            data = TimeSeries.toStationary(data);

            //hourly
            //var seasons = new int[] { 24, 24 * 7, 24 * 7 * 4, 24 * 7 * 4 * 6, 24 * 7 * 4 * 12};
            //var arSes = new int[] { 1, 2, 24, 25 };

            //daily
            //var seasons = new int[] { 7, 7*4, 7*4*12 };
            //var arSes = new int[] { 1, 7, 7*4 };

            //var arma = TimeSeries.ARMASimple2(data, arSes, seasons);

            //fitted model from matlab
            var arlags = new int[] { 1, 2, 24, 25 };
            //var ar = new TimeSeries.LagOp(new double[] { 1.04216, -0.125323, 0.777886, -0.699448 }, arlags);
            var malags = new int[] { 24, 168 };
            //var ma = new TimeSeries.LagOp(new double[] { -0.44595, 0.175135 }, malags);
            //var xarma = TimeSeries.ARMASimple3(ar, ma, 0.166685, 2.80023);

            //our fitting procedure.. difference...? not much...
            var arma = TimeSeries.ARMASimple2(data, arlags, malags);

            arma = TimeSeries.ARMASimple3(arma.AR, arma.MA, arma.Const, volatility);

            var inSampleRes = TimeSeries.Infer(arma, data);

            var sims = arma.Simulate(numberOfSimulations, horizon, data, inSampleRes);

            var hoursSteps = timeStepsInLevels.Select(x => x * 24).ToArray();

            var desezonalizedData = Desezonalize(data, 168);

            //add the spikes
            //Then perform the spike estimation
            var spikesThreshold = 1.7;
            var spikeIndices    = EstimateSpikesOnMovSDs(desezonalizedData, 24, 2, spikesThreshold);

            //select hour
            var peakHour         = 16;
            var peakhourData     = TakeShortPeriods(data, 1, peakHour, 24);
            var peakSpikeIndices = EstimateSpikesOnMovSDs(peakhourData, 7, 2, spikesThreshold);
            var distrib          = EstimateSpikesDistribution(peakhourData, peakSpikeIndices, Forecast.SpikePreprocess.SimilarDay, spikesThreshold);

            //for testing..
            var n = new Normal(distrib.Item1.Mean, distrib.Item1.Variance);
            var p = new Poisson(distrib.Item2.Lambda * 24);

            //replace spikes now...
            //TODO: replace at the right hour... yes...
            sims = Simulations.spikeSimulationsReplace(sims, p, n);

            //fit the forward curve
            sims = Simulations.liftSeriesToPriceCurve(sims, hoursSteps, priceLevels);

            return(Json(sims));
        }