示例#1
0
 private void getStockTickData(string code)
 {
     foreach (var date in tradedays)
     {
         var    tick    = tickRepo.GetStockTransaction(code, date, date);
         var    day     = stockDailyRepo.GetStockTransaction("510050.SH", date, date);
         double open    = day[0].Open;
         var    minute  = tranferTickToMinuteDayByDay(code, date, open, tick);
         var    minute2 = stockMinutelyRepo.GetStockTransaction("510050.SH", date, date);
     }
 }
示例#2
0
        private Dictionary <DateTime, StockTransaction> getUnderlyingDailyData(DateTime startDate, DateTime endDate)
        {
            Dictionary <DateTime, StockTransaction> underlyingDailyData = new Dictionary <DateTime, StockTransaction>();
            var data = stockDailyRepo.GetStockTransaction(underlying, startDate, endDate);

            foreach (var item in data)
            {
                underlyingDailyData.Add(item.DateTime, item);
            }
            this.underlyingDailyDataList = data;
            return(underlyingDailyData);
        }
示例#3
0
        public void compute(DateTime startDate, DateTime endDate)
        {
            var startday = DateTimeExtension.DateUtils.PreviousTradeDay(startDate, duration + 1);
            var endday   = DateTimeExtension.DateUtils.PreviousTradeDay(endDate, duration + 1);

            priceList = stockDailyRepo.GetStockTransaction(code, startday, endDate);
            var tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);

            if (priceDic == null || priceDic.Count() == 0)
            {
                foreach (var item in priceList)
                {
                    priceDic.Add(item.DateTime, item.Close);
                }
            }
            for (int i = 0; i < tradedays.Count() - duration; i++)
            {
                var call = -getHedgeCost(tradedays[i], tradedays[i + duration], code);
                Console.WriteLine("call from {0} to {1} costs {2}!", tradedays[i], tradedays[i + duration], call);
            }
        }
        public void compute(DateTime startDate, DateTime endDate)
        {
            var tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
            //获取日线数据
            var underlyingDaily1 = stockDailyRepo.GetStockTransaction(code1, tradedays.First(), tradedays.Last());
            var underlyingDaily2 = stockDailyRepo.GetStockTransaction(code2, tradedays.First(), tradedays.Last());
            int length           = underlyingDaily1.Count();

            double[] y                     = new double[length];
            double[] x                     = new double[length];
            double[] z                     = new double[length];
            double[] alphaList             = new double[length];
            double[] betaList              = new double[length];
            double[] cointegrationSequence = new double[length];
            //向上穿越下轨1为1,向上穿越中轨为2,向上穿越上轨1为3,
            //向下穿越下轨1位-1,向下穿越中轨为-2,向下穿越上轨1为-3,
            //向上穿越上轨2为4,向下穿越下轨2为-4,其他为0
            double[] signal = new double[length];
            List <signalWithTime> signalList = new List <signalWithTime>();

            double[] longsignal  = new double[length];
            double[] shortsignal = new double[length];
            int      duration    = 30;
            int      duration1   = duration;
            double   lambda1     = 2;
            double   lambda2     = 3;
            double   y0          = underlyingDaily1[0].Close * underlyingDaily1[0].AdjFactor;
            double   x0          = underlyingDaily2[0].Close * underlyingDaily2[0].AdjFactor;

            for (int i = 0; i < tradedays.Count(); i++)
            {
                if ((i - duration1) >= 0)
                {
                    y[i] = underlyingDaily1[i].Close * underlyingDaily1[i].AdjFactor / (underlyingDaily1[i - duration1].Close * underlyingDaily1[i - duration1].AdjFactor);
                    x[i] = underlyingDaily2[i].Close * underlyingDaily2[i].AdjFactor / (underlyingDaily2[i - duration1].Close * underlyingDaily2[i - duration1].AdjFactor);
                }
                else
                {
                    y[i] = underlyingDaily1[i].Close * underlyingDaily1[i].AdjFactor / y0;
                    x[i] = underlyingDaily2[i].Close * underlyingDaily2[i].AdjFactor / x0;
                }
                //z[i] = Math.Log(y[i] / x[i]);
                z[i] = (y[i]) / (x[i]);
            }
            var    myboll = getBollingerBand(z, duration);
            double scale  = 0.1;
            List <BollingerBandwithPrice> myboll2 = new List <BollingerBandwithPrice>();

            for (int i = 0; i < myboll.Length; i++)
            {
                if (myboll[i] != null)
                {
                    BollingerBandwithPrice boll0 = new BollingerBandwithPrice();
                    boll0.mean  = myboll[i].mean;
                    boll0.std   = myboll[i].std;
                    boll0.price = z[i];
                    boll0.time  = tradedays[i].Date;
                    boll0.low2  = boll0.mean - lambda2 * boll0.std;
                    boll0.low1  = boll0.mean - lambda1 * boll0.std;
                    boll0.up2   = boll0.mean + lambda2 * boll0.std;
                    boll0.up1   = boll0.mean + lambda1 * boll0.std;
                    if (Math.Abs(boll0.price - boll0.mean) <= scale * boll0.std)
                    {
                        boll0.area = 0;
                    }
                    else if (boll0.price - boll0.mean > scale * boll0.std && boll0.price - boll0.up1 < -scale * boll0.std)
                    {
                        boll0.area = 1;
                    }
                    else if (Math.Abs(boll0.price - boll0.up1) <= scale * boll0.std)
                    {
                        boll0.area = 2;
                    }
                    else if (boll0.price - boll0.up1 > scale * boll0.std && boll0.price - boll0.up2 < -scale * boll0.std)
                    {
                        boll0.area = 3;
                    }
                    else if (Math.Abs(boll0.price - boll0.up2) <= scale * boll0.std)
                    {
                        boll0.area = 4;
                    }
                    else if (boll0.price - boll0.up2 > scale * boll0.std)
                    {
                        boll0.area = 5;
                    }
                    else if (boll0.price - boll0.mean < -scale * boll0.std && boll0.price - boll0.low1 > scale * boll0.std)
                    {
                        boll0.area = -1;
                    }
                    else if (Math.Abs(boll0.price - boll0.low1) <= scale * boll0.std)
                    {
                        boll0.area = -2;
                    }
                    else if (boll0.price - boll0.low1 < -scale * boll0.std && boll0.price - boll0.low2 > scale * boll0.std)
                    {
                        boll0.area = -3;
                    }
                    else if (Math.Abs(boll0.price - boll0.low2) <= scale * boll0.std)
                    {
                        boll0.area = -4;
                    }
                    else if (boll0.price - boll0.low2 < -scale * boll0.std)
                    {
                        boll0.area = -5;
                    }
                    myboll2.Add(boll0);
                }
            }
            var dt = DataTableExtension.ToDataTable(myboll2);

            DataTableExtension.SaveCSV(dt, "E:\\result\\bollinger\\boll.csv");
            for (int i = 1; i < length; i++)
            {
                if (myboll[i - 1] == null || myboll[i - 1].std == 0)
                {
                    signal[i - 1] = 0;
                    continue;
                }
                if (underlyingDaily1[i].TradeStatus != "交易" || underlyingDaily2[i].TradeStatus != "交易")
                {
                    signal[i] = signal[i - 1];
                    continue;
                }
                double upper1         = myboll[i].mean + lambda1 * myboll[i].std;
                double lower1         = myboll[i].mean - lambda1 * myboll[i].std;
                double middle         = myboll[i].mean;
                double upper2         = myboll[i].mean + lambda2 * myboll[i].std;
                double lower2         = myboll[i].mean - lambda2 * myboll[i].std;
                double upper1Previous = myboll[i - 1].mean + lambda1 * myboll[i - 1].std;
                double lower1Previous = myboll[i - 1].mean - lambda1 * myboll[i - 1].std;
                double middlePrevious = myboll[i - 1].mean;
                double upper2Previous = myboll[i - 1].mean + lambda2 * myboll[i - 1].std;
                double lower2Previous = myboll[i - 1].mean - lambda2 * myboll[i - 1].std;
                if (z[i] > lower1 && z[i - 1] <= lower1Previous && z[i] < middle)
                {
                    signal[i] = 1;
                }
                else if (z[i] > middle && z[i - 1] <= middlePrevious && z[i] < upper1)
                {
                    signal[i] = 2;
                }
                else if (z[i] > upper1 && z[i - 1] <= upper1Previous && z[i] < upper2)
                {
                    signal[i] = 3;
                }
                else if (z[i] < lower1 && z[i - 1] >= lower1Previous && z[i] > lower2)
                {
                    signal[i] = -1;
                }
                else if (z[i] < middle && z[i - 1] >= middlePrevious && z[i] > lower1)
                {
                    signal[i] = -2;
                }
                else if (z[i] < upper1 && z[i - 1] >= upper1Previous && z[i] > middle)
                {
                    signal[i] = -3;
                }
                else if (z[i] > upper2 && z[i - 1] <= upper2Previous)
                {
                    signal[i] = 4;
                }
                else if (z[i] < lower2 && z[i - 1] >= lower2Previous)
                {
                    signal[i] = -4;
                }
                else
                {
                    signal[i] = 0;
                }
            }

            //for (int i = duration+1; i < length; i++)
            //{
            //    if (myboll[i - 1] == null || myboll[i - 1].std == 0)
            //    {
            //        signal[i - 1] = 0;
            //        continue;
            //    }
            //    if (underlyingDaily1[i].TradeStatus != "交易" || underlyingDaily2[i].TradeStatus != "交易")
            //    {
            //        signal[i] = signal[i - 1];
            //        continue;
            //    }
            //    int j = i - duration;
            //    //上穿下轨1
            //    if (myboll2[j-1].area<=-2 && myboll2[j].area==-1)
            //    {
            //        double ratio = 0;
            //        for (int k = j-1; k >j-6; k--)
            //        {
            //            if (myboll2[k].area<=-2)
            //            {
            //                ratio += 1;
            //            }
            //        }
            //        ratio = ratio / 6;
            //        if (ratio<0.5)
            //        {
            //            signal[i] = 1;
            //        }

            //    }
            //    //上穿中轨
            //    else if (myboll2[j-1].area==-1 && myboll2[j].area==1)
            //    {
            //        signal[i] = 2;
            //    }
            //    //上穿上轨1
            //    else if (myboll2[j - 1].area == 1 && myboll2[j].area == 3)
            //    {
            //        signal[i] = 3;
            //    }
            //    //下穿下轨1
            //    else if (myboll2[j - 1].area == -1 && myboll2[j].area == -3)
            //    {
            //        signal[i] = -1;
            //    }
            //    //下穿中轨
            //    else if (myboll2[j - 1].area == 1 && myboll2[j].area == -1)
            //    {
            //        signal[i] = -2;
            //    }
            //    //下穿上轨1
            //    else if (myboll2[j - 1].area >= 2 && myboll2[j].area == 1)
            //    {
            //        double ratio = 0;
            //        for (int k = j - 1; k > j - 6; k--)
            //        {
            //            if (myboll2[k].area >=2)
            //            {
            //                ratio += 1;
            //            }
            //        }
            //        ratio = ratio / 6;
            //        if (ratio < 0.5)
            //        {
            //            signal[i] = -3;
            //        }
            //    }
            //    //上穿上轨2
            //    else if (myboll2[j - 1].area == 3 && myboll2[j].area == 5)
            //    {
            //        signal[i] = 4;
            //    }
            //    //下穿下轨2
            //    else if (myboll2[j - 1].area == -3 && myboll2[j].area == -5)
            //    {
            //        signal[i] = -4;
            //    }
            //    else
            //    {
            //        signal[i] = 0;
            //    }
            //}

            for (int i = 0; i < length; i++)
            {
                var signal0 = new signalWithTime();
                signal0.signal = signal[i];
                signal0.time   = tradedays[i].Date;
                signalList.Add(signal0);
            }
            List <OneByOneTransaction> data         = new List <OneByOneTransaction>();
            List <netvalueDaily>       netvalueList = new List <netvalueDaily>();

            bollingerBrand1(underlyingDaily1, underlyingDaily2, signal, duration, myboll2, ref data, ref netvalueList);
            double sharpe = Utilities.strategyPerformance.sharpeRatioByDailyNetValue(netvalueList.Select(s => s.netvalue).ToList());
            List <OneByOneTransaction> orderedData = data.OrderByDescending(s => Math.Abs(s.closePrice - s.openPrice)).ToList();
            var dt2 = DataTableExtension.ToDataTable(netvalueList);

            DataTableExtension.SaveCSV(dt2, "E:\\result\\bollinger\\nv.csv");
            var dt3 = DataTableExtension.ToDataTable(data);

            DataTableExtension.SaveCSV(dt3, "E:\\result\\bollinger\\transaction.csv");
        }
 private void DataPreparation(DateTime startDate, DateTime endDate)
 {
     var tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
     var etfDaily  = stockDailyRepo.GetStockTransaction(code, startDate, endDate);
 }
