LESSON 7 Portfolio Management

上一章中我们把 data pipeline 包含进了我们的策略中,现在就是要定义我们如何利用生成的数据来重新平衡重新布局我们的资产组合。我们的目标是基于资产的情绪分数,找到一个利润最高的目标资产组合结构,同时还要维持一个有一些约束限制的结构(出于考虑风险?)。这就是组合优化问题。

Quantopian 所带的 Optimize API 让我们可以很方便的将我们 pipeline 的输出结果转化成一个对象以及一些约束,我们可以使用 order_optimal_portfolio 来将我们现在的资产组合过渡到满足我们目标的目标资产组合组成。

第一步是定义对象。我们会用到函数 MaximizeAlpha,这个函数会按照各自的情绪分数把资源成比例的分配给各个资产。

# Import Optimize API module
import quantopian.optimize as optdef rebalance(context, data):# Create MaximizeAlpha objective using# sentiment_score data from pipeline outputobjective = opt.MaximizeAlpha(context.output.sentiment_score)

接下来我们需要指定一个关于约束的列表内容,正是我们希望我们的资产组合所能满足的,就是在初始化 initial 中定义一些门槛值并把它们储存成 context 的变量:

# Constraint parameters
context.max_leverage = 1.0
context.max_pos_size = 0.015
context.max_turnover = 0.95

现在要在 rebalance 中指出这些约束,通过我们上面所定义的门槛。

# Import Optimize API module
import quantopian.optimize as optdef rebalance(context, data):# Create MaximizeAlpha objective using # sentiment_score data from pipeline outputobjective = opt.MaximizeAlpha(context.output.sentiment_score)# Create position size constraintconstrain_pos_size = opt.PositionConcentration.with_equal_bounds(-context.max_pos_size,context.max_pos_size)# Ensure long and short books# are roughly the same sizedollar_neutral = opt.DollarNeutral()# Constrain target portfolio's leveragemax_leverage = opt.MaxGrossExposure(context.max_leverage)# Constrain portfolio turnovermax_turnover = opt.MaxTurnover(context.max_turnover)

可以看到我们在定义了对象 objective 之后,又定义了三个约束。第一个是 constrain_pos_size,约定的内容是持有的比重,也就是单只资产我们所能持有的占我们所有资产里面的比重,我们例子中给出的数值是0.015,也就是说,不管我们是做多还是做空,它都不应该占我们所持有的净资产的0.015以上,毕竟单只资产持有比重太高就意味着风险更高。第二个是 max_leverage,杠杆率,我们限制最大的杠杆率为1,也就是不允许使用杠杆工具来冒更大的风险。第三个是 turnover 周转率,0.95的数值也是在限制我们不能一次性将所有的资产做出改变,也是出了稳定的目的。

最后把我们对象 objective 和约束传递给 order_optimal_portfolio 来计算得到一个目标组成,并给出需要执行的命令来调整我们的资产组合,总之就是这个函数就可以完成我们的要的结果。把这个放在 rebalance 中,重新理一下思路,就是我们在每周的第一个交易日就会执行 rebalance ,重新布局我们的资产,而我们所做的期望,就是通过情绪分数来判断的;同时不是简单的多多挑选情绪分数高的资产,那样子的话就会变成只持有最高的那只资产,这也是我们为什么要给出那几个约束,通过持有率的限制,禁止借入杠杆,周转率也不能高到极值100%,相当于线性优化问题,得到的结果就是我们所能达到的总的情绪分数最高的一个组合。

# Import Algorithm API functions
from quantopian.algorithm import order_optimal_portfolio# Import Optimize API module
import quantopian.optimize as optdef rebalance(context, data):# Create MaximizeAlpha objective using # sentiment_score data from pipeline outputobjective = opt.MaximizeAlpha(context.output.sentiment_score)# Create position size constraintconstrain_pos_size = opt.PositionConcentration.with_equal_bounds(-context.max_pos_size,context.max_pos_size)# Ensure long and short books# are roughly the same sizedollar_neutral = opt.DollarNeutral()# Constrain target portfolio's leveragemax_leverage = opt.MaxGrossExposure(context.max_leverage)# Constrain portfolio turnovermax_turnover = opt.MaxTurnover(context.max_turnover)# Rebalance portfolio using objective# and list of constraintsorder_optimal_portfolio(objective=objective,constraints=[max_leverage,dollar_neutral,constrain_pos_size,max_turnover,])

order_optimal_portfolio 需要传入的几个参数都在上面给好了,也是用 opt,也就是 optimize 这个模块来完成的。

Risk Management 风险管理

       除了给我们的目标资产组合设置约束,我们还要限制面对各种风险因子的敞口,因为这些会深远地影响我们策略。例如,因为 stockwits 中情绪指标的瞬变性质 transient nature,以及我们依赖于情绪指标的意向也会波动,我们的策略也就是暴露在短期的反复无常的风险中。

