Esempio n. 1
0
        public static double[] PriceDataFE_pred(Series <DateTime, double> input)
        {
            int shiftn = 0;

            var data = input.Shift(shiftn);

            var MA3  = data.Window(3).Select(x => x.Value.Mean());
            var MA5  = data.Window(5).Select(x => x.Value.Mean());
            var MA10 = data.Window(10).Select(x => x.Value.Mean());

            var dataMA3  = (data / MA3).Select(x => Math.Log(x.Value));
            var dataMA5  = (data / MA5).Select(x => Math.Log(x.Value));
            var dataMA10 = (data / MA10).Select(x => Math.Log(x.Value));

            var MA3MA5  = (MA3 / MA5).Select(x => Math.Log(x.Value));
            var MA3MA10 = (MA3 / MA10).Select(x => Math.Log(x.Value));
            var MA5MA10 = (MA5 / MA10).Select(x => Math.Log(x.Value));

            var MMP3  = data.Window(3).Select(x => Math.Log(x.Value.Max() / x.Value.Min()));
            var MMP5  = data.Window(5).Select(x => Math.Log(x.Value.Max() / x.Value.Min()));
            var MMP10 = data.Window(10).Select(x => Math.Log(x.Value.Max() / x.Value.Min()));

            string dataMA3column  = "PriceMA3" + Convert.ToString(shiftn);
            string dataMA5column  = "PriceMA5" + Convert.ToString(shiftn);
            string dataMA10column = "PriceMA10" + Convert.ToString(shiftn);

            string MA3MA5column  = "MA3MA5PRICE" + Convert.ToString(shiftn);
            string MA3MA10column = "MA3MA10PRICE" + Convert.ToString(shiftn);
            string MA5MA10column = "MA5MA10PRICE" + Convert.ToString(shiftn);

            string MMP3column  = "MMP3" + Convert.ToString(shiftn);
            string MMP5column  = "MMP5" + Convert.ToString(shiftn);
            string MMP10column = "MMP10" + Convert.ToString(shiftn);

            var Features = new FrameBuilder.Columns <DateTime, string> {
                { dataMA3column, dataMA3 },
                { dataMA5column, dataMA5 },
                { dataMA10column, dataMA10 },
                { MA3MA5column, MA3MA5 },
                { MA3MA10column, MA3MA10 },
                { MA5MA10column, MA5MA10 },
                { MMP3column, MMP3 },
                { MMP5column, MMP5 },
                { MMP10column, MMP10 }
            }.Frame;

            var row_length = Features.RowCount;
            var col_length = Features.ColumnCount;

            double[] delay_1 = Features.GetRowAt <double>(row_length - 1).Values.ToArray <double>();

            double[] features_pred = new double[col_length];

            for (int i = 0; i < col_length; i++)
            {
                features_pred[i] = delay_1[i];
            }

            return(features_pred);
        }
Esempio n. 2
0
        public static void SumOfFrame()
        {
            var builder = new FrameBuilder.Columns <int, string>();

            builder.Add("column1", new[] { 1, 2, 3, 4 }.ToOrdinalSeries());
            builder.Add("column2", new[] { 1, 2, 3, 4 }.ToOrdinalSeries());
            builder.Add("column3", new[] { 1, 2, 3, 4 }.ToOrdinalSeries());
            builder.Add("column4", new[] { 1, 2, 3, 4 }.ToOrdinalSeries());
            var df  = builder.Frame;
            var sum = df.Sum().GetAllValues().ToArray();

            Assert.AreEqual(10.0, sum[0].Value);
            Assert.AreEqual(10.0, sum[1].Value);
        }
Esempio n. 3
0
        public static void FramesOrderedAfterBuild()
        {
            var builder = new FrameBuilder.Columns <int, string>();

            builder.Add("column1", new[] { 1, 2, 3, 4 }.ToOrdinalSeries());
            builder.Add("column2", new[] { 1, 2, 3, 4 }.ToOrdinalSeries());
            builder.Add("column3", new[] { 1, 2, 3, 4 }.ToOrdinalSeries());
            builder.Add("column4", new[] { 1, 2, 3, 4 }.ToOrdinalSeries());
            var frame = builder.Frame;

            Assert.AreEqual(
                new[] { "column1", "column2", "column3", "column4" },
                frame.ColumnKeys.ToArray()
                );
        }
