Beispiel #1
0
        private void prepare(string code, DateTime startDate, DateTime endDate)
        {
            //获取交易日信息
            this.tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
            //获取基本信息
            this.code = code;
            //获取日线数据
            var dailyData = stockDailyRepo.GetStockTransactionWithRedis(code, startDate, endDate);

            //获取分钟线数据
            foreach (var date in tradedays)
            {
                var minuteKLine = stockMinutelyRepo.GetStockTransactionWithRedis(code, date, date);
                underlyingKLine.Add(date, minuteKLine);
            }
            foreach (var item in dailyData)
            {
                var KLines = underlyingKLine[item.DateTime];
                foreach (var KLine in KLines)
                {
                    KLine.AdjFactor = item.AdjFactor;
                }
            }
            for (int n = 3; n < 50; n++)
            {
                var dic = getMA(underlyingKLine, n);
                MADic.Add(n, dic);
            }
        }
        //将计算用的数据准备好
        private void dataPrepare(string underlyingCode, DateTime startDate, DateTime endDate, int pushForwardDays = 0)
        {
            //获取交易日信息
            this.tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
            //获取日线数据
            var dayNow = stockDailyRepo.GetStockTransactionWithRedis(underlyingCode, startDate.AddDays(-pushForwardDays), endDate);

            if (this.DailyKLine.ContainsKey(underlyingCode))
            {
                var data = DailyKLine[underlyingCode];
                data = dayNow;
            }
            else
            {
                DailyKLine.Add(underlyingCode, dayNow);
            }
            //选取需要获取数据的交易日
            List <DateTime> myTradedays = new List <DateTime>();

            //从日线上观察波动剧烈的日期,并记录数据

            for (int i = 1; i < DailyKLine[underlyingCode].Count(); i++)
            {
                if (DailyKLine[underlyingCode][i].High / DailyKLine[underlyingCode][i - 1].Close >= 1.07)
                {
                    var today = DailyKLine[underlyingCode][i].DateTime.Date;
                    if (myTradedays.Contains(today) == false)
                    {
                        myTradedays.Add(DailyKLine[underlyingCode][i].DateTime.Date);
                    }
                    var nextDay = DateTimeExtension.DateUtils.NextTradeDay(DailyKLine[underlyingCode][i].DateTime.Date).Date;
                    if (myTradedays.Contains(nextDay) == false)
                    {
                        myTradedays.Add(nextDay);
                    }
                }
            }

            //foreach (var item in DailyKLine[underlyingCode])
            //{
            //    if (item.High / item.Low - 1 > 0.05)
            //    {
            //        var today = item.DateTime.Date;
            //        if (myTradedays.Contains(today)==false)
            //        {
            //            myTradedays.Add(item.DateTime.Date);
            //        }
            //        var nextDay = DateTimeExtension.DateUtils.NextTradeDay(item.DateTime.Date).Date;
            //        if (myTradedays.Contains(nextDay)==false)
            //        {
            //            myTradedays.Add(nextDay);
            //        }
            //    }
            //}

            //getMinuteData(underlyingCode, myTradedays);

            getTickData(underlyingCode, myTradedays);
        }