我们将会使用 Quantopian 中的风险模型来管理我们面对各种风险时的敞口,这个模型可以计算16种不同的风险因子对应的敞口。如果要在我们的算法调用这些数据,就用 risk_loading_pipeline 函数,将会返回一个 pipeline 可以产生一个输出列表,包含了 Risk Model 里面的各个风险因子对应的敞口的数据。

跟我们前面做的一样,我们也需要将这个 data pipeline 连接进我们的策略中,并且给它命名。之后我们就可以在 before_trading_start 中获取我们要的输出并且存储在 context 中:

# Import Algorithm API functions
from quantopian.algorithm import (attach_pipeline,pipeline_output,
)# Import Risk API method
from quantopian.pipeline.experimental import risk_loading_pipelinedef initialize(context):# Constraint parameterscontext.max_leverage = 1.0context.max_pos_size = 0.015context.max_turnover = 0.95# Attach data pipelinesattach_pipeline(make_pipeline(),'data_pipe')attach_pipeline(risk_loading_pipeline(),'risk_pipe')# Schedule rebalance functionschedule_function(rebalance,date_rules.week_start(),time_rules.market_open(),)def before_trading_start(context, data):# Get pipeline outputs and# store them in contextcontext.output = pipeline_output('data_pipe')context.risk_factor_betas = pipeline_output('risk_pipe')

接下来就是添加一个 RiskModelExposure 来约束我们的资产组合的优化逻辑。这个约束用到了从 Risk Model 中生成的数据,并给所有的各项风险敞口设置上限。这下面的代码中,传递的第一个对象是 context.risk_factor_betas,就是我们在上面获取的关于风险因子的敞口的数据 pipeline 的输出,正是一个 DataFrame 格式的内容;然后 version,我的理解应该就是 optimize 中有着关于风险敞口的默认上限可以使用。

# Constrain target portfolio's risk exposure
# By default, max sector exposure is set at
# 0.2, and max style exposure is set at 0.4
factor_risk_constraints = opt.experimental.RiskModelExposure(context.risk_factor_betas,version=opt.Newest
)

最终,接下来的算法围绕我们的策略和资产组合构建逻辑,已经准备好接受回测了。拷贝,点击相关的按钮就可以运行完整的回测了。以下就是完整的代码,重新整理一下思路:可以大致分成两个重点部分,初始化和交易前的操作。我们在前面 import 了一些工具来帮助我们获取历史数据并且进行一定的加工,例如 Pipeline,stockwits.bull_bear_minus以及均线工具SimpleMovingAverage;在选定了以三日情绪指标均值作为参考之后我们就要开始构建资产组合,但出了风险的考虑,我们不能直接就全部份额持有最高的那只,所以一方面我们在 context 中补充了一些约束 constraints,然后又 import 了风险敞口的数据 pipeline,来供我们在满足简单的持有份额周转率杠杆率以外,还可以再考虑上各个风险因子敞口也不能太大,这一系列内容放置在了 rabalance 中,因为我们的策略可以看成一个周策略,每周调整一次,而 rebalancec 设定在 schedule_function 中,设定的执行时间就是每周的第一个交易日开始之时。里面有一些语句的意思不是特别明朗,不过大致也还可以猜得出前后呼应的意思,多联系应该就会熟悉了。

# Import Algorithm API functions
from quantopian.algorithm import (attach_pipeline,pipeline_output,order_optimal_portfolio,
)# Import Optimize API module
import quantopian.optimize as opt# Pipeline imports
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.psychsignal import stocktwits
from quantopian.pipeline.factors import SimpleMovingAverage# Import built-in universe and Risk API method
from quantopian.pipeline.filters import QTradableStocksUS
from quantopian.pipeline.experimental import risk_loading_pipelinedef initialize(context):# Constraint parameterscontext.max_leverage = 1.0context.max_pos_size = 0.015context.max_turnover = 0.95# Attach data pipelinesattach_pipeline(make_pipeline(),'data_pipe')attach_pipeline(risk_loading_pipeline(),'risk_pipe')# Schedule rebalance functionschedule_function(rebalance,date_rules.week_start(),time_rules.market_open(),)def before_trading_start(context, data):# Get pipeline outputs and# store them in contextcontext.output = pipeline_output('data_pipe')context.risk_factor_betas = pipeline_output('risk_pipe')# Pipeline definition
def make_pipeline():sentiment_score = SimpleMovingAverage(inputs=[stocktwits.bull_minus_bear],window_length=3,mask=QTradableStocksUS())return Pipeline(columns={'sentiment_score': sentiment_score,},screen=sentiment_score.notnull())def rebalance(context, data):# Create MaximizeAlpha objective using# sentiment_score data from pipeline outputobjective = opt.MaximizeAlpha(context.output.sentiment_score)# Create position size constraintconstrain_pos_size = opt.PositionConcentration.with_equal_bounds(-context.max_pos_size,context.max_pos_size)# Ensure long and short books# are roughly the same sizedollar_neutral = opt.DollarNeutral()# Constrain target portfolio's leveragemax_leverage = opt.MaxGrossExposure(context.max_leverage)# Constrain portfolio turnovermax_turnover = opt.MaxTurnover(context.max_turnover)# Constrain target portfolio's risk exposure# By default, max sector exposure is set at# 0.2, and max style exposure is set at 0.4factor_risk_constraints = opt.experimental.RiskModelExposure(context.risk_factor_betas,version=opt.Newest)# Rebalance portfolio using objective# and list of constraintsorder_optimal_portfolio(objective=objective,constraints=[max_leverage,dollar_neutral,constrain_pos_size,max_turnover,factor_risk_constraints,])

