예제 #1
0
 /// <summary>
 /// 构造函数
 /// </summary>
 /// <param name="date">指定日期</param>
 public GetStocks(int startDate, int endDate, string indexName)
 {
     this.startDate = startDate;
     this.endDate   = endDate;
     this.indexName = indexName;
     if (myTradeDays == null)
     {
         myTradeDays = new TradeDays(startDate, endDate);
     }
     if (stockList == null)
     {
         w.start();
         stockList = getExitsStocks();
     }
 }
예제 #2
0
        private void GetBonusPlan()
        {
            bonusList = new SortedDictionary <string, stockBonus>();
            w.start();
            //利用万德wset的“分红预案”抓取数据
            WindData wd = w.wset("dividendproposal", "ordertype=1;startdate=2015-06-30;enddate=2020-12-31;sectorid=a001010100000000;field=wind_code,sec_name,progress,cash_dividend,fellow_preplandate");

            object[] stockList = wd.data as object[];
            int      num       = stockList.Length / 5;

            for (int i = 0; i < num; i++)
            {
                stockBonus myBonus = new stockBonus();
                myBonus.code      = Convert.ToString(stockList[i * 5]);
                myBonus.name      = (string)stockList[i * 5 + 1];
                myBonus.progress  = (string)stockList[i * 5 + 2];
                myBonus.planBonus = (stockList[i * 5 + 3] == null? 0:(double)stockList[i * 5 + 3]);
                string[] date = Convert.ToString(stockList[i * 5 + 4]).Split(new char[] { '/', ' ' });
                myBonus.planDate = Convert.ToInt32(date[0]) * 10000 + Convert.ToInt32(date[1]) * 100 + Convert.ToInt32(date[2]);
                if (TradeDays.GetTimeSpan(myBonus.planDate, yesterday) <= 125 && myBonus.code.Substring(7, 2) == "SH")
                {
                    if (bonusList.ContainsKey(myBonus.code) == false)
                    {
                        bonusList.Add(myBonus.code, myBonus);
                    }
                    else if (TradeDays.GetTimeSpan(myBonus.planDate, yesterday) < TradeDays.GetTimeSpan(bonusList[myBonus.code].planDate, yesterday))
                    {
                        bonusList[myBonus.code] = myBonus;
                    }
                }
            }
            foreach (var item in GetStocks.stockList)
            {
                string code = item.Key;
                if (bonusList.ContainsKey(code) == false)
                {
                    stockBonus myBonus = new stockBonus();
                    myBonus.code     = item.Value.code;
                    myBonus.name     = item.Value.name;
                    myBonus.progress = "没有分红预案";
                    bonusList.Add(myBonus.code, myBonus);
                }
            }
        }
