量化交易11-backtrader回测两只乌鸦、三只乌鸦K线形态图

量化交易11-backtrader回测两只乌鸦、三只乌鸦K线形态图,第1张

两只乌鸦的K线形态图定义: 

两只乌鸦形态只能预测顶部反转和熊市反转。


如图所示,第一天的白色蜡烛线支持了市场原有的上升趋势。


第二天,市场高开低走,但仍留下一个向上跳空缺口。


第三天,市场在第二天蜡烛线的实体部分内开盘,然后一路下滑,最后弥补了第二天的向上跳空缺口,突破到第一天的

以上定义来自于:两只乌鸦K线形态分析__赢家财富网

 三只乌鸦

三只乌鸦又称暴跌三杰,它是一种类似于红三兵的K线组合信号,可以认为是红三兵的翻转形式,他有哪些形态特点呢?应用中应注意哪些方面呢?下面将重点讲解三只乌鸦

形态要点:

1. 三只乌鸦是有三根连续下跌的阴线组成,阴线实体相当。


2. 第二根,三根K线高开低走,接近最低价收盘。


原文地址:什么是“三只乌鸦” - 知乎

笔者基于上述的理论,定义出策略:出现底部十字星全仓买入,出现两只乌鸦或者三只乌鸦全仓卖出

老规矩,线上代码:

#出现底部十字星全仓买入,出现两只乌鸦,三只乌鸦,全仓卖出
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

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

    def __init__(self):
        self.star = dict()
        self.crows = dict()
        self.twocrows = 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)
            print(opens)
            # 计算十字星数据,结果为-100底部十字星,结果为100顶部十字星,0非十字星
            res = talib.CDLDOJISTAR(opens, highs, lows, closes)
            # 三只乌鸦形态
            crowres = talib.CDL3BLACKCROWS(opens, highs, lows, closes)
            # 两只乌鸦形态
            twocrowres = talib.CDL2CROWS(opens, highs, lows, closes)
            # 数据放入self中
            print('十字星数据')
            self.star[data._id] = res
            print('二只乌鸦数据')
            self.twocrows[data._id] = twocrowres
            print('三只乌鸦数据')
            self.crows[data._id] = crowres

    def next(self):
        # 得到当前的账户价值
        total_value = self.broker.getcash()
        for data in self.datas:
            pos = self.getposition(data).size
            # 函数出现100就代表出现十字星形态,做买入
            if total_value > 0 and self.star[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('出现底部十字星,全仓买入,买入数量' + str(size) )


            if pos > 0 and self.crows[data._id][self.count] == 100 or self.crows[data._id][self.count] == -100:
                 # 全部卖出
                 # 跟踪订单避免重复
                 self.sell(data=data, size=pos)
                 print('出现三只乌鸦,卖出数量' + str(pos))

            if pos > 0 and self.twocrows[data._id][self.count] == 100 or self.twocrows[data._id][self.count] == -100:
                 # 全部卖出
                 # 跟踪订单避免重复
                 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}')


pro = ts.pro_api('cbb257058b7cb228769b4949437c27c27e5132e882747dc80f01a5a5')

def ts_get_daily_stock(code, start_dt, end_dt):
    start_dt = start_dt.replace("'", "", 3);
    end_dt = end_dt.replace("'", "", 3);
    # start_dt = '20190101'
    # end_dt=''
    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


# 读取选股的结果

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, :]

code = []
code = min_a['ts_code']  # 股票代码

start_dts = []
start_dts = min_a['start_dt']  # 股票代码起始时间

end_dts = []
end_dts = min_a['end_dt']  # 股票代码结束时间

for i in range(len(code)):
    data = ts_get_daily_stock(code.iloc[i], start_dts.iloc[i], end_dts.iloc[i])  # 字段分别为股票代码、开始日期、结束日期
    data.to_csv(code.iloc[i] + '.csv')

cerebro = bt.Cerebro()
for i in range(len(code)):  # 循环获取股票历史数据
    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(2008, 2, 20),
                               todate=datetime.datetime(2022, 4, 5)
                               )
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(f'总资金: {round(portvalue,2)}')
print(f'净收益: {round(pnl,2)}')

cerebro.plot()

执行结果:


总资金: 57720.8
净收益: -42279.2

笔者依旧用上一章节的数据源

本章节引入了两个新的函数:

talib.CDL2CROWS(opens, highs, lows, closes)  # 两只乌鸦形态

 talib.CDL3BLACKCROWS(opens, highs, lows, closes)  # 三只乌鸦形态

结果还是100或者-100

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/570051.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)

保存