public void BacktestMACD(decimal entryPrice, decimal exitPrice)
        {
            // 12/26 "slow" moving average for BNBUSD...buy when slow ma hits -0.2 and scale in more at -0.4
            var candles = ReadCandles("BINANCE", "BNBUSDT", 60);
            //var ema = GMath.GetCandlesEMA(candles, 26);
            var macd     = GMath.GetCandlesMACD(candles, 12, 26, 9);
            var backtest = new Backtest(string.Format("Entry:{0} Exit:{1}", entryPrice, exitPrice));
            BacktestRoundTrip inTrade = null;

            foreach (var kv in macd)
            {
                if (inTrade != null)
                {
                    if (kv.Value.Signal >= exitPrice)
                    {
                        inTrade.Exit = new BacktestTrade(OrderSide.Sell, exitPrice, kv.Key);
                        //Console.WriteLine("EXIT : {0} {1:0.0000}", kv.Key, kv.Value.Signal);
                        backtest.Add(inTrade);
                        inTrade = null;
                    }
                }
                else
                {
                    if (kv.Value.Signal <= entryPrice)
                    {
                        inTrade       = new BacktestRoundTrip();
                        inTrade.Entry = new BacktestTrade(OrderSide.Buy, entryPrice, kv.Key);
                        //Console.WriteLine("ENTRY: {0} {1:0.0000}", kv.Key, kv.Value.Signal);
                    }
                }
            }
            backtest.PrintTrades();
        }
    public override DatedDataCollectionGen<double> GenerateWeightSeries(Backtest.ProductBase product_, DateTime? minDate_)
    {
      var pxs = product_.Prices;
      var mas = new DatedDataCollectionGen<double>[m_windows.Length];

      for (int i = 0; i < mas.Length; ++i)
        mas[i] = HelperMethods.GetMA(pxs, m_windows[i]);

      double[] scores = new double[mas[0].Length];
      var dates = mas[0].Dates;

      for (int i = 0; i < dates.Length; ++i)
      {
        var date = dates[i];
        var px = pxs.ValueOnDate(date);

        for (int m = 0; m < mas.Length; ++m)
        {
          var maValue = mas[m].ValueOnDate(date);

          if (px > maValue)
            scores[i] += m_weightings[m_windows[m]];
          else
            scores[i] -= m_weightings[m_windows[m]];
        }
      }

      return new DatedDataCollectionGen<double>(dates, scores);
    }
 private static void TestShingle(int s)
 {
     using (var db = new Db())
     {
         var sh = db.Shingles.Find(s);
         Console.Write($"{sh.text}");
         var b = new Backtest
         {
             StrategyNr        = strategyNr,
             TakeProfitPercent = 3,
             StopLossPercent   = 1.5m,
             DaysToTimeout     = 5,
             SignalName        = s + " " + sh.text,
         };
         var     sus            = db.ShingleUses.Where(x => x.ShingleID == s && x.Article.Ticker != null).OrderBy(x => x.Article.ReceivedUTC).ToArray();
         decimal totalProfit    = 0;
         var     PredictionList = new List <Prediction>();
         var     LastTrade      = DateTime.MinValue;
         foreach (var su in sus)
         {
             if (su.Article.ReceivedUTC < LastTrade)
             {
                 continue;
             }
             Prediction t = Trade(DirectionType.Sell, su.Article.Ticker, su.Article.ReceivedUTC, b.TakeProfitPercent, b.StopLossPercent, b.Comment, b.DaysToTimeout, b.StrategyNr);
             if (t != null)
             {
                 PredictionList.Add(t);
                 totalProfit += t.Profit;
                 LastTrade    = t.TimeClose;
             }
         }
         if (PredictionList.Count > 0)
         {
             b.StrategyNr         = strategyNr++;
             b.Wins               = PredictionList.Count(x => x.Profit > 0);
             b.Loses              = PredictionList.Count(x => x.Profit <= 0);
             b.Takeprofits        = PredictionList.Count(x => x.Exit == ExitReason.TakeProfit);
             b.Stoploses          = PredictionList.Count(x => x.Exit == ExitReason.StopLoss);
             b.Timeouts           = PredictionList.Count(x => x.Exit == ExitReason.Timeout);
             b.Buys               = PredictionList.Count(x => x.BuySignal);
             b.Sells              = PredictionList.Count(x => !x.BuySignal);
             b.BuyProfit          = PredictionList.Where(x => x.BuySignal).Select(x => x.Profit).Sum();
             b.SellProfit         = PredictionList.Where(x => !x.BuySignal).Select(x => x.Profit).Sum();
             b.WinProfit          = PredictionList.Where(x => x.Profit > 0).Select(x => x.Profit).Sum();
             b.LossProfit         = PredictionList.Where(x => x.Profit < 0).Select(x => x.Profit).Sum();
             b.TimeoutProfit      = PredictionList.Where(x => x.Exit == ExitReason.Timeout).Select(x => x.Profit).Sum();
             b.AverageTradeLength = PredictionList.Select(x => (decimal)((x.TimeClose - x.TimeOpen).Days)).Average();
             b.TimeCalculated     = DateTime.Now;
             b.TillDate           = new DateTime(1900, 1, 1);
             b.FromDate           = new DateTime(1900, 1, 1);
             db.Backtests.Add(b);
             db.SaveChanges();
         }
         Console.WriteLine($" {totalProfit}");
     }
 }
        public static string Backtest(string buyScript, string sellScript, List <Bar> bars)
        {
            Backtest backtest = new Backtest();

            backtest.License        = TradeScriptKey;
            backtest.OnScriptError += backtest_OnError;
            AppendData(backtest, bars);
            return(backtest.RunBacktest(buyScript, sellScript, string.Empty, string.Empty, 0.00001f));
        }