예제 #3
0
        private void EvaluateBonus()
        {
            //利用万德wset的“分红送转”抓取数据
            foreach (var item in GetStocks.stockList)
            {
                stockBonus    bonus               = bonusList[item.Key];
                List <int>    dateList            = new List <int>();
                List <double> historicalBonusList = new List <double>();
                WindData      wd        = w.wset("corporationaction", "startdate=2014-01-01;enddate=2020-06-20;windcode=" + bonus.code + ";field=ex_dividend_date,wind_code,sec_name,cash_payout_ratio,ex_dividend_note");
                object[]      stockList = wd.data as object[];
                int           num       = (stockList == null ? 0 : stockList.Length / 5);
                for (int i = 0; i < num; i++)
                {
                    string[] dateStr   = Convert.ToString(stockList[i * 5]).Split(new char[] { '/', ' ' });
                    int      date      = Convert.ToInt32(dateStr[0]) * 10000 + Convert.ToInt32(dateStr[1]) * 100 + Convert.ToInt32(dateStr[2]);
                    double   planBonus = (stockList[i * 5 + 3] == null ? 0 : (double)stockList[i * 5 + 3]);
                    dateList.Add(date);
                    historicalBonusList.Add(planBonus);
                }
                //判断去年是否有2次分红
                int thisYear = 0, lastYear = 0;
                for (int i = 0; i < dateList.Count; i++)
                {
                    int    date    = dateList[i];
                    double myBonus = historicalBonusList[i];
                    if (date / 10000 + 1 == yesterday / 10000 && myBonus > 0)
                    {
                        lastYear += 1;
                    }
                    if (date / 10000 == yesterday / 10000 && myBonus > 0)
                    {
                        thisYear += 1;
                    }
                }
                if (lastYear == 1 &&  thisYear == 1)
                {
                    bonus.firstBonus  = historicalBonusList[historicalBonusList.Count() - 1];
                    bonus.firstDate   = dateList[dateList.Count() - 1];
                    bonus.firstStatus = "明确";
                }
                if (lastYear == 1 && thisYear == 0)
                {
                    if (bonus.planBonus != 0)
                    {
                        bonus.firstBonus  = bonus.planBonus;
                        bonus.firstDate   = TradeDays.GetRecentTradeDay(dateList[dateList.Count() - 1] + 10000);
                        bonus.firstStatus = "有预案但日期未明确";
                    }
                    else
                    {
                        string   str     = DateTime.ParseExact(yesterday.ToString(), "yyyyMMdd", null).ToString("yyyy-MM-dd");
                        WindData eps     = w.wsd(bonus.code, "eps_ttm", "ED-0TD", str, "Days=Alldays");//利用EPS来估算分红
                        double[] epsList = eps.data as double[];
                        double   thisEps = epsList[0];
                        if (thisEps < 0)
                        {
                            bonus.firstStatus = "去年亏损无分红";
                            bonus.firstBonus  = 0;
                            bonus.firstDate   = 0;
                        }
                        else
                        {
                            str     = DateTime.ParseExact((yesterday - 10000).ToString(), "yyyyMMdd", null).ToString("yyyy-MM-dd");
                            eps     = w.wsd(bonus.code, "eps_ttm", "ED-0TD", str, "Days=Alldays");
                            epsList = eps.data as double[];
                            double lastEps = (epsList == null?0:epsList[0]);
                            if (lastEps == 0)
                            {
                                bonus.firstStatus = "去年无EPS数据无法预测";
                                bonus.firstBonus  = 0;
                                bonus.firstDate   = 0;
                            }
                            else
                            {
                                bonus.firstBonus  = historicalBonusList[historicalBonusList.Count() - 1] / lastEps * thisEps;
                                bonus.firstDate   = TradeDays.GetRecentTradeDay(dateList[dateList.Count() - 1] + 10000);
                                bonus.firstStatus = "无预案按上次分红预测";
                            }
                        }
                    }
                }
                if (lastYear >= 2 && thisYear == 2)
                {
                    bonus.firstBonus   = historicalBonusList[historicalBonusList.Count() - 2];
                    bonus.firstDate    = dateList[dateList.Count() - 2];
                    bonus.firstStatus  = "明确";
                    bonus.secondBonus  = historicalBonusList[historicalBonusList.Count() - 1];
                    bonus.secondDate   = dateList[dateList.Count() - 1];
                    bonus.secondStatus = "明确";
                }
                if (lastYear >= 2 && thisYear == 1)
                {
                    bonus.firstBonus  = historicalBonusList[historicalBonusList.Count() - 1];
                    bonus.firstDate   = dateList[dateList.Count() - 1];
                    bonus.firstStatus = "明确";
                    if (bonus.planBonus != 0)
                    {
                        bonus.secondBonus  = bonus.planBonus;
                        bonus.secondDate   = TradeDays.GetRecentTradeDay(dateList[dateList.Count() - 2] + 10000);
                        bonus.secondStatus = "有预案但日期未明确";
                    }
                    else
                    {
                        bonus.secondDate   = TradeDays.GetRecentTradeDay(dateList[dateList.Count() - 2] + 10000);
                        bonus.secondStatus = "无预案按上次分红预测";
                        bonus.secondBonus  = historicalBonusList[historicalBonusList.Count() - 2] / historicalBonusList[historicalBonusList.Count() - 3] * historicalBonusList[historicalBonusList.Count() - 1];
                    }
                }
                if (lastYear >= 2 && thisYear == 0)
                {
                    if (bonus.planBonus != 0)
                    {
                        bonus.firstBonus   = bonus.planBonus;
                        bonus.firstDate    = TradeDays.GetRecentTradeDay(dateList[dateList.Count() - 2] + 10000);
                        bonus.firstStatus  = "有预案但日期未明确";
                        bonus.secondDate   = TradeDays.GetRecentTradeDay(dateList[dateList.Count() - 1] + 10000);
                        bonus.secondStatus = "无预案按上次分红预测";
                        bonus.secondBonus  = historicalBonusList[historicalBonusList.Count() - 1] / historicalBonusList[historicalBonusList.Count() - 2] * bonus.planBonus;
                    }
                    else
                    {
                        string   str     = DateTime.ParseExact(yesterday.ToString(), "yyyyMMdd", null).ToString("yyyy-MM-dd");
                        WindData eps     = w.wsd(bonus.code, "eps_ttm", "ED-0TD", str, "Days=Alldays");
                        double[] epsList = eps.data as double[];
                        double   thisEps = epsList[0];
                        if (thisEps < 0)
                        {
                            bonus.firstStatus  = "去年亏损无分红";
                            bonus.firstBonus   = 0;
                            bonus.firstDate    = 0;
                            bonus.secondStatus = "去年亏损无分红";
                            bonus.secondBonus  = 0;
                            bonus.secondDate   = 0;
                        }
                        else
                        {
                            str     = DateTime.ParseExact((yesterday - 10000).ToString(), "yyyyMMdd", null).ToString("yyyy-MM-dd");
                            eps     = w.wsd(bonus.code, "eps_ttm", "ED-0TD", str, "Days=Alldays");
                            epsList = eps.data as double[];
                            double lastEps = (epsList == null ? 0 : epsList[0]);
                            if (lastEps == 0)
                            {
                                bonus.firstStatus  = "去年无EPS数据无法预测";
                                bonus.firstBonus   = 0;
                                bonus.firstDate    = 0;
                                bonus.secondStatus = "去年无EPS数据无法预测";
                                bonus.secondBonus  = 0;
                                bonus.secondDate   = 0;
                            }
                            else
                            {
                                bonus.firstBonus   = historicalBonusList[historicalBonusList.Count() - 2] / lastEps * thisEps;
                                bonus.firstDate    = TradeDays.GetRecentTradeDay(dateList[dateList.Count() - 2] + 10000);
                                bonus.firstStatus  = "无预案按上次分红预测";
                                bonus.secondBonus  = historicalBonusList[historicalBonusList.Count() - 1] / lastEps * thisEps;
                                bonus.secondDate   = TradeDays.GetRecentTradeDay(dateList[dateList.Count() - 1] + 10000);
                                bonus.secondStatus = "无预案按上次分红预测";
                            }
                        }
                    }
                }
                if (lastYear == 0 && thisYear == 0)
                {
                    if (bonus.planBonus > 0)
                    {
                        bonus.firstBonus  = bonus.planBonus;
                        bonus.firstDate   = 0;
                        bonus.firstStatus = "有预案但日期未明确";
                    }
                    else
                    {
                        bonus.firstStatus = "无预案无分红数据";
                    }
                }
                if (lastYear == 0 && thisYear == 1)
                {
                    bonus.firstBonus  = historicalBonusList[historicalBonusList.Count() - 1];
                    bonus.firstDate   = dateList[dateList.Count() - 1];
                    bonus.firstStatus = "明确";
                    if (bonus.planBonus > 0)
                    {
                        bonus.secondBonus  = bonus.planBonus;
                        bonus.secondDate   = 0;
                        bonus.secondStatus = "有预案但日期未明确";
                    }
                }
                if (lastYear == 0 &&  thisYear == 2)
                {
                    bonus.firstBonus   = historicalBonusList[historicalBonusList.Count() - 2];
                    bonus.firstDate    = dateList[dateList.Count() - 2];
                    bonus.firstStatus  = "明确";
                    bonus.secondBonus  = historicalBonusList[historicalBonusList.Count() - 1];
                    bonus.secondDate   = dateList[dateList.Count() - 1];
                    bonus.secondStatus = "明确";
                }
                if (bonus.firstStatus == "有预案但日期未明确" || bonus.firstStatus == "无预案按上次分红预测")
                {
                    if (bonus.firstDate <= yesterday)
                    {
                        bonus.firstDate    = 0;
                        bonus.firstStatus += "预测日期已过";
                    }
                }
                if (bonus.secondStatus == "有预案但日期未明确" || bonus.secondStatus == "无预案按上次分红预测")
                {
                    if (bonus.secondDate <= yesterday)
                    {
                        bonus.secondDate    = 0;
                        bonus.secondStatus += "预测日期已过";
                    }
                }
                evaluateBonusList.Add(bonus.code, bonus);
            }

            //预处理,默认除息除权日是分红的前一天
            foreach (var item in GetStocks.stockList)
            {
                stockBonus bonus = evaluateBonusList[item.Key];

                if (bonus.firstDate > 0)
                {
                    bonus.firstRegisterDate = TradeDays.GetPreviousTradeDay(bonus.firstDate);
                }
                if (bonus.secondDate > 0)
                {
                    bonus.SecondRegisterDate = TradeDays.GetPreviousTradeDay(bonus.secondDate);
                }
                evaluateBonusList[item.Key] = bonus;
            }


            //利用万德接口wset的“分红实施”来获取股权登记日
            string   lastYearStr = (yesterday / 10000 - 1).ToString();
            WindData register    = w.wset("bonus", "orderby=报告期;year=" + lastYearStr + ";period=y1;sectorid=a001010100000000;field=wind_code,sec_name,shareregister_date,dividend_payment_date");

            object[] stockList2 = register.data as object[];
            int      num2       = (stockList2 == null?0:stockList2.Length / 4);

            for (int i = 0; i < num2; i++)
            {
                string code = Convert.ToString(stockList2[i * 4]);
                if (evaluateBonusList.ContainsKey(code))
                {
                    string[]   date     = Convert.ToString(stockList2[i * 4 + 3]).Split(new char[] { '/', ' ' });
                    int        planDate = Convert.ToInt32(date[0]) * 10000 + Convert.ToInt32(date[1]) * 100 + Convert.ToInt32(date[2]);
                    stockBonus bonus    = evaluateBonusList[code];
                    if (planDate == bonus.firstDate)
                    {
                        date = Convert.ToString(stockList2[i * 4 + 2]).Split(new char[] { '/', ' ' });
                        bonus.firstRegisterDate = Convert.ToInt32(date[0]) * 10000 + Convert.ToInt32(date[1]) * 100 + Convert.ToInt32(date[2]);
                    }
                    if (planDate == bonus.secondDate)
                    {
                        date = Convert.ToString(stockList2[i * 4 + 2]).Split(new char[] { '/', ' ' });
                        bonus.SecondRegisterDate = Convert.ToInt32(date[0]) * 10000 + Convert.ToInt32(date[1]) * 100 + Convert.ToInt32(date[2]);
                    }
                    evaluateBonusList[code] = bonus;
                }
            }
        }
