示例#1
0
            /// <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;
                        }
                    }
                }
            }
示例#2
0
            /// <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, "");
                }
            }
示例#3
0
        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());
            }
        }
示例#4
0
        public override bool DoSell(string code, TradeBout bout, DateTime d, Properties strategyParam, BacktestParameter backtestParam, out string reason)
        {
            reason = "";
            if (bout == null)
            {
                return(false);
            }
            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;

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

            //跳过已完成的
            if (bout.Completed)
            {
                return(false);
            }

            TimeSeries <ITimeSeriesItem <char> > btpoints = ds.DayTradeLine.buysellPoints;

            if (btpoints == null || btpoints.Count <= 0)
            {
                return(false);
            }

            ITimeSeriesItem <char> item = btpoints[d];

            if (item == null || item.Value == 'B')
            {
                return(false);
            }

            KLineItem klineItemDay = kline[d];

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

            double price = klineItemDay.CLOSE;
            //if (price < bout.BuyInfo.TradePrice)
            //    return true;

            int amount = bout.BuyInfo.Amount;

            bout.RecordTrade(2, klineItemDay.Date, TradeDirection.Sell, price, amount, backtestParam.Volumecommission, backtestParam.Stampduty, "日线出S点");

            return(false);
        }
示例#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);
            }
            //取得策略参数
            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);
        }
示例#6
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);
        }