Beispiel #3
0
        public void getStockDailyData(DateTime startDate, DateTime endDate)
        {
            var list = stockInfoRepo.GetStockListInfoFromSql();

            foreach (var item in list)
            {
                DateTime startTime = startDate;
                DateTime endTime   = endDate;
                if (startDate < item.IPODate)
                {
                    startTime = item.IPODate;
                }
                if (endDate > item.DelistDate)
                {
                    endTime = item.DelistDate;
                }
                var data = stockDailyRepo.GetStockTransactionWithRedis(item.code, startTime, endTime);
                Console.WriteLine("code:{0} dailyData form {1} to {2} complete!", item.code, startTime, endTime);
            }
        }
        //将计算用的数据准备好
        private void dataPrepare(string underlyingCode, string indexCode, DateTime startDate, DateTime endDate, int N = 20)
        {
            //获取交易日信息
            this.tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
            //获取基本信息
            this.indexCode      = indexCode;
            this.underlyingCode = underlyingCode;
            //获取日线数据
            var indexData = stockDailyRepo.GetStockTransactionWithRedis(indexCode, startDate, endDate);

            //获取分钟线数据
            foreach (var date in tradedays)
            {
                var minuteKLine = stockMinutelyRepo.GetStockTransactionWithRedis(underlyingCode, date, date);
                underlyingKLine.Add(date, minuteKLine);
                var minuteKLine2 = stockMinutelyRepo.GetStockTransactionWithRedis(indexCode, date, date);
                indexKLine.Add(date, minuteKLine2);
            }
            for (int n = 10; n <= 30; n++)
            {
                Dictionary <DateTime, double> range = new Dictionary <DateTime, double>();
                foreach (var date in tradedays)
                {
                    var    index      = indexKLine[date];
                    var    underlying = underlyingKLine[date];
                    double HH         = 0;     //最高价的最高价
                    double HC         = 0;     //收盘价的最高价
                    double LC         = 99999; //收盘价的最低价
                    double LL         = 99999; //最低价的最低价
                    for (int i = 0; i < n; i++)
                    {
                        if (index[i].High > HH)
                        {
                            HH = index[i].High;
                        }
                        if (index[i].Close > HC)
                        {
                            HC = index[i].Close;
                        }
                        if (index[i].Close < LC)
                        {
                            LC = index[i].Close;
                        }
                        if (index[i].Low < LL)
                        {
                            LL = index[i].Low;
                        }
                    }
                    double rangeNow = Math.Max(HH - LC, HC - LL);
                    range.Add(date, rangeNow);
                }
                RangeDic.Add(n, range);
            }
        }
        private Dictionary <DateTime, StockTransaction> getUnderlyingDailyData(DateTime startDate, DateTime endDate)
        {
            Dictionary <DateTime, StockTransaction> underlyingDailyData = new Dictionary <DateTime, StockTransaction>();
            var data = stockDailyRepo.GetStockTransactionWithRedis(underlying, startDate, endDate);

            foreach (var item in data)
            {
                underlyingDailyData.Add(item.DateTime, item);
            }
            this.underlyingDailyDataList = data;
            return(underlyingDailyData);
        }
        //将计算用的数据准备好
        private void dataPrepare(string underlyingCode, DateTime startDate, DateTime endDate, int N = 20)
        {
            //获取交易日信息
            this.tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
            //获取基本信息
            this.underlyingCode = underlyingCode;
            //获取日线数据
            var underlyingData = stockDailyRepo.GetStockTransactionWithRedis(underlyingCode, startDate, endDate);

            for (int n = 1; n <= N; n++)
            {
                Dictionary <DateTime, double> range = new Dictionary <DateTime, double>();
                for (int i = n; i < underlyingData.Count() - 1; i++)
                {
                    double HH = 0;     //最高价的最高价
                    double HC = 0;     //收盘价的最高价
                    double LC = 99999; //收盘价的最低价
                    double LL = 99999; //最低价的最低价
                    for (int k = i - n; k <= i - 1; k++)
                    {
                        if (underlyingData[k].High > HH)
                        {
                            HH = underlyingData[k].High;
                        }
                        if (underlyingData[k].Close > HC)
                        {
                            HC = underlyingData[k].Close;
                        }
                        if (underlyingData[k].Close < LC)
                        {
                            LC = underlyingData[k].Close;
                        }
                        if (underlyingData[k].Low < LL)
                        {
                            LL = underlyingData[k].Low;
                        }
                    }
                    double lastClose = underlyingData[i - 1].Close;
                    double rangeNow  = Math.Max(HH - LC, HC - LL);
                    range.Add(underlyingData[i].DateTime, rangeNow);
                }
                RangeDic.Add(n, range);
            }

            //获取分钟线数据
            foreach (var date in tradedays)
            {
                var minuteKLine = stockMinutelyRepo.GetStockTransactionWithRedis(underlyingCode, date, date);
                underlyingKLine.Add(date, minuteKLine);
            }
        }
Beispiel #7
0
        private void dataPrepareAll(string underlyingCode, DateTime startDate, DateTime endDate)
        {
            //获取交易日信息
            this.tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
            //获取日线数据
            var dayNow = stockDailyRepo.GetStockTransactionWithRedis(underlyingCode, startDate, endDate);

            if (this.DailyKLine.ContainsKey(underlyingCode))
            {
                var data = DailyKLine[underlyingCode];
                data = dayNow;
            }
            else
            {
                DailyKLine.Add(underlyingCode, dayNow);
            }
            //选取需要获取数据的交易日
            List <DateTime> myTradedays = dateRepo.GetStockTransactionDate(startDate, endDate);


            getMinuteData(underlyingCode, myTradedays);

            //getTickData(underlyingCode, myTradedays);
        }
