/// <summary> /// 两两配对的longdelta期权的筛选 /// </summary> /// <param name="days"></param> /// <returns></returns> private List <LongDeltaPair> getLongDeltaPair(int days) { List <LongDeltaPair> pairs = new List <LongDeltaPair>(); double etfUpper = etfPrice * Math.Exp(2 * volSurface[days, 500] * Math.Sqrt(days / 252.0)); double etfLower = etfPrice * Math.Exp(-2 * volSurface[days, 500] * Math.Sqrt(days / 252.0)); //两两循环选择最优配对 foreach (var item1 in optionPrice) { OptionGreek option1 = item1.Value; double price1 = computeFuturePrice(days, option1.code, etfPrice); foreach (var item2 in optionPrice) { OptionGreek option2 = item2.Value; if (option1.code != option2.code && option1.duration >= days && option2.duration >= days) { //选取delta为正的组合开始计算。 LongDeltaPair pair = new LongDeltaPair(); double profit = 0; double loss = 0; if (option1.delta > option2.delta) { pair.option1 = option1.code; pair.option2 = option2.code; pair.mark = Math.Abs(computeMarkOfPairs(option1.code, option2.code, days, etfUpper, etfLower, ref profit, ref loss)); pair.profit = profit; pair.loss = loss; } else { pair.option1 = option2.code; pair.option2 = option1.code; pair.mark = Math.Abs(computeMarkOfPairs(option2.code, option1.code, days, etfUpper, etfLower, ref profit, ref loss)); pair.profit = profit; pair.loss = loss; } if (pair.profit > 0 && pair.mark > 0.5 && pair.profit / Convert.ToDouble(days) * 252.0 > 1) { pairs.Add(pair); } } } } return(pairs.OrderBy(f => - f.mark).ToList()); }
/// <summary> /// 获取期权和50ETF实时快照数据 /// </summary> /// <param name="optionList"></param> /// <param name="etfPrice"></param> /// <returns></returns> private Dictionary <string, OptionGreek> getOptionPrice(List <OptionInfo> optionList, ref double etfPrice) { Dictionary <string, OptionGreek> option = new Dictionary <string, OptionGreek>(); string code = "510050.SH"; for (int i = 0; i < optionList.Count(); i++) { OptionGreek greek = new OptionGreek(); greek.code = optionList[i].optionCode; greek.duration = DateUtils.GetSpanOfTradeDays(today, optionList[i].endDate); option.Add(greek.code, greek); code += "," + greek.code; } WindData wd = w.wsq(code, "rt_last,rt_ask1,rt_asize1,rt_bid1,rt_bsize1,rt_delta,rt_gamma,rt_vega,rt_theta,rt_imp_volatility", ""); if (wd.data is double[]) { double[] dataList = (double[])wd.data; int length = dataList.Length / 10; etfPrice = dataList[0]; for (int i = 1; i < length; i++) { string optionCode = optionList[i - 1].optionCode; double strike = optionList[i - 1].strike; OptionGreek greek = option[optionCode]; greek.lastPrice = dataList[i * 10 + 0]; greek.ask = dataList[i * 10 + 1]; greek.askv = dataList[i * 10 + 2]; greek.bid = dataList[i * 10 + 3]; greek.bidv = dataList[i * 10 + 4]; greek.delta = dataList[i * 10 + 5]; greek.gamma = dataList[i * 10 + 6]; greek.vega = dataList[i * 10 + 7]; greek.theta = dataList[i * 10 + 8]; greek.impv = dataList[i * 10 + 9]; greek.coordinate = Math.Round(1000 * Math.Log(strike / etfPrice), 0) + 500; option[optionCode] = greek; } } return(option); }