Example #1
0
        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);
        }
Example #2
0
            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);
            }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
        public override bool DoSell(string code, TradeBout bout, DateTime d, Properties strategyParam, BacktestParameter backtestParam, out string reason)
        {
            reason = "";

            if (bout == null)
            {
                return(false);
            }
            if (bout.Completed)
            {
                return(false);
            }

            //取得策略参数
            int sell_maxholddays = strategyParam.Get <int>("maxholddays");                  //最大持仓天数

            int sell_notrun_num = strategyParam.Get <int>("sell_notrun_num");               //主力线与价格趋势不符允许出现的最大次数
            int sell_selectnum  = strategyParam.Get <int>("sell_selectnum");                //可以尝试的最大卖出次数

            double sell_mainvalve      = strategyParam.Get <double>("sell_mainvalve");      //主力线高位阈值
            double sell_mainvalve_diff = strategyParam.Get <double>("sell_mainvalve_diff"); //主力线高位增幅


            double sell_slopediff = strategyParam.Get <double>("sell_slopediff");   //主力线和收盘价的斜率差阈值

            sell_slopediff = (sell_slopediff / 180) * Math.PI;
            double sell_slopepoint = strategyParam.Get <double>("sell_slopepoint"); //线性回归斜率的卖点

            sell_slopepoint = (sell_slopepoint / 180) * Math.PI;
            GetInMode p_getinMode = (GetInMode)strategyParam.Get <GetInMode>("getinMode");

            //取得行情数据
            IndicatorRepository repository = (IndicatorRepository)backtestParam.Get <Object>("repository");

            if (repository == null)
            {
                return(false);
            }
            TimeSerialsDataSet ds = repository[bout.Code];

            if (ds == null)
            {
                return(false);
            }

            KLine kline = ds.DayKLine;
            TimeSeries <ITimeSeriesItem <List <double> > > dayFunds      = ds.DayFundTrend;
            TimeSeries <ITimeSeriesItem <double> >         dayFundsCross = ds.DayFundTrendCross;

            DateTime curDate = d;

            DateTime buyDate = bout.BuyInfo.TradeDate;//买入日期

            d = buyDate.AddDays(1);
            int days = 1;                 //买入后的第几天

            double prevMainFundValue = 0; //前一日的主力值
            double mainFunddiff      = 0; //主力线当日与前一日的差值
            int    is_slope_run      = 0; //主力线和收盘价走势是否一致,0未知;1一致;-1,-2不一致
            int    sellnum           = 0; //择机卖出次数

            int    state       = 0;       //当日状态;0未知;1 择机卖出(在连续sell_selectnum内只要不亏损就卖)
            String stateReason = "";      //卖出原因

            while (d <= curDate)
            {
                //查找d日的资金线,找不到则跳过这天
                int dayFundIndex = dayFunds.IndexOf(d);
                if (dayFundIndex < 0)
                {
                    d = d.AddDays(1);
                    continue;
                }
                ITimeSeriesItem <List <double> > dayFundsItem = dayFunds[dayFundIndex];
                //查找当日K线,找不到则跳过这天
                int dayKLineIndex = kline.IndexOf(d);
                if (dayKLineIndex < 0)
                {
                    d = d.AddDays(1);
                    continue;
                }
                KLineItem dayLineItem = kline[dayKLineIndex];


                //对买入后的每一天
                //1.计算以d日收盘价卖出的盈利情况
                bout.RecordTrade(2, d, TradeDirection.Sell, kline[dayKLineIndex].CLOSE, bout.BuyInfo.Amount, backtestParam.Volumecommission, backtestParam.Stampduty);
                double earnRate = bout.EarningsRate;
                bout.TradeInfos[1] = null;

                //如果是择机卖出状态
                if (state == 1)
                {
                    if (sellnum > sell_selectnum || earnRate > 0)
                    {
                        bout.RecordTrade(2, d, TradeDirection.Sell, kline[dayKLineIndex].CLOSE, bout.BuyInfo.Amount, backtestParam.Volumecommission, backtestParam.Stampduty, stateReason + ",延迟天数=" + sellnum.ToString());
                        break;
                    }
                    sellnum += 1;
                    d        = d.AddDays(1);
                    days    += 1;
                    continue;
                }

                //如果超过最大持仓天数,则进入到择机卖出
                if (days >= sell_maxholddays)
                {
                    state = 1;
                    continue;
                }

                //趋势不一致出现sell_notrun_num次,择机卖出
                if (is_slope_run <= -1 * sell_notrun_num)
                {
                    stateReason = "主力线趋势不符" + is_slope_run.ToString() + "次数";
                    state       = 1;
                    d           = d.AddDays(1);
                    days       += 1;
                    continue;
                }
                //主力线超出预定值
                if (sell_mainvalve != 0 && dayFunds[dayFundIndex].Value[0] >= sell_mainvalve)
                {
                    if (prevMainFundValue == 0)
                    {
                        prevMainFundValue = dayFunds[dayFundIndex].Value[0];
                        d     = d.AddDays(1);
                        days += 1;
                        continue;
                    }
                    else if ((dayFunds[dayFundIndex].Value[0] - prevMainFundValue) > sell_mainvalve_diff)
                    {
                        d     = d.AddDays(1);
                        days += 1;
                        continue;
                    }
                    mainFunddiff = (dayFunds[dayFundIndex].Value[0] - prevMainFundValue);
                    //如果盈利率小于0,延迟数天卖出
                    if (earnRate <= 0)
                    {
                        state       = 1;
                        stateReason = "主力线突破高位且增幅减缓" + mainFunddiff.ToString("F3");
                        d           = d.AddDays(1);
                        days       += 1;
                        continue;
                    }
                    //卖出操作
                    bout.RecordTrade(2, d, TradeDirection.Sell, dayLineItem.CLOSE, bout.BuyInfo.Amount, backtestParam.Volumecommission, backtestParam.Stampduty, "主力线突破高位且增幅减缓" + mainFunddiff.ToString("F3"));
                    break;
                }
                //计算线性回归斜率
                int           begin = dayFunds.IndexOf(buyDate);
                int           end   = dayFundIndex;
                List <double> list1 = new List <double>();
                for (int k = begin; k <= end; k++)
                {
                    list1.Add(dayFunds[k].Value[0]);
                }
                double fundT = list1.Normalization().SLOPE();

                begin = kline.IndexOf(buyDate);
                end   = dayKLineIndex;
                List <double> list2 = new List <double>();
                for (int k = begin; k <= end; k++)
                {
                    list2.Add(kline[k].CLOSE);
                }
                double closeT = list2.Normalization().SLOPE();

                //log.Info("斜率=" + fundT.ToString("F3") + "-" + closeT.ToString("F3") + "=" + Math.Abs(fundT - closeT).ToString("F3"));
                //两个线性回归斜率不一致
                if (Math.Abs(fundT - closeT) >= sell_slopediff)
                {
                    is_slope_run -= 1;
                }
                else //两个线性回归斜率一致
                {
                    if (fundT <= sell_slopepoint)
                    {
                        KLineItem prevKlineItem = kline[dayKLineIndex - 1];
                        if (prevKlineItem.CLOSE > dayLineItem.CLOSE)//价格下降了
                        {
                            if (earnRate > 0)
                            {
                                bout.RecordTrade(2, d, TradeDirection.Sell, dayLineItem.CLOSE, bout.BuyInfo.Amount, backtestParam.Volumecommission, backtestParam.Stampduty, "斜率一致且增幅小于阈值(" + fundT.ToString("F2") + "<" + sell_slopepoint.ToString("F2"));
                                break;
                            }
                        }

                        /*if(earnRate>0)
                         * {
                         *  bout.RecordTrade(2, d, TradeDirection.Sell, dayLineItem.CLOSE, bout.BuyInfo.Amount, backtestParam.volumecommission, backtestParam.stampduty, "斜率一致且增幅小于阈值("+ fundT.ToString("F2")+"<"+ sell_slopepoint.ToString("F2"));
                         *  break;
                         * }*/
                    }
                }
                //进入下一天
                d     = d.AddDays(1);
                days += 1;
                continue;
            }

            return(false);
        }
        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);
        }