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> > weedCross = ds.FundTrendCrossCreateOrLoad(TimeUnit.day); if (dayFunds == null || dayFunds.Count <= 0 || weekFunds == null || weekFunds.Count <= 0 || dayCross == null || dayCross.Count <= 0 || weedCross == null || weedCross.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.Parse(strategyParam.Get <String>("getinMode")); for (int i = 0; i < dayCross.Count; i++) { ITimeSeriesItem <double> dayCrossItem = dayCross[i]; if (dayCrossItem == null) { continue; } if (dayCrossItem.Date < begin || dayCrossItem.Date >= end) { continue; } if (dayCrossItem.Value < 0) { continue; } if (p_day_low != 0 && dayCrossItem.Value > p_day_low) { continue; } DateTime td = CalendarUtils.GetWeek(dayCrossItem.Date, DayOfWeek.Friday); ITimeSeriesItem <double> weekCrossItem1 = weedCross[td]; ITimeSeriesItem <double> weekCrossItem2 = weedCross[td.AddDays(-7)]; if (weekCrossItem1 == null && weekCrossItem2 == null) { continue; } if (p_week_low != 0 && (weekCrossItem1 != null && weekCrossItem1.Value > p_week_low && weekCrossItem2 != null && weekCrossItem2.Value > p_week_low)) { continue; } KLine dayLine = ds.DayKLine; if (dayLine == null) { continue; } KLineItem dayLineItem = dayLine[dayCrossItem.Date]; if (dayLineItem == null) { continue; } TradeBout bout = new TradeBout(ds.Code); bout.RecordTrade(1, dayCrossItem.Date, TradeDirection.Buy, dayLineItem.CLOSE, (int)(p_getinMode.Value / dayLineItem.CLOSE), 0, 0, Name); 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); } 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 List <TradeInfo> DoBuy(Properties strategyParam, DateTime d, StrategyContext context) { //取得行情库 IndicatorRepository repository = (IndicatorRepository)context.Get <Object>("repository"); if (repository == null) { return(null); } //读取代码 List <String> codes = LoadCodes(strategyParam, context); if (codes == null || codes.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")); GrailParameter p_grail = GrailParameter.Parse(strategyParam.Get <String>("grail")); double stampduty = context.Get <double>("stampduty"); double volumecommission = context.Get <double>("volumecommission"); List <TradeInfo> results = new List <TradeInfo>(); //遍历 foreach (String code in codes) { TimeSerialsDataSet ds = repository[code]; if (ds == null) { continue; } KLine klineDay = ds.DayKLine; if (klineDay == null) { continue; } KLineItem klineItemDay = klineDay[d]; if (klineItemDay == null) { continue; } TimeSeries <ITimeSeriesItem <List <double> > > fundDay = ds.DayFundTrend; if (fundDay == null) { continue; } ITimeSeriesItem <List <double> > fundItemDay = fundDay[d]; if (fundItemDay == null) { continue; } int index = fundDay.IndexOf(fundItemDay); if (index <= 0) { continue; } ITimeSeriesItem <List <double> > prevfundItemDay = fundDay[index - 1]; if (!p_grail.CanBuy(d, code)) //大盘禁止买入的跳过 { continue; } if (p_mainforcelow > 0)//判断主力线上穿p_mainforcelow { if (fundItemDay.Value[0] < p_mainforcelow) { continue; } if (prevfundItemDay.Value[0] > p_mainforcelow) { continue; } } if (p_mainforceslope > 0) //判断主力线上升速度超过p_mainforceslope { if (fundItemDay.Value[0] - prevfundItemDay.Value[0] < p_mainforceslope) { continue; } } TradeInfo tradeInfo = new TradeInfo() { Direction = TradeDirection.Buy, Code = code, Amount = (int)(p_fundpergetin.Value / klineItemDay.CLOSE), EntrustPrice = klineItemDay.CLOSE, EntrustDate = d, TradeDate = d, TradePrice = klineItemDay.CLOSE, Stamps = stampduty, Fee = volumecommission, TradeMethod = TradeInfo.TM_AUTO, Reason = (p_mainforcelow <= 0 ? "" : "[主力线低位" + p_mainforcelow.ToString("F2") + "]") + (p_mainforceslope <= 0 ? "" : "[主力线上升速度超过" + p_mainforceslope.ToString("F2") + "]") }; results.Add(tradeInfo); } return(results); }
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); }