# -*- coding: utf-8 -*-
import datetime as dt
import numpy as np
import pandas as pd
import QuantStudio.api as QS
if __name__=='__main__':
HDB = QS.FactorDB.HDF5DB(sys_args={"主目录":"C:\\HDF5Data"})
HDB.connect()
RDB = QS.RiskDB.HDF5FRDB(sys_args={"主目录":"C:\\RiskData"})
RDB.connect()
# 创建投资组合构造器
import matlab.engine
MatlabEng = matlab.engine.start_matlab(option="-desktop")# 启动一个新的 MATLAB
#MatlabEng = matlab.engine.connect_matlab(name="MATLAB_147264")# 链接到一个已经启动的 MATLAB
PC = QS.PortfolioConstructor.MatlabPC(matlab_eng=MatlabEng)
#PC = QS.PortfolioConstructor.CVXPC(sys_args={"优化选项":{"solver":"MOSEK"}})
# 设置相关数据
TargetDT = dt.datetime(2017, 12, 29)
FT = HDB.getTable("ElementaryFactor")
TargetIDs = FT.getID()[:500]
PC["目标ID"] = TargetIDs
PC["预期收益"] = FT.readData(factor_names=["月收益率"], ids=TargetIDs, dts=[TargetDT]).iloc[0, 0, :]
RT = RDB.getTable("BarraRiskData")
#PC["协方差矩阵"] = RT.readCov(dts=[TargetDT], ids=TargetIDs)[TargetDT]
PC["因子协方差阵"] = RT.readFactorCov(dts=[TargetDT]).loc[TargetDT]
PC["风险因子"] = RT.readFactorData(dts=[TargetDT], ids=
TargetIDs).loc[:, TargetDT, :]
PC["特异性风险"] = RT.readSpecificRisk(dts=[TargetDT], ids=TargetIDs).loc[TargetDT, :]
PC["成交金额"] = FT.readData(factor_names=["成交金额"], ids=TargetIDs, dts=[TargetDT]).iloc[0, 0, :]
PC["初始投资组合"] = pd.Series(0.0,index=TargetIDs)
PC["总财富"] = 1000000000
# 设置优化目标
Objective = QS.PortfolioConstructor.MeanVarianceObjective(pc=PC)
Objective["收益项系数"] = 0.0
Objective["风险厌恶系数"] = 1.0
PC["优化目标"] = Objective
# 设置约束条件
# 预算约束
iConstraint = QS.PortfolioConstructor.BudgetConstraint(pc=PC)
iConstraint["限制上限"] = 1.0
iConstraint["限制下限"] = 1.0
PC["约束条件"].append(iConstraint)
# 权重约束
iConstraint = QS.PortfolioConstructor.WeightConstraint(pc=PC)
iConstraint["限制上限"] = 1.0
iConstraint["限制下限"] = 0.0
PC["约束条件"].append(iConstraint)
# 求解优化问题
Portfolio, ResultInfo = PC.solve()
print(Portfolio)
print(ResultInfo)
HDB.disconnect()
RDB.disconnect()
脚本首先创建了因子库 HDB, 风险库 RDB 用于提供相关数据, 接着实例化一个投资组合构造器对象 PC, 这个构造器依赖于 MATLAB 的优化器, 所以这两句是在创建一个 MATLAB engine 对象:
import matlab.engine
MatlabEng = matlab.engine.start_matlab(option="-desktop")# 启动一个新的 MATLAB
#MatlabEng = matlab.engine.connect_matlab(name="MATLAB_147264")# 链接到一个已经启动的 MATLAB
如果 MATLAB 已经启动, 可以向上面注释掉的那行代码一样传入 MATLAB engine 的名字调用 connect_matlab 方法连接到打开的 MATLAB, 没有启动的话可以用 matlab.engine.start_matlab 来启动一个新的 MATLAB, 关于 MATLAB engine 的相关信息参照 MATLAB 帮助文档. 此外, 该构造器调用的是 MATLAB 里的 yalmip 工具箱, 关于此工具箱的安装, 参照 “连接(TODO)”, 用户可以使用 yalmip 调用自己可获得的性能更好的优化器, 比如 CPLEX, MOSEK 等. 这里假设 MATLAB 以及 yalmip 已经设置好了.
接下来是设置 PC 的相关参数和数据, 比如预期收益, 风险矩阵等等. 这里预期收益暂时使用月收益率数据代表(最小方差模型不需要预期收益, 也可以不用设置, 这里只是为了演示参数设置), 风险数据从风险数据库中读取.
之后便是定义优化问题, 设置优化目标和约束条件, 优化目标通过 PortfolioConstructor 子模块下提供的各种优化目标类实例化得到, 这里使用 MeanVarianceObjective 均值方差目标, 约束条件也是通过 PortfolioConstructor 子模块下提供的各种约束条件类实例化得到, 这里使用了两种约束条件: BudgetConstraint(预算约束), WeightConstraint(权重约束), 优化目标和约束条件对象的初始化需要提供所属的投资组合构建器作为参数.
最后调用投资组合构建器的 solve 方法求解优化问题得到投资组合, solve 返回值有两个: Portfolio 是投资组合, ResultInfo 是优化问题求解的相关信息, 数据类型为字典, 如果求解成功, Portfolio 为 Series 类型, index 是 ID 列表, 值为对应权重, ResultInfo 中的 key “Status” 对应的 value 为 1; 如果求解失败, Portfolio 为 None, ResultInfo 中的 key “Status” 对应的 value 为非 1 的值.
8.3. API 参考
8.3.1. 约束条件
class BasePC.Constraint(pc, sys_args={}, config_file=None, **kwargs)
约束条件基类, 所有的约束条件均继承自此类, 不能实例化对象
class BasePC.BudgetConstraint(pc, sys_args={}, config_file=None, **kwargs)
预算约束条件, 继承自 BasePC.Constraint,
Args
限制上限: 预算约束上限, float, 默认值 1.0, 如果为 inf, 表示无上限, 如果限制上限等于限制下限, 则为预算等式约束
限制下限: 预算约束下限, float, 默认值 1.0, 如果为 -inf, 表示无下限, 如果限制上限等于限制下限, 则为预算等式约束
相对基准: 是否减去基准组合的权重, bool, 默认值 False
舍弃优先级: 在优化问题求解失败时调整约束条件的舍弃优先级, float, 默认值 -1, QuantStudio 会在优化问题求解失败时按照优先级从大到小依次舍弃某些约束条件, 直到问题可解, <=-1 表示不可舍弃.
class BasePC.WeightConstraint(pc, sys_args={}, config_file=None, **kwargs)
权重约束条件, 继承自 BasePC.Constraint,
Args
目标ID: 施加约束的 ID 过滤条件, str, 默认值 “”, 空字符串表示对所有的 ID 都施加约束
限制上限: 权重约束上限, float 或者 str, 默认值 1.0, 如果类型为 float 并且值为 inf, 表示无上限, 如果限制上限等于限制下限, 则为固定权重约束; 如果类型为 str, 则该字符串必须为因子名称, 表示以给定的因子值作为限制上限
限制下限: 权重约束下限, float 或者 str, 默认值 0.0, 如果类型为 float 并且值为 -inf, 表示无下限, 如果限制上限等于限制下限, 则为固定权重约束; 如果类型为 str, 则该字符串必须为因子名称, 表示以给定的因子值作为限制下限
相对基准: 是否减去基准组合的权重, bool, 默认值 False
舍弃优先级: 在优化问题求解失败时调整约束条件的舍弃优先级, float, 默认值 -1, QuantStudio 会在优化问题求解失败时按照优先级从大到小依次舍弃某些约束条件, 直到问题可解, <=-1 表示不可舍弃.
class BasePC.FactorExposeConstraint(pc, sys_args={}, config_file=None, **kwargs)
因子暴露约束条件, 继承自 BasePC.Constraint,
Args
因子类型: 因子的数据类型, str, 可选: “数值型”, “类别型”, 默认值 “数值型”, 类别型因子会转换成 0-1 编码格式
因子名称: 需要施加约束的因子名列表, list(str)
限制上限: 因子暴露约束上限, float, 默认值 0.0, 如果为 inf, 表示无上限, 如果限制上限等于限制下限, 则为固定暴露约束
限制下限: 因子暴露约束下限, float, 默认值 0.0, 如果为 -inf, 表示无下限, 如果限制上限等于限制下限, 则为固定暴露约束
相对基准: 是否减去基准组合的权重, bool, 默认值 False
舍弃优先级: 在优化问题求解失败时调整约束条件的舍弃优先级, float, 默认值 -1, QuantStudio 会在优化问题求解失败时按照优先级从大到小依次舍弃某些约束条件, 直到问题可解, <=-1 表示不可舍弃.
class BasePC.ExpectedReturnConstraint(pc, sys_args={}, config_file=None, **kwargs)
预期收益约束条件, 继承自 BasePC.Constraint,
Args
限制下限: 预期收益约束下限, float, >0, 默认值 0.0
相对基准: 是否减去基准组合的权重, bool, 默认值 False
舍弃优先级: 在优化问题求解失败时调整约束条件的舍弃优先级, float, 默认值 -1, QuantStudio 会在优化问题求解失败时按照优先级从大到小依次舍弃某些约束条件, 直到问题可解, <=-1 表示不可舍弃.
class BasePC.VolatilityConstraint(pc, sys_args={}, config_file=None, **kwargs)
波动率约束条件, 继承自 BasePC.Constraint,
Args
限制上限: 波动率约束上限, float, >0, 默认值 0.06
相对基准: 是否减去基准组合的权重, bool, 默认值 False
舍弃优先级: 在优化问题求解失败时调整约束条件的舍弃优先级, float, 默认值 -1, QuantStudio 会在优化问题求解失败时按照优先级从大到小依次舍弃某些约束条件, 直到问题可解, <=-1 表示不可舍弃.
class BasePC.TurnoverConstraint(pc, sys_args={}, config_file=None, **kwargs)
换手约束条件, 继承自 BasePC.Constraint,
Args
限制类型: str, 可选: “总换手限制”, “总买入限制”, “总卖出限制”, “买卖限制”, “买入限制”, “卖出限制”, 默认值 “总换手限制”
成交额倍数: 限制成交额占市场成交额的比例乘数, float, 默认值 1.0
限制上限: 换手约束上限, float, >0, 默认值 0.7
舍弃优先级: 在优化问题求解失败时调整约束条件的舍弃优先级, float, 默认值 -1, QuantStudio 会在优化问题求解失败时按照优先级从大到小依次舍弃某些约束条件, 直到问题可解, <=-1 表示不可舍弃.
class BasePC.NonZeroNumConstraint(pc, sys_args={}, config_file=None, **kwargs)
非零数目约束条件, 继承自 BasePC.Constraint,
Args
限制上限: 非零数目约束上限, float, >0, 默认值 150
相对基准: 是否减去基准组合的权重, bool, 默认值 False
舍弃优先级: 在优化问题求解失败时调整约束条件的舍弃优先级, float, 默认值 -1, QuantStudio 会在优化问题求解失败时按照优先级从大到小依次舍弃某些约束条件, 直到问题可解, <=-1 表示不可舍弃.
class BasePC.MeanVarianceObjective(pc, sys_args={}, config_file=None, **kwargs)
均值方差目标, 继承自 BasePC.OptimizationObjective
Args
相对基准: 是否减去基准组合的权重, bool, 默认值 False
收益项系数: 收益项前面的系数, float, 默认值 0.0
风险厌恶系数: float, 默认值 1.0
换手惩罚系数: 换手惩罚项前面的系数, float, 默认值 0.0
买入惩罚系数: 买入惩罚项前面的系数, float, 默认值 0.0
卖出惩罚系数: 卖出惩罚项前面的系数, float, 默认值 0.0
class BasePC.MaxSharpeObjective(pc, sys_args={}, config_file=None, **kwargs)
最大夏普率目标, 继承自 BasePC.OptimizationObjective
Args
相对基准: 是否减去基准组合的权重, bool, 默认值 False
class BasePC.RiskBudgetObjective(pc, sys_args={}, config_file=None, **kwargs)
风险预算目标, 继承自 BasePC.OptimizationObjective
Args
预算因子: 提供预算数据的因子名, str, 默认值 “等权”
class BasePC.MaxDiversificationObjective(pc, sys_args={}, config_file=None, **kwargs)
最大分散化目标, 继承自 BasePC.OptimizationObjective
预期收益: Series(index=[ID]) 或 None(默认值), None 表示不需要该数据
协方差矩阵: DataFrame(index=[ID], columns=[ID]) 或 None(默认值), None 表示不需要该数据
因子协方差阵: DataFrame(index=[因子名], columns=[因子名]) 或 None(默认值), None 表示不需要该数据
风险因子: DataFrame(index=[ID], columns=[因子名]) 或 None(默认值), None 表示不需要该数据
特异性风险: Series(index=[ID]) 或 None(默认值), None 表示不需要该数据
初始投资组合: Series(权重, index=[ID]) 或 None(默认值), None 表示不需要该数据
基准投资组合: Series(权重, index=[ID]) 或 None(默认值), None 表示不需要该数据
成交金额: Series(index=[ID]) 或 None(默认值), None 表示不需要该数据
因子暴露: DataFrame(index=[ID], columns=[因子名]) 或 None(默认值), None 表示不需要该数据
总财富: float, >=0
目标ID: 最终形成的投资组合所属的 ID 序列, list(str)
优化目标: 优化目标对象, OptimObjective
约束条件: 约束条件对象列表, list(Constraint)
优化选项: 优化器的特定参数, dict, 默认值空字典
class MatlabPC.MatlabPC(matlab_eng=None, lock=None, sys_args={}, config_file=None, **kwargs)
基于 MATLAB 的投资组合构造器, 继承自 BasePC.PortfolioConstructor, 没有新的属性和方法
matlab_eng (matlab.engine.MatlabEngine) – MATLAB Engine for Python 对象
lock (Lock) – 如果 matlab_eng 是共享对象, 需要提供资源锁防止冲突, None 表示 matlab_eng 是该构造器专用的
sys_args (dict) – 对象参数
config_file (str) – 对象配置文件地址