示例#7
0
        /// <summary>
        /// 执行回测
        /// </summary>
        /// <param name="props"></param>
        /// <returns></returns>
        public virtual TotalStat doTestByDate(List <TradeRecords> tradeRecoreds)
        {
            List <TradeBout> bouts = new List <TradeBout>();

            tradeRecoreds.ForEach(x => bouts.AddRange(x.Bouts));

            double   marketValueMin         = backtestParam.Initfunds; //日最低市值
            double   marketValueMax         = backtestParam.Initfunds; //日最高市值
            double   lastmarketValueMax     = backtestParam.Initfunds; //上一个日最高市值
            DateTime lastmarketValueMaxDate = backtestParam.BeginDate;
            double   curFund = backtestParam.Initfunds;                //当前资金

            TotalStat stat = new TotalStat();
            List <DateDetailRecord> records    = new List <DateDetailRecord>(); //日详细记录
            List <TradeBout>        holdTrades = new List <TradeBout>();        //日持仓回合
            List <int>    holdDays             = new List <int>();              //持仓日期
            List <String> codes     = new List <string>();                      //交易的股票代码
            List <int>    buyCounts = new List <int>();                         //每天买入的回合数

            IndicatorRepository repository = (IndicatorRepository)backtestParam.Get <Object>("repository");
            String reason = "";

            //遍历每一天
            for (DateTime d = backtestParam.BeginDate; d <= backtestParam.EndDate; d = d.AddDays(1))
            {
                //跳过非工作日
                //if (!CalendarUtils.IsWorkDay(d))
                //     continue;


                //生成空的当日记录
                DateDetailRecord record = new DateDetailRecord();
                record.date = d;
                //找到当日的买入回合、卖出回合
                bouts.ForEach(y =>
                {
                    if (y.BuyInfo.TradeDate.Date == d.Date)
                    {
                        record.buyBouts.Add(y);
                    }
                    else if (y.SellInfo.TradeDate.Date == d.Date)
                    {
                        record.sellBouts.Add(y);
                    }
                });

                //当日没有发生买卖操作,也没有持仓,跳过
                if (record.buyBouts.Count <= 0 && record.sellBouts.Count <= 0 && holdTrades.Count <= 0)
                {
                    continue;
                }



                //将buyTrades按照优先规则排序,待实现

                //计算当日买入的花销,如果超过了资金允许买入的量,则删除一部分
                record.willBuyCount = record.buyBouts.Count;
                for (int i = 0; i < record.buyBouts.Count; i++)
                {
                    if (record.buyBouts[i].BuyInfo.TradeCost > curFund)//资金不够
                    {
                        bouts.Remove(record.buyBouts[i]);
                        record.buyBouts.RemoveAt(i--);
                    }
                    else if (isForbidBuy(d, record.buyBouts[i].Code, out reason))//如果策略实现禁止买入
                    {
                        bouts.Remove(record.buyBouts[i]);
                        record.buyBouts.RemoveAt(i--);
                    }
                    else
                    {
                        curFund -= record.buyBouts[i].BuyInfo.TradeCost; //买入
                        holdTrades.Add(record.buyBouts[i]);              //买入后变成持仓
                    }
                }
                record.buyCount = record.buyBouts.Count;
                if (stat.MaxTradeCountPerDay < record.buyBouts.Count)
                {
                    stat.MaxTradeCountPerDay = record.buyBouts.Count;
                }
                buyCounts.Add(record.buyBouts.Count);

                //判断持仓中的股票是否被禁止持仓
                for (int i = 0; i < holdTrades.Count; i++)
                {
                    TradeBout info = holdTrades[i];
                    if (!isForbidHold(d, info.Code, out reason))
                    {
                        continue;
                    }
                    info.SellInfo.Reason = reason + "(" + info.SellInfo.Reason + ")";
                    record.sellBouts.Add(info);
                    holdTrades.RemoveAt(i--);
                }


                //卖出收入放回资金
                for (int i = 0; i < record.sellBouts.Count; i++)
                {
                    if (!codes.Contains(record.sellBouts[i].Code))//记录交易的股票
                    {
                        codes.Add(record.sellBouts[i].Code);
                    }
                    stat.BoutNum += 1;           //回合数加1
                    if (record.sellBouts[i].Win) //胜数加1
                    {
                        stat.WinNum += 1;
                    }
                    holdDays.Add(record.sellBouts[i].PositionDays);    //记录持仓日期

                    curFund += record.sellBouts[i].SellInfo.TradeCost; //回收资金
                    holdTrades.Remove(record.sellBouts[i]);            //从持仓中拿掉
                }
                record.SellCount = record.sellBouts.Count;

                //计算市值
                record.holdCount = holdTrades.Count;
                if (holdTrades.Count <= 0)//如果没有持仓,市值就是资金量
                {
                    marketValueMax = marketValueMin = curFund;
                    records.Add(record);
                }
                else//如果有持仓,则计算市值=资金量+持仓当日市值
                {
                    double min = 0, max = 0;
                    foreach (TradeBout info in holdTrades)
                    {
                        TimeSerialsDataSet ds = repository[info.Code];
                        KLine     kline       = ds.DayKLine;
                        KLineItem klineitem   = kline.GetNearest(d, true, -1);
                        if (klineitem == null)//有一个回合找不到当日K线数据,则当日市值不再计算
                        {
                            min = max = 0;
                            this.log.Warn("日期" + d.ToString("yyyyMMdd") + "中有回合缺少当日和历史K线:" + info.Code);
                            break;
                        }
                        min += info.BuyInfo.Amount * klineitem.LOW;
                        max += info.BuyInfo.Amount * klineitem.HIGH;
                        record.holdBouts.Add(info.Code + "," + info.BuyInfo.Amount + "," + info.BuyInfo.TradePrice.ToString("F2") + "," + klineitem.CLOSE);
                    }
                    if (min != 0)
                    {
                        marketValueMin = curFund + min;
                    }
                    if (max != 0)
                    {
                        marketValueMax = curFund + max;
                    }
                    if (min != 0 && max != 0)
                    {
                        records.Add(record);
                    }
                }
                //记录资金和市值数据
                record.curFund        = curFund;
                record.marketValueMin = marketValueMin;
                record.marketValueMax = marketValueMax;
                if (marketValueMin < backtestParam.Initfunds)
                {
                    record.retracement = (backtestParam.Initfunds - marketValueMin) / backtestParam.Initfunds;
                }
                if (stat.MaxInitRetracementRate < record.retracement)
                {
                    stat.MaxInitRetracementRate = record.retracement;
                    stat.MaxInitRetracementDate = d;
                }
                if (marketValueMax > lastmarketValueMax)
                {
                    lastmarketValueMax     = marketValueMax;
                    lastmarketValueMaxDate = d;
                    record.retracement     = 0;
                }
                else
                {
                    record.retracement      = (lastmarketValueMax - marketValueMax) / lastmarketValueMax;
                    stat.MaxRetracementRate = record.retracement;
                    stat.MaxRetracementDate = d;
                }
            }

            //清除没有卖出的回合
            for (int i = 0; i < holdTrades.Count; i++)
            {
                curFund += holdTrades[i].BuyInfo.TradeCost;
                bouts.Remove(holdTrades[i]);
            }
            holdTrades.Clear();
            marketValueMin = marketValueMax = curFund;
            if (records.Count > 0)
            {
                DateDetailRecord extends = new DateDetailRecord();
                extends.date           = records[records.Count - 1].date.AddDays(1);
                extends.curFund        = curFund;
                extends.marketValueMax = marketValueMax;
                extends.marketValueMin = marketValueMin;
                records.Add(extends);
            }

            //结果统计
            stat.Records = records;

            stat.AverageTradeCountPerDay = buyCounts.Count <= 0?0:buyCounts.Average();
            stat.AvgHoldDays             = holdDays.Count <= 0?0:(int)holdDays.Average();
            stat.Count        = codes.Count;
            stat.MaxHoldDays  = holdDays.Count <= 0 ? 0 : holdDays.Max();
            stat.TotalFund    = curFund;
            stat.TotalProfilt = (curFund - backtestParam.Initfunds) / backtestParam.Initfunds;
            stat.WinRate      = stat.WinNum * 1.0 / stat.BoutNum;

            return(stat);
        }
