在量化投资配置,还是“与交易为生”的投资能力上摇摆。

今天咱们换一个通道指标:布林带——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
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!

(0)
股市刺客的头像股市刺客
上一篇 2024 年 7 月 26 日
下一篇 2024 年 7 月 26 日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注