示例#6
0
        public void compute(DateTime startDate, DateTime endDate)
        {
            var tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
            List <ETFConsitituent> etfInfo    = new List <ETFConsitituent>();
            List <double>          amountList = getAmount(code, startDate, endDate);

            double[] arbitraryPurchase = new double[28802];
            double[] arbitraryRedeem   = new double[28802];
            bool[]   isNan             = new bool[28802];
            for (int i = 0; i < 28802; i++)
            {
                isNan[i] = true;
            }
            for (int k = 0; k < tradedays.Count(); k++)
            {
                DateTime date = tradedays[k];
                etfInfo = getETFInfo(code, date);
                foreach (var item in etfInfo)
                {
                    if (item.cash_substitution_mark == "必须")
                    {
                        for (int i = 0; i < 28802; i++)
                        {
                            if (isNan[i] == true)
                            {
                                arbitraryPurchase[i] += -item.substitution_amout;
                            }
                        }
                    }
                    else
                    {
                        var stockData = stockRepo.GetStockTransaction(item.code, date, date.AddHours(17));
                        if (stockData != null && stockData.Count > 0)
                        {
                            var stock = DataTimeStampExtension.ModifyStockTickData(stockData);
                            for (int i = 0; i < stock.Count(); i++)
                            {
                                if (isNan[i] == true && stock[i] != null && stock[i].AskV1 != 0 && stock[i].BidV1 != 0)
                                {
                                    arbitraryPurchase[i] += -item.volume * stock[i].Ask1;
                                    //arbitraryRedeem[i] += item.volume * stock[i].Bid1;
                                }
                                if (stock[i] == null)
                                {
                                    isNan[i]             = false;
                                    arbitraryPurchase[i] = 0;
                                    //arbitraryRedeem[i] = 0;
                                }
                            }
                        }
                        else
                        {
                            if (item.cash_substitution_mark == "禁止")
                            {
                                for (int i = 0; i < 28802; i++)
                                {
                                    arbitraryPurchase[i] = 0;
                                    isNan[i]             = false;
                                }
                            }
                            else
                            {
                                var stock = stockDailyRepo.GetStockTransaction(item.code, date, date);
                                for (int i = 0; i < 28802; i++)
                                {
                                    if (isNan[i] == true)
                                    {
                                        arbitraryPurchase[i] += -item.volume * stock[stock.Count() - 1].Close * (1 + item.premium_ratio / 100.0);
                                    }
                                }
                            }
                        }
                    }
                }
                var etf = DataTimeStampExtension.ModifyStockTickData(stockRepo.GetStockTransaction(code, date, date.AddHours(17)));
                for (int i = 0; i < etf.Count(); i++)
                {
                    if (isNan[i] == true && etf[i] != null && etf[i].AskV1 != 0 && etf[i].BidV1 != 0)
                    {
                        arbitraryPurchase[i] += amountList[k] * etf[i].Bid1;
                        // arbitraryRedeem[i] += -amountList[k] * etf[i].Ask1;
                    }
                    if (etf[i] == null)
                    {
                        isNan[i]             = false;
                        arbitraryPurchase[i] = 0;
                        //arbitraryRedeem[i] = 0;
                    }
                }
                Console.WriteLine("today {0} change {1}", date, arbitraryPurchase.Max());
            }
        }