Esempio n. 4
0
        public static Frame <DateTime, string> PriceDataFE(Series <DateTime, double> input)
        {
            int shiftn = 1;

            var data = input.Shift(shiftn);

            var MA3  = data.Window(3).Select(x => x.Value.Mean());
            var MA5  = data.Window(5).Select(x => x.Value.Mean());
            var MA10 = data.Window(10).Select(x => x.Value.Mean());

            var dataMA3  = (data / MA3).Select(x => Math.Log(x.Value));
            var dataMA5  = (data / MA5).Select(x => Math.Log(x.Value));
            var dataMA10 = (data / MA10).Select(x => Math.Log(x.Value));

            var MA3MA5  = (MA3 / MA5).Select(x => Math.Log(x.Value));
            var MA3MA10 = (MA3 / MA10).Select(x => Math.Log(x.Value));
            var MA5MA10 = (MA5 / MA10).Select(x => Math.Log(x.Value));

            var MMP3  = data.Window(3).Select(x => Math.Log(x.Value.Max() / x.Value.Min()));
            var MMP5  = data.Window(5).Select(x => Math.Log(x.Value.Max() / x.Value.Min()));
            var MMP10 = data.Window(10).Select(x => Math.Log(x.Value.Max() / x.Value.Min()));

            string dataMA3column  = "PriceMA3" + Convert.ToString(shiftn);
            string dataMA5column  = "PriceMA5" + Convert.ToString(shiftn);
            string dataMA10column = "PriceMA10" + Convert.ToString(shiftn);

            string MA3MA5column  = "MA3MA5PRICE" + Convert.ToString(shiftn);
            string MA3MA10column = "MA3MA10PRICE" + Convert.ToString(shiftn);
            string MA5MA10column = "MA5MA10PRICE" + Convert.ToString(shiftn);

            string MMP3column  = "MMP3" + Convert.ToString(shiftn);
            string MMP5column  = "MMP5" + Convert.ToString(shiftn);
            string MMP10column = "MMP10" + Convert.ToString(shiftn);

            var Features = new FrameBuilder.Columns <DateTime, string> {
                { dataMA3column, dataMA3 },
                { dataMA5column, dataMA5 },
                { dataMA10column, dataMA10 },
                { MA3MA5column, MA3MA5 },
                { MA3MA10column, MA3MA10 },
                { MA5MA10column, MA5MA10 },
                { MMP3column, MMP3 },
                { MMP5column, MMP5 },
                { MMP10column, MMP10 }
            }.Frame;

            return(Features);
        }
Esempio n. 5
0
        public static void CanGetColumnDynamically()
        {
            for (int i = 1; i <= 2; i++) // Run this twice, to check that instance references are right
            {
                var df =
                    new FrameBuilder.Columns<int, string> {
                    { "Test", new SeriesBuilder<int> { {1, 11.1}, {2,22.2} }.Series }
                }.Frame;
                dynamic dfd = df;

                Series<int, double> s0 = dfd.Test;
                dynamic s1 = dfd.Test;

                Assert.AreEqual(11.1, s0[1]);
                Assert.AreEqual(11.1, s1[1]);
            }
        }
Esempio n. 6
0
File: Frame.cs Progetto: mysl/Deedle
        public static void CanGetColumnDynamically()
        {
            for (int i = 1; i <= 2; i++)             // Run this twice, to check that instance references are right
            {
                var df =
                    new FrameBuilder.Columns <int, string> {
                    { "Test", new SeriesBuilder <int> {
                          { 1, 11.1 }, { 2, 22.2 }
                      }.Series }
                }.Frame;
                dynamic dfd = df;

                Series <int, double> s0 = dfd.Test;
                dynamic s1 = dfd.Test;

                Assert.AreEqual(11.1, s0[1]);
                Assert.AreEqual(11.1, s1[1]);
            }
        }
Esempio n. 7
0
        public static void CanAddSeriesDynamically()
        {
            for (int i = 1; i <= 2; i++) // Run this twice, to check that instance references are right
            {
                var df =
                    new FrameBuilder.Columns<int, string> {
                    { "Test", new SeriesBuilder<int> { {1, 11.1}, {2,22.4} }.Series }
                }.Frame;
                dynamic dfd = df;
                dfd.Test1 = new[] { 1, 2 };
                dfd.Test2 = df.GetColumn<double>("Test");
                dfd.Test3 = new Dictionary<int, string> { { 1, "A" }, { 2, "B" } };
                var row = df.Rows[2];

                Assert.AreEqual(22.4, row["Test"]);
                Assert.AreEqual(2, row["Test1"]);
                Assert.AreEqual(22.4, row["Test2"]);
                Assert.AreEqual("B", ((KeyValuePair<int, string>)row["Test3"]).Value);
            }
        }