示例#8
0
        /// <summary>
        /// 执行卖出操作
        /// </summary>
        /// <param name="tradeRecord"></param>
        /// <param name="strategyParam"></param>
        /// <param name="backtestParam"></param>
        public virtual void Execute(TradeRecords tradeRecord, Properties strategyParam, BacktestParameter backtestParam)
        {
            #region 1初始化行情库
            if (tradeRecord == null)
            {
                return;
            }

            IndicatorRepository repository = (IndicatorRepository)backtestParam.Get <Object>("repository");
            if (repository == null)
            {
                return;
            }

            #endregion

            #region 2 取得策略参数

            int    p_maxbuynum      = strategyParam.Get <int>("maxbuynum", 0);
            double p_maxprofilt     = strategyParam.Get <double>("maxprofilt");
            int    p_maxholddays    = strategyParam.Get <int>("maxholddays");
            double p_stoploss       = strategyParam.Get <double>("stoploss");
            int    p_choosedays     = strategyParam.Get <int>("choosedays");
            double p_chooseprofilt  = strategyParam.Get <double>("chooseprofilt");
            double p_addholdprofilt = strategyParam.Get <double>("addholdprofilt");
            double p_addholdamount  = strategyParam.Get <double>("addholdamount");
            #endregion


            String           code  = tradeRecord.Code;
            List <TradeBout> bouts = tradeRecord.Bouts;

            #region 3 遍历每一个买入回合
            for (int i = 0; i < bouts.Count; i++)
            {
                #region 3.1 取得该回合的行情数据
                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;
                }

                bool chooseToSell = false;//择机卖出状态,是指持仓价值较低

                int bIndex = kline.IndexOf(bout.BuyInfo.TradeDate);
                if (bIndex < 0)
                {
                    continue;
                }
                KLineItem klineItemDay = kline[bIndex];
                DateTime  d            = klineItemDay.Date;


                #endregion

                #region 3.2 如果超过了最大持仓数限制,该回合跳过
                if (p_maxbuynum > 0)
                {
                    //计算当前回合的买入日期这天有多少持仓
                    int count = 0;
                    bouts.ForEach(x => { if (x.Completed && bout.BuyInfo.TradeDate.Date >= x.BuyInfo.TradeDate.Date && bout.BuyInfo.TradeDate.Date < x.SellInfo.TradeDate.Date)
                                         {
                                             count++;
                                         }
                                  });

                    if (count > p_maxbuynum)
                    {
                        continue;
                    }
                }
                #endregion


                #region 3.3 寻找卖点
                String reason = "";
                for (int index = bIndex + 1; index < kline.Count; index++)
                {
                    klineItemDay = kline[index];
                    d            = klineItemDay.Date;


                    #region A 计算以当日最高价和收盘价卖出的盈利
                    double diff        = klineItemDay.HIGH - bout.BuyInfo.TradePrice;
                    double percentHigh = diff / bout.BuyInfo.TradePrice;
                    diff = klineItemDay.CLOSE - bout.BuyInfo.TradePrice;
                    double percentClose = diff / bout.BuyInfo.TradePrice;
                    #endregion

                    #region B 盈利超过预定
                    if (p_maxprofilt > 0 && percentHigh >= p_maxprofilt) //盈利超过预定
                    {
                        double price  = bout.BuyInfo.TradePrice * (1 + p_maxprofilt);
                        int    amount = bout.BuyInfo.Amount;
                        bout.RecordTrade(2, klineItemDay.Date, TradeDirection.Sell, price, amount, backtestParam.Volumecommission, backtestParam.Stampduty, "盈利>=" + p_maxprofilt.ToString("F2"));
                        break;
                    }
                    #endregion

                    #region C 择机卖出状态
                    if (chooseToSell)
                    {
                        for (int t = 0; t < p_choosedays; t++)
                        {
                            index += t;
                            if (index >= kline.Count)
                            {
                                break;
                            }
                            double percent = (kline[index].HIGH - bout.BuyInfo.TradePrice) / bout.BuyInfo.TradePrice;
                            if (percent >= p_chooseprofilt)
                            {
                                double price  = bout.BuyInfo.TradePrice * (1 + p_chooseprofilt);
                                int    amount = bout.BuyInfo.Amount;
                                bout.RecordTrade(2, kline[index].Date, TradeDirection.Sell, price, amount, backtestParam.Volumecommission, backtestParam.Stampduty, (reason == "" ? "" : reason + ",并") + "在第" + (t + 1).ToString() + "天择机卖出");
                                break;
                            }
                        }
                        if (!bout.Completed)
                        {
                            if (index >= kline.Count)
                            {
                                return;
                            }
                            double price  = kline[index].CLOSE;
                            int    amount = bout.BuyInfo.Amount;
                            bout.RecordTrade(2, kline[index].Date, TradeDirection.Sell, price, amount, backtestParam.Volumecommission, backtestParam.Stampduty, (reason == "" ? "" : reason + ",并") + "择机强制卖出");
                        }
                        break;
                    }
                    #endregion

                    #region D 持仓超过n天进入到择机卖出状态
                    if (p_maxholddays != 0 && CalendarUtils.WorkDayCount(bout.BuyInfo.TradeDate, klineItemDay.Date) >= p_maxholddays)
                    {
                        reason       = "持仓超过" + p_maxholddays.ToString() + "天";
                        chooseToSell = true;
                        continue;
                    }
                    #endregion


                    #region E 达到止损线,进入到择机卖出状态
                    double loss = (klineItemDay.LOW - bout.BuyInfo.TradePrice) / bout.BuyInfo.TradePrice;
                    if (p_stoploss > 0 && loss < 0 && loss < -1 * p_stoploss)
                    {
                        reason = "达到止损" + p_stoploss.ToString("F2");
                        bout.RecordTrade(2, d, TradeDirection.Sell, bout.BuyInfo.TradePrice * (1 - p_stoploss), bout.BuyInfo.Amount, backtestParam.Volumecommission, backtestParam.Stampduty, reason);
                        break;
                    }
                    #endregion

                    #region F调用子类的算法来寻找卖点
                    if (!bout.Completed)
                    {
                        chooseToSell = DoSell(code, bout, d, strategyParam, backtestParam, out reason);
                    }
                    if (bout.Completed)
                    {
                        break;
                    }
                    #endregion

                    #region 判断是否加仓或者减仓
                    if (p_addholdprofilt > 0 && p_addholdamount > 0)
                    {
                        if (percentClose > p_addholdprofilt)
                        {
                            int       addamount = (int)(bout.BuyInfo.Amount * p_addholdamount);
                            TradeInfo tradeInfo = new TradeInfo();
                            tradeInfo.Code       = bout.Code;
                            tradeInfo.Amount     = addamount;
                            tradeInfo.Direction  = TradeDirection.Buy;
                            tradeInfo.Reason     = "加仓";
                            tradeInfo.Fee        = backtestParam.Volumecommission;
                            tradeInfo.Stamps     = backtestParam.Stampduty;
                            tradeInfo.TradeDate  = klineItemDay.Date;
                            tradeInfo.TradePrice = klineItemDay.CLOSE;

                            bout.BuyInfo.TradePrice = (bout.BuyInfo.Amount * bout.BuyInfo.TradePrice + addamount * klineItemDay.CLOSE) / (bout.BuyInfo.Amount + addamount);
                            bout.BuyInfo.Amount    += addamount;
                        }
                    }
                    #endregion
                }

                #endregion //寻找卖点结束
            }

            #endregion //遍历每一个买入回合结束
        }
