public void compute(DateTime startDate, DateTime endDate) { var tradedays = dateRepo.GetStockTransactionDate(startDate, endDate); //获取日线数据 var underlyingDaily1 = stockDailyRepo.GetStockTransactionWithRedis(code1, tradedays.First(), tradedays.Last()); var underlyingDaily2 = stockDailyRepo.GetStockTransactionWithRedis(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"); }
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 double computeChoiceParameter(List <DateTime> tradedays, List <StockTransaction> underlyingDaily1, List <StockTransaction> underlyingDaily2, int duration, double lambda1, double trailingParameter) { int duration1 = 1000000; double lambda2 = lambda1 + 1; int length = underlyingDaily1.Count(); double[] y = new double[length]; double[] x = new double[length]; double[] z = 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]; 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]); } 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); } } 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 = 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()); //var dt = DataTableExtension.ToDataTable(myboll2); //DataTableExtension.SaveCSV(dt, "E:\\result\\bollinger\\boll.csv"); //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"); return(sharpe); }