示例#7
0
        public void compute(DateTime startDate, DateTime endDate)
        {
            var tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
            //获取日线数据
            var underlyingDaily = stockDailyRepo.GetStockTransaction(code, tradedays.First(), tradedays.Last());

            //获取分钟线数据
            foreach (var date in tradedays)
            {
                var underlyingToday = stockMinutelyRepo.GetStockTransaction(code, date, date);
                underlying.Add(date, underlyingToday);
                minutes = underlyingToday.Count();
                underlyingAll.AddRange(underlyingToday);
            }
            double bestSharpe = 0;
            double bestf1     = 0.64;
            double bestf2     = 0.48;
            double bestf3     = 0.08;
            double step       = 0.04;

            //for (int i = 1; i <= 1/step; i=i+1)
            //{
            //    for (int j = 1; j <= 1 / step; j = j + 1)
            //    {
            //        for (int k = 1; k <= 1 / step; k = k + 1)
            //        {
            //            double f1 = i * step;
            //            double f2 = j * step;
            //            double f3 = k * step;
            //            double[] netvalue0 = getPerformance(startDate, endDate, tradedays, underlyingDaily, f1, f2, f3);
            //            var nv = getNetValueCurveDaily(getNetValueDaily(underlyingAll, netvalue0));
            //            double sharpe = Utilities.strategyPerformance.sharpeRatioByDailyNetValue(nv);
            //            if (sharpe>bestSharpe)
            //            {
            //                bestf1 = f1;
            //                bestf2 = f2;
            //                bestf3 = f3;
            //                bestSharpe = sharpe;
            //                Console.WriteLine("Best parameters:f1={0}, f2={1}, f3={2}, sharpe={3}", f1, f2, f3, sharpe);
            //            }
            //        }
            //    }
            //}

            double[] netvalue = getPerformance(startDate, endDate, tradedays, underlyingDaily, bestf1, bestf2, bestf3);
            var      nvDaily  = getNetValueDaily(underlyingAll, netvalue);

            DataTableExtension.SaveCSV(DataTableExtension.ToDataTable <netvalueDaily>(nvDaily), "E:\\result\\break\\netvalue.csv");
            statisticDataOfTransaction(transactionData, tradedays);
            double mean = 0;
            double num  = 0;

            for (int i = -5; i <= 5; i = i + 1)
            {
                for (int j = -5; j <= 5; j = j + 1)
                {
                    for (int k = -5; k <= 5; k = k + 1)
                    {
                        double f1 = bestf1 + i * step * 0.25;
                        double f2 = bestf2 + j * step * 0.25;
                        double f3 = bestf3 + k * step * 0.25;
                        if (f1 <= 0 || f2 <= 0 || f3 <= 0)
                        {
                            continue;
                        }
                        double[] netvalue0 = getPerformance(startDate, endDate, tradedays, underlyingDaily, f1, f2, f3);
                        var      nv        = getNetValueCurveDaily(getNetValueDaily(underlyingAll, netvalue0));
                        double   sharpe    = Utilities.strategyPerformance.sharpeRatioByDailyNetValue(nv);
                        mean += sharpe;
                        num  += 1;
                        Console.WriteLine("parameters around best:f1={0}, f2={1}, f3={2}, sharpe={3}", f1, f2, f3, sharpe);
                    }
                }
            }
            Console.WriteLine("mean:{0}", mean / num);
        }