Exemple #5
0
        static void Main(string[] args)
        {
            //Framework.Current.StrategyManager.Mode = StrategyMode.Live;

            //SmartQuant.Scenario scenario = new IndicatorTest(Framework.Current);
            //SmartQuant.Scenario scenario = new Backtest86400(Framework.Current);
            //SmartQuant.Scenario scenario = new Realtime86400(Framework.Current);
            // 在使用Backtest之前,需要先使用 PbTickDataExport._Main 生成 数据文件 D:\1.data 才能测试
            SmartQuant.Scenario scenario = new Backtest(Framework.Current);
            //SmartQuant.Scenario scenario = new RealtimeLoadOnStart(Framework.Current);
            //SmartQuant.Scenario scenario = new BacktestLoadOnStart(Framework.Current);

            scenario.Run();
        }
Exemple #6
0
    protected override void chartSignal(Backtest.ProductBase product_, Controls.LineChartDataDisplay chart_)
    {
      chart_.ClearSeries();
      chart_.AddSeries(product_.Prices, "Prices", 40, "##0.0##");
      chart_.AddSeries(HelperMethods.GetRollingStat(product_.Prices, MA, Statistics.Average), "MA", 40, "##0.0##");

      var series = product_.Prices;

      var rollingStdev = HelperMethods.GetRollingStat(product_.Prices.ToReturns(), 252, x => Statistics.Stdev(x)*Math.Sqrt(252d));

      chart_.AddSeries(rollingStdev, "Stdev", 80,
        "##0.0#%");

      chart_.AddSeries(
        HelperMethods.GetRollingStat(rollingStdev, 252, x => HelperMethods.GetPercentRank(x, x.Length - 1)),
        "Stdev_Pctile", 120, "0.00");
    }
Exemple #7
0
    public override void Chart(Controls.LineChartDataDisplay lcdd_, Backtest.ProductBase product_)
    {
      var pxs = product_.Prices;

      lcdd_.ClearSeries();
      lcdd_.AddSeries(pxs, string.Format("{0} price", product_.Name), 40, "##0.0##");

      if (MA1.HasValue)
        lcdd_.AddSeries(HelperMethods.GetRollingStat(pxs, MA1.Value, Statistics.Average),
          string.Format("MA({0})", MA1), 40, "##0.0##");

      if(MA2.HasValue)
        lcdd_.AddSeries(HelperMethods.GetRollingStat(pxs, MA2.Value, Statistics.Average),
          string.Format("MA({0})", MA2), 40, "##0.0##");

      if (MA3.HasValue)
        lcdd_.AddSeries(HelperMethods.GetRollingStat(pxs, MA3.Value, Statistics.Average),
          string.Format("MA({0})", MA3), 40, "##0.0##");
    }
Exemple #8
0
    public override DatedDataCollectionGen<double> GenerateWeightSeries(Backtest.ProductBase product_, DateTime? minDate_)
    {
      var pxs = product_.Prices;
      var mas = HelperMethods.GetRollingStat(pxs, MA, Statistics.Average);

      var scores = new double[mas.Length];

      for (int i = 0; i < scores.Length; ++i)
      {
        var px = pxs.ValueOnDate(mas.Dates[i]);
        var ma = mas.Data[i];

        if (px > ma)
          scores[i] = 1d;
        else
          scores[i] = -1d;
      }

      return new DatedDataCollectionGen<double>(mas.Dates, scores);
    }
Exemple #9
0
        public ctlBackTest(frmMain2 oMain, ctlData oData)
        {
            InitializeComponent();

            m_frmMain = oMain;
            m_ctlData = oData;
            oBacktest = new BacktestClass {
                License = "XRT93NQR79ABTW788XR48"
            };
            oScript = new ScriptOutputClass {
                License = "XRT93NQR79ABTW788XR48"
            };
            GetScriptNames();
            txtBars.GotFocus     += (sender, e) => Text_Focus((TextBoxBase)sender);
            txtInterval.GotFocus += (sender, e) => Text_Focus((TextBoxBase)sender);
            txtSymbol.GotFocus   += (sender, e) => Text_Focus((TextBoxBase)sender);

            oScript.ScriptError   += oScript_ScriptError;
            oBacktest.ScriptError += oBacktest_ScriptError;
        }
