private void getStockTickData(string code) { foreach (var date in tradedays) { var tick = tickRepo.GetStockTransaction(code, date, date); var day = stockDailyRepo.GetStockTransaction("510050.SH", date, date); double open = day[0].Open; var minute = tranferTickToMinuteDayByDay(code, date, open, tick); var minute2 = stockMinutelyRepo.GetStockTransaction("510050.SH", date, date); } }
private Dictionary <DateTime, StockTransaction> getUnderlyingDailyData(DateTime startDate, DateTime endDate) { Dictionary <DateTime, StockTransaction> underlyingDailyData = new Dictionary <DateTime, StockTransaction>(); var data = stockDailyRepo.GetStockTransaction(underlying, startDate, endDate); foreach (var item in data) { underlyingDailyData.Add(item.DateTime, item); } this.underlyingDailyDataList = data; return(underlyingDailyData); }
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.GetStockTransaction(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); } }
public void compute(DateTime startDate, DateTime endDate) { var tradedays = dateRepo.GetStockTransactionDate(startDate, endDate); //获取日线数据 var underlyingDaily1 = stockDailyRepo.GetStockTransaction(code1, tradedays.First(), tradedays.Last()); var underlyingDaily2 = stockDailyRepo.GetStockTransaction(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"); }
private void DataPreparation(DateTime startDate, DateTime endDate) { var tradedays = dateRepo.GetStockTransactionDate(startDate, endDate); var etfDaily = stockDailyRepo.GetStockTransaction(code, startDate, endDate); }
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.GetStockTransaction(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()); } }
public void compute(DateTime startDate, DateTime endDate) { var tradedays = dateRepo.GetStockTransactionDate(startDate, endDate); //获取日线数据 var underlyingDaily = stockDailyRepo.GetStockTransaction(code, tradedays.First(), tradedays.Last()); //获取分钟线数据 foreach (var date in tradedays) { var underlyingToday = stockMinutelyRepo.GetStockTransaction(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); }
//计算从开始日期到结束日期的对冲成本 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.GetStockTransaction(indexCode, startDate, endDate); double startPrice = stock[0].Open; double strike = startPrice; foreach (var date in tradedays) { //获取当日期货合约代码 var list = getSpecialFutureList(date); //获取当日收盘前标的价格 // var index = stockMinutelyRepo.GetStockTransaction(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.GetStockTransaction(code1, tradedays.First(), tradedays.Last()); var underlyingDaily2 = stockDailyRepo.GetStockTransaction(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"); }