Beispiel #8
0
        //将计算用的数据准备好
        private void dataPrepare(string underlyingCode, DateTime startDate, DateTime endDate, int N = 20)
        {
            //获取交易日信息
            this.tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
            //获取基本信息
            this.underlyingCode = underlyingCode;
            //获取日线数据
            var underlyingData = stockDailyRepo.GetStockTransactionWithRedis(underlyingCode, startDate, endDate);

            for (int n = 1; n <= N; n++)
            {
                Dictionary <DateTime, double> vol = new Dictionary <DateTime, double>();
                for (int i = n; i < underlyingData.Count() - 1; i++)
                {
                    List <double> openToClose = new List <double>();
                    for (int j = Math.Max(0, i - n); j < i; j++)
                    {
                        if (underlyingData[j].Volume > 0)
                        {
                            openToClose.Add(underlyingData[j].Close / underlyingData[j].Open - 1);
                        }
                    }
                    if (openToClose.Count() > n / 2)
                    {
                        double volNow = getVol(openToClose);
                        if (volNow > 0)
                        {
                            vol.Add(underlyingData[i].DateTime, volNow);
                        }
                    }
                }
                volDic.Add(n, vol);
            }

            //获取分钟线数据
            foreach (var date in tradedays)
            {
                var minuteKLine = stockMinutelyRepo.GetStockTransactionWithRedis(underlyingCode, date, date);
                underlyingKLine.Add(date, minuteKLine);
            }
        }
        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.GetStockTransactionWithRedis(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);
            }
        }
Beispiel #10
0
        private void prepare(string underlyingCode, string indexCode, DateTime startDate, DateTime endDate)
        {
            //获取交易日信息
            this.tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
            //获取基本信息
            this.indexCode      = indexCode;
            this.underlyingCode = underlyingCode;
            //获取日线数据
            var indexData = stockDailyRepo.GetStockTransactionWithRedis(indexCode, startDate, endDate);

            volatilityDaily = getDailyVolatility(indexData);
            //获取分钟线数据
            foreach (var date in tradedays)
            {
                var minuteKLine = stockMinutelyRepo.GetStockTransactionWithRedis(underlyingCode, date, date);
                underlyingKLine.Add(date, minuteKLine);
                var minuteKLine2 = stockMinutelyRepo.GetStockTransactionWithRedis(indexCode, date, date);
                indexKLine.Add(date, minuteKLine2);
            }
            volatilityMinutely = getMinutelyVolatility(indexKLine, 1);
        }