Exemple #10
0
        /// <summary>
        /// Wait for the backtest to complete
        /// </summary>
        /// <param name="projectId">Project id to scan</param>
        /// <param name="backtestId">Backtest id previously started</param>
        /// <returns>Completed backtest object</returns>
        private Backtest WaitForBacktestCompletion(int projectId, string backtestId)
        {
            var result = new Backtest();
            var finish = DateTime.Now.AddSeconds(60);

            while (DateTime.Now < finish)
            {
                result = _api.ReadBacktest(projectId, backtestId);
                if (result.Progress == 1)
                {
                    break;
                }
                if (!result.Success)
                {
                    break;
                }
                Thread.Sleep(1000);
            }
            return(result);
        }
Exemple #11
0
        public ctlBacktest(frmMain oMain, ctlData oData)
        {
            InitializeComponent();

            _mFrmMain  = oMain;
            _mCtlData  = oData;
            _oBacktest = new BacktestClass {
                License = "XRT93NQR79ABTW788XR48"
            };
            _oScript = new ScriptOutputClass {
                License = "XRT93NQR79ABTW788XR48"
            };

            txtBars.GotFocus     += (sender, e) => TextFocus((TextBoxBase)sender);
            txtInterval.GotFocus += (sender, e) => TextFocus((TextBoxBase)sender);
            txtSymbol.GotFocus   += (sender, e) => TextFocus((TextBoxBase)sender);

            _oScript.ScriptError   += OScriptScriptError;
            _oBacktest.ScriptError += OBacktestScriptError;
        }
 public override DatedDataCollectionGen<double> GenerateWeightSeries(Backtest.ProductBase product_,
   DateTime? wtsMinDate_)
 {
   return GenerateWeightSeries(product_.Prices, wtsMinDate_);
 }
