今天咱们换一个通道指标:布林带——backtrader内置的指数,不需要自己实现,使用默认参数20,2。
# 参数定义
params = (
('period', 20),
('devfactor', 2)
)
def __init__(self):
self.bbands = bt.indicators.BollingerBands(period=self.params.period, devfactor=self.params.devfactor)
self.order = None
下面是策略逻辑——收盘价突破上轨时买入,突破下轨时平仓:
def next(self):
if self.order:
return
if self.data.close[0] > self.bbands.lines.top[0]:
if self.position.size == 0:
commission_info = self.broker.getcommissioninfo(self.data)
cash = self.broker.get_cash() - commission_info.getsize(1, self.data.close[0])
size = cash // self.data.close[0]
self.buy(size=size)
# print(f'BUY: {size} shares')
elif self.data.close[0] < self.bbands.lines.bot[0]:
if self.position.size > 0: size = self.position.size self.close(size=size) # print(f'SELL: {size} shares')
使用empyrical来计算风险、收益指标:
import empyrical as em max_drawdown = em.max_drawdown(returns) print('夏普比:%.2f'%em.sharpe_ratio(returns)) print('最大回撤:%.2f'%max_drawdown) print('年化收益:%.2f'%em.annual_return(returns))
代码所在位置:
empyrical的年化收益计算逻辑:
num_years = len(returns) / ann_factor # Pass array to ensure index -1 looks up successfully. ending_value = cum_returns_final(returns, starting_value=1) return ending_value ** (1 / num_years) - 1
而quantstats——区别在于这个years,它计算的是日期区间,比如20100101-20101231,那就是365天——这里应该取len(returns),它的years偏大,计算出来的年化收益率偏小。
years = (returns.index[-1] - returns.index[0]).days / periods res = abs(total + 1.0) ** (1.0 / years) - 1
投资,含投机,获利的本质逻辑,是建立概率优势。
结果还是不确定的,但重复博弈结果是有正收益的,这就是一个好的交易系统。
然后咱们再来聊,基本面价值投资(成长型投资),技术分析,量化投资,套利,高频交易等。
普通人做所谓价值投资我是不太看好的。
价值发现的时间,可能是数年甚至更久。这期间会发生什么事情,普通人是没有渠道获知的。
普通人根本判断不了什么是好公司,好的商业模式。
——替代方案是大类资产配置,选择低相关性的长期向上指数,动态再平衡即可。
然后就是偏短线的量化,价量为主,辅以其他一些数据——量化投机。
以控制回撤为前提,获取市场alpha。
从这个意义上看,期货就是一个挺好的选择。
吾日三省吾身
“没有实力做支撑的愤怒毫无意义”。
“你生气,说明你没有赢它的把握”。
不必愤怒,而是持续,抓紧一切机会提升自己,然后潇洒离开那些烂人烂事。
backtrader,去年我们花了不少时间,当然,我在backtrader的基础上做了很多封装。
backtrader的策略模板,结合“积木式”的策略模块(全系统代码下载)。
量化投资里的风险收益分析与可视化:empyrical和pyfolio实战,与backtrader整合
按quantlab5.x的规划,我们同样纳入backtrader,但不做太多的封装。
使用notebook来呈现它的策略开发过程。
首先同样是数据预处理和加载:
backtrader与bt、pybroker不同:
它是加载一个个独立的dataframe,然后需要加一个字段——openinterest,这是期货里的概念,暂时用不到,直接置为0即可。
@staticmethod
def get_backtrader_df(symbol: str):
df = CSVDataloader.get_df([symbol])
df.set_index('date', inplace=True)
df['openinterest'] = 0
df = df[['open', 'high', 'low', 'close', 'volume', 'openinterest']]
return df
同样实现昨天的策略:
class roc_trend(bt.Strategy):
# 参数定义
params = dict(
period=20, # 动量周期
)
def __init__(self):
self.roc = bt.indicators.ROC(self.data, period=self.p.period)
# self.roc = bt.talib.ROC(self.data, period=self.p.period)
def next(self): if not self.position: # not in the market if self.roc[-1] > 0.08: # if fast crosses slow to the upside self.order_target_percent(self.data, 0.99) # enter long # self.buy() # enter long elif self.roc[-1] < 0: # in the market & cross to the downside self.close() # close long position
客观讲,backtreader更接近传统像zipline和quantopian的逻辑:
支持order_target_percent(目标比例仓位)这样的api。
我们使用quantstats做结果分析:
代码在如下位置:
对比一下:
吾日三省吾身
人们习惯低估做成一件事情的难度,尤其在开发回测系统这件事上。
要做一个demo几行代码就够了,比如一个向量化的信号回测策略。
但,要写一个完善的,稳定的系统,那需要考虑的事情,细节就相当多了。
一开始,低估难度,追求可控性,选择自己从零开始写。
刚开始当然很爽,很有成就感。
但越后面,发现稳定性,扩展性,功能。
不如选择成熟的框架,即便一开始有学习成本,甚至有些看似不合理的地方。
第二个问题,在选择框架方面,同样过于追求可控性,代码可读性。忽视了,其实,稳定性,生态,扩张性才是最重要的。真正需要改造框架的机会不多!
第三个问题,在界面上,网站上,数据自动更新,缓存上,规则配置上花了不少时间,没有直奔主题。真正的点是策略,可实盘交易的策略,交易体系。
——大道至简!福尔摩斯只关心且精通与侦破有关的知识,对于地球围绕太阳转还是反过来,他完全不关心,甚至觉得,你就算知道了,也应该尽快忘掉它!。
精力有限,专注于最重要的事情上并取得突破。
在量化投资配置,还是“与交易为生”的投资能力上摇摆。——这是基础逻辑。
“具备职业投资的能力,但不需要依赖它谋生”——以出世的心态做入世的事情。
感悟
阅读三体有一个体会,当你在一段关系中,由于某种原因暂时无法离开,如同三体人在黑暗森林威慑下,应该报持何种态度对待地球人?
1、真心诚意地满足对方。
2、时刻准备让自己离的开它。
一段感情如是,职场纷争亦然。
几个心态:
“允许一切发生”的淡定与释然。
“凡事发生必有利于我”——生命中看似让你不爽,不愉快的人和事,必定是来“提醒你”,还有进步与提升的空间,或者,在某些方面需要最出改变。
“避免与猪在泥地里摔跤”。
你要做的是,有能力离开泥地。
社会运行规律是价值交换,让自己强大。
然后笑看风云。
你会发现身边的人都会越来越美好。
今天咱们换一个通道指标:布林带——backtrader内置的指数,不需要自己实现,使用默认参数20,2。
# 参数定义
params = (
('period', 20),
('devfactor', 2)
)
def __init__(self):
self.bbands = bt.indicators.BollingerBands(period=self.params.period, devfactor=self.params.devfactor)
self.order = None
下面是策略逻辑——收盘价突破上轨时买入,突破下轨时平仓:
def next(self):
if self.order:
return
if self.data.close[0] > self.bbands.lines.top[0]:
if self.position.size == 0:
commission_info = self.broker.getcommissioninfo(self.data)
cash = self.broker.get_cash() - commission_info.getsize(1, self.data.close[0])
size = cash // self.data.close[0]
self.buy(size=size)
# print(f'BUY: {size} shares')
elif self.data.close[0] < self.bbands.lines.bot[0]:
if self.position.size > 0: size = self.position.size self.close(size=size) # print(f'SELL: {size} shares')
使用empyrical来计算风险、收益指标:
import empyrical as em max_drawdown = em.max_drawdown(returns) print('夏普比:%.2f'%em.sharpe_ratio(returns)) print('最大回撤:%.2f'%max_drawdown) print('年化收益:%.2f'%em.annual_return(returns))
代码所在位置:
empyrical的年化收益计算逻辑:
num_years = len(returns) / ann_factor # Pass array to ensure index -1 looks up successfully. ending_value = cum_returns_final(returns, starting_value=1) return ending_value ** (1 / num_years) - 1
而quantstats——区别在于这个years,它计算的是日期区间,比如20100101-20101231,那就是365天——这里应该取len(returns),它的years偏大,计算出来的年化收益率偏小。
years = (returns.index[-1] - returns.index[0]).days / periods res = abs(total + 1.0) ** (1.0 / years) - 1
投资,含投机,获利的本质逻辑,是建立概率优势。
结果还是不确定的,但重复博弈结果是有正收益的,这就是一个好的交易系统。
然后咱们再来聊,基本面价值投资(成长型投资),技术分析,量化投资,套利,高频交易等。
普通人做所谓价值投资我是不太看好的。
价值发现的时间,可能是数年甚至更久。这期间会发生什么事情,普通人是没有渠道获知的。
普通人根本判断不了什么是好公司,好的商业模式。
——替代方案是大类资产配置,选择低相关性的长期向上指数,动态再平衡即可。
然后就是偏短线的量化,价量为主,辅以其他一些数据——量化投机。
以控制回撤为前提,获取市场alpha。
从这个意义上看,期货就是一个挺好的选择。
吾日三省吾身
“没有实力做支撑的愤怒毫无意义”。
“你生气,说明你没有赢它的把握”。
不必愤怒,而是持续,抓紧一切机会提升自己,然后潇洒离开那些烂人烂事。
按quantlab5.x的规划,我们同样纳入backtrader,但不做太多的封装。
使用notebook来呈现它的策略开发过程。
首先同样是数据预处理和加载:
backtrader与bt、pybroker不同:
它是加载一个个独立的dataframe,然后需要加一个字段——openinterest,这是期货里的概念,暂时用不到,直接置为0即可。
@staticmethod
def get_backtrader_df(symbol: str):
df = CSVDataloader.get_df([symbol])
df.set_index('date', inplace=True)
df['openinterest'] = 0
df = df[['open', 'high', 'low', 'close', 'volume', 'openinterest']]
return df
同样实现昨天的策略:
class roc_trend(bt.Strategy):
# 参数定义
params = dict(
period=20, # 动量周期
)
def __init__(self):
self.roc = bt.indicators.ROC(self.data, period=self.p.period)
# self.roc = bt.talib.ROC(self.data, period=self.p.period)
def next(self): if not self.position: # not in the market if self.roc[-1] > 0.08: # if fast crosses slow to the upside self.order_target_percent(self.data, 0.99) # enter long # self.buy() # enter long elif self.roc[-1] < 0: # in the market & cross to the downside self.close() # close long position
客观讲,backtreader更接近传统像zipline和quantopian的逻辑:
支持order_target_percent(目标比例仓位)这样的api。
我们使用quantstats做结果分析:
代码在如下位置:
对比一下:
吾日三省吾身
人们习惯低估做成一件事情的难度,尤其在开发回测系统这件事上。
要做一个demo几行代码就够了,比如一个向量化的信号回测策略。
但,要写一个完善的,稳定的系统,那需要考虑的事情,细节就相当多了。
一开始,低估难度,追求可控性,选择自己从零开始写。
刚开始当然很爽,很有成就感。
但越后面,发现稳定性,扩展性,功能。
不如选择成熟的框架,即便一开始有学习成本,甚至有些看似不合理的地方。
第二个问题,在选择框架方面,同样过于追求可控性,代码可读性。忽视了,其实,稳定性,生态,扩张性才是最重要的。真正需要改造框架的机会不多!
第三个问题,在界面上,网站上,数据自动更新,缓存上,规则配置上花了不少时间,没有直奔主题。真正的点是策略,可实盘交易的策略,交易体系。
——大道至简!福尔摩斯只关心且精通与侦破有关的知识,对于地球围绕太阳转还是反过来,他完全不关心,甚至觉得,你就算知道了,也应该尽快忘掉它!。
精力有限,专注于最重要的事情上并取得突破。
在量化投资配置,还是“与交易为生”的投资能力上摇摆。——这是基础逻辑。
“具备职业投资的能力,但不需要依赖它谋生”——以出世的心态做入世的事情。
感悟
阅读三体有一个体会,当你在一段关系中,由于某种原因暂时无法离开,如同三体人在黑暗森林威慑下,应该报持何种态度对待地球人?
1、真心诚意地满足对方。
2、时刻准备让自己离的开它。
一段感情如是,职场纷争亦然。
几个心态:
“允许一切发生”的淡定与释然。
“凡事发生必有利于我”——生命中看似让你不爽,不愉快的人和事,必定是来“提醒你”,还有进步与提升的空间,或者,在某些方面需要最出改变。
“避免与猪在泥地里摔跤”。
你要做的是,有能力离开泥地。
社会运行规律是价值交换,让自己强大。
然后笑看风云。
你会发现身边的人都会越来越美好。
发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/103214
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!