示例#8
0
        //计算从开始日期到结束日期的对冲成本
        private double deltaHedgePerDate(DateTime startDate, DateTime endDate, Dictionary <DateTime, double> vol)
        {
            double option     = 0;
            var    tradedays  = dateRepo.GetStockTransactionDate(startDate, endDate);
            int    deltaIndex = 220;
            //计算历史波动率参数
            string hedgeCode = "";
            double deltaNow  = 0;
            double pnl       = 0;
            double cash      = 0;
            //按第一天的开盘价确定期初价格和行权价
            var    stock      = stockDailyRepo.GetStockTransaction(indexCode, startDate, endDate);
            double startPrice = stock[0].Open;
            double strike     = startPrice;

            foreach (var date in tradedays)
            {
                //获取当日期货合约代码
                var list = getSpecialFutureList(date);
                //获取当日收盘前标的价格
                // var index = stockMinutelyRepo.GetStockTransaction(indexCode, date, date);
                var    index      = allData[date][indexCode];
                var    indexPrice = index[deltaIndex].Close;
                double duration   = (DateUtils.GetSpanOfTradeDays(date, endDate) + 1 / 12) / 252.0;
                //按标的计算收盘前delta值
                double deltaTarget = ImpliedVolatilityExtension.ComputeOptionDelta(strike, duration, 0.04, 0, "认沽", vol[date], indexPrice);

                //对冲未开仓进行开仓
                if (hedgeCode == "")
                {
                    hedgeCode = list.Last().Value.code;
                    double futurePrice = allData[date][hedgeCode][deltaIndex + 1].Close;
                    cash    += -futurePrice * deltaTarget;
                    deltaNow = deltaTarget;
                }
                //如果对冲的合约快到期时,进行移仓操作,移仓到季月合约
                if (list.ContainsKey(hedgeCode) && list[hedgeCode].expireDate.Date.AddDays(-7) <= date.Date)
                {
                    double futurePriceFront = allData[date][hedgeCode][deltaIndex + 1].Close;
                    hedgeCode = list.Last().Value.code;
                    double futurePriceNext = allData[date][hedgeCode][deltaIndex + 1].Close;
                    cash    += futurePriceFront * deltaNow - futurePriceNext * deltaTarget;
                    deltaNow = deltaTarget;
                }
                else if (list.ContainsKey(hedgeCode)) //对冲的合约未到期,继续对冲
                {
                    double futurePrice = allData[date][hedgeCode][deltaIndex + 1].Close;
                    cash    += -futurePrice * (deltaTarget - deltaNow);
                    deltaNow = deltaTarget;
                }
                //错误情况
                if (list.ContainsKey(hedgeCode) == false && hedgeCode != "")
                {
                    throw new ArgumentOutOfRangeException("对冲选取错误!!");
                }
            }
            //计算最后一天的PNL=cash+期货值的钱+付出去的期权收益
            var    lastDate        = tradedays.Last();
            double futureLastPrice = allData[lastDate][hedgeCode][239].Close;
            double indexLastPrice  = stock.Last().Close;

            pnl    = -(cash + deltaNow * futureLastPrice - Math.Max(startPrice - indexLastPrice, 0));
            option = pnl / startPrice;
            return(option);
        }
        public void compute(DateTime startDate, DateTime endDate)
        {
            var tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
            //获取日线数据
            var    underlyingDaily1  = stockDailyRepo.GetStockTransaction(code1, tradedays.First(), tradedays.Last());
            var    underlyingDaily2  = stockDailyRepo.GetStockTransaction(code2, tradedays.First(), tradedays.Last());
            int    duration          = 15;
            double lambda1           = 2.4;
            double trailingParameter = 0.025;

            getParameter(tradedays, underlyingDaily1, underlyingDaily2, ref duration, ref lambda1, ref trailingParameter);
            int length = underlyingDaily1.Count();

            double[] y                     = new double[length];
            double[] x                     = new double[length];
            double[] z                     = new double[length];
            double[] alphaList             = new double[length];
            double[] betaList              = new double[length];
            double[] cointegrationSequence = new double[length];
            //向上穿越下轨1为1,向上穿越中轨为2,向上穿越上轨1为3,
            //向下穿越下轨1位-1,向下穿越中轨为-2,向下穿越上轨1为-3,
            //向上穿越上轨2为4,向下穿越下轨2为-4,其他为0
            double[] signal = new double[length];
            List <signalWithTime> signalList = new List <signalWithTime>();

            double[] longsignal  = new double[length];
            double[] shortsignal = new double[length];
            int      duration1   = 1000000;
            double   lambda2     = 2.1;
            double   y0          = underlyingDaily1[0].Close * underlyingDaily1[0].AdjFactor;
            double   x0          = underlyingDaily2[0].Close * underlyingDaily2[0].AdjFactor;

            for (int i = 0; i < tradedays.Count(); i++)
            {
                if ((i - duration1) >= 0)
                {
                    y[i] = underlyingDaily1[i].Close * underlyingDaily1[i].AdjFactor / (underlyingDaily1[i - duration1].Close * underlyingDaily1[i - duration1].AdjFactor);
                    x[i] = underlyingDaily2[i].Close * underlyingDaily2[i].AdjFactor / (underlyingDaily2[i - duration1].Close * underlyingDaily2[i - duration1].AdjFactor);
                }
                else
                {
                    y[i] = underlyingDaily1[i].Close * underlyingDaily1[i].AdjFactor / y0;
                    x[i] = underlyingDaily2[i].Close * underlyingDaily2[i].AdjFactor / x0;
                }
                z[i] = Math.Log(y[i] / x[i]);
            }

            //计算x,y收益率的相关性
            double[] yy = new double[length - 1];
            double[] xx = new double[length - 1];
            for (int i = 1; i < length; i++)
            {
                yy[i - 1] = y[i] / y[i - 1] - 1;
                xx[i - 1] = x[i] / x[i - 1] - 1;
            }
            double corr = MathUtility.correlation(y, x);

            Console.WriteLine("corr:{0}", corr);
            var    myboll = getBollingerBand(z, duration);
            double scale  = 0.1;
            List <BollingerBandwithPrice> myboll2 = new List <BollingerBandwithPrice>();

            for (int i = 0; i < myboll.Length; i++)
            {
                if (myboll[i] != null)
                {
                    BollingerBandwithPrice boll0 = new BollingerBandwithPrice();
                    boll0.mean  = myboll[i].mean;
                    boll0.std   = myboll[i].std;
                    boll0.price = z[i];
                    boll0.time  = tradedays[i].Date;
                    boll0.low2  = boll0.mean - lambda2 * boll0.std;
                    boll0.low1  = boll0.mean - lambda1 * boll0.std;
                    boll0.up2   = boll0.mean + lambda2 * boll0.std;
                    boll0.up1   = boll0.mean + lambda1 * boll0.std;
                    if (Math.Abs(boll0.price - boll0.mean) <= scale * boll0.std)
                    {
                        boll0.area = 0;
                    }
                    else if (boll0.price - boll0.mean > scale * boll0.std && boll0.price - boll0.up1 < -scale * boll0.std)
                    {
                        boll0.area = 1;
                    }
                    else if (Math.Abs(boll0.price - boll0.up1) <= scale * boll0.std)
                    {
                        boll0.area = 2;
                    }
                    else if (boll0.price - boll0.up1 > scale * boll0.std && boll0.price - boll0.up2 < -scale * boll0.std)
                    {
                        boll0.area = 3;
                    }
                    else if (Math.Abs(boll0.price - boll0.up2) <= scale * boll0.std)
                    {
                        boll0.area = 4;
                    }
                    else if (boll0.price - boll0.up2 > scale * boll0.std)
                    {
                        boll0.area = 5;
                    }
                    else if (boll0.price - boll0.mean < -scale * boll0.std && boll0.price - boll0.low1 > scale * boll0.std)
                    {
                        boll0.area = -1;
                    }
                    else if (Math.Abs(boll0.price - boll0.low1) <= scale * boll0.std)
                    {
                        boll0.area = -2;
                    }
                    else if (boll0.price - boll0.low1 < -scale * boll0.std && boll0.price - boll0.low2 > scale * boll0.std)
                    {
                        boll0.area = -3;
                    }
                    else if (Math.Abs(boll0.price - boll0.low2) <= scale * boll0.std)
                    {
                        boll0.area = -4;
                    }
                    else if (boll0.price - boll0.low2 < -scale * boll0.std)
                    {
                        boll0.area = -5;
                    }
                    myboll2.Add(boll0);
                }
            }
            var dt = DataTableExtension.ToDataTable(myboll2);

            DataTableExtension.SaveCSV(dt, "E:\\result\\bollinger\\boll.csv");
            for (int i = 1; i < length; i++)
            {
                if (myboll[i - 1] == null || myboll[i - 1].std == 0)
                {
                    signal[i - 1] = 0;
                    continue;
                }
                if (underlyingDaily1[i].TradeStatus != "交易" || underlyingDaily2[i].TradeStatus != "交易")
                {
                    signal[i] = 0;
                    continue;
                }
                double upper1         = myboll[i].mean + lambda1 * myboll[i].std;
                double lower1         = myboll[i].mean - lambda1 * myboll[i].std;
                double middle         = myboll[i].mean;
                double upper2         = myboll[i].mean + lambda2 * myboll[i].std;
                double lower2         = myboll[i].mean - lambda2 * myboll[i].std;
                double upper1Previous = myboll[i - 1].mean + lambda1 * myboll[i - 1].std;
                double lower1Previous = myboll[i - 1].mean - lambda1 * myboll[i - 1].std;
                double middlePrevious = myboll[i - 1].mean;
                double upper2Previous = myboll[i - 1].mean + lambda2 * myboll[i - 1].std;
                double lower2Previous = myboll[i - 1].mean - lambda2 * myboll[i - 1].std;
                if (z[i] > lower1 && z[i - 1] <= lower1Previous && z[i] < middle)
                {
                    signal[i] = 1;
                }
                else if (z[i] > middle && z[i - 1] <= middlePrevious && z[i] < upper1)
                {
                    signal[i] = 2;
                }
                else if (z[i] > upper1 && z[i - 1] <= upper1Previous && z[i] < upper2)
                {
                    signal[i] = 3;
                }
                else if (z[i] < lower1 && z[i - 1] >= lower1Previous && z[i] > lower2)
                {
                    signal[i] = -1;
                }
                else if (z[i] < middle && z[i - 1] >= middlePrevious && z[i] > lower1)
                {
                    signal[i] = -2;
                }
                else if (z[i] < upper1 && z[i - 1] >= upper1Previous && z[i] > middle)
                {
                    signal[i] = -3;
                }
                else if (z[i] > upper2 && z[i - 1] <= upper2Previous)
                {
                    signal[i] = 4;
                }
                else if (z[i] < lower2 && z[i - 1] >= lower2Previous)
                {
                    signal[i] = -4;
                }
                else
                {
                    signal[i] = 0;
                }
            }

            for (int i = 0; i < length; i++)
            {
                var signal0 = new signalWithTime();
                signal0.signal = signal[i];
                signal0.time   = tradedays[i].Date;
                signalList.Add(signal0);
            }
            List <OneByOneTransaction> data         = new List <OneByOneTransaction>();
            List <netvalueDaily>       netvalueList = new List <netvalueDaily>();

            bollingerBrand1(underlyingDaily1, underlyingDaily2, signal, duration, myboll2, trailingParameter, ref data, ref netvalueList);
            double sharpe = Utilities.strategyPerformance.sharpeRatioByDailyNetValue(netvalueList.Select(s => s.netvalue).ToList());
            List <OneByOneTransaction> orderedData = data.OrderByDescending(s => Math.Abs(s.closePrice - s.openPrice)).ToList();
            var dt2 = DataTableExtension.ToDataTable(netvalueList);

            DataTableExtension.SaveCSV(dt2, "E:\\result\\bollinger\\nv.csv");
            var dt3 = DataTableExtension.ToDataTable(data);

            DataTableExtension.SaveCSV(dt3, "E:\\result\\bollinger\\transaction.csv");
        }