Exemple #13
0
        public static void BackTest(string Date, string Weeks)
        {
            ///////////////////////////
            ///
            /// Setting backtest object
            ///
            //////////////////////////

            Backtest Mybacktest     = new Backtest();
            Backtest Mybacktest_adj = new Backtest();

            // Initial the two backtest

            Mybacktest.Init();
            Mybacktest_adj.Init();

            ///////////////////////////
            ///
            /// Setting data container to store the information
            /// outside the for loop
            ///
            ///////////////////////////

            // setting netvalue lists for both standard strategy and dynamic strategy

            List <double> Hisc_netValue = new List <double>();
            List <double> Adj_netValue  = new List <double>();

            // setting lists to store Fixed Income ETFs and Equity ETFs
            // we are holding during this trading week for the caculation of
            // Turnover Utility function

            List <string> ETFs_holding_FI  = new List <string>();
            List <string> ETFs_holding_Equ = new List <string>();

            // setting matrix to store the trading history during this backtest

            string[][] trading_history_ETF           = new string[Convert.ToInt64(Weeks)][];
            double[][] trading_history_allocation    = new double[Convert.ToInt64(Weeks)][];
            double[][] ADJtrading_history_allocation = new double[Convert.ToInt64(Weeks)][];

            // setting two variable drawdown and position ratio for the caculation
            // in Dynamic strategy, position ratio means the percentage of Fixed Income
            // ETFs we are currently holding

            double DrawDown       = 0;
            double Position_ratio = 0.2;

            int FI_holding_weeks  = 0;
            int Equ_holding_weeks = 0;

            double[] FI_holding_allocation  = new double[5];
            double[] Equ_holding_allocation = new double[5];

            //////////////////////////////////
            ///
            /// For loop backtest
            ///
            /////////////////////////////////


            for (int i = 0; i < Convert.ToInt64(Weeks); i++)
            {
                // seting Datapreprocessing class for both Fixed Income ETFs and Equity ETFs

                DataPreProcessing pro_FI  = new DataPreProcessing();
                DataPreProcessing pro_Equ = new DataPreProcessing();

                // caculate the date of today start from the 'Date'
                // which is given by backtest function

                var Today = DateTime.Parse(Date).AddDays(i * 7);

                // print the date we trained the model and trade

                Console.WriteLine("Date: {0}", Today.ToString());

                // cleaning data use data preprocessing class

                pro_FI.Run(Today.ToString(), 112, "Fixed Income");
                pro_Equ.Run(Today.ToString(), 112, "Equity");

                // Set prediction vector

                double[] predictions_FI  = new double[pro_FI.Trade_ETF.Count];
                double[] predictions_Equ = new double[pro_Equ.Trade_ETF.Count];

                // Set blend ETFs list to store the Top 10 etfs which is going to be
                // longed by the algorithm

                List <string> Blend_ETFs = new List <string>();

                /////////////////////////////
                ///                   ///////
                /// FI ETF prediction ///////
                ///                   ///////
                /////////////////////////////

                for (int j = 0; j < pro_FI.Trade_ETF.Count; j++)
                {
                    // Grab the data from the datapreprocessing object class

                    var y = pro_FI.Target_List[j];
                    var fy = new FrameBuilder.Columns <DateTime, string> {
                        { "Y", y }
                    }.Frame;
                    var data          = pro_FI.Feature_List[j].Join(fy);
                    var pred_Features = pro_FI.pred_Feature_List[j];

                    data.SaveCsv("dataset.csv");

                    // Training machine learning and predict

                    var prediction = Learning.FitGBT(pred_Features);

                    predictions_FI[j] = prediction;
                }

                // Get the minimum scores of top 5 ETF

                var hold_FI = PredRanking(predictions_FI, 5);

                // Get the namelist of top 5 ETF

                List <string> ETFs_FI = new List <string>();

                for (int m = 0; m < pro_FI.Trade_ETF.Count; m++)
                {
                    if (predictions_FI[m] >= hold_FI)
                    {
                        ETFs_FI.Add(pro_FI.Trade_ETF[m]);
                    }
                }


                // Caculate the bid-ask spread cost if trade all 5 ETFs given by algorithm

                double[] FixedIncomeSpread = new double[5];
                FixedIncomeSpread = GetBidAskSpread(ETFs_FI.ToArray());

                // Cacualte the Unitility and decide if we should trade this week

                if (i == 0)
                {
                    ETFs_holding_FI = ETFs_FI;
                }
                else
                {
                    // get all prediction results of both holding etf and etfs which we may be going to trade

                    double[] holding_pred = ETFname2Prediction(ETFs_holding_FI, predictions_FI, pro_FI);
                    double[] long_pred    = ETFname2Prediction(ETFs_FI, predictions_FI, pro_FI);

                    // caculate the trade diff which is the utility of trading this week

                    double trade_diff = long_pred.Sum() -
                                        holding_pred.Sum() -
                                        CaculateRebalanceCost(ETFs_FI,
                                                              ETFs_holding_FI,
                                                              FI_holding_allocation,
                                                              pro_FI);

                    // check if it is worth of trading

                    if (trade_diff < 0)
                    {
                        // It is not worth of trading and ETFs portfolio will be same

                        FI_holding_weeks += 1;
                        ETFs_FI           = ETFs_holding_FI;

                        // setting spread equals to 0 because we are not going to trade this week

                        FixedIncomeSpread = new double[] { 0, 0, 0, 0, 0 };
                    }
                    else
                    {
                        FI_holding_weeks = 0;

                        // It is worth of changing positions and trading this week !

                        // recaculate the spread costs because we may not going to trade all
                        // ETFs which we are holding right now.

                        for (int m = 0; m < 5; m++)
                        {
                            for (int n = 0; n < 5; n++)
                            {
                                if (ETFs_FI[m] == ETFs_holding_FI[n])
                                {
                                    FixedIncomeSpread[m] = 0;
                                }
                                else
                                {
                                    continue;
                                }
                            }
                        }

                        // resetting the fixed income ETFs  we are holding

                        ETFs_holding_FI = ETFs_FI;
                    }
                }

                Console.WriteLine("Long the following ETFs: ");

                // Store the Fixed Income ETFs namelist to blend ETFs list

                for (int n = 0; n < ETFs_FI.Count; n++)
                {
                    Console.WriteLine(ETFs_FI[n]);
                    Blend_ETFs.Add(ETFs_FI[n]);
                }

                ///////////////////////////////////
                ///                         ///////
                /// Equity ETF prediction   ///////
                ///                         ///////
                ///////////////////////////////////


                for (int j = 0; j < pro_Equ.Trade_ETF.Count; j++)
                {
                    // Run machine learning and predict next week for all ETFss

                    var y = pro_Equ.Target_List[j];

                    var fy = new FrameBuilder.Columns <DateTime, string> {
                        { "Y", y }
                    }.Frame;
                    var data          = pro_Equ.Feature_List[j].Join(fy);
                    var pred_Features = pro_Equ.pred_Feature_List[j];

                    data.SaveCsv("dataset.csv");

                    var prediction = Learning.FitGBT(pred_Features);

                    predictions_Equ[j] = prediction;
                }


                List <string> ETFs_Equ = new List <string>();

                // Find the min score of top 5 best ETFs

                var hold_Equ = PredRanking(predictions_Equ, 5);

                for (int m = 0; m < pro_Equ.Trade_ETF.Count; m++)
                {
                    if (predictions_Equ[m] >= hold_Equ)
                    {
                        ETFs_Equ.Add(pro_Equ.Trade_ETF[m]);
                    }
                }

                // caculate the bidAsk Spread

                double[] EquityBASpread = new double[5];
                EquityBASpread = GetBidAskSpread(ETFs_Equ.ToArray());

                if (i == 0)
                {
                    ETFs_holding_Equ = ETFs_Equ;
                }
                else
                {
                    double[] holding_pred = ETFname2Prediction(ETFs_holding_Equ, predictions_Equ, pro_Equ);
                    double[] long_pred    = ETFname2Prediction(ETFs_Equ, predictions_Equ, pro_Equ);

                    // Caculate the Utility

                    double trade_diff = long_pred.Sum() -
                                        holding_pred.Sum() -
                                        CaculateRebalanceCost(ETFs_Equ,
                                                              ETFs_holding_Equ,
                                                              Equ_holding_allocation,
                                                              pro_Equ);

                    // check if it is worth of trading this week

                    if (trade_diff < 0)
                    {
                        Equ_holding_weeks += 1;
                        ETFs_Equ           = ETFs_holding_Equ;
                        EquityBASpread     = new double[] { 0, 0, 0, 0, 0 };
                    }
                    else
                    {
                        // Recacluate the spread costs

                        Equ_holding_weeks = 0;

                        for (int m = 0; m < 5; m++)
                        {
                            for (int n = 0; n < 5; n++)
                            {
                                if (ETFs_Equ[m] == ETFs_holding_Equ[n])
                                {
                                    EquityBASpread[m] = 0;
                                }
                                else
                                {
                                    continue;
                                }
                            }
                        }

                        ETFs_holding_Equ = ETFs_Equ;
                    }
                }

                // Store the Equity ETFs we are going to long in Blend ETFs list

                for (int n = 0; n < ETFs_Equ.Count; n++)
                {
                    Console.WriteLine(ETFs_Equ[n]);
                    Blend_ETFs.Add(ETFs_Equ[n]);
                }

                //  Caculate optimized allocations for both Fixed income and Equity ETFs

                //////////////////////////////

                Console.WriteLine("Holding weeks for current Fixed Income ETFs is {0}", FI_holding_weeks);
                Console.WriteLine("Holding weeks for current Equity ETFs is {0}", Equ_holding_weeks);

                double[] AllocationFI = new double[5];

                if (FI_holding_weeks == 0)
                {
                    AllocationFI          = PO.ETF2AllocationOwnOptim(ETFs_FI, pro_FI);
                    FI_holding_allocation = AllocationFI;
                }
                else if (FI_holding_weeks < 15)
                {
                    AllocationFI = FI_holding_allocation;
                }
                else
                {
                    FI_holding_weeks      = 0;
                    AllocationFI          = PO.ETF2AllocationOwnOptim(ETFs_FI, pro_FI);
                    FI_holding_allocation = AllocationFI;
                }

                //////////////////////////////

                double[] AllocationEqu = new double[5];

                if (Equ_holding_weeks == 0)
                {
                    AllocationEqu          = PO.ETF2AllocationOwnOptim(ETFs_Equ, pro_Equ);
                    Equ_holding_allocation = AllocationEqu;
                }
                else if (Equ_holding_weeks < 15)
                {
                    AllocationEqu = Equ_holding_allocation;
                }
                else
                {
                    Equ_holding_weeks      = 0;
                    AllocationEqu          = PO.ETF2AllocationOwnOptim(ETFs_Equ, pro_Equ);
                    Equ_holding_allocation = AllocationEqu;
                }

                //////////////////////////////

                // Setting allocations which is an array to store allocations for strandard strategy

                double[] allocations = new double[10];

                for (int fi = 0; fi < 5; fi++)
                {
                    allocations[fi] = AllocationFI[fi] * 0.2;
                }

                for (int equ = 0; equ < 5; equ++)
                {
                    allocations[equ + 5] = AllocationEqu[equ] * 0.8;
                }


                // Setting ALLOCATION which is an array to store allocations for strandard strategy

                double[] ALLOCATION = new double[10];

                for (int fi = 0; fi < 5; fi++)
                {
                    ALLOCATION[fi] = AllocationFI[fi] * Position_ratio;
                }

                for (int equ = 0; equ < 5; equ++)
                {
                    ALLOCATION[equ + 5] = AllocationEqu[equ] * (1 - Position_ratio);
                }

                //  Transform ETFs list to an array

                string[] ETFs = new string[10];

                for (int etf = 0; etf < 10; etf++)
                {
                    ETFs[etf] = Blend_ETFs[etf];
                }

                // Storing the ETFs trading history and allocations

                trading_history_ETF[i] = new string[10];
                trading_history_ETF[i] = ETFs;

                trading_history_allocation[i] = new double[10];
                trading_history_allocation[i] = allocations;

                ADJtrading_history_allocation[i] = new double[10];
                ADJtrading_history_allocation[i] = ALLOCATION;

                // Get the spread array for all ETFs

                double[] spread = new double[10];

                Array.Copy(FixedIncomeSpread, spread, FixedIncomeSpread.Length);
                Array.Copy(EquityBASpread, 0, spread, FixedIncomeSpread.Length, EquityBASpread.Length);

                // Caculate the weighted spread for the adjustment in netvalue

                double weighted_spread = 0;

                for (int spreadItem = 0; spreadItem < 10; spreadItem++)
                {
                    weighted_spread += allocations[spreadItem] * spread[spreadItem];
                }

                // clearing the NetValue

                Hisc_netValue.Add(Mybacktest.Rebalance(Today, ETFs, allocations) * (1 - weighted_spread));
                Adj_netValue.Add(Mybacktest_adj.Rebalance(Today, ETFs, ALLOCATION) * (1 - weighted_spread));

                // Caculate the current drawdown and adjust the position ratio which is
                //  the percentage for the fixed income ETFs

                if (i == 0)
                {
                    DrawDown = 0;
                }
                else
                {
                    DrawDown = 1 - Hisc_netValue.Last() / Hisc_netValue.Max();
                }

                // Adjust the position ratio

                if (DrawDown > 0.1)
                {
                    Position_ratio = 0.8;
                }
                else if (DrawDown > 0.08)
                {
                    Position_ratio = 0.6;
                }
                else if (DrawDown > 0.05)
                {
                    Position_ratio = 0.4;
                }
                else
                {
                    Position_ratio = 0.2;
                }

                // Print out the current drawdown and position ratio.

                Console.WriteLine("Current drawdown is: {0}", DrawDown);
                Console.WriteLine("Fixed Income has been adjusted to: {0} %", Position_ratio * 100);
            }


            // Result analysis for NetValue

            /////////////////////
            ///
            /// Backtest Metrics of Strandard Strategy
            ///
            ////////////////////


            var StrategyNetValue = Hisc_netValue.ToArray();

            double MaxDD = 0;

            for (int i = 1; i < StrategyNetValue.Length; i++)
            {
                var    MaxNetValue = StrategyNetValue.Take(i).Max();
                double drawdown    = 1 - StrategyNetValue[i] / MaxNetValue;

                if (drawdown > MaxDD)
                {
                    MaxDD = drawdown;
                }
            }

            Console.WriteLine("Maximum drawdown of This Strategy is: {0}", MaxDD);

            var AnnualReturn = Math.Log(StrategyNetValue.Last()) /
                               (Convert.ToDouble(Weeks) / 50);

            Console.WriteLine("Annual Return of This Strategy is: {0}", AnnualReturn);

            var StrategyReturn = NetValue2Return(StrategyNetValue);

            Console.WriteLine("Standard Deviation of This Strategy is: {0}",
                              Statistics.StandardDeviation(StrategyReturn));

            double[] BTmetrics = new double[3];
            BTmetrics[0] = AnnualReturn;
            BTmetrics[1] = MaxDD;
            BTmetrics[2] = Statistics.StandardDeviation(StrategyReturn) * Math.Sqrt(50);

            // Result analysis for AdjNetValue

            /////////////////////
            ///
            /// Backtest Metrics of Dynamic Strategy
            ///
            /////////////////////

            var ADJStrategyNetValue = Adj_netValue.ToArray();

            double ADJMaxDD = 0;

            for (int i = 1; i < ADJStrategyNetValue.Length; i++)
            {
                var    MaxNetValue = ADJStrategyNetValue.Take(i).Max();
                double drawdown    = 1 - ADJStrategyNetValue[i] / MaxNetValue;

                if (drawdown > ADJMaxDD)
                {
                    ADJMaxDD = drawdown;
                }
            }


            Console.WriteLine("Maximum drawdown of ADJ Strategy is: {0}", ADJMaxDD);

            var ADJAnnualReturn = Math.Log(ADJStrategyNetValue.Last()) /
                                  (Convert.ToDouble(Weeks) / 50);

            Console.WriteLine("Annual Return of ADJ Strategy is: {0}", ADJAnnualReturn);

            var ADJStrategyReturn = NetValue2Return(ADJStrategyNetValue);

            Console.WriteLine("Standard Deviation of This Strategy is: {0}",
                              Statistics.StandardDeviation(ADJStrategyReturn));

            double[] ADJBTmetrics = new double[3];
            ADJBTmetrics[0] = ADJAnnualReturn;
            ADJBTmetrics[1] = ADJMaxDD;
            ADJBTmetrics[2] = Statistics.StandardDeviation(ADJStrategyReturn) * Math.Sqrt(50);

            // Output all results to CSV
            // Without position adjustment
            SaveArrayAsCSV_(trading_history_allocation, "StrandardTradingHistoryAllocation.csv");
            SaveArrayAsCSV(BTmetrics, "StandardBacktestMetrics.csv");
            SaveArrayAsCSV(StrategyNetValue, "StandardNet_value.csv");
            // With position adjustmnet
            SaveArrayAsCSV_(ADJtrading_history_allocation, "DynamicTradingHistoryAllocation.csv");
            SaveArrayAsCSV(ADJBTmetrics, "DynamicBacktestMetrics.csv");
            SaveArrayAsCSV(ADJStrategyNetValue, "DynamicNetValue.csv");

            SaveArrayAsCSV_ <string>(trading_history_ETF, "ETFTradingHistoryforALL.csv");

            Console.ReadKey();
        }
 protected override void chartSignal(Backtest.ProductBase product_, Controls.LineChartDataDisplay chart_)
 {
   chart_.AddSeries(product_.Prices, "Prices", 40, "##0.0##");
   chart_.AddSeries(GenerateWeightSeries(product_, product_.Prices.Dates[0]), "Score", 80, "##0.0%");
 }
    protected override void chartSignal(Backtest.ProductBase product_, Controls.LineChartDataDisplay chart_)
    {
      //chart_.AddSeries(getPeriodReturns(product_.Prices), "NPeriodReturns", 80, "##0.0#%");

      //chart_.AddSeries(getZScores(product_.Prices), "zScores", 80, "##0.0#");

      chart_.AddSeries(GenerateWeightSeries(product_,null), "SignalScores", 80, "##0.0#");
    }
 public abstract void Chart(SI.Controls.LineChartDataDisplay lcdd_, Backtest.ProductBase product_);
