예제 #1
0
        public override IEnumerable <Bar> Run(DateTime?startTime, DateTime?endTime)
        {
            //========== initialization ==========

            WarmupStartTime = Globals.WARMUP_START_TIME;
            StartTime       = Globals.START_TIME;
            EndTime         = Globals.END_TIME;

            Deposit(Globals.INITIAL_CAPITAL);
            CommissionPerShare = Globals.COMMISSION;

            // our universe consists of risky & safe assets
            var riskyAssets = AddDataSources(RISKY_ASSETS);
            var safeAssets  = AddDataSources(SAFE_ASSETS);
            var universe    = riskyAssets.Concat(safeAssets);

            var bench = AddDataSource(BENCHMARK);

            //========== simulation loop ==========

            foreach (var simTime in SimTimes)
            {
                // calculate indicators on overy bar
                Dictionary <Instrument, double> momentum = Instruments
                                                           .ToDictionary(
                    i => i,
                    i => (1.0 * i.Close.Momentum(21)[0]
                          + 3.0 * i.Close.Momentum(63)[0]
                          + 6.0 * i.Close.Momentum(126)[0]
                          + 12.0 * i.Close.Momentum(252)[0]) / 22.0);

                // skip if there are any instruments missing from our universe
                if (!HasInstruments(universe) || !HasInstrument(bench))
                {
                    continue;
                }

                // trigger rebalancing
                if (SimTime[0].Month != NextSimTime.Month) // monthly
                {
                    // calculate covariance
                    var covar = new PortfolioSupport.Covariance(Instruments, 12, 21); // 12 monthly bars

                    // calculate efficient frontier for universe
                    // note how momentum and covariance are annualized here
                    var cla = new PortfolioSupport.MarkowitzCLA(
                        universe.Select(ds => ds.Instrument),
                        i => 252.0 * momentum[i],
                        (i, j) => 252.0 / covar.BarSize * covar[i, j],
                        i => 0.0,
                        i => safeAssets.Contains(i.DataSource) ? 1.0 : MAX_RISKY_ALLOC);

                    // find portfolio with specified risk
                    var pf = cla.TargetVolatility(TVOL);

                    Output.WriteLine("{0:MM/dd/yyyy}: {1}", SimTime[0], pf.ToString());

                    // adjust all positions
                    _alloc.LastUpdate = SimTime[0];
                    foreach (var i in pf.Weights.Keys)
                    {
                        _alloc.Allocation[i] = pf.Weights[i];

                        int targetShares  = (int)Math.Floor(NetAssetValue[0] * pf.Weights[i] / i.Close[0]);
                        int currentShares = i.Position;

                        var ticket = i.Trade(targetShares - currentShares);

                        if (ticket != null)
                        {
                            if (i.Position == 0)
                            {
                                ticket.Comment = "open";
                            }
                            else if (targetShares == 0)
                            {
                                ticket.Comment = "close";
                            }
                            else
                            {
                                ticket.Comment = "rebalance";
                            }
                        }
                    }
                }

                // plotter output
                if (!IsOptimizing && TradingDays > 0)
                {
                    _plotter.AddNavAndBenchmark(this, FindInstrument(BENCHMARK));
                    _plotter.AddStrategyHoldings(this, universe.Select(ds => ds.Instrument));
                    if (_alloc.LastUpdate == SimTime[0])
                    {
                        _plotter.AddTargetAllocationRow(_alloc);
                    }

                    if (IsDataSource)
                    {
                        var v = 10.0 * NetAssetValue[0] / Globals.INITIAL_CAPITAL;
                        yield return(Bar.NewOHLC(
                                         this.GetType().Name, SimTime[0],
                                         v, v, v, v, 0));
                    }
                }
            }

            //========== post processing ==========

            if (!IsOptimizing)
            {
                _plotter.AddTargetAllocation(_alloc);
                _plotter.AddOrderLog(this);
                _plotter.AddPositionLog(this);
                _plotter.AddPnLHoldTime(this);
                _plotter.AddMfeMae(this);
                _plotter.AddParameters(this);
            }

            FitnessValue = this.CalcFitness();
        }