Quantopian自学笔记04相关推荐

  1. 网络安全自学笔记04 - 路由器技术

    路由器技术概念 一.路由器工作在网络层 1.网络层功能 定义了基于IP协议的逻辑地址 连接不同的媒介类型 选择数据通过网络的最佳路径 网络层传输的数据单元是IP数据包 2.网络层的IP数据报 版本:I ...

  2. Quantopian自学笔记01

    听了一个前辈的指导,说学习量化可以在 quantopian 这个平台上学习,虽然国内也是有相关的,但是还是想训练自己的英文能力,于是还是决定看外国的.然后百度了一下相关的教程很少,不知为啥用的人不多, ...

  3. Quantopian自学笔记03

    LESSON 5 Algorithm API 在上一章中我们学习了如何创造一个 data pipeline 来为我们的策略挑选投资对象,以及计算这些对象,各种资产的情绪分数.接下来的课程将会在 Qua ...

  4. Quantopian自学笔记02

    LESSON 4 : Strategy Analysis. 在学会了如果导入数据并 manipulate 操纵数据后,我们就要试着为我们的 long-short equity strategy 构建一 ...

  5. Java自学笔记总结04

    Java自学笔记04 一.Lambda表达式 1.1 函数式编程思想概述 1.2 体验Lambda表达式 1.3 Lambda表达式的标准格式 1.4 Lambda表达式的使用 1.5 Lambda表 ...

  6. Linux自学笔记 | 10 常用命令 - 压缩解压类

    Linux自学笔记 | 10 常用命令 - 压缩解压类 Linux自学笔记 | 01 文件系统和目录结构 Linux自学笔记 | 02 VIM编辑器的安装与使用 Linux自学笔记 | 03 Linu ...

  7. Java自学笔记——Java面向对象——04.抽象类、接口、内部类

    Java 面向对象各节 Java自学笔记--Java面向对象--01.回顾方法 Java自学笔记--Java面向对象--02.构造器.类和对象 Java自学笔记--Java面向对象--03.封装.继承 ...

  8. DWR自学笔记(1)HelloWorld

    DWR自学笔记(1)HelloWorld 由于新公司的项目是基于DWR的,所以准备自学DWR,参考资料方佳玮的<DWR中文文档v0.9>,百度文献等.学习主要基于DWR3.0,很多方法之前 ...

  9. FPGA自学笔记--串口通信发送多字节数据(verilog版)

    1.需求分析 关于uart协议实现这部分大家可以参考我上一篇的博客.<FPGA自学笔记--串口通信实现(vivado&verilog版)>.在上一篇博客中,主要实现了将单字节的数据 ...

最新文章

  1. JS中confirm,alert,prompt函数
  2. go文件服务器mimetype,网络:什么是 MIME TYPE?
  3. 理解IDS的主动响应机制
  4. java web定义数组_Java基础之数组--数组常用操作
  5. codeforces 977A-C语言解题报告
  6. Could not connect to SMTP host: smtp.qq.com, port: 465, response: -1 clojure邮箱发送
  7. 在iOS项目中引入MVVM
  8. Nginx与tomcat集成
  9. Spring框架学习---Spring Framework上篇
  10. jmeter404_jmeter压力测试报告
  11. pwn题shellcode收集
  12. 默纳克主板c2图纸+底座图纸。维修利器
  13. endnote修改正文中参考文献标注_如何在Endnote中修改参考文献格式
  14. J2EE:赛迪网J2EE视频总结
  15. 数值分析(12):Rung-Kutta法及单步法的收敛性和稳定性分析
  16. 综述 | 语义分割经典网络及轻量化模型盘点
  17. 在AS模拟器上访问本地电脑tomcat部署的资源报错java.net.ConnectException: Failed to connect to localhost/127.0.0.1:8081
  18. 什么是云原生数据库?
  19. 【每日早报】2019/09/18
  20. K折交叉验证K-CV与StratifiedKFold

热门文章

  1. 机器学习: 贝叶斯算法的应用
  2. VIBE运动检测算法实现(二)
  3. 论文阅读之《Quasi-Unsupervised Color Constancy 》
  4. 艾伦·麦席森·图灵的传奇人生
  5. 时序数据到底是什么,为什么我们需要时序数据库?
  6. 国会大厦骚乱,与一家极不可靠的面部识别公司……
  7. 的统一,展现出更深远的思想,使读者领会更深的道理。 语言优美:所谓优美,就是指散文的语言清新明丽(也美丽
  8. ABP VNext学习日记14
  9. 7-1 验证哥德巴赫猜想
  10. 全面梳理关系型数据库和NoSQL的使用情景