Exemple #17
0
    public override DatedDataCollectionGen<double> GenerateWeightSeries(Backtest.ProductBase product_, DateTime? minDate_)
    {
      var cumultRet = product_.Prices.ToReturns(product_.Convention).ToCumulative();
      var ma1 = HelperMethods.GetMA(cumultRet, MA1);
      var ma2 = HelperMethods.GetMA(cumultRet, MA2);
      var ma3 = HelperMethods.GetMA(cumultRet, MA3);

      var ks = HelperMethods.GetRollingStat(cumultRet, KWindow, HelperMethods.GetK);

      var turnoverThreshold = MinZScoreWinLength ?? 0d;

      if (product_ is Backtest.ProductFX
          && ((Backtest.ProductFX)product_).CoreProduct.IsGroup(Data.FXGroup.NDF))
        turnoverThreshold = 0.35;

      //var ccy = ((Backtest.ProductFX) product_).CoreProduct;

      var scores = new List<double>();

      for (int i = 0; i < ma3.Dates.Length; ++i)
      {
        var date = ma3.Dates[i];

        //var cov = Singleton<SI.Data.CovarianceSource>.Instance.GetCovarianceForDateElesePrevious(date);

        var m1 = ma1.ValueOnExactDate(date);
        var m2 = ma2.ValueOnExactDate(date);
        var m3 = ma3.ValueOnExactDate(date);
        var k = ks.ValueOnDate(date);

        var v = cumultRet.ValueOnExactDate(date);

        var todayScore = 0d;

        //if (v > m1 && v > m2 && v > m3)
        //{
        //  todayScore = 0.1; // 1.0
        //}
        //else if (v < m1 && v > m2 && v > m3)
        //{
        //  todayScore = 0.05; // 0.25
        //}
        //else if (v < m1 && v < m2 && v > m3)
        //{
        //  todayScore = -0.05; // -0.25
        //}
        //else if (v < m1 && v < m2 && v < m3)
        //{
        //  todayScore = -0.1; // -1.0
        //}
        //else if (v > m1 && v < m2 && v < m3)
        //{
        //  todayScore = -0.05; // -0.25
        //}
        //else if (v > m1 && v > m2 && v < m3)
        //{
        //  todayScore = 0.05; // 0.25
        //}
        //else
        //{
        //  todayScore = 0.0;
        //}

        //if (todayScore > 0d && k < KCutoff)
        //  todayScore = 0d;

        //if (todayScore < 0d && k > -KCutoff)
        //  todayScore = 0d;

        if (v > m1 && v > m2 && v > m3 && k > KCutoff)
          todayScore = 0.1;
        else if (v < m1 && v > m2 && v > m3 && k > KCutoff)
          todayScore = 0.05;
        else if (v < m1 && v < m2 && v > m3 & k < -KCutoff)
          todayScore = -0.05;
        else if (v < m1 && v < m2 && v < m3 & k < -KCutoff)
          todayScore = -0.1;
        else
          todayScore = 0d;

        if (i < 100)
        {
          scores.Add(todayScore);
          continue;
        }

        var yestScore = scores.Last();

        var shiftScore = Math.Abs(todayScore - yestScore);

        if (shiftScore > 0d)
        {
          // find the full period in which we've been in this score
          var index = scores.Count - 1;
          {
            while (index >= 0 && scores[index] == yestScore)
            {
              --index;
            }

            index = index + 1; // just move up to the first day that we had the same score as 'yestScore'
          }

          // get the cumulative return values in which we maintained the previous state

          var subValues = cumultRet.GetSubValues(ma3.Dates[index], ma3.Dates[i - 1]);

          // work out the maximum zScore during this period

          double zScoreUse;
          {
            var vol = product_.GetVol(date, Backtest.VolType.covar);

            var highRange = Math.Abs(v - subValues.Data.Max());
            var lowRange = Math.Abs(v -  subValues.Data.Min());

            zScoreUse = Math.Max(highRange, lowRange)*Math.Sqrt(252)/(vol*1.65);
          }

          if (MinZScoreWinLength.HasValue && subValues.Length < MinZScoreWinLength.Value)
          {
            todayScore = yestScore;
            //Console.WriteLine(string.Format("{0}-{1}", date, zScoreUse));
          }
          else if (zScoreUse < turnoverThreshold)
            todayScore = yestScore;
        }


        scores.Add(todayScore);
      }

      return new DatedDataCollectionGen<double>(ma3.Dates, scores.ToArray());
    }
