/// <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); }