示例#9
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);
            }
示例#10
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);
            }
            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);
        }
示例#11
0
        public override bool DoSell(String code, TradeBout bout, DateTime d, Properties strategyParam, BacktestParameter backtestParam, out String reason)
        {
            reason = "";
            if (bout == null)
            {
                return(false);
            }
            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;

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

            //跳过已完成的
            if (bout.Completed)
            {
                return(false);
            }

            //取得策略参数
            int p_spoints           = strategyParam.Get <int>("spoints");
            int p_totaldropcount    = strategyParam.Get <int>("totaldropcount");
            int p_continuedropcount = strategyParam.Get <int>("continuedropcount");


            #region 判断发出S点卖出:p_spoints=1表示日线出S点,p_spoints=2表示60分钟线出S点
            if (p_spoints > 0 && ds.DayTradeLine != null && ds.DayTradeLine.buysellPoints != null && ds.DayTradeLine.buysellPoints.Count > 0)
            {
                ITimeSeriesItem <char> bsptItemDay = ds.DayTradeLine.buysellPoints[d];
                if (bsptItemDay != null && bsptItemDay.Value == 'S')
                {
                    KLineItem klineItemDay = kline[d];
                    if (klineItemDay != null)
                    {
                        double price  = klineItemDay.CLOSE;
                        int    amount = bout.BuyInfo.Amount;
                        bout.RecordTrade(2, klineItemDay.Date, TradeDirection.Sell, price, amount, backtestParam.Volumecommission, backtestParam.Stampduty, "日线出S点");
                        return(false);
                    }
                }
            }
            #endregion

            #region 根据价格下降情况判断是否卖出
            if (p_continuedropcount > 0 || p_totaldropcount > 0)
            {
                int bIndex = kline.IndexOf(bout.BuyInfo.TradeDate);

                int index = bIndex + 1;
                if (index >= kline.Count)
                {
                    return(false);
                }
                KLineItem item = kline[index];
                DateTime  td   = item.Date;

                int    totaldropcount = 0, continuedropcount = 0;
                double prevPrice = bout.BuyInfo.TradePrice;
                bool   prevDrop  = item.Average < prevPrice;
                while (td <= d && index < kline.Count - 1)
                {
                    double price = item.Average;
                    if (price < prevPrice)
                    {
                        totaldropcount += 1;
                        if (prevDrop)
                        {
                            continuedropcount += 1;
                        }
                        prevDrop = true;
                    }
                    else
                    {
                        prevDrop = false;
                    }

                    index += 1;
                    item   = kline[index];
                    td     = item.Date;
                }

                //进入到伺机卖出状态
                if (p_continuedropcount != 0 && continuedropcount >= p_continuedropcount)
                {
                    return(true);
                }
                //进入到伺机卖出情况
                if (p_totaldropcount != 0 && totaldropcount >= p_totaldropcount)
                {
                    return(true);
                }
            }
            #endregion


            return(false);
        }