Exemple #18
0
        private static void TestStrategy005(decimal TPPercent, decimal SLPercent, int DaysToTimeout, double BuyLimit, double SellLimit)
        {
            var PredictionList = new List <Prediction>();

            using (var ctx = new Db())
            {
                int?strategyNr = ctx.Database.SqlQuery <int?>("select 1 + max (StrategyNr) from fact.predictions").FirstOrDefault();
                var b          = new Backtest
                {
                    StrategyNr        = strategyNr == null ? 0 : strategyNr.Value,
                    TimeCalculated    = DateTime.Now,
                    TakeProfitPercent = TPPercent,
                    StopLossPercent   = SLPercent,
                    DaysToTimeout     = DaysToTimeout,
                    SignalName        = "Signal006",
                    SellLimit         = SellLimit,
                    BuyLimit          = BuyLimit,
                    FromDate          = new DateTime(2016, 12, 1),
                    TillDate          = new DateTime(2017, 1, 15),
                    MinShingleSamples = 10,
                    ShingleInterval   = DaysToTimeout,
                    Comment           = $"Signal006 Buylimit:{BuyLimit:0.##} Selllimit:{SellLimit:0.##} "
                };

                var orders = GetSignals006(10, BuyLimit, SellLimit, TPPercent, SLPercent, b.FromDate, b.TillDate);
                foreach (var ord in orders)
                {
                    var lastTrade = ctx.Database.SqlQuery <DateTime?>("select max(TimeClose) from fact.predictions where Ticker = @ticker and StrategyNr = @nr",
                                                                      new SqlParameter("@ticker", ord.Ticker),
                                                                      new SqlParameter("@nr", b.StrategyNr)).FirstOrDefault();
                    if (lastTrade != null && lastTrade.Value >= ord.Issued)
                    {
                        continue;
                    }
                    Prediction t = Trade(ord.Direction, ord.Ticker, ord.Issued, b.TakeProfitPercent, b.StopLossPercent, b.Comment, DaysToTimeout, b.StrategyNr);
                    if (t == null)
                    {
                        continue;
                    }
                    DisplayPrediction(t);
                    PredictionList.Add(t);
                    ctx.Predictions.Add(t);
                    ctx.SaveChanges();
                }
                if (PredictionList.Count > 0)
                {
                    b.Wins               = PredictionList.Count(x => x.Profit > 0);
                    b.Loses              = PredictionList.Count(x => x.Profit <= 0);
                    b.Takeprofits        = PredictionList.Count(x => x.Exit == ExitReason.TakeProfit);
                    b.Stoploses          = PredictionList.Count(x => x.Exit == ExitReason.StopLoss);
                    b.Timeouts           = PredictionList.Count(x => x.Exit == ExitReason.Timeout);
                    b.Buys               = PredictionList.Count(x => x.BuySignal);
                    b.Sells              = PredictionList.Count(x => !x.BuySignal);
                    b.BuyProfit          = PredictionList.Where(x => x.BuySignal).Select(x => x.Profit).Sum();
                    b.SellProfit         = PredictionList.Where(x => !x.BuySignal).Select(x => x.Profit).Sum();
                    b.WinProfit          = PredictionList.Where(x => x.Profit > 0).Select(x => x.Profit).Sum();
                    b.LossProfit         = PredictionList.Where(x => x.Profit < 0).Select(x => x.Profit).Sum();
                    b.TimeoutProfit      = PredictionList.Where(x => x.Exit == ExitReason.Timeout).Select(x => x.Profit).Sum();
                    b.AverageTradeLength = PredictionList.Select(x => (decimal)((x.TimeClose - x.TimeOpen).Days)).Average();
                    ctx.Backtests.Add(b);
                    ctx.SaveChanges();
                }
            }
        }
Exemple #19
0
    protected override void chartSignal(Backtest.ProductBase product_, Controls.LineChartDataDisplay chart_)
    {
      var cumultRet = product_.Prices.ToReturns(product_.Convention).ToCumulative();
      var ma1 = HelperMethods.GetMA(cumultRet, MA1);
      var ma2 = HelperMethods.GetMA(cumultRet, MA2);
      var ma3 = HelperMethods.GetMA(cumultRet, MA3);

      var ks = HelperMethods.GetRollingStat(cumultRet, KWindow, HelperMethods.GetK);


      chart_.ClearSeries();
      chart_.AddSeries(cumultRet, "Prices", 40, "##0.0##");
      chart_.AddSeries(ma1, string.Format("MA({0})", MA1), 40, "##0.0##");
      chart_.AddSeries(ma2, string.Format("MA({0})", MA2), 40, "##0.0##");
      chart_.AddSeries(ma3, string.Format("MA({0})", MA3), 40, "##0.0##");

      chart_.AddSeries(ks, string.Format("K({0})", KWindow), 80, "##0.0");
    }