예제 #2
0
        public override void Run()
        {
            //---------- initialization

            StartTime = DateTime.Parse("01/01/1990");
            EndTime   = DateTime.Now.Date - TimeSpan.FromDays(5);

            // our universe consists of risky & safe assets
            var universe = RISKY_ASSETS
                           .Concat(SAFE_ASSETS).ToList();

            // add all data sources
            AddDataSource(BENCHMARK);
            foreach (var nick in universe)
            {
                AddDataSource(nick);
            }

            Deposit(1e6);
            CommissionPerShare = 0.015;

            //---------- simulation loop

            foreach (var simTime in SimTimes)
            {
                // calculate indicators on overy bar
                Dictionary <Instrument, double> momentum = Instruments
                                                           .ToDictionary(
                    i => i,
                    i => (1.0 * i.Close.Momentum(21)[0]
                          + 3.0 * i.Close.Momentum(63)[0]
                          + 6.0 * i.Close.Momentum(126)[0]
                          + 12.0 * i.Close.Momentum(252)[0]) / 22.0);

                // skip if there are any instruments missing from our universe
                if (!HasInstruments(universe))
                {
                    continue;
                }

                // trigger rebalancing
                if (SimTime[0].Month != SimTime[1].Month) // monthly
                {
                    // calculate covariance
                    var covar = new PortfolioSupport.Covariance(Instruments, 12, 21); // 12 monthly bars

                    // calculate efficient frontier for universe
                    // note how momentum and covariance are annualized here
                    var cla = new PortfolioSupport.MarkowitzCLA(
                        Instruments.Where(i => universe.Contains(i.Nickname)),
                        i => 252.0 * momentum[i],
                        (i, j) => 252.0 / covar.BarSize * covar[i, j], // TODO: is sqrt correct?
                        i => 0.0,
                        i => SAFE_ASSETS.Contains(i.Nickname) ? 1.0 : MAX_RISKY_ALLOC);

                    // find portfolio with specified risk
                    var pf = cla.TargetVolatility(TVOL);

                    Output.WriteLine("{0:MM/dd/yyyy}: {1}", SimTime[0], pf.ToString());

                    // adjust all positions
                    foreach (var i in pf.Weights.Keys)
                    {
                        int targetShares  = (int)Math.Floor(NetAssetValue[0] * pf.Weights[i] / i.Close[0]);
                        int currentShares = i.Position;

                        var ticket = i.Trade(targetShares - currentShares);

                        if (ticket != null)
                        {
                            if (i.Position == 0)
                            {
                                ticket.Comment = "open";
                            }
                            else if (targetShares == 0)
                            {
                                ticket.Comment = "close";
                            }
                            else
                            {
                                ticket.Comment = "rebalance";
                            }
                        }
                    }
                }

                _benchmark = _benchmark ?? FindInstrument(BENCHMARK);
                _plotter.SelectChart(Name, "date");
                _plotter.SetX(SimTime[0]);
                _plotter.Plot("NAV", NetAssetValue[0]);
                _plotter.Plot(_benchmark.Symbol, _benchmark.Close[0]);

                _plotter.SelectChart(Name + " holdings", "date");
                _plotter.SetX(SimTime[0]);
                foreach (var n in universe)
                {
                    var i = FindInstrument(n);
                    _plotter.Plot(i.Symbol, i.Position * i.Close[0] / NetAssetValue[0]);
                }
            }

            //---------- post-processing

            _plotter.SelectChart(Name + " trades", "date");
            foreach (LogEntry entry in Log)
            {
                _plotter.SetX(entry.BarOfExecution.Time);
                _plotter.Plot("action", entry.Action);
                _plotter.Plot("type", entry.InstrumentType);
                _plotter.Plot("instr", entry.Symbol);
                _plotter.Plot("qty", entry.OrderTicket.Quantity);
                _plotter.Plot("fill", entry.FillPrice);
                _plotter.Plot("gross", -entry.OrderTicket.Quantity * entry.FillPrice);
                _plotter.Plot("commission", -entry.Commission);
                _plotter.Plot("net", -entry.OrderTicket.Quantity * entry.FillPrice - entry.Commission);
                _plotter.Plot("comment", entry.OrderTicket.Comment ?? "");
            }
        }