示例#12
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);
        }
示例#13
0
        /// <summary>
        /// 导入数据
        /// </summary>
        public bool doMergeToRepository()
        {
            showBeginMessage("开始合并数据...");
            if (repository == null)
            {
                repository = new IndicatorRepository(FileUtils.GetDirectory(props.Get <String>("repository")));
                repository.Initilization();
            }
            String datapath = FileUtils.GetDirectory(props.Get <String>("datapath"));

            DirectoryInfo dInfo = new DirectoryInfo(datapath);

            FileInfo[] fInfos = dInfo.GetFiles("*.scv");
            if (fInfos == null || fInfos.Length <= 0)
            {
                showResultMessage("没有需要导入的新文件", 1);
                return(false);
            }
            try
            {
                foreach (FileInfo fInfo in fInfos)
                {
                    String             code = fInfo.Name.Substring(3, 6);
                    TimeSerialsDataSet ds   = repository[code];
                    KLine kline             = ds.DayKLine;
                    if (ds == null)
                    {
                        continue;
                    }
                    showProgressMessage(code);
                    CSVFile csvFile = new CSVFile();
                    csvFile.Load(fInfo.FullName, Encoding.UTF8, false, ",");
                    List <String> lines = csvFile.Lines;
                    for (int i = lines.Count - 1; i >= 0; i--)
                    {
                        if (lines[i] == null || lines[i].Trim() == "")
                        {
                            continue;
                        }
                        String[] ss = lines[i].Split(',');
                        if (ss == null || ss.Length < 7)
                        {
                            continue;
                        }

                        DateTime  d    = DateUtils.Parse(ss[0]);
                        KLineItem item = kline[d];
                        if (item != null)
                        {
                            break;
                        }

                        double[] v = new double[6];
                        for (int j = 0; j < v.Length; j++)
                        {
                            v[j] = double.Parse(ss[j + 1]);
                        }
                        item      = new KLineItem();
                        item.Date = d;
                        item.SetValue <double>("OPEN", v[0]);
                        item.SetValue <double>("HIGH", v[1]);
                        item.SetValue <double>("LOW", v[2]);
                        item.SetValue <double>("CLOSE", v[3]);
                        item.SetValue <double>("VOLUME", v[4]);
                        item.SetValue <double>("TURNOVER", v[5]);
                        kline.Add(item);
                    }

                    ds.Save("kline", TimeUnit.day);
                }
                showResultMessage("");
                return(true);
            }
            catch (Exception e)
            {
                showResultMessage("导入失败", -1, e.Message);
                return(false);
            }
        }
示例#14
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);
            }

            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);
        }
示例#15
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);
        }