Esempio n. 8
0
File: Frame.cs Progetto: mysl/Deedle
        public static void CanAddSeriesDynamically()
        {
            for (int i = 1; i <= 2; i++)             // Run this twice, to check that instance references are right
            {
                var df =
                    new FrameBuilder.Columns <int, string> {
                    { "Test", new SeriesBuilder <int> {
                          { 1, 11.1 }, { 2, 22.4 }
                      }.Series }
                }.Frame;
                dynamic dfd = df;
                dfd.Test1 = new[] { 1, 2 };
                dfd.Test2 = df.GetColumn <double>("Test");
                dfd.Test3 = new Dictionary <int, string> {
                    { 1, "A" }, { 2, "B" }
                };
                var row = df.Rows[2];

                Assert.AreEqual(22.4, row["Test"]);
                Assert.AreEqual(2, row["Test1"]);
                Assert.AreEqual(22.4, row["Test2"]);
                Assert.AreEqual("B", ((KeyValuePair <int, string>)row["Test3"]).Value);
            }
        }
Esempio n. 9
0
        public static double[] Features_engineering_pred(Series <DateTime, double> input)
        {
            // Features engineering function for generating prediction input

            int shiftn = 0;

            var data = input.Shift(shiftn);

            var data2 = data.Select(x => Math.Pow(x.Value, 2));

            var MA3  = data.Window(3).Select(x => x.Value.Mean());
            var MA5  = data.Window(5).Select(x => x.Value.Mean());
            var MA10 = data.Window(10).Select(x => x.Value.Mean());

            var diffdataMA3  = (data / MA3).Select(x => x.Value - 1);
            var diffdataMA5  = (data / MA5).Select(x => x.Value - 1);
            var diffdataMA10 = (data / MA10).Select(x => x.Value - 1);

            var diffMA3MA5  = (MA3 / MA5).Select(x => x.Value - 1);
            var diffMA3MA10 = (MA3 / MA10).Select(x => x.Value - 1);
            var diffMA5MA10 = (MA5 / MA10).Select(x => x.Value - 1);

            var SD3  = data.Window(3).Select(x => x.Value.StdDev());
            var SD5  = data.Window(5).Select(x => x.Value.StdDev());
            var SD10 = data.Window(10).Select(x => x.Value.StdDev());

            var RSI3  = data.Window(3).Select(x => RSI_func(x, 3));
            var RSI5  = data.Window(5).Select(x => RSI_func(x, 5));
            var RSI10 = data.Window(10).Select(x => RSI_func(x, 10));

            var K3  = data.Window(3).Select(x => K_func(x, 3));
            var K5  = data.Window(5).Select(x => K_func(x, 5));
            var K10 = data.Window(10).Select(x => K_func(x, 10));

            string Returncolumn = "Return" + Convert.ToString(shiftn);
            string Powercolumn  = "Power" + Convert.ToString(shiftn);

            string MA3column  = "MA3" + Convert.ToString(shiftn);
            string MA5column  = "MA5" + Convert.ToString(shiftn);
            string MA10column = "MA10" + Convert.ToString(shiftn);

            string SD3column  = "SD3" + Convert.ToString(shiftn);
            string SD5column  = "SD5" + Convert.ToString(shiftn);
            string SD10column = "SD10" + Convert.ToString(shiftn);

            string CompareDataColumn1 = "dataMA3" + Convert.ToString(shiftn);
            string CompareDataColumn2 = "dataMA5" + Convert.ToString(shiftn);
            string CompareDataColumn3 = "dataMA10" + Convert.ToString(shiftn);

            string Compare1column = "MA3MA5" + Convert.ToString(shiftn);
            string Compare2column = "MA3MA10" + Convert.ToString(shiftn);
            string Compare3column = "MA5MA10" + Convert.ToString(shiftn);

            string RSI3column  = "RSI3" + Convert.ToString(shiftn);
            string RSI5column  = "RSI5" + Convert.ToString(shiftn);
            string RSI10column = "RSI10" + Convert.ToString(shiftn);

            string K3column  = "K3" + Convert.ToString(shiftn);
            string K5column  = "K5" + Convert.ToString(shiftn);
            string K10column = "K10" + Convert.ToString(shiftn);

            var Features = new FrameBuilder.Columns <DateTime, string> {
                { Returncolumn, data },
                { Powercolumn, data2 },
                { MA3column, MA3 },
                { MA5column, MA5 },
                { MA10column, MA10 },
                { Compare1column, diffMA3MA5 },
                { Compare2column, diffMA3MA10 },
                { Compare3column, diffMA5MA10 },
                { CompareDataColumn1, diffdataMA3 },
                { CompareDataColumn2, diffdataMA5 },
                { CompareDataColumn3, diffdataMA10 },
                { SD3column, SD3 },
                { SD5column, SD5 },
                { SD10column, SD10 },
                { RSI3column, RSI3 },
                { RSI5column, RSI5 },
                { RSI10column, RSI10 },
                { K3column, K3 },
                { K5column, K5 },
                { K10column, K10 }
            }.Frame;

            var row_length = Features.RowCount;
            var col_length = Features.ColumnCount;

            double[] delay_1 = Features.GetRowAt <double>(row_length - 1).Values.ToArray <double>();
            double[] delay_2 = Features.GetRowAt <double>(row_length - 2).Values.ToArray <double>();
            double[] delay_3 = Features.GetRowAt <double>(row_length - 3).Values.ToArray <double>();

            double[] features_pred = new double[col_length * 3];

            for (int i = 0; i < col_length; i++)
            {
                features_pred[i] = delay_1[i];
            }
            for (int i = 0; i < col_length; i++)
            {
                features_pred[i + col_length] = delay_2[i];
            }
            for (int i = 0; i < col_length; i++)
            {
                features_pred[i + col_length * 2] = delay_3[i];
            }

            return(features_pred);
        }
