/// <summary>
        /// 根据计算规则获取当日交易日的股指期货列表
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        private Dictionary <string, CFEFutures> getFutureList(DateTime date)
        {
            var number                          = 3; //3为选择3个合约,4为选择4个合约
            List <CFEFutures> list              = new List <CFEFutures>();
            List <DateTime>   dateList          = new List <DateTime>();
            Dictionary <string, CFEFutures> dic = new Dictionary <string, CFEFutures>();
            var expireDateOfThisMonth           = DateUtils.NextOrCurrentTradeDay(DateUtils.GetThirdFridayOfMonth(date.Year, date.Month));

            if (date > expireDateOfThisMonth)
            {
                date = DateUtils.GetFirstDateOfNextMonth(date);
            }
            dateList.Add(date);
            var date2 = DateUtils.GetFirstDateOfNextMonth(date);

            dateList.Add(date2);
            var date3 = DateUtils.GetLastDateOfThisSeason(date2);

            if (date3.Month == date2.Month)
            {
                date3 = DateUtils.GetFirstDateOfNextMonth(date3);
                date3 = DateUtils.GetLastDateOfThisSeason(date3);
            }
            dateList.Add(date3);
            var date4 = DateUtils.GetLastDateOfThisSeason(DateUtils.GetFirstDateOfNextMonth(date3));

            dateList.Add(date4);
            for (int i = 0; i < number; i++)
            {
                date = dateList[i];
                var    future = new CFEFutures();
                string year   = date.Year.ToString();
                year = year.Substring(year.Length - 2, 2);
                string month = "0" + date.Month.ToString();
                month             = month.Substring(month.Length - 2, 2);
                future.code       = code + year + month + ".CFE";
                future.expireDate = DateUtils.NextOrCurrentTradeDay(DateUtils.GetThirdFridayOfMonth(date.Year, date.Month));
                list.Add(future);
            }
            foreach (var item in list)
            {
                dic.Add(item.code, item);
            }
            return(dic);
        }
        public void compute(DateTime startDate, DateTime endDate)
        {
            var    tradedays   = dateRepo.GetStockTransactionDate(startDate, endDate);
            var    choice      = new Dictionary <DateTime, List <CFEFuturesChoice> >();
            string myHoldStr   = "";
            var    tradeRecord = new List <CFEFuturesTradeRecord>();
            var    parameters  = startDate.ToShortDateString() + '_' + endDate.ToShortDateString() + "_treshold" + treshold.ToString() + "_slip" + slip.ToString();

            if (!ExistInSqlServer(code, parameters))
            {
                CreateDBOrTableIfNecessary(code, parameters);
            }
            DataTable dt = new DataTable();

            dt.Columns.Add("code");
            dt.Columns.Add("tdatetime", typeof(DateTime));
            dt.Columns.Add("expiredate", typeof(DateTime));
            dt.Columns.Add("indexPrice");
            dt.Columns.Add("price");
            dt.Columns.Add("annulizedBasis");

            foreach (var date in tradedays)
            {
                var list        = getFutureList(date);
                var index       = stockMinutelyRepo.GetStockTransactionWithRedis(indexCode, date, date);
                var dataList    = new Dictionary <string, List <StockTransaction> >();
                var holdNow     = new CFEFutures();
                var choiceToday = new List <CFEFuturesChoice>();

                if (myHoldStr != "")
                {
                    holdNow = list[myHoldStr];
                }
                foreach (var item in list)
                {
                    var data = stockMinutelyRepo.GetStockTransactionWithRedis(item.Key, date, date);
                    dataList.Add(item.Key, data);
                }
                for (int i = 5; i < 235; i++)
                {
                    DateTime         expireDate = new DateTime();
                    CFEFuturesChoice record     = new CFEFuturesChoice();
                    double           basis      = -10000;
                    if (myHoldStr == "")
                    {
                        var transaction = new CFEFuturesTradeRecord();
                        foreach (var item in list)
                        {
                            double basisNow = getAnuualizedBasis(item.Value, date, dataList[item.Value.code][i].Close, index[i].Close);
                            if (basisNow > basis)
                            {
                                holdNow                = item.Value;
                                basis                  = basisNow;
                                expireDate             = item.Value.expireDate;
                                myHoldStr              = item.Key;
                                transaction.code       = item.Key;
                                transaction.indexPrice = index[i].Close;
                                transaction.price      = dataList[item.Value.code][i].Close;
                                transaction.time       = index[i].DateTime;
                                transaction.direction  = -1;
                                transaction.expireDate = item.Value.expireDate;
                            }
                        }
                        //第一次开仓
                        tradeRecord.Add(transaction);
                    }
                    else
                    {
                        double modify               = 0;
                        var    closeRecord          = new CFEFuturesTradeRecord();
                        var    transaction          = new CFEFuturesTradeRecord();
                        var    latestBasis          = tradeRecord.Last().price - tradeRecord.Last().indexPrice;
                        var    latestTime           = tradeRecord.Last().time;
                        var    latestExpireDate     = tradeRecord.Last().expireDate;
                        var    latestAnnulizedBasis = getAnuualizedBasis2(latestBasis, latestTime, latestExpireDate);
                        closeRecord.time       = index[i].DateTime;
                        closeRecord.indexPrice = index[i].Close;
                        closeRecord.direction  = 1;
                        closeRecord.code       = holdNow.code;
                        closeRecord.price      = dataList[holdNow.code][i].Close;
                        closeRecord.expireDate = holdNow.expireDate;
                        basis = getAnuualizedBasis(holdNow, date, dataList[holdNow.code][i].Close, index[i].Close);
                        foreach (var item in list)
                        {
                            if (item.Value != holdNow)
                            {
                                modify = slip;
                            }
                            double basisNow          = getAnuualizedBasis(item.Value, date, dataList[item.Value.code][i].Close - modify, index[i].Close);
                            double annulizedBasisNow = getAnuualizedBasis2(dataList[item.Value.code][i].Close - modify + latestBasis - dataList[holdNow.code][i].Close, latestTime, item.Value.expireDate);
                            if ((annulizedBasisNow > latestAnnulizedBasis + treshold && DateUtils.GetSpanOfTradeDays(date, item.Value.expireDate) > 10) || DateUtils.GetSpanOfTradeDays(date, holdNow.expireDate) < 5)
                            //if (DateUtils.GetSpanOfTradeDays(date, holdNow.expireDate) < 5)
                            {
                                holdNow                = item.Value;
                                basis                  = basisNow;
                                expireDate             = item.Value.expireDate;
                                myHoldStr              = item.Key;
                                transaction.code       = item.Key;
                                transaction.indexPrice = index[i].Close;
                                transaction.price      = dataList[item.Value.code][i].Close;
                                transaction.time       = index[i].DateTime;
                                transaction.direction  = -1;
                                transaction.expireDate = expireDate;
                            }
                        }
                        if (transaction.code != null)
                        {
                            tradeRecord.Add(closeRecord);
                            tradeRecord.Add(transaction);
                        }
                    }
                    record.code           = holdNow.code;
                    record.expireDate     = holdNow.expireDate;
                    record.annulizedBasis = basis;
                    record.indexPrice     = index[i].Close;
                    record.price          = dataList[holdNow.code][i].Close;
                    choiceToday.Add(record);
                    DataRow dr = dt.NewRow();
                    dr["code"]           = record.code;
                    dr["tdatetime"]      = index[i].DateTime;//etf[i].TransactionDateTime;
                    dr["expiredate"]     = record.expireDate;
                    dr["indexPrice"]     = record.indexPrice;
                    dr["price"]          = record.price;
                    dr["annulizedBasis"] = record.annulizedBasis;
                    dt.Rows.Add(dr);
                }
                choice.Add(date, choiceToday);
            }
            var pnl      = getPnL(tradeRecord);
            var netValue = getNetValue(tradeRecord, tradedays);

            Console.WriteLine(pnl);
            SaveResultToMssql(dt, code, parameters);

            DataTable dt2 = new DataTable();

            dt2.Columns.Add("code");
            dt2.Columns.Add("tdatetime", typeof(DateTime));
            dt2.Columns.Add("expiredate", typeof(DateTime));
            dt2.Columns.Add("indexPrice");
            dt2.Columns.Add("price");
            dt2.Columns.Add("direction");
            for (int i = 0; i < tradeRecord.Count(); i++)
            {
                DataRow dr     = dt2.NewRow();
                var     record = tradeRecord[i];
                dr["code"]       = record.code;
                dr["tdatetime"]  = record.time;
                dr["expiredate"] = record.expireDate;
                dr["indexPrice"] = record.indexPrice;
                dr["price"]      = record.price;
                dr["direction"]  = record.direction;
                dt2.Rows.Add(dr);
            }
            if (!ExistInSqlServer2(code, parameters))
            {
                CreateDBOrTableIfNecessary2(code, parameters);
            }
            SaveResultToMssql2(dt2, code, parameters);

            DataTable dt3 = new DataTable();

            dt3.Columns.Add("code");
            dt3.Columns.Add("tdatetime", typeof(DateTime));
            dt3.Columns.Add("expiredate", typeof(DateTime));
            dt3.Columns.Add("basis");
            dt3.Columns.Add("annulizedBasis");
            dt3.Columns.Add("basisWithSlip");
            dt3.Columns.Add("annulizedBasisWithSlip");
            for (int i = 0; i < netValue.Count(); i++)
            {
                DataRow dr     = dt3.NewRow();
                var     record = netValue[i];
                dr["code"]                   = record.code;
                dr["tdatetime"]              = record.time;
                dr["expiredate"]             = record.expireDate;
                dr["basis"]                  = record.basis;
                dr["annulizedBasis"]         = record.annulizedBasis;
                dr["basisWithSlip"]          = record.basisWithSlip;
                dr["annulizedBasisWithSlip"] = record.annulizedBasisWithSlip;
                dt3.Rows.Add(dr);
            }
            if (!ExistInSqlServer3(code, parameters))
            {
                CreateDBOrTableIfNecessary3(code, parameters);
            }
            SaveResultToMssql3(dt3, code, parameters);
        }
        /// <summary>
        /// 计算年化基差
        /// </summary>
        /// <param name="future"></param>
        /// <param name="today"></param>
        /// <param name="futurePrice"></param>
        /// <param name="indexPrice"></param>
        /// <returns></returns>
        private double getAnuualizedBasis(CFEFutures future, DateTime today, double futurePrice, double indexPrice)
        {
            double term = DateUtils.GetSpanOfTradeDays(today, future.expireDate) / 252.0;

            return((futurePrice - indexPrice) / term);
        }