示例#16
0
        /// <summary>
        /// 执行方法
        /// </summary>
        /// <param name="context"></param>
        public override void Execute(CommandContext context)
        {
            logger.Debug("执行命令:" + this.ToString());
            //取得参数
            everydayLinePath      = (String)context.GetExternalValue(everydayLinePath);
            dayLineReposorityPath = (String)context.GetExternalValue(dayLineReposorityPath);
            mergeDateString       = (String)context.GetExternalValue(mergeDateString);
            mergeDate             = DateUtils.Parse(mergeDateString);
            logger.Debug("取得参数:源路径=" + everydayLinePath + ",合并路径=" + dayLineReposorityPath + ",日期=" + mergeDateString);
            if (!everydayLinePath.EndsWith("\\"))
            {
                everydayLinePath += "\\";
            }
            if (!dayLineReposorityPath.EndsWith("\\"))
            {
                dayLineReposorityPath += "\\";
            }

            IndicatorRepository repository = (IndicatorRepository)context.GetExternalValue("{$repository}");

            //检查路径
            DirectoryInfo dFromInfo = new DirectoryInfo(everydayLinePath);

            if (!dFromInfo.Exists)
            {
                throw new Exception("单日日线存储路径不存在:" + everydayLinePath);
            }

            DirectoryInfo dToInfo = new DirectoryInfo(dayLineReposorityPath);

            if (!dToInfo.Exists)
            {
                throw new Exception("日线存储仓库路径不存在:" + dayLineReposorityPath);
            }

            FileInfo[] finfos = dFromInfo.GetFiles("*.txt");
            logger.Debug("共有" + (finfos == null ? "0" : finfos.Length.ToString()) + "个单日K线数据待合并...");
            foreach (FileInfo fInfo in finfos)
            {
                logger.Debug("处理" + fInfo.Name + "...");
                String   market = fInfo.Name.Substring(0, fInfo.Name.IndexOf("#"));
                String   code   = fInfo.Name.substring(0, "#", ".");
                String[] lines  = File.ReadAllLines(fInfo.FullName);

                for (int i = 0; i < lines.Length; i++)
                {
                    if (lines[i] == null || lines[i] == "")
                    {
                        continue;
                    }
                    if (!lines[i].Contains(","))
                    {
                        continue;
                    }
                    String[] ss = lines[i].Trim().Split(',');
                    if (ss == null || ss.Length != 7)
                    {
                        continue;
                    }
                    if (ss[0] == null)
                    {
                        continue;
                    }
                    DateTime d = DateUtils.InitDate;
                    if (!DateUtils.TryParse(ss[0].Trim(), out d))
                    {
                        continue;
                    }
                    if (d.Date != this.mergeDate.Date)
                    {
                        continue;
                    }
                    KLineItem item = new KLineItem();
                    item.SetValue <String>(KLineItem.PD_CODE.Name, code);
                    item.SetValue <DateTime>(KLineItem.PD_TIME.Name, d);
                    item.SetValue <double>(KLineItem.PD_OPEN.Name, ConvertUtils.ConvertTo <double>(ss[1].Trim()));
                    item.SetValue <double>(KLineItem.PD_HIGH.Name, ConvertUtils.ConvertTo <double>(ss[2].Trim()));
                    item.SetValue <double>(KLineItem.PD_LOW.Name, ConvertUtils.ConvertTo <double>(ss[3].Trim()));
                    item.SetValue <double>(KLineItem.PD_CLOSE.Name, ConvertUtils.ConvertTo <double>(ss[4].Trim()));
                    item.SetValue <double>(KLineItem.PD_VOLUMN.Name, ConvertUtils.ConvertTo <double>(ss[5].Trim()));
                    item.SetValue <double>(KLineItem.PD_TURNOVER.Name, ConvertUtils.ConvertTo <double>(ss[6].Trim()));

                    TimeSerialsDataSet ds = repository[code];
                    if (ds == null)
                    {
                        continue;
                    }
                    ds.DayKLine[d.Date] = item;
                    ds.Save("kline", TimeUnit.day);
                    logger.Debug("合并到" + market.ToUpper() + code + ".csv");
                }
            }
        }
示例#17
0
        private void createTrainTestData()
        {
            if (repository == null)
            {
                repository = new IndicatorRepository(textBox2.Text);
                repository.Initilization();
            }

            String   filename = textBox7.Text;
            FileInfo fInfo    = new FileInfo(filename);


            String[] lines = File.ReadAllLines(filename);
            for (int i = 0; i < lines.Length; i++)
            {
                if (lines[i] == null || lines[i].Trim() == "")
                {
                    continue;
                }

                int index = lines[i].IndexOf("\"");
                if (index < 0)
                {
                    continue;
                }
                index = lines[i].IndexOf("\"", index + 1);
                if (index < 0)
                {
                    continue;
                }
                index = lines[i].IndexOf("\"", index + 1);
                if (index < 0)
                {
                    continue;
                }

                String label = lines[i].substring(index - 1, "\"", "\"");
                //"[-6.4500000000000002, '2007-05-17', 6]"
                String[] ss = label.Split(',');
                if (ss == null || ss.Length < 3)
                {
                    continue;
                }
                String sDate = ss[1].Trim().Substring(1, 10);
                String code  = ss[2].Substring(0, ss[2].Length - 2).Trim();
                int    len   = code.Length;
                for (int j = 0; j < 6 - len; j++)
                {
                    code = "0" + code;
                }

                DateTime d = DateTime.ParseExact(sDate, "yyyy-MM-dd", null);

                TimeSerialsDataSet ds = repository[code];
                if (ds == null)
                {
                    lines[i] = lines[i].Substring(0, index) + "\"[0.0,'" + sDate + "'," + code + "]\"";
                    continue;
                }

                KLine     kline = ds.DayKLine;
                KLineItem item  = kline[d];
                if (item == null)
                {
                    lines[i] = lines[i].Substring(0, index) + "\"[0.0,'" + sDate + "'," + code + "]\"";
                    continue;
                }
                double maxprofilt = -100;
                int    itemIndex  = kline.IndexOf(item);
                for (int k = itemIndex + 1; k < itemIndex + 5; k++)
                {
                    if (k >= kline.Count)
                    {
                        break;
                    }
                    double p = (kline[k].CLOSE - item.CLOSE) / item.CLOSE;
                    if (maxprofilt < p)
                    {
                        maxprofilt = p;
                    }
                }
                if (maxprofilt == -100)
                {
                    lines[i] = lines[i].Substring(0, index) + "\"[0.0,'" + sDate + "'," + code + "]\"";
                    continue;
                }
                lines[i] = lines[i].Substring(0, index) + "\"[" + maxprofilt.ToString("F3") + ",'" + sDate + "'," + code + "]\"";
            }

            File.WriteAllLines(filename + "2", lines);
        }
