量化交易14-backtrader回测南方三星、三个白兵、脱离、藏婴吞没、弃婴、捉腰带线、反击线等形态

笔者此时会把我们常见的8种形态放在一起进行回测,然后得出结论,从而大家演示这几种函数的使用方法。

#cdl3starsinsouth - 南方三星(筑底上涨)
#cdl3whitesoldiers - 三个白兵(上涨)
#cdlbreakaway - 脱离(反转上涨)
#cdlconcealbabyswall - 藏婴吞没(反转上涨)
#cdlabandonedbaby - 弃婴(上涨或者下跌)
#cdlbelthold - 捉腰带线(上涨或者下跌)
#cdlcounterattack - 反击线(上涨或者下跌)

先上代码:

#cdl3starsinsouth - 南方三星(筑底上涨)
#cdl3whitesoldiers - 三个白兵(上涨)
#cdlbreakaway - 脱离(反转上涨)
#cdlconcealbabyswall - 藏婴吞没(反转上涨)
#cdlabandonedbaby - 弃婴(上涨或者下跌)
#cdlbelthold - 捉腰带线(上涨或者下跌)
#cdlcounterattack - 反击线(上涨或者下跌)

import tushare as ts
import pandas as pd

import datetime  # For datetime objects
import os.path  # To manage paths
import sys  # To find out the script name (in argv[0])
# Import the backtrader platform
import backtrader as bt
import talib as talib
import numpy as np
import StockData

class MyStrategy(bt.Strategy):
    # 策略参数
    params = dict(
        printlog=False
    )

    def __init__(self):
        self.star = dict()
        self.cdl3inside = dict()
        self.cdl3linestrike = dict()
        self.cdl3starsinsouth = dict() #南方三星(筑底上涨)
        self.cdl3whitesoldiers = dict() # 三个白兵(上涨)
        self.cdlbreakaway = dict()# 脱离(反转上涨)
        self.cdlconcealbabyswall = dict() # 藏婴吞没(反转上涨)
        self.cdlabandonedbaby = dict() #弃婴(上涨或者下跌)
        self.cdlbelthold = dict() # 捉腰带线(上涨或者下跌)
        self.cdlcounterattack = dict() # 反击线(上涨或者下跌)

        # 定义全局变量
        self.count = 0
        for data in self.datas:
            # 转为tabib要求的数据格式
            opens = np.array(data.open.array)
            highs = np.array(data.high.array)
            lows = np.array(data.low.array)
            closes = np.array(data.close.array)

            self.cdl3starsinsouth[data._id] = talib.CDL3STARSINSOUTH(opens, highs, lows, closes)  # 南方三星(筑底上涨)
            self.cdl3whitesoldiers[data._id] = talib.CDL3WHITESOLDIERS(opens, highs, lows, closes)  # 三个白兵(上涨)
            self.cdlbreakaway[data._id] = talib.CDLBREAKAWAY(opens, highs, lows, closes)  # 脱离(反转上涨)
            self.cdlconcealbabyswall[data._id] = talib.CDLCONCEALBABYSWALL(opens, highs, lows, closes)  # 藏婴吞没(反转上涨)
            self.cdlabandonedbaby[data._id] = talib.CDLABANDONEDBABY(opens, highs, lows, closes)  # 弃婴(上涨或者下跌)
            self.cdlbelthold[data._id] = talib.CDLBELTHOLD(opens, highs, lows, closes)  # 捉腰带线(上涨或者下跌)
            self.cdlcounterattack[data._id] = talib.CDLBELTHOLD(opens, highs, lows, closes)  # 反击线(上涨或者下跌)


    def next(self):
        # 得到当前的账户价值
        total_value = self.broker.getcash()
        for data in self.datas:
            pos = self.getposition(data).size
            # 三线打击K线形态
            if total_value > 0 and \
            (self.cdl3starsinsouth[data._id][self.count] == 100 or \
            self.cdl3whitesoldiers[data._id][self.count] == 100 or \
            self.cdlbreakaway[data._id][self.count] == 100 or \
            self.cdlconcealbabyswall[data._id][self.count] == 100 or \
            self.cdlabandonedbaby[data._id][self.count] == 100 or \
            self.cdlbelthold[data._id][self.count] == 100 or \
            self.cdlcounterattack[data._id][self.count] == 100):

                p_value = total_value * 0.9 / 10
                size = ((int(total_value / self.data.close[0]))) - ((int(total_value / self.data.close[0])) % 100) - 100
                if(size > 100 ):
                    self.buy(data=data, size=size)
                    print('三线打击K线形态,全仓买入,买入数量' + str(size) )

            #三日连涨,截至今天,如果还有持仓一并全部卖出
            if pos > 0 and \
            ( self.cdlabandonedbaby[data._id][self.count] == 100 or \
            self.cdlbelthold[data._id][self.count] == 100 or \
            self.cdlcounterattack[data._id][self.count] == 100 or \
            self.count == len(data.open.array) ):
                 # 全部卖出
                 # 跟踪订单避免重复
                 self.sell(data=data, size=pos)
                 print('出现三日连涨定律,卖出数量' + str(pos))

        #自增处理
        self.count = self.count + 1

    def log(self, txt, dt=None, doprint=False):
        if self.params.printlog or doprint:
            dt = dt or self.datas[0].datetime.date(0)
            print(f'{dt.isoformat()},{txt}')

    # 记录交易执行情况(可省略,默认不输出结果)
    def notify_order(self, order):
        # 如果order为submitted/accepted,返回空
        if order.status in [order.Submitted, order.Accepted]:
            return
        # 如果order为buy/sell executed,报告价格结果
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log(f'买入:\n价格:{order.executed.price:.2f},\
                成本:{order.executed.value:.2f},\
                数量:{order.executed.size:.2f},\
                手续费:{order.executed.comm:.2f}')
                self.buyprice = order.executed.price
                self.buycomm = order.executed.comm
            else:
                self.log(f'卖出:\n价格:{order.executed.price:.2f},\
                成本: {order.executed.value:.2f},\
                数量:{order.executed.size:.2f},\
                手续费{order.executed.comm:.2f}')
            self.bar_executed = len(self)
            # 如果指令取消/交易失败, 报告结果
        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('交易失败')
        self.order = None

    # 记录交易收益情况(可省略,默认不输出结果)
    def notify_trade(self, trade):
        if not trade.isclosed:
            return
        self.log(f'策略收益:\n毛收益 {trade.pnl:.2f}, 净收益 {trade.pnlcomm:.2f}')