Esempio n. 10
0
        public static Frame <DateTime, string> Features_engineering(Series <DateTime, double> input, int shiftn)
        {
            //Features Engineering function for training machine learning

            var data = input.Shift(shiftn);

            var data2 = data.Select(x => Math.Pow(x.Value, 2));

            var MA3  = data.Window(3).Select(x => x.Value.Mean());
            var MA5  = data.Window(5).Select(x => x.Value.Mean());
            var MA10 = data.Window(10).Select(x => x.Value.Mean());

            var diffdataMA3  = (data / MA3).Select(x => x.Value - 1);
            var diffdataMA5  = (data / MA5).Select(x => x.Value - 1);
            var diffdataMA10 = (data / MA10).Select(x => x.Value - 1);

            var diffMA3MA5  = (MA3 / MA5).Select(x => x.Value - 1);
            var diffMA3MA10 = (MA3 / MA10).Select(x => x.Value - 1);
            var diffMA5MA10 = (MA5 / MA10).Select(x => x.Value - 1);

            var SD3  = data.Window(3).Select(x => x.Value.StdDev());
            var SD5  = data.Window(5).Select(x => x.Value.StdDev());
            var SD10 = data.Window(10).Select(x => x.Value.StdDev());

            var RSI3  = data.Window(3).Select(x => RSI_func(x, 3));
            var RSI5  = data.Window(5).Select(x => RSI_func(x, 5));
            var RSI10 = data.Window(10).Select(x => RSI_func(x, 10));

            var K3  = data.Window(3).Select(x => K_func(x, 3));
            var K5  = data.Window(5).Select(x => K_func(x, 5));
            var K10 = data.Window(10).Select(x => K_func(x, 10));

            string Returncolumn = "Return" + Convert.ToString(shiftn);
            string Powercolumn  = "Power" + Convert.ToString(shiftn);

            string MA3column  = "MA3" + Convert.ToString(shiftn);
            string MA5column  = "MA5" + Convert.ToString(shiftn);
            string MA10column = "MA10" + Convert.ToString(shiftn);

            string SD3column  = "SD3" + Convert.ToString(shiftn);
            string SD5column  = "SD5" + Convert.ToString(shiftn);
            string SD10column = "SD10" + Convert.ToString(shiftn);

            string CompareDataColumn1 = "dataMA3" + Convert.ToString(shiftn);
            string CompareDataColumn2 = "dataMA5" + Convert.ToString(shiftn);
            string CompareDataColumn3 = "dataMA10" + Convert.ToString(shiftn);

            string Compare1column = "MA3MA5" + Convert.ToString(shiftn);
            string Compare2column = "MA3MA10" + Convert.ToString(shiftn);
            string Compare3column = "MA5MA10" + Convert.ToString(shiftn);

            string RSI3column  = "RSI3" + Convert.ToString(shiftn);
            string RSI5column  = "RSI5" + Convert.ToString(shiftn);
            string RSI10column = "RSI10" + Convert.ToString(shiftn);

            string K3column  = "K3" + Convert.ToString(shiftn);
            string K5column  = "K5" + Convert.ToString(shiftn);
            string K10column = "K10" + Convert.ToString(shiftn);

            var Features = new FrameBuilder.Columns <DateTime, string> {
                { Returncolumn, data },
                { Powercolumn, data2 },
                { MA3column, MA3 },
                { MA5column, MA5 },
                { MA10column, MA10 },
                { Compare1column, diffMA3MA5 },
                { Compare2column, diffMA3MA10 },
                { Compare3column, diffMA5MA10 },
                { CompareDataColumn1, diffdataMA3 },
                { CompareDataColumn2, diffdataMA5 },
                { CompareDataColumn3, diffdataMA10 },
                { SD3column, SD3 },
                { SD5column, SD5 },
                { SD10column, SD10 },
                { RSI3column, RSI3 },
                { RSI5column, RSI5 },
                { RSI10column, RSI10 },
                { K3column, K3 },
                { K5column, K5 },
                { K10column, K10 }
            }.Frame;


            return(Features);
        }
        //------------------------------------------------------------------------------------------------
        public Frame<DateTime, string> computeFuturesSpreads()
        //------------------------------------------------------------------------------------------------
        {
            Log_.InfoFormat("Computing spreads...");
            CombinedStatic = SpreadSeriesBuilder.combineFuturesAndBondStatic(BondStatic,FuturesStatic);

            var columns = FuturesPrices.Columns;
            
            FrameBuilder.Columns<DateTime, string> frameblder = new FrameBuilder.Columns<DateTime, string>();

            // Iterate over columns for prices
            foreach (var col in FuturesPrices.ColumnKeys)
            {
                var series = columns[col].As<double>();
                //series = series.Select(kvp => calcFuturesMeasure(SpreadMetric_, col, kvp.Value, kvp.Key));

                var dte_idx = series.Keys.ToList();
                SeriesBuilder<DateTime,double> sb = new SeriesBuilder<DateTime, double>();
                Tuple<DateTime, double> prev = null;

                /* THIS ABSOLUTELY HAS TO BE IN ASCENDING ORDER */
                dte_idx.Sort();

                foreach(var dte in dte_idx)
                {
                    var res         = series.TryGet(dte);
                    if (res.HasValue)
                    {
                        double price = res.Value;
                        
                        var staticRow = CombinedStatic.Rows.TryGet(col).ValueOrDefault;
                        
                        /* This section is to account for deficiencies in our database. */
                        // Quit if we don't have static 
                        if (staticRow == null)
                        {
                            sb.Add(dte, double.NaN);
                            continue;
                        }

                        // Quit if we have a bad price
                        if (price == 0.0)
                        {
                            sb.Add(dte, double.NaN);
                            continue;
                        }

                        // Quit if contract isn't even trading
                        var firstTradeDate = staticRow.GetAs<DateTime>("fut_first_trade_dt");
                        var lastTradeDate = staticRow.GetAs<DateTime>("last_tradeable_dt");

                        if (dte > lastTradeDate || dte < firstTradeDate)
                        {
                            sb.Add(dte, double.NaN);
                            continue;
                        }
                        
                        // Get price for AUD
                        if (Conv_.Country == BondAnalytics.Country.AU)
                        {
                            DateTime maturity = TimeSeriesUtilities.LazySafeTryGetAs(staticRow, "Maturity", DateTime.MinValue);
                            int tenor = (int)Math.Round((maturity - dte).Days / 365.25);
                            price = BondAnalytics.CalcAUDFuturesContractValue(price, tenor);
                        }

                        // ASSUMPTION: Our DB seems to front fill by default. Skip days where no data is present
                        /*if (prev != null && price == prev.Item2)
                        {
                            sb.Add(dte, double.NaN);
                            continue;
                        } */

                        

                        double metric = calcFuturesMeasure(SpreadMetric_, col, price, dte, previous: prev);

                        prev = new Tuple<DateTime, double>(dte, price);
                        sb.Add(dte, metric);
                    }
                    else
                    {
                        sb.Add(dte, double.NaN);
                    }                
                }
                frameblder.Add(col, sb.Series);
            }

            var output = frameblder.Frame;
            

            Log_.InfoFormat("Complete:");
            //output.Print();
            
            return output.SortRowsByKey();
        }
Esempio n. 12
0
    public static void FramesOrderedAfterBuild()
    {
      var builder = new FrameBuilder.Columns<int, string>();
      builder.Add("column1", new[] { 1, 2, 3, 4 }.ToOrdinalSeries());
      builder.Add("column2", new[] { 1, 2, 3, 4 }.ToOrdinalSeries());
      builder.Add("column3", new[] { 1, 2, 3, 4 }.ToOrdinalSeries());
      builder.Add("column4", new[] { 1, 2, 3, 4 }.ToOrdinalSeries());
      var frame = builder.Frame;

      Assert.AreEqual(
        new[] { "column1", "column2", "column3", "column4" },
        frame.ColumnKeys.ToArray()
        );
    }
Esempio n. 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();
        }