void OnExport(DataGrid dataGrid1) { SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.Filter = "CSV(*.csv)|*.csv"; saveFileDialog.FilterIndex = 1; saveFileDialog.RestoreDirectory = true; var result = saveFileDialog.ShowDialog(BootStrapService.Default.Shell.GetWindow()); if (result.HasValue && result.Value) { var content = TradeRecords.GetCsvContent(); var file = saveFileDialog.FileName; using (Stream stream = File.OpenWrite(file)) { using (var writer = new StreamWriter(stream, System.Text.Encoding.Unicode)) { var data = content.Replace(",", "\t"); writer.Write(data); writer.Close(); } stream.Close(); } ShowMessage(LanguageService.Default.GetLanguageValue(MessageKeys.Export_Sucesses)); } }
protected override void OnLoaded() { base.OnLoaded(); AmountMonitor.Default.MonitorCallBack += walletAmountData => { Application.Current.Dispatcher.Invoke(() => { CanUseMoney = walletAmountData.CanUseAmount; WaitMoney = walletAmountData.WaitAmount; TotalMoney = walletAmountData.TotalAmount; }); }; TradeRecodesMonitor.Default.MonitorCallBack += tradeRecords => { Application.Current.Dispatcher.Invoke(() => { if (tradeRecords.Count <= 5) { TradeRecords = tradeRecords; } else { TradeRecords.Clear(); tradeRecords.Take(5).ToList().ForEach(x => TradeRecords.Add(x)); } }); }; }
/// <summary> /// 根据个股S点卖出 /// </summary> /// <param name="bouts"></param> /// <param name="ds"></param> /// <param name="strategyParam"></param> /// <param name="backtestParam"></param> public void DoSell1(TradeRecords tradeRecords, TimeSerialsDataSet ds, Properties strategyParam, BacktestParameter backtestParam) { TimeSeries <ITimeSeriesItem <char> > dayTradePt = ds.CubePtCreateOrLoad(); if (dayTradePt == null) { return; } if (tradeRecords == null || tradeRecords.Bouts == null || tradeRecords.Bouts.Count <= 0) { return; } KLine dayLine = ds.DayKLine; if (dayLine == null) { return; } foreach (TradeBout bout in tradeRecords.Bouts) { DateTime buyDate = bout.BuyInfo.TradeDate; KeyValuePair <int, ITimeSeriesItem> dayTradePtItem = dayTradePt.GetNearest(buyDate, false); if (dayTradePtItem.Key < 0) { continue; } if (dayTradePtItem.Value == null) { continue; } int index = dayTradePt.IndexOf(dayTradePtItem.Value.Date); for (int k = index; k < dayTradePt.Count; k++) { if (dayTradePt[k].Value == 'S') { KLineItem dayLineItem = dayLine[dayTradePt[k].Date]; if (dayLineItem == null) { break; } bout.RecordTrade(2, dayLineItem.Date, TradeDirection.Sell, dayLineItem.CLOSE, bout.BuyInfo.Amount, 0, 0, "发S点"); break; } } } }
void OnScrollChanged(bool isdd) { StaticViewModel.GlobalViewModel.IsLoading = true; Task task = new Task(() => { var filterData = GetFilterCondition(); var tradeRecordsResult = OmniCoinService.Default.ListFilterTrans(filterData, TradeRecords.Count, true, 20); if (!tradeRecordsResult.IsFail) { Application.Current.Dispatcher.Invoke(() => { tradeRecordsResult.Value.ToList().ForEach(x => TradeRecords.Add(x)); }); } }); task.ContinueWith(t => { StaticViewModel.GlobalViewModel.IsLoading = false; }); task.Start(); }
void RefreshRecords(bool showLoading = true) { refreshTimer.Stop(); var count = TradeRecords.Count; if (count < 20) { count = 20; } if (showLoading) { StaticViewModel.GlobalViewModel.IsLoading = true; } Task task = new Task(() => { var filterData = GetFilterCondition(); var tradeRecordsResult = OmniCoinService.Default.ListFilterTrans(filterData, 0, true, count); if (!tradeRecordsResult.IsFail) { Application.Current.Dispatcher.Invoke(() => { TradeRecords.Clear(); tradeRecordsResult.Value.ToList().ForEach(x => TradeRecords.Add(x)); }); } }); task.ContinueWith(t => { if (showLoading) { StaticViewModel.GlobalViewModel.IsLoading = false; } _timerCount = 10; refreshTimer.Start(); }); task.Start(); }
/// <summary> /// 根据个股主力线高位卖出 /// </summary> /// <param name="bouts"></param> /// <param name="ds"></param> /// <param name="strategyParam"></param> /// <param name="backtestParam"></param> public void DoSell2(TradeRecords tradeRecords, TimeSerialsDataSet ds, Properties strategyParam, BacktestParameter backtestParam) { if (tradeRecords == null || tradeRecords.Bouts == null || tradeRecords.Bouts.Count <= 0) { return; } TimeSeries <ITimeSeriesItem <List <double> > > dayFunds = ds.DayFundTrend; KLine dayLine = ds.DayKLine; if (dayLine == null) { return; } foreach (TradeBout bout in tradeRecords.Bouts) { DateTime buyDate = bout.BuyInfo.TradeDate; //找20个工作日的收盘价最高值 KLineItem klineItem = dayLine.GetNearest(buyDate, false); if (klineItem == null) { continue; } int index = dayLine.IndexOf(klineItem); DateTime sellDate = buyDate; double sellPrice = 0; for (int i = index + 1; i < Math.Min(index + 41, dayLine.Count); i++) { if (dayLine[i].CLOSE > sellPrice) { sellPrice = dayLine[i].CLOSE; sellDate = dayLine[i].Date; } } bout.RecordTrade(2, sellDate, TradeDirection.Sell, sellPrice, bout.BuyInfo.Amount, 0, 0, ""); } }
public virtual void DoSell(TradeRecords tradeRecords, TimeSerialsDataSet ds, Properties strategyParam, BacktestParameter backtestParam) { DoSell1(tradeRecords, ds, strategyParam, backtestParam); }
public override TradeRecords DoBuy(TimeSerialsDataSet ds, Properties strategyParam, BacktestParameter backtestParam) { TimeSeries <ITimeSeriesItem <List <double> > > dayFunds = ds.FundTrendCreateOrLoad(TimeUnit.day); TimeSeries <ITimeSeriesItem <List <double> > > weekFunds = ds.FundTrendCreateOrLoad(TimeUnit.week); TimeSeries <ITimeSeriesItem <double> > dayCross = ds.FundTrendCrossCreateOrLoad(TimeUnit.day); TimeSeries <ITimeSeriesItem <double> > weekCross = ds.FundTrendCrossCreateOrLoad(TimeUnit.day); if (dayFunds == null || dayFunds.Count <= 0 || weekFunds == null || weekFunds.Count <= 0 || dayCross == null || dayCross.Count <= 0 || weekCross == null || weekCross.Count <= 0) { return(null); } TradeRecords tr = new TradeRecords(ds.Code); DateTime begin = backtestParam.BeginDate; DateTime end = backtestParam.EndDate; double p_day_low = strategyParam.Get <double>("day_low"); double p_day_bias = strategyParam.Get <double>("day_bias"); double p_week_low = strategyParam.Get <double>("week_low"); double p_week_bias = strategyParam.Get <double>("week_bias"); GetInMode p_getinMode = (GetInMode)strategyParam.Get <Object>("getinMode"); for (int i = 0; i < dayFunds.Count; i++) { ITimeSeriesItem <List <double> > dayFundItem = dayFunds[i]; if (dayFundItem == null) { continue; } if (dayFundItem.Date < begin || dayFundItem.Date >= end) { continue; } if ((dayFundItem.Value[0] - dayFundItem.Value[1]) < p_day_bias) { continue; } DateTime td = CalendarUtils.GetWeek(dayFundItem.Date, DayOfWeek.Friday); ITimeSeriesItem <List <double> > weekFundItem = weekFunds[td]; if (weekFundItem == null) { continue; } if ((weekFundItem.Value[0] - weekFundItem.Value[1]) < p_week_bias) { continue; } KLine dayLine = ds.DayKLine; if (dayLine == null) { continue; } KLineItem dayLineItem = dayLine[dayFundItem.Date]; if (dayLineItem == null) { continue; } TradeBout bout = new TradeBout(ds.Code); bout.RecordTrade(1, dayFundItem.Date, TradeDirection.Buy, dayLineItem.CLOSE, (int)(p_getinMode.Value / dayLineItem.CLOSE), 0, 0, Name); tr.Bouts.Add(bout); } return(tr); }
public void Execute() { List <String> codes = new List <string>(); System.IO.File.ReadAllLines(FileUtils.GetDirectory() + "test.csv") .ToList().ForEach(x => codes.Add(x.Split(',')[1])); IndicatorRepository repository = new IndicatorRepository("d:\\repository\\"); repository.Initilization(); foreach (String code in codes) { //生成数据 TimeSerialsDataSet ds = repository[code]; KLine dayLine = ds.DayKLine; KLine weekLine = dayLine.CreateWeek(); ds.WeekKLine = weekLine; TimeSeries <ITimeSeriesItem <double> > dayClose = dayLine.Select <double>("close", 0, 0); TimeSeries <ITimeSeriesItem <double> > weekClose = weekLine.Select <double>("close", 0, 0); TradingLine dayTradeLine = ds.CubeCreateOrLoad(TimeUnit.day); TradingLine weekTradeLine = ds.CubeCreateOrLoad(TimeUnit.week); TimeSeries <ITimeSeriesItem <List <double> > > dayFunds = ds.FundTrendCreate(TimeUnit.day); TimeSeries <ITimeSeriesItem <List <double> > > weekFunds = ds.FundTrendCreate(TimeUnit.week); TimeSeries <ITimeSeriesItem <double> > dayCross = ds.FundTrendCrossCreateOrLoad(TimeUnit.day); TimeSeries <ITimeSeriesItem <double> > weedCross = ds.FundTrendCrossCreateOrLoad(TimeUnit.week); //测试买入 List <TradeBout> bouts = new List <TradeBout>(); TimeSeries <ITimeSeriesItem <char> > dayTradePt = dayTradeLine.buysellPoints; for (int i = 0; i < dayTradePt.Count; i++) { ITimeSeriesItem <char> item = dayTradePt[i]; if (item.Value == 'S') { continue; } if (item.Date < begin || item.Date > end) { continue; } DateTime buyPtDate = item.Date; int index = dayFunds.IndexOf(buyPtDate); while (index <= dayFunds.Count) { ITimeSeriesItem <List <double> > fundItem = dayFunds[index]; if (fundItem == null) { index += 1; continue; } if (fundItem.Value[0] <= fundItem.Value[1]) { index += 1; continue; } TradeBout bout = new TradeBout(code); KLineItem klineItem = dayLine.GetNearest(fundItem.Date, false); if (klineItem == null) { index += 1; continue; } bout.RecordTrade(1, klineItem.Date, TradeDirection.Buy, klineItem.CLOSE, (int)(funds / klineItem.CLOSE), 0, 0, "发出B点且主力=" + fundItem.Value[0].ToString("F3") + "大于散户" + fundItem.Value[1].ToString("F3") + ",日期=" + fundItem.Date.ToString("yyyyMMdd")); bouts.Add(bout); break; } } //测试卖出 for (int i = 0; i < bouts.Count; i++) { DateTime buyDate = bouts[i].BuyInfo.TradeDate; int buyIndex = dayLine.IndexOf(buyDate); int index = buyIndex + 1; while (index <= dayLine.Count - 1) { KLineItem item = dayLine[index]; if (index - buyIndex >= maxdays) { bouts[i].RecordTrade(2, item.Date, TradeDirection.Sell, item.CLOSE, bouts[i].BuyInfo.Amount, 0, 0, "大于" + maxdays.ToString() + "天卖出"); break; } else { double profile = (item.HIGH - bouts[i].BuyInfo.TradePrice) / bouts[i].BuyInfo.TradePrice; if (profile >= maxProfilt) { bouts[i].RecordTrade(2, item.Date, TradeDirection.Sell, (bouts[i].BuyInfo.TradePrice * (1 + maxProfilt)), bouts[i].BuyInfo.Amount, 0, 0, "利润大于" + maxdays.ToString() + "天卖出"); break; } } index += 1; } } //去掉未完成的 for (int i = 0; i < bouts.Count; i++) { if (!bouts[i].Completed) { bouts.RemoveAt(i--); } } TradeRecords tradeRecords = new TradeRecords(); tradeRecords.Bouts.AddRange(bouts); //打印结果 for (int i = 0; i < bouts.Count; i++) { Console.WriteLine(bouts[i].ToString()); } Console.WriteLine(tradeRecords.ToString()); } }
public override TradeRecords Execute(String code, Properties strategyParam, BacktestParameter backtestParam, ISeller seller = null) { IndicatorRepository repository = (IndicatorRepository)backtestParam.Get <Object>("repository"); if (repository == null) { return(null); } //取得策略参数 double buy_mainlow = strategyParam.Get <double>("buy_mainlow"); //主力线低位买入 int buy_cross = strategyParam.Get <int>("buy_cross"); GetInMode p_getinMode = (GetInMode)strategyParam.Get <GetInMode>("getinMode"); //取得行情数据 TradeRecords tr = new TradeRecords(code); TimeSerialsDataSet ds = repository[code]; if (ds == null) { return(null); } KLine kline = ds.DayKLine; if (kline == null) { return(null); } MACD macd = (MACD)ds.Create("macd", TimeUnit.day, false); if (macd == null) { return(null); } //买入条件判定 for (int i = 0; i < macd.Count; i++) { MACDItem macdItem = macd[i]; if (macdItem.Date < backtestParam.BeginDate || macdItem.Date >= backtestParam.EndDate) { continue; } if (macdItem.CROSS <= 0) { continue; } if (macdItem.DIF > buy_mainlow) { continue; } DateTime d = macdItem.Date; KLineItem klineItem = kline[d]; if (klineItem == null) { continue; } TradeBout bout = new TradeBout(code); bout.RecordTrade(1, d, TradeDirection.Buy, klineItem.CLOSE, (int)(p_getinMode.Value / klineItem.CLOSE), backtestParam.Volumecommission, backtestParam.Stampduty, "低位金叉" + macdItem.DIF.ToString("F2")); tr.Bouts.Add(bout); } return(tr); }
public override TradeRecords Execute(string code, Properties strategyParam, BacktestParameter backtestParam, ISeller seller = null) { IndicatorRepository repository = (IndicatorRepository)backtestParam.Get <Object>("repository"); //取得策略参数 double buy_mainlow = strategyParam.Get <double>("buy_mainlow"); //主力线低位买入 int buy_cross = strategyParam.Get <int>("buy_cross"); GetInMode p_getinMode = (GetInMode)strategyParam.Get <GetInMode>("getinMode"); TradeRecords tr = new TradeRecords(code); TimeSerialsDataSet ds = repository[code]; if (ds == null) { return(null); } KLine kline = ds.DayKLine; if (kline == null) { return(null); } TimeSeries <ITimeSeriesItem <List <double> > > dayFunds = ds.DayFundTrend; TimeSeries <ITimeSeriesItem <double> > dayFundsCross = ds.DayFundTrendCross; if (buy_cross == 0 && dayFunds == null) { return(null); } else if (buy_cross == 1 && (dayFundsCross == null || dayFunds == null)) { return(null); } #region 判断主力线低位决定买入点 if (buy_cross == 0) { for (int i = 0; i < dayFunds.Count; i++) { if (dayFunds[i].Date.Date <backtestParam.BeginDate || dayFunds[i].Date.Date> backtestParam.EndDate) { continue; } if (double.IsNaN(dayFunds[i].Value[0])) { continue; } if (dayFunds[i].Value[0] > buy_mainlow) { continue; } //主力线开始低于buy_mainlow... i += 1; while (i < dayFunds.Count) { if (dayFunds[i].Value[0] <= buy_mainlow) { i += 1; continue; } //主力线出了buy_mainlow KLineItem klineItem = kline[dayFunds[i].Date]; if (klineItem == null) { break; } int tIndex = kline.IndexOf(klineItem); if (tIndex >= kline.Count - 1) { break; } KLineItem klineItemNext = kline[tIndex + 1]; TradeBout bout = new TradeBout(code); double price = klineItem.CLOSE; if (price > klineItemNext.HIGH || price < klineItemNext.LOW) { break; } bout.RecordTrade(1, dayFunds[i].Date.Date, TradeDirection.Buy, price, (int)(p_getinMode.Value / price), backtestParam.Volumecommission, backtestParam.Stampduty, "主力线低于" + buy_mainlow.ToString("F2")); tr.Bouts.Add(bout); break; } } } #endregion #region 判断金叉决定买入点 else if (buy_cross == 1) { for (int i = 0; i < dayFundsCross.Count; i++) { if (dayFundsCross[i].Date.Date <backtestParam.BeginDate || dayFundsCross[i].Date.Date> backtestParam.EndDate) { continue; } if (dayFundsCross[i].Value <= 0) { continue; } ITimeSeriesItem <List <double> > dayFundItem = dayFunds[dayFundsCross[i].Date]; if (dayFundItem == null) { continue; } if (buy_mainlow != 0 && dayFundItem.Value[0] >= buy_mainlow) { continue; } KLineItem klineItem = kline[dayFundItem.Date]; if (klineItem == null) { continue; } int tIndex = kline.IndexOf(klineItem); if (tIndex >= kline.Count - 1) { continue; } KLineItem klineItemNext = kline[tIndex + 1]; TradeBout bout = new TradeBout(code); double price = klineItem.CLOSE; if (price > klineItemNext.HIGH || price < klineItemNext.LOW) { continue; } bout.RecordTrade(1, dayFunds[i].Date.Date, TradeDirection.Buy, price, (int)(p_getinMode.Value / price), backtestParam.Volumecommission, backtestParam.Stampduty, "主力线低于" + buy_mainlow.ToString("F2")); tr.Bouts.Add(bout); } } #endregion return(tr); }
/// <summary> /// 执行卖出操作 /// </summary> /// <param name="tradeRecord"></param> /// <param name="strategyParam"></param> /// <param name="backtestParam"></param> public override void Execute(TradeRecords tradeRecord, Properties strategyParam, BacktestParameter backtestParam) { //初始化行情库 if (tradeRecord == null) { return; } IndicatorRepository repository = (IndicatorRepository)backtestParam.Get <Object>("repository"); if (repository == null) { return; } //取得策略参数 int p_maxday = strategyParam.Get <int>("maxholddays"); //遍历每一个买入回合 String code = tradeRecord.Code; List <TradeBout> bouts = tradeRecord.Bouts; for (int i = 0; i < bouts.Count; i++) { TradeBout bout = bouts[i]; TimeSerialsDataSet ds = repository[bout.Code]; if (ds == null) { continue; } if (bout.Completed) { continue; //跳过已完成的 } KLine kline = ds.DayKLine; if (kline == null) { continue; } int bIndex = kline.IndexOf(bout.BuyInfo.TradeDate); //寻找p_maxday天内最大收益那天 KLineItem maxProfileItem = null; for (int index = bIndex + 1; index <= bIndex + 1 + p_maxday; index++) { if (index >= kline.Count) { break; } KLineItem item = kline[index]; if (item.CLOSE > (maxProfileItem == null?0: maxProfileItem.CLOSE)) { maxProfileItem = item; } } if (maxProfileItem == null) { continue; } bout.RecordTrade(2, maxProfileItem.Date, TradeDirection.Sell, maxProfileItem.CLOSE, bout.BuyInfo.Amount, backtestParam.Volumecommission, backtestParam.Stampduty, ""); } }
public override TradeRecords Execute(string code, Properties strategyParam, BacktestParameter backtestParam, ISeller seller = null) { IndicatorRepository repository = (IndicatorRepository)backtestParam.Get <Object>("repository"); if (repository == null) { return(null); } TimeSerialsDataSet ds = repository[code]; if (ds == null) { return(null); } TimeSeries <ITimeSeriesItem <char> > ts = ds.DayTradeLine.buysellPoints; if (ts == null) { return(null); } TimeSeries <ITimeSeriesItem <List <double> > > fundTrends = ds.DayFundTrend; KLine kline = ds.DayKLine; TradeRecords tr = new TradeRecords(code); GetInMode getin = GetInMode.Parse(strategyParam.Get <String>("getinMode")); int diffdays = strategyParam.Get <int>("diffdays"); for (int i = 0; i < ts.Count; i++) { if (ts[i].Date.Date < backtestParam.BeginDate) { continue; } if (ts[i].Date.Date >= backtestParam.EndDate) { continue; } if (ts[i].Value == 'S') { continue; } TradeBout bout = new TradeBout(code); //主力线大于散户线,且连续diffdays天与散户线拉大距离 if (diffdays > 0 && fundTrends != null) { int fi = fundTrends.IndexOf(ts[i].Date); if (fi < 0 || fi < diffdays - 1) { continue; } ITimeSeriesItem <List <double> > ftItem = fundTrends[fi]; if (ftItem.Value[0] >= 30) { continue; } double diff = ftItem.Value[0] - ftItem.Value[1]; if (diff <= 0) { continue; } bool continuekuoda = true; for (int t = 1; t < diffdays; t++) { ftItem = fundTrends[fi - i]; double tDiff = ftItem.Value[0] - ftItem.Value[1]; if (diff < tDiff) { continuekuoda = false; break; } diff = tDiff; } if (!continuekuoda) { continue; } } KLineItem item = kline[ts[i].Date]; bout.RecordTrade(1, ts[i].Date, TradeDirection.Buy, item.CLOSE, (int)(getin.Value / item.CLOSE), backtestParam.Volumecommission, backtestParam.Stampduty, "B"); tr.Bouts.Add(bout); } return(tr); }
public override TradeRecords Execute(string code, Properties strategyParam, BacktestParameter backtestParam, ISeller seller = null) { //获取行情数据 IndicatorRepository repository = (IndicatorRepository)backtestParam.Get <Object>("repository"); if (repository == null) { return(null); } TimeSerialsDataSet ds = repository[code]; if (ds == null) { return(null); } KLine kline = ds.DayKLine; if (kline == null) { return(null); } DateTime beginDate = backtestParam.BeginDate; DateTime endDate = backtestParam.EndDate; int bIndex = kline.IndexOf(beginDate, false); if (bIndex < 0) { return(null); } //获取参数 int maxholddays = strategyParam.Get <int>("maxholddays"); double maxprofilt = strategyParam.Get <double>("maxprofilt"); //遍历K线 List <Object[]> listEarn = new List <object[]>(); List <Object[]> listLoss = new List <object[]>(); TradeRecords tr = new TradeRecords(); for (int index = bIndex; index < kline.Count; index++) { KLineItem item = kline[index]; if (item.Date >= endDate) { break; } double buyPrice = item.CLOSE; double maxProfiltEffenicePerStock = double.MinValue + 1; double maxLossEffenicePerStock = double.MaxValue - 1; int maxProfiltHoldDays = 0; int maxLossHoldDays = 0; KLineItem sellEarnItem = null; KLineItem sellLossItem = null; for (int i = 1; i < maxholddays; i++) { if (index + i >= kline.Count) { break; } KLineItem item2 = kline[index + i]; if ((item2.Date - item.Date).TotalDays > maxholddays) { break; } double eraningRates = (item2.CLOSE - buyPrice) / buyPrice; if (eraningRates > 0 && eraningRates >= maxprofilt && maxProfiltEffenicePerStock < eraningRates) { maxProfiltEffenicePerStock = eraningRates / i; maxProfiltHoldDays = i; sellEarnItem = item2; } if (eraningRates < 0 && maxLossEffenicePerStock > eraningRates) { maxLossEffenicePerStock = eraningRates; maxLossHoldDays = i; sellLossItem = item2; } } if (maxProfiltHoldDays > 0) { Object[] objs = new Object[] { item, sellEarnItem, maxProfiltEffenicePerStock, (sellEarnItem.CLOSE - buyPrice) / buyPrice }; listEarn.Add(objs); index = kline.IndexOf(sellEarnItem); } if (maxLossHoldDays > 0) { Object[] objs = new Object[] { item, sellLossItem, maxLossEffenicePerStock, (sellLossItem.CLOSE - buyPrice) / buyPrice }; listLoss.Add(objs); } } if (listEarn.Count <= 0) { return(null); } Comparison <Object[]> comparsionEran = (x, y) => { return((int)((double)y[2] - (double)x[2])); }; listEarn.Sort(comparsionEran); List <String> strs = new List <string>(); foreach (Object[] objs in listEarn) { KLineItem buyItem = (KLineItem)objs[0]; KLineItem sellItem = (KLineItem)objs[1]; String str = code + "," + ((double)objs[2]).ToString("F3") + "," + ((double)objs[3]).ToString("F3") + "," + (sellItem.Date - buyItem.Date).TotalDays.ToString() + "," + buyItem.Date.ToString("yyyyMMdd") + "," + sellItem.Date.ToString("yyyyMMdd") + "," + buyItem.CLOSE.ToString("F2") + "," + sellItem.CLOSE.ToString("F2"); strs.Add(str); logger.Info(str); } System.IO.File.AppendAllLines(backtestParam.Resultpath + "temp.csv", strs.ToArray(), Encoding.UTF8); return(null); }
/// <summary> /// 装载数据 /// </summary> /// <param name="code"></param> /// <param name="path"></param> /// <param name="resultonly"></param> /// <param name="backtestserialno"></param> /// <returns></returns> public static StrategyDataSet CreateOrLoad(String code, String datapath, String resultpath, bool resultonly = false, String backtestserialno = "") { StrategyDataSet ds = new StrategyDataSet(code, datapath, resultpath); //读取回测结果 String backtestresultfile = resultpath + code + ".backtest." + backtestserialno + ".result"; if (System.IO.File.Exists(backtestresultfile)) { ds.tradeRecords = TradeRecords.Load(backtestresultfile); } if (resultonly && ds.tradeRecords.Count > 0) { return(ds); } //加载日线 ds.LoadDayKLine(); if (ds.klineDay == null || ds.klineDay.Count <= 0) { return(ds); } ds.tradeLineDay = new TradingLine(); //加载或计算买线 String tradeBuyLineDayFilename = datapath + code + ".day.itstereo.buy"; if (System.IO.File.Exists(tradeBuyLineDayFilename)) { ds.tradeLineDay.buyLine = new TimeSeries <ITimeSeriesItem <double> >(code, TimeUnit.day); ds.tradeLineDay.buyLine.Load(tradeBuyLineDayFilename); } else { ds.CreateBuySellLine(); } //加载或计算卖线 String tradeSellLineDayFilename = datapath + ds.code + ".day.itstereo.sell"; if (System.IO.File.Exists(tradeSellLineDayFilename)) { ds.tradeLineDay.sellLine = new TimeSeries <ITimeSeriesItem <double> >(code, TimeUnit.day); } ds.tradeLineDay.sellLine.Load(tradeSellLineDayFilename); //加载买卖点 String buysellPointsFilename = datapath + ds.code + ".day.itstereo.pt"; if (System.IO.File.Exists(buysellPointsFilename)) { ds.tradeLineDay.buysellPoints = new TimeSeries <ITimeSeriesItem <char> >(code, TimeUnit.day); } ds.tradeLineDay.buysellPoints.Load(buysellPointsFilename); //加载资金动向线 String fundDayFilename = datapath + ds.code + ".day.ifmovement"; if (System.IO.File.Exists(fundDayFilename)) { ds.fundDay = new TimeSeries <ITimeSeriesItem <List <double> > >(code, TimeUnit.day); ds.fundDay.Load(fundDayFilename); } else { ds.fundDay = ds.klineDay.executeIndicator(); ds.fundDay.Save(fundDayFilename); } return(ds); }
public override TradeRecords Execute(string code, Properties strategyParam, BacktestParameter backtestParam, ISeller seller = null) { IndicatorRepository repository = (IndicatorRepository)backtestParam.Get <Object>("repository"); if (repository == null) { return(null); } //创建数据集 TimeSerialsDataSet ds = repository[code]; if (ds == null) { return(null); } KLine klineDay = ds.DayKLine; if (klineDay == null || klineDay.Count < 0) { return(null); } TimeSeries <ITimeSeriesItem <List <double> > > fundDay = ds.DayFundTrend; if (fundDay == null || fundDay.Count <= 0) { return(null); } double p_mainforcelow = strategyParam.Get <double>("mainforcelow"); int p_monthbutpt = strategyParam.Get <int>("monthbutpt", 0); //double p_mainforceclimb = strategyParam.Get<double>("mainforceclimb"); double p_mainforceslope = strategyParam.Get <double>("mainforceslope"); int p_mainforcerough = strategyParam.Get <int>("mainforcerough"); int p_buypointdays = strategyParam.Get <int>("buypointdays"); int p_maxbuynum = strategyParam.Get <int>("maxbuynum"); GetInMode p_fundpergetin = GetInMode.Parse(strategyParam.Get <String>("getinMode")); TradeRecords tradeRecords = new TradeRecords(code); //遍历回测中的每一天 DateTime d = backtestParam.BeginDate; int beginIndex = klineDay.IndexOf(d, true); if (beginIndex < 0) { return(tradeRecords); } for (int index = beginIndex; index < klineDay.Count; index++) { KLineItem klineItemDay = klineDay[index]; if (klineItemDay == null) { continue; } d = klineItemDay.Date; ITimeSeriesItem <List <double> > fundItemDay = fundDay[d]; if (fundItemDay == null) { continue; } int fIndex = fundDay.IndexOf(fundItemDay); //是否进入到主力线低位 if (p_mainforcelow != 0 && fundItemDay.Value[0] >= p_mainforcelow) { continue; } //是否主力线爬升离开低位 if (p_mainforcelow != 0) { for (fIndex = fIndex + 1; fIndex < fundDay.Count; fIndex++) { fundItemDay = fundDay[fIndex]; if (fundItemDay == null) { continue; } if (fundItemDay.Value[0] <= p_mainforcelow) { continue; } if (fundItemDay.Date < backtestParam.BeginDate || fundItemDay.Date > backtestParam.EndDate)//数据错误 { return(tradeRecords); } d = fundItemDay.Date; index = klineDay.IndexOf(d); klineItemDay = klineDay[index]; break; } if (fIndex >= fundDay.Count) { return(tradeRecords); } } //看主力线爬升速度 if (p_mainforceslope != 0 && fIndex > 0) { //爬升速度不够快 if ((fundItemDay.Value[0] - fundDay[fIndex - 1].Value[0]) < p_mainforceslope) { continue; } } //看主力线是否持续爬升 if (p_mainforcerough > 0) { bool cont = true; for (int temp = 0; temp < p_mainforcerough; temp++) { fIndex += temp; if (fIndex >= fundDay.Count) { cont = false; break; } fundItemDay = fundDay[fIndex]; if (fundItemDay.Value[0] < fundDay[fIndex - 1].Value[0]) { cont = false; break; } } if (!cont) { continue; } d = fundItemDay.Date; index = klineDay.IndexOf(d); klineItemDay = klineDay[index]; } //看是否在买点附近 TradingLine tradingLine = ds.DayTradeLine; if (p_buypointdays >= 0 && tradingLine != null && tradingLine.buysellPoints != null && tradingLine.buysellPoints.Count > 0) { int bsptIndex = tradingLine.buysellPoints.IndexOf(d, true); ITimeSeriesItem <char> bsptItemDay = bsptIndex < 0 ? null : tradingLine.buysellPoints[bsptIndex]; if (bsptItemDay != null && bsptItemDay.Value == 'S') { bsptItemDay = bsptIndex >= tradingLine.buysellPoints.Count - 1 ? null : tradingLine.buysellPoints[bsptIndex + 1]; } if (bsptItemDay == null || (bsptItemDay.Date.Date - d).TotalDays > p_buypointdays) { continue; } } //月线买点才能买入 TimeSeries <ITimeSeriesItem <char> > ptMonths = ds.CubePtCreateOrLoad(TimeUnit.month); if (p_monthbutpt == 1 && ptMonths != null && ptMonths.Count > 0) { int t1 = 0; for (; t1 < ptMonths.Count - 1; t1++) { if (d.Date >= ptMonths[t1].Date.Date && d.Date <= ptMonths[t1 + 1].Date.Date) { break; } } if (t1 < ptMonths.Count - 1) { if (ptMonths[t1].Value != 'B') { continue; } } } //准备执行买入 String reason = ""; double price = klineItemDay.CLOSE; double fund = p_fundpergetin.Value;// price * p_maxholdnum; int amount = (int)(fund / price); TradeBout newBout = new TradeBout(ds.Code); newBout.RecordTrade(1, d, TradeDirection.Buy, price, amount, backtestParam.Volumecommission, 0, reason); tradeRecords.Bouts.Add(newBout); } return(tradeRecords); }