# 取数据
st = StockData.Data()
st.get_stock_data()
code = st.get_code()


for i in range(len(code)):  # 循环获取股票历史数据
    print('回测的数据为:' + code.iloc[i] + '.csv')
    dataframe = pd.read_csv(code.iloc[i] + '.csv', index_col=0, parse_dates=True)
    dataframe['openinterest'] = 0
    # data = bt.feeds.PandasData(dataname=dataframe,  fromdate=datetime.datetime(2010, 2, 20), todate=datetime.datetime(2022, 4, 5))
    data = bt.feeds.PandasData(dataname=dataframe)

    # 数据放入策略对象
    cerebro = bt.Cerebro()

    cerebro.adddata(data)

    # 回测设置
    startcash = 100000.0
    cerebro.broker.setcash(startcash)
    # 设置佣金为千分之一
    cerebro.broker.setcommission(commission=0.001)
    # 添加策略
    cerebro.addstrategy(MyStrategy, printlog=True)
    cerebro.run()
    # 获取回测结束后的总资金
    portvalue = cerebro.broker.getvalue()
    pnl = portvalue - startcash
    # 打印结果
    print(code.iloc[i] + f'结论总资金: {round(portvalue,2)}')
    print(code.iloc[i] + f'结论净收益: {round(pnl,2)}')

    # 图形化
    cerebro.plot()

代码有变更,单独把获取数据的代码,提取出来:

#从tushare读取股票数据信息,配置的内容在stock_alpha.csv中
import tushare as ts
import pandas as pd
import os

class Data:
    code = []
    __start_dts = []
    __end_dts = []

    def __init__(self):
        print('初始化')

    #股票的配置文件信息
    def get_stock_config(self):
        df = pd.read_csv('stock_alpha.csv')
        df.columns = ['ts_code', 'name', 'alpha', 'start_dt', 'end_dt']
        min_a = df.sort_values(by='alpha')
        min_a = min_a.iloc[:10, :]
        self.code = min_a['ts_code']  # 股票代码
        self.start_dts = min_a['start_dt']  # 股票代码起始时间
        self.end_dts = min_a['end_dt']  # 股票代码结束时间
        for i in range(len(self.code)):
            if os.stat(self.code.iloc[i] + '.csv').st_size == 0:
                data = Data.ts_get_daily_stock(self.code.iloc[i], self.start_dts.iloc[i], self.end_dts.iloc[i])  # 字段分别为股票代码、开始日期、结束日期
                data.to_csv(self.code.iloc[i] + '.csv')

    #读取股票信息
    def ts_get_daily_stock(code, start_dt, end_dt):
        pro = ts.pro_api('cbb257058b7cb228769b4949437c27c27e5132e882747dc80f01a5a5')
        start_dt = start_dt.replace("'", "", 3);
        end_dt = end_dt.replace("'", "", 3);
        print(code, start_dt, end_dt)
        data = pro.daily(ts_code=code, start_date=start_dt, end_date=end_dt)
        data['trade_date'] = pd.to_datetime(data['trade_date'])
        data['trade_date'] = pd.to_datetime(data['trade_date'])
        data = data.sort_values(by='trade_date')
        data.index = data['trade_date']
        data['openinterest'] = 0
        data['volume'] = data['vol']
        data = data[
            ['open', 'close', 'high', 'low', 'volume']
        ]
        return data

    def get_stock_data(self):
        return Data.get_stock_config(self)

    def get_code(self):
        return self.code

st = Data()
print(st.get_stock_data())
print(st.get_code())
 

代码中的stock_alpha.csv见之前章节中

猜你喜欢

转载自blog.csdn.net/q15399129775/article/details/124137380