예제 #4
0
        /// <summary>
        /// 根据程序运行日期,获取截止至昨日的指数成分股的列表
        /// </summary>
        /// <returns>指数成分股列表</returns>
        private Dictionary <string, stockFormat> getExitsStocks()
        {
            Dictionary <string, stockFormat> list = new Dictionary <string, stockFormat>();
            int yesterday = TradeDays.GetPreviousTradeDay(Convert.ToInt32(DateTime.Now.ToString("yyyyMMdd")));

            foreach (int day in myTradeDays.myTradeDays)
            {
                string todayStr = DateTime.ParseExact(day.ToString(), "yyyyMMdd", null).ToString("yyyy-MM-dd");

                if (day <= yesterday)
                {
                    WindData wd        = w.wset("sectorconstituent", "date=" + todayStr + ";windcode=" + indexName);
                    object[] stockList = wd.data as object[];
                    int      num       = stockList.Length / 3;
                    for (int i = 0; i < num; i++)
                    {
                        stockFormat myStock = new stockFormat();
                        myStock.code = Convert.ToString(stockList[i * 3 + 1]);
                        myStock.name = (string)stockList[i * 3 + 2];
                        if (list.ContainsKey(myStock.code) == false)
                        {
                            myStock.existsDate = new List <int>();
                            myStock.existsDate.Add(day);
                            myStock.existsDate.Add(day);
                            list.Add(myStock.code, myStock);
                        }
                        else
                        {
                            int enterDate = list[myStock.code].existsDate[list[myStock.code].existsDate.Count() - 2];
                            int quitDate  = list[myStock.code].existsDate[list[myStock.code].existsDate.Count() - 1];
                            if (day > TradeDays.GetNextTradeDay(quitDate))
                            {
                                list[myStock.code].existsDate.Add(day);
                                list[myStock.code].existsDate.Add(day);
                            }
                            else
                            {
                                list[myStock.code].existsDate[list[myStock.code].existsDate.Count() - 1] = day;
                            }
                        }
                    }
                }
            }
            //若计算时间不包括历史时间,必须读取昨日的数据作为基准
            if (list.Count == 0)
            {
                string   yesterdayStr = DateTime.ParseExact(yesterday.ToString(), "yyyyMMdd", null).ToString("yyyy-MM-dd"); List <stockFormat> myList = new List <stockFormat>();
                WindData wd        = w.wset("sectorconstituent", "date=" + yesterdayStr + ";windcode=" + indexName);
                object[] stockList = wd.data as object[];
                int      num       = stockList.Length / 3;
                for (int i = 0; i < num; i++)
                {
                    stockFormat myStock = new stockFormat();
                    myStock.code       = Convert.ToString(stockList[i * 3 + 1]).Substring(0, 6);
                    myStock.name       = (string)stockList[i * 3 + 2];
                    myStock.existsDate = new List <int>();
                    myStock.existsDate.Add(yesterday);
                    myStock.existsDate.Add(yesterday);
                }
            }

            //从stockModify.csv中读取指数成分股变动股票和日期

            #region modify
            int maxDate = yesterday;

            /*
             * DataTable dt = CsvApplication.OpenCSV("stockModify.csv");
             * SortedDictionary<int, List<stockModify>> stockModifyList = new SortedDictionary<int, List<stockModify>>();
             * for (int i = 0; i < dt.Rows.Count; i++)
             * {
             *  stockModify stock = new stockModify();
             *  stock.code = dt.Rows[i][0].ToString();
             *  stock.name = dt.Rows[i][1].ToString();
             *  stock.date = Convert.ToInt32(dt.Rows[i][2].ToString());
             *  stock.direction = dt.Rows[i][3].ToString();
             *  if (stockModifyList.ContainsKey(stock.date))
             *  {
             *      stockModifyList[stock.date].Add(stock);
             *  }
             *  else
             *  {
             *      List<stockModify> stockList0 = new List<stockModify>();
             *      stockList0.Add(stock);
             *      stockModifyList.Add(stock.date, stockList0);
             *  }
             * }
             *
             *
             * //根据文档对我的数据进行处理,如果变动时间大于昨日时间,需要对我的股票列表进行修正
             *
             * foreach (var stockList in stockModifyList)
             * {
             *  if (stockList.Value[0].date > yesterday)
             *  {
             *      foreach (var stock in stockList.Value)
             *      {
             *          if (stock.direction == "out")
             *          {
             *              if (list.ContainsKey(stock.code) == true)
             *              {
             *                  list[stock.code].existsDate[list[stock.code].existsDate.Count() - 1] = stock.date;
             *              }
             *          }
             *          if (stock.direction == "in")
             *          {
             *              if (stockList.Value[0].date > maxDate)
             *              {
             *                  maxDate = stockList.Value[0].date;
             *              }
             *              if (list.ContainsKey(stock.code) == true)
             *              {
             *                  list[stock.code].existsDate.Add(stock.date);
             *                  list[stock.code].existsDate.Add(stock.date);
             *              }
             *              else
             *              {
             *                  stockFormat myStock = new stockFormat();
             *                  myStock.name = stock.name;
             *                  myStock.code = stock.code;
             *                  myStock.existsDate = new List<int>();
             *                  myStock.existsDate.Add(stock.date);
             *                  myStock.existsDate.Add(stock.date);
             *              }
             *          }
             *      }
             *  }
             * }
             */
            #endregion

            //按照回测日期给股票列表进行修正
            foreach (var stock in list)
            {
                if (stock.Value.existsDate[stock.Value.existsDate.Count() - 1] == yesterday || stock.Value.existsDate[stock.Value.existsDate.Count() - 1] == maxDate)
                {
                    stock.Value.existsDate[stock.Value.existsDate.Count() - 1] = endDate;
                }
            }
            return(list);
        }