Beispiel #11
0
 private void DataPreparation(DateTime startDate, DateTime endDate)
 {
     var tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
     var etfDaily  = stockDailyRepo.GetStockTransactionWithRedis(code, startDate, endDate);
 }
        private void dataPrepare(DateTime startDate, DateTime endDate)
        {
            //获取交易日信息
            this.tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
            List <DateTime> ceilDate = new List <DateTime>();
            string          bondCode;
            string          underlyingCode;

            //获取可转债信息
            this.bondInfo = GetConvertibleBondInfos(endDate);
            //获取日线数据
            try
            {
                foreach (var info in bondInfo)
                {
                    underlyingCode = info.stockCode;
                    DateTime startTime = startDate;
                    DateTime endTime   = endDate;
                    if (startTime < info.startDate)
                    {
                        startTime = info.startDate;
                    }
                    if (endTime > info.endDate)
                    {
                        endTime = info.endDate;
                    }
                    if (dailyData.ContainsKey(underlyingCode) == false)
                    {
                        var underlyingData = stockDailyRepo.GetStockTransactionWithRedis(underlyingCode, startTime.AddDays(-10), endTime);
                        dailyData.Add(underlyingCode, underlyingData);
                        endTime = DateTimeExtension.DateUtils.PreviousTradeDay(info.endDate, 7);
                        if (endTime > endDate.Date)
                        {
                            endTime = endDate.Date;
                        }
                        if (startDate > endTime)
                        {
                            startDate = endTime;
                        }
                        var bondData = stockDailyRepo.GetStockTransactionWithRedis(info.code, info.startDate, endTime);
                        dailyData.Add(info.code, bondData);
                        if (info.startDate > endTime)
                        {
                            continue;
                        }
                        var tempDataTable = windReader.GetDailyDataTable(info.code, "clause_conversion2_swapshareprice,underlyingcode,clause_conversion_2_swapsharestartdate,clause_conversion_2_swapshareenddate", info.startDate, endTime);
                        List <ConvertibleBondDailyInfo> bondDaily = new List <ConvertibleBondDailyInfo>();
                        foreach (DataRow dt in tempDataTable.Rows)
                        {
                            ConvertibleBondDailyInfo bondDailyInfoNow = new ConvertibleBondDailyInfo();
                            bondDailyInfoNow.code            = info.code;
                            bondDailyInfoNow.name            = info.name;
                            bondDailyInfoNow.startDate       = info.startDate;
                            bondDailyInfoNow.endDate         = info.endDate;
                            bondDailyInfoNow.stockCode       = info.stockCode;
                            bondDailyInfoNow.conversionPrice = Convert.ToDouble(dt["clause_conversion2_swapshareprice"]);
                            //bondDailyInfoNow.forceConvertDate = Convert.ToDateTime(dt["clause_conversion_2_forceconvertdate"]);
                            bondDailyInfoNow.conversionStartDate = Convert.ToDateTime(dt["clause_conversion_2_swapsharestartdate"]);
                            bondDailyInfoNow.conversionEndDate   = Convert.ToDateTime(dt["clause_conversion_2_swapshareenddate"]);
                            bondDailyInfoNow.date = Convert.ToDateTime(dt["datetime"]);
                            bondDaily.Add(bondDailyInfoNow);
                        }
                        bondDailyInfo.Add(info.code, bondDaily);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }


            int num = 0;

            foreach (var item in dailyData)
            {
                var data = item.Value;
                var code = item.Key;
                num = num + 1;
                Console.WriteLine(num);
                for (int i = 1; i < data.Count(); i++)
                {
                    if (data[i] == null || data[i].DateTime.Date < startDate)
                    {
                        continue;
                    }
                    DateTime day = data[i].DateTime.Date;

                    //获取其对应的可转债
                    bondCode = getConvetibleCodeByStockCode(code, day, bondInfo);
                    //判断是否涨停
                    var    dataToday     = data[i];
                    var    dataYesterday = data[i - 1];
                    double price         = Math.Round(dataYesterday.Close * dataYesterday.AdjFactor / dataToday.AdjFactor * 1.1, 2);
                    //获取日内数据
                    try
                    {
                        if (data[i].High >= 0.99 * price && bondCode != "")
                        {
                            //获取分钟数据
                            //var data1 = stockMinutelyRepo.GetStockTransactionWithRedis(bondCode, day, day);
                            //var data2 = stockMinutelyRepo.GetStockTransactionWithRedis(code, day, day);
                            //if (minuteData.ContainsKey(data[i].DateTime) == true)
                            //{
                            //    minuteData[data[i].DateTime].Add(bondCode, data1);
                            //    minuteData[data[i].DateTime].Add(code, data2);
                            //}
                            //else
                            //{
                            //    Dictionary<string, List<StockTransaction>> dataNow = new Dictionary<string, List<StockTransaction>>();
                            //    dataNow.Add(bondCode, data1);
                            //    dataNow.Add(code, data2);
                            //    minuteData.Add(day, dataNow);
                            //}
                            //获取tick数据
                            DateTime startTime = day.Date + new TimeSpan(9, 30, 0);
                            DateTime endTime   = day.Date + new TimeSpan(15, 0, 0);
                            var      data3     = tickRepo.GetStockTransaction(bondCode, startTime, endTime);
                            var      data4     = tickRepo.GetStockTransaction(code, startTime, endTime);
                            if (tickData.ContainsKey(day.Date) == true)
                            {
                                tickData[day.Date].Add(bondCode, data3);
                                tickData[day.Date].Add(code, data4);
                            }
                            else
                            {
                                Dictionary <string, List <StockTickTransaction> > dataNow = new Dictionary <string, List <StockTickTransaction> >();
                                dataNow.Add(bondCode, data3);
                                dataNow.Add(code, data4);
                                tickData.Add(day.Date, dataNow);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                        Console.WriteLine("code:{0} date:{1} No data!", bondCode, day);
                    }
                }
            }
        }
Beispiel #13
0
        public void compute(DateTime startDate, DateTime endDate)
        {
            var tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
            //获取日线数据
            var underlyingDaily1 = stockDailyRepo.GetStockTransactionWithRedis(code1, tradedays.First(), tradedays.Last());
            var underlyingDaily2 = stockDailyRepo.GetStockTransactionWithRedis(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");
        }
Beispiel #14
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.GetStockTransactionWithRedis(indexCode, startDate, endDate);
            double startPrice = stock[0].Open;
            double strike     = startPrice;

            foreach (var date in tradedays)
            {
                //获取当日期货合约代码
                var list = getSpecialFutureList(date);
                //获取当日收盘前标的价格
                // var index = stockMinutelyRepo.GetStockTransactionWithRedis(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.GetStockTransactionWithRedis(code1, tradedays.First(), tradedays.Last());
            var    underlyingDaily2  = stockDailyRepo.GetStockTransactionWithRedis(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");
        }
        public void getMonitorData()
        {
            List <ConvertibleBondMonitor> recordList = new List <ConvertibleBondMonitor>();
            DateTime endDate = DateTime.Now;

            if (endDate.TimeOfDay < new TimeSpan(16, 10, 00))
            {
                endDate = DateTimeExtension.DateUtils.LatestTradeDay(endDate.AddDays(-1));
                endDate = endDate.Date;
            }
            DateTime startDate = endDate.AddDays(-60).Date;

            //获取交易日信息
            this.tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
            //获取可转债信息
            this.bondInfo = GetConvertibleBondInfos(endDate);
            foreach (var item in bondInfo)//每个可转债进行遍历
            {
                DateTime startTime = startDate;
                DateTime endTime   = endDate;
                if (startTime < item.startDate)
                {
                    startTime = item.startDate;
                }
                if (item.startDate > endDate)
                {
                    continue;
                }
                //获取债券的信息
                var bondInfo = getBondDailyInfo(item, endDate);
                //获取股票的日线数据
                var stockData = stockDailyRepo.GetStockTransactionWithRedis(bondInfo.stockCode, startTime.AddDays(-30), endDate);
                //获取债券的日线数据
                var bondData = stockDailyRepo.GetStockTransactionWithRedis(bondInfo.code, startTime, endDate);
                //找到股票第一个不涨停股票的数据
                var nonCeilingStockData = getStartDate(stockData);
                var lastStockData       = stockData[stockData.Count() - 1];
                //找到可转债第一个不涨停的数据
                var nonCeilingBondData = getBondDataByDate(bondData, nonCeilingStockData.DateTime);
                //计算正股波动率
                double volatility            = getStockVolatility(stockData);
                var    nonCeilingOptionPrice = getEstimateOptionPrice(nonCeilingStockData.DateTime, bondInfo, volatility, nonCeilingStockData.Close * nonCeilingStockData.AdjFactor / lastStockData.AdjFactor);
                double stockCeilPrice        = Math.Round(lastStockData.Close * 1.1, 2);
                var    ceilingOptionPrice    = getEstimateOptionPrice(nonCeilingStockData.DateTime, bondInfo, volatility, stockCeilPrice);
                double estimateBondPrice     = nonCeilingBondData.Close + 100 / bondInfo.conversionPrice * (ceilingOptionPrice - nonCeilingOptionPrice);
                double delta = 1;
                double estimateBondPrice2     = nonCeilingBondData.Close + (stockCeilPrice - nonCeilingStockData.Close) * delta * 100 / bondInfo.conversionPrice;
                ConvertibleBondMonitor record = new ConvertibleBondMonitor();
                record.ceilingStockPrice = stockCeilPrice;
                record.code                      = bondInfo.code;
                record.conversionPrice           = bondInfo.conversionPrice;
                record.estimateCeilingBondPrice  = estimateBondPrice;
                record.name                      = bondInfo.name;
                record.nonCeilingBondPrice       = nonCeilingBondData.Close;
                record.nonCeilingStockPrice      = nonCeilingStockData.Close;
                record.stockCode                 = bondInfo.stockCode;
                record.updateTime                = endDate;
                record.estimateCeilingBondPrice2 = estimateBondPrice2;
                recordList.Add(record);
            }
            var    dt      = DataTableExtension.ToDataTable(recordList);
            string dateStr = endDate.ToString("yyyy-MM-dd");
            string str     = string.Format("E:\\result\\bond\\convertibleBond{0}.csv", dateStr);

            DataTableExtension.SaveCSV(dt, str);
        }
Beispiel #17
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.GetStockTransactionWithRedis(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());
            }
        }
Beispiel #18
0
        public void compute(DateTime startDate, DateTime endDate)
        {
            var tradedays = dateRepo.GetStockTransactionDate(startDate, endDate);
            //获取日线数据
            var underlyingDaily = stockDailyRepo.GetStockTransactionWithRedis(code, tradedays.First(), tradedays.Last());

            //获取分钟线数据
            foreach (var date in tradedays)
            {
                var underlyingToday = stockMinutelyRepo.GetStockTransactionWithRedis(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);
        }
        public List <StockBonusEstimate> getIndexBonus(DateTime date, string index, List <indexStockInfo> indexStockList)
        {
            var codeList         = getIndexStocks(date, index);
            var bonusDic         = getStockBonusList(codeList, date);
            var bonusDicLastYear = getStockBonusListByYear(bonusDic, date.Year - 1);
            var bonusDicThisYear = getStockBonusListByYear(bonusDic, date.Year);
            var bonusPlanDic     = getStockBonusPlan(codeList, date);
            var epsDic           = getStockEPSRatio(codeList, date);
            //获取当前日期
            var      now         = DateTime.Now.Date;
            double   indexClose  = stockDailyRepo.GetStockTransactionWithRedis(index, date, date)[0].Close;
            DateTime lastYearEnd = new DateTime(date.Year - 1, 12, 31);
            DateTime thisYearMid = new DateTime(date.Year, 6, 30);
            List <StockBonusEstimate> estimateList = new List <StockBonusEstimate>();

            foreach (var code in codeList)
            {
                StockBonusEstimate estimate = new StockBonusEstimate();
                double             epsRatio = 0;
                var bonusLastYear           = new List <StockBonusInfo>();
                var bonusThisYear           = new List <StockBonusInfo>();
                var bonusPlan      = new List <StockBonusPlan>();
                int lastYearNumber = 0;
                int thisYearNumber = 0;
                if (epsDic.ContainsKey(code))
                {
                    epsRatio = epsDic[code];
                }
                if (bonusDicLastYear.ContainsKey(code))
                {
                    bonusLastYear  = bonusDicLastYear[code];
                    lastYearNumber = bonusLastYear.Count();
                }
                if (bonusDicThisYear.ContainsKey(code))
                {
                    bonusThisYear  = bonusDicThisYear[code];
                    thisYearNumber = bonusThisYear.Count();
                }
                if (bonusPlanDic.ContainsKey(code))
                {
                    bonusPlan = bonusPlanDic[code];
                }


                //去年无分红
                if (lastYearNumber == 0)
                {
                    //按分红公告统计
                    foreach (var item in bonusThisYear)
                    {
                        estimate                   = new StockBonusEstimate();
                        estimate.code              = item.code;
                        estimate.secName           = item.secName;
                        estimate.dividend          = item.cashPayoutRatio;
                        estimate.dividendDate      = item.exDividendDate;
                        estimate.status            = "去年无分红;分红公告明确";
                        estimate.shareRegisterDate = DateTimeExtension.DateUtils.LatestTradeDay(estimate.dividendDate.AddDays(-1));
                        if (estimate.dividendDate <= now)
                        {
                            estimate.status += "已分红";
                        }
                        estimateList.Add(estimate);
                    }
                    //分红无公告的,按分红预案统计
                    if (thisYearNumber == 0 && bonusPlan.Count > 0)
                    {
                        foreach (var item in bonusPlan)
                        {
                            estimate                   = new StockBonusEstimate();
                            estimate.code              = item.code;
                            estimate.secName           = item.name;
                            estimate.dividend          = item.dividend;
                            estimate.status            = "去年无分红;分红预案明确;分红日期未知";
                            estimate.dividendDate      = new DateTime(date.Year, 12, 31);
                            estimate.shareRegisterDate = new DateTime(date.Year, 12, 31);
                            estimateList.Add(estimate);
                        }
                    }
                    //既没有分红公告也没有分红预案的,按不分红统计
                }
                //去年分红一次
                else if (lastYearNumber == 1)
                {
                    //先按分红公告统计
                    foreach (var item in bonusThisYear)
                    {
                        estimate                   = new StockBonusEstimate();
                        estimate.code              = item.code;
                        estimate.secName           = item.secName;
                        estimate.dividend          = item.cashPayoutRatio;
                        estimate.dividendDate      = item.exDividendDate;
                        estimate.status            = "去年分红1次;分红公告明确";
                        estimate.shareRegisterDate = DateTimeExtension.DateUtils.LatestTradeDay(estimate.dividendDate.AddDays(-1));
                        if (estimate.dividendDate <= now)
                        {
                            estimate.status += "已分红";
                        }
                        estimateList.Add(estimate);
                    }
                    //有分红公告分红1次的和分红预案比较是否有遗漏的,分红两次的不需要比较
                    if (thisYearNumber == 1 && bonusPlan.Count > 0)
                    {
                        //需要吗?
                    }
                    //没有分红公告但是有分红预案的公告,按照分红预案的信息
                    if (thisYearNumber == 0 && bonusPlan.Count > 0)
                    {
                        foreach (var item in bonusPlan)
                        {
                            estimate                   = new StockBonusEstimate();
                            estimate.code              = item.code;
                            estimate.secName           = item.name;
                            estimate.dividend          = item.dividend;
                            estimate.dividendDate      = DateTimeExtension.DateUtils.PreviousOrCurrentTradeDay(bonusLastYear[0].exDividendDate.AddYears(+1));
                            estimate.status            = "去年分红1次;分红预案明确;分红日期未知";
                            estimate.shareRegisterDate = DateTimeExtension.DateUtils.LatestTradeDay(estimate.dividendDate.AddDays(-1));
                            if (estimate.dividendDate < now)
                            {
                                estimate.dividendDate      = new DateTime(date.Year, 12, 31);
                                estimate.status            = estimate.status + ";对应日期已过分红日期未知";
                                estimate.shareRegisterDate = new DateTime(date.Year, 12, 31);
                            }
                            estimateList.Add(estimate);
                        }
                    }
                    //没有分红公告也没有分红预案,按照EPS和去年分红信息来估计
                    if (thisYearNumber == 0 && bonusPlan.Count == 0 && epsRatio > 0)
                    {
                        estimate                   = new StockBonusEstimate();
                        estimate.code              = bonusLastYear[0].code;
                        estimate.secName           = bonusLastYear[0].secName;
                        estimate.dividend          = bonusLastYear[0].cashPayoutRatio * epsRatio;
                        estimate.dividendDate      = DateTimeExtension.DateUtils.PreviousOrCurrentTradeDay(bonusLastYear[0].exDividendDate.AddYears(+1));
                        estimate.shareRegisterDate = DateTimeExtension.DateUtils.LatestTradeDay(estimate.dividendDate.AddDays(-1));
                        estimate.status            = "去年分红1次;无公告无预案按eps估计";
                        if (estimate.dividendDate < now)
                        {
                            estimate.dividendDate      = new DateTime(date.Year, 12, 31);
                            estimate.status            = estimate.status + ";对应日期已过分红日期未知";
                            estimate.shareRegisterDate = new DateTime(date.Year, 12, 31);
                        }
                        estimateList.Add(estimate);
                    }
                }
                //去年分红两次
                else if (lastYearNumber >= 2)
                {
                    int thisyear = 0;
                    //先按分红公告统计
                    foreach (var item in bonusThisYear)
                    {
                        estimate                   = new StockBonusEstimate();
                        estimate.code              = item.code;
                        estimate.secName           = item.secName;
                        estimate.dividend          = item.cashPayoutRatio;
                        estimate.dividendDate      = item.exDividendDate;
                        estimate.status            = "去年分红2次;分红公告明确";
                        estimate.shareRegisterDate = DateTimeExtension.DateUtils.LatestTradeDay(estimate.dividendDate.AddDays(-1));
                        if (estimate.dividendDate <= now)
                        {
                            estimate.status += "已分红";
                        }
                        estimateList.Add(estimate);
                        thisyear += 1;
                    }
                    if (bonusThisYear.Count == 0)
                    {
                        foreach (var item in bonusPlan)
                        {
                            estimate              = new StockBonusEstimate();
                            estimate.code         = item.code;
                            estimate.secName      = item.name;
                            estimate.dividend     = item.dividend;
                            estimate.dividendDate = DateTimeExtension.DateUtils.PreviousOrCurrentTradeDay(bonusLastYear[0].exDividendDate.AddYears(+1));
                            estimate.status       = "去年分红2次;分红预案明确;分红时间未知";
                            if (thisyear == 0)
                            {
                                estimate.dividendDate = DateTimeExtension.DateUtils.PreviousOrCurrentTradeDay(bonusLastYear[0].exDividendDate.AddYears(+1));
                                if (estimate.dividendDate < now)
                                {
                                    estimate.dividendDate = DateTimeExtension.DateUtils.PreviousOrCurrentTradeDay(bonusLastYear[1].exDividendDate.AddYears(+1));
                                    estimate.status       = estimate.status + ":去年对应的第1次分红日期已过";
                                }
                                estimate.shareRegisterDate = DateTimeExtension.DateUtils.LatestTradeDay(estimate.dividendDate.AddDays(-1));
                            }
                            else
                            {
                                estimate.dividendDate      = DateTimeExtension.DateUtils.PreviousOrCurrentTradeDay(bonusLastYear[1].exDividendDate.AddYears(+1));
                                estimate.shareRegisterDate = DateTimeExtension.DateUtils.LatestTradeDay(estimate.dividendDate.AddDays(-1));
                            }
                            if (estimate.dividendDate < now)
                            {
                                estimate.dividendDate      = new DateTime(date.Year, 12, 31);
                                estimate.status            = estimate.status + ";对应日期已过分红日期未知";
                                estimate.shareRegisterDate = new DateTime(date.Year, 12, 31);
                            }
                            estimateList.Add(estimate);
                            thisyear += 1;
                        }
                    }
                    else if (bonusThisYear.Count == 1)
                    {
                        foreach (var item in bonusPlan)
                        {
                            estimate                   = new StockBonusEstimate();
                            estimate.code              = item.code;
                            estimate.secName           = item.name;
                            estimate.dividend          = item.dividend;
                            estimate.dividendDate      = DateTimeExtension.DateUtils.PreviousOrCurrentTradeDay(bonusLastYear[0].exDividendDate.AddYears(+1));
                            estimate.status            = "去年分红2次;分红预案明确;分红时间未明确";
                            estimate.shareRegisterDate = DateTimeExtension.DateUtils.LatestTradeDay(estimate.dividendDate.AddDays(-1));
                            if (estimate.dividendDate < now)
                            {
                                estimate.dividendDate      = new DateTime(date.Year, 12, 31);
                                estimate.status            = estimate.status + ";对应日期已过分红日期未知";
                                estimate.shareRegisterDate = new DateTime(date.Year, 12, 31);
                            }
                            estimateList.Add(estimate);
                            thisyear += 1;
                        }
                    }
                    else if (bonusThisYear.Count == 2)
                    {
                        //搞定
                    }

                    //利用去年分红数据估计
                    if (thisyear == 0 && epsRatio > 0)
                    {
                        estimate                   = new StockBonusEstimate();
                        estimate.code              = bonusLastYear[0].code;
                        estimate.secName           = bonusLastYear[0].secName;
                        estimate.dividend          = bonusLastYear[0].cashPayoutRatio * epsRatio;
                        estimate.dividendDate      = DateTimeExtension.DateUtils.PreviousOrCurrentTradeDay(bonusLastYear[0].exDividendDate.AddYears(+1));
                        estimate.status            = "去年分红2次;按eps估计第1次分红";
                        estimate.shareRegisterDate = DateTimeExtension.DateUtils.LatestTradeDay(estimate.dividendDate.AddDays(-1));
                        if (estimate.dividendDate < now)
                        {
                            estimate.dividendDate      = DateTimeExtension.DateUtils.PreviousOrCurrentTradeDay(bonusLastYear[1].exDividendDate.AddYears(+1));
                            estimate.shareRegisterDate = DateTimeExtension.DateUtils.LatestTradeDay(estimate.dividendDate.AddDays(-1));
                            estimate.status            = estimate.status + ":去年对应的第1次分红日期已过";
                        }
                        if (estimate.dividendDate < now)
                        {
                            estimate.dividendDate      = new DateTime(date.Year, 12, 31);
                            estimate.status            = estimate.status + ";对应日期已过分红日期未知";
                            estimate.shareRegisterDate = new DateTime(date.Year, 12, 31);
                        }
                        estimateList.Add(estimate);
                        estimate                   = new StockBonusEstimate();
                        estimate.code              = bonusLastYear[1].code;
                        estimate.secName           = bonusLastYear[1].secName;
                        estimate.dividend          = bonusLastYear[1].cashPayoutRatio * epsRatio;
                        estimate.dividendDate      = DateTimeExtension.DateUtils.PreviousOrCurrentTradeDay(bonusLastYear[1].exDividendDate.AddYears(+1));
                        estimate.status            = "去年分红2次;按eps估计第2次分红";
                        estimate.shareRegisterDate = DateTimeExtension.DateUtils.LatestTradeDay(estimate.dividendDate.AddDays(-1));
                        if (estimate.dividendDate < now)
                        {
                            estimate.dividendDate      = new DateTime(date.Year, 12, 31);
                            estimate.status            = estimate.status + ";对应日期已过分红日期未知";
                            estimate.shareRegisterDate = new DateTime(date.Year, 12, 31);
                        }
                        estimateList.Add(estimate);
                    }
                    else if (thisyear == 1 && epsRatio > 0)
                    {
                        estimate                   = new StockBonusEstimate();
                        estimate.code              = bonusLastYear[1].code;
                        estimate.secName           = bonusLastYear[1].secName;
                        estimate.dividend          = bonusLastYear[1].cashPayoutRatio * epsRatio;
                        estimate.dividendDate      = DateTimeExtension.DateUtils.PreviousOrCurrentTradeDay(bonusLastYear[1].exDividendDate.AddYears(+1));
                        estimate.status            = "去年分红2次;按eps估计第2次分红";
                        estimate.shareRegisterDate = DateTimeExtension.DateUtils.LatestTradeDay(estimate.dividendDate.AddDays(-1));
                        if (estimate.dividendDate < now)
                        {
                            estimate.dividendDate      = new DateTime(date.Year, 12, 31);
                            estimate.status            = estimate.status + ";对应日期已过分红日期未知";
                            estimate.shareRegisterDate = new DateTime(date.Year, 12, 31);
                        }
                        estimateList.Add(estimate);
                    }
                }
            }
            //计算具体的指数点
            foreach (var item in estimateList)
            {
                foreach (var stock in indexStockList)
                {
                    if (item.code == stock.code)
                    {
                        double points = stock.weight * item.dividend / stock.close * indexClose * 0.01;
                        item.points = points;
                    }
                }
            }


            return(estimateList);
        }