示例#18
0
        /// <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, "");
            }
        }
示例#19
0
        public override TradeInfo DoSell(HoldRecord holdRecord, DateTime d, Properties strategyParam, StrategyContext context)
        {
            if (holdRecord == null)
            {
                return(null);
            }

            //取得行情库
            IndicatorRepository repository = (IndicatorRepository)context.Get <Object>("repository");

            if (repository == null)
            {
                return(null);
            }
            TimeSerialsDataSet ds = repository[holdRecord.code];

            if (ds == null)
            {
                return(null);
            }
            KLine     klineDay     = ds.DayKLine;
            KLineItem klineItemDay = klineDay[d];

            if (klineItemDay == null)
            {
                return(null);
            }

            //取得策略参数
            double         p_maxprofilt     = strategyParam.Get <double>("maxprofilt");
            int            p_maxholddays    = strategyParam.Get <int>("maxholddays");
            double         p_stoploss       = strategyParam.Get <double>("stoploss");
            int            p_choosedays     = strategyParam.Get <int>("choosedays");
            double         p_chooseprofilt  = strategyParam.Get <double>("chooseprofilt");
            GrailParameter p_grail          = GrailParameter.Parse(strategyParam.Get <String>("grail"));
            double         stampduty        = context.Get <double>("stampduty");
            double         volumecommission = context.Get <double>("volumecommission");

            //大盘要求必须卖
            if (p_grail.MustSell(d, holdRecord.code))
            {
                TradeInfo tradeInfo = new TradeInfo()
                {
                    Direction    = TradeDirection.Sell,
                    Code         = holdRecord.code,
                    Amount       = holdRecord.amount,
                    EntrustPrice = klineItemDay.CLOSE,
                    EntrustDate  = d,
                    TradeDate    = d,
                    TradePrice   = klineItemDay.CLOSE,
                    Stamps       = stampduty,
                    Fee          = volumecommission,
                    TradeMethod  = TradeInfo.TM_AUTO,
                    Reason       = "大盘指数要求卖出"
                };
                return(tradeInfo);
            }

            double profilt = (klineItemDay.CLOSE - holdRecord.buyPrice) / holdRecord.buyPrice;

            //判断是否到达最大收益
            if (p_maxprofilt > 0)
            {
                if (profilt >= p_maxprofilt)
                {
                    TradeInfo tradeInfo = new TradeInfo()
                    {
                        Direction    = TradeDirection.Sell,
                        Code         = holdRecord.code,
                        Amount       = holdRecord.amount,
                        EntrustPrice = klineItemDay.CLOSE,
                        EntrustDate  = d,
                        TradeDate    = d,
                        TradePrice   = klineItemDay.CLOSE,
                        Stamps       = stampduty,
                        Fee          = volumecommission,
                        TradeMethod  = TradeInfo.TM_AUTO,
                        Reason       = "盈利达到" + p_maxprofilt.ToString("F2")
                    };
                    return(tradeInfo);
                }
            }

            //盈利超过个股预期
            if (holdRecord.expect > 0)
            {
                if (profilt >= p_maxprofilt)
                {
                    TradeInfo tradeInfo = new TradeInfo()
                    {
                        Direction    = TradeDirection.Sell,
                        Code         = holdRecord.code,
                        Amount       = holdRecord.amount,
                        EntrustPrice = klineItemDay.CLOSE,
                        EntrustDate  = d,
                        TradeDate    = d,
                        TradePrice   = klineItemDay.CLOSE,
                        Stamps       = stampduty,
                        Fee          = volumecommission,
                        TradeMethod  = TradeInfo.TM_AUTO,
                        Reason       = "盈利达到个股预期" + holdRecord.expect.ToString("F2")
                    };
                    return(tradeInfo);
                }
            }

            //预期要求立即卖出
            if (holdRecord.expect == -1)
            {
                TradeInfo tradeInfo = new TradeInfo()
                {
                    Direction    = TradeDirection.Sell,
                    Code         = holdRecord.code,
                    Amount       = holdRecord.amount,
                    EntrustPrice = klineItemDay.CLOSE,
                    EntrustDate  = d,
                    TradeDate    = d,
                    TradePrice   = klineItemDay.CLOSE,
                    Stamps       = stampduty,
                    Fee          = volumecommission,
                    TradeMethod  = TradeInfo.TM_AUTO,
                    Reason       = "个股预期极低"
                };
                return(tradeInfo);
            }

            //个股观望天数超过预期
            int holdDays = CalendarUtils.WorkDayCount(holdRecord.buyDate, d);

            if (holdRecord.expect < 0)
            {
                if (holdDays >= holdRecord.expect * -1)
                {
                    TradeInfo tradeInfo = new TradeInfo()
                    {
                        Direction    = TradeDirection.Sell,
                        Code         = holdRecord.code,
                        Amount       = holdRecord.amount,
                        EntrustPrice = klineItemDay.CLOSE,
                        EntrustDate  = d,
                        TradeDate    = d,
                        TradePrice   = klineItemDay.CLOSE,
                        Stamps       = stampduty,
                        Fee          = volumecommission,
                        TradeMethod  = TradeInfo.TM_AUTO,
                        Reason       = "个股预期观望超过" + (-1 * holdRecord.expect).ToString() + "天"
                    };
                    return(tradeInfo);
                }
            }

            //达到止损线
            if (p_stoploss > 0)
            {
                if (-1 * profilt > p_stoploss)
                {
                    TradeInfo tradeInfo = new TradeInfo()
                    {
                        Direction    = TradeDirection.Sell,
                        Code         = holdRecord.code,
                        Amount       = holdRecord.amount,
                        EntrustPrice = klineItemDay.CLOSE,
                        EntrustDate  = d,
                        TradeDate    = d,
                        TradePrice   = klineItemDay.CLOSE,
                        Stamps       = stampduty,
                        Fee          = volumecommission,
                        TradeMethod  = TradeInfo.TM_AUTO,
                        Reason       = "到达止损线" + p_stoploss.ToString("F2")
                    };
                    return(tradeInfo);
                }
            }

            //达到最大持仓天数
            if (p_maxholddays > 0)
            {
                if (holdDays > p_maxholddays)
                {
                    TradeInfo tradeInfo = new TradeInfo()
                    {
                        Direction    = TradeDirection.Sell,
                        Code         = holdRecord.code,
                        Amount       = holdRecord.amount,
                        EntrustPrice = klineItemDay.CLOSE,
                        EntrustDate  = d,
                        TradeDate    = d,
                        TradePrice   = klineItemDay.CLOSE,
                        Stamps       = stampduty,
                        Fee          = volumecommission,
                        TradeMethod  = TradeInfo.TM_AUTO,
                        Reason       = "到达最大持仓天数" + p_maxholddays.ToString()
                    };
                    return(tradeInfo);
                }
            }
            return(null);
        }
示例#20
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);
        }
示例#21
0
        private void button12_Click(object sender, EventArgs e)
        {
            String   code  = textBox4.Text;
            DateTime begin = dateTimePicker3.Value;
            DateTime end   = dateTimePicker4.Value;
            int      days  = int.Parse(textBox5.Text);

            if (repository == null)
            {
                repository = new IndicatorRepository(textBox2.Text);
                repository.Initilization();
            }

            TimeSerialsDataSet ds = repository[code];

            if (ds == null || ds.DayKLine == null)
            {
                MessageBox.Show("代码" + code + "缺少K线数据");
            }

            KLine     klineDay = ds.DayKLine;
            KLineItem item     = null;

            List <double[]> datas = new List <double[]>();

            for (int i = 0; i < klineDay.Count; i++)
            {
                item = klineDay[i];
                if (item.Date < begin)
                {
                    continue;
                }
                if (item.Date > end)
                {
                    break;
                }

                double maxprofilt = -100;
                for (int j = i + 1; j <= i + 1 + days; j++)
                {
                    if (j >= klineDay.Count)
                    {
                        break;
                    }
                    double p = (klineDay[j].CLOSE - item.CLOSE) / item.CLOSE;
                    if (maxprofilt < p)
                    {
                        maxprofilt = p;
                    }
                }
                if (maxprofilt == -100)
                {
                    continue;
                }
                double[] values = new double[2];
                values[0] = item.CLOSE;
                values[1] = maxprofilt;
                datas.Add(values);
            }

            if (datas.Count <= 0)
            {
                MessageBox.Show("没有有效数据");
                return;
            }
            String[] lines = datas.ConvertAll(x => x[0].ToString("F2") + "," + x[1].ToString("F3")).ToArray();
            File.WriteAllLines("d:\\" + code + ".csv", lines);
        }