In [1]:
import xalpha as xa
import pandas as pd

xa.set_display("notebook")
holdings.py is found and loaded within xalpha dir

我们探索下 xalpha 的交易模拟功能,以回测一系列主动基虚拟交易为例

基金池

绝对收益

  • 广发趋势优选 000215
  • 安信稳健增值 001316
  • 海富通阿尔法 519062

债基混合

  • 鹏华丰禄 003547 0 股票仓位
  • 易方达丰和 002969 15 股票仓位
  • 易方达裕翔 002351 25 股票仓位
  • 易方达安心回馈 001182 40 股票仓位

股基混合

  • 519697 交银优势行业
  • 519732 交银双息
  • 163415 兴权商业模式优选

进攻纯股基

  • 001178 前海再融资
  • 001938 中欧时代先锋
  • 000751 嘉实新兴产业
In [2]:
fundlist = [
    "000215",
    "001316",
    "519062",
    "003547",
    "002969",
    "002351",
    "001182",
    "519697",
    "519732",
    "163415",
    "001178",
    "001938",
    "000751",
]
In [3]:
infolist = [xa.fundinfo(code) for code in fundlist]
In [4]:
startdate = [f.price.iloc[0].date for f in infolist]
startdate
# 看一下这些基金是从什么时候创建的
Out[4]:
[Timestamp('2013-09-11 00:00:00'),
 Timestamp('2015-05-25 00:00:00'),
 Timestamp('2014-11-20 00:00:00'),
 Timestamp('2016-10-27 00:00:00'),
 Timestamp('2016-11-23 00:00:00'),
 Timestamp('2016-01-22 00:00:00'),
 Timestamp('2015-05-29 00:00:00'),
 Timestamp('2009-01-21 00:00:00'),
 Timestamp('2013-09-04 00:00:00'),
 Timestamp('2012-12-18 00:00:00'),
 Timestamp('2015-05-18 00:00:00'),
 Timestamp('2015-11-03 00:00:00'),
 Timestamp('2014-09-17 00:00:00')]

那么我们从20170101开始一揽子买入, 先写个账单

In [5]:
df = pd.DataFrame([[1000 for _ in fundlist]], columns=fundlist)
In [6]:
df["date"] = pd.datetime(2017, 1, 1)
df
/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ipykernel_launcher.py:1: FutureWarning: The pandas.datetime class is deprecated and will be removed from pandas in a future version. Import from datetime instead.
  """Entry point for launching an IPython kernel.
Out[6]:
In [7]:
sys = xa.mul(status=df)  # 获取模拟交易组合
In [8]:
sys.summary()
# 可以看出至今收益贡献最大的是交银双息和嘉实新兴
Out[8]:

你还可以查看任意天数的投资概览

In [9]:
sys.summary("2018-11-01")  # 熊市时刻,还是保持了相当的正收益
Out[9]:
In [10]:
# 计算一下截止今天的投资内部收益率
sys.xirrrate()  # 年化18%
Out[10]:
0.1785344940303062
In [11]:
# 计算一下 2018年的内部收益率
sys.xirrrate(date="2018-12-31", startdate="2018-01-01")
Out[11]:
-0.041628407100152635
In [12]:
sys.v_positions()
Out[12]:
In [13]:
# 按大类分布的扇形图
sys.v_category_positions()
Out[13]:
In [14]:
## 底层股票持仓透视, 你其实可以通过这种方式来跟踪机构的股票池和抱团情况
sys.get_stock_holdings()
Out[14]:
In [15]:
sys.get_stock_holdings(date="2019-12-01", threhold=50)
# 可以调整透视的时间和股票阈值
# 可以看到2020以来格力平安等遭到组合的减持
Out[15]:
In [16]:
# 我们可以查看整个组合最底层具体的股票,债券,现金的仓位分布情况
sys.get_portfolio()
# 可以看到基本上股债平衡
Out[16]:
{'bond': 8446.478429, 'cash': 1416.611418, 'stock': 10343.429751}
In [15]:
# 可以查看单只的买入卖出情况
sys.fundtradeobj[1].v_tradecost()
# 图上的蓝点对应一次现金分红
# 关于如何设定账单,以控制每次分红选择分红再投入还是现金分红,请参考文档
# 具体针对该例子,如何实现分红再投入的比较,请参考该 issue: https://github.com/refraction-ray/xalpha/issues/34
Out[15]:

做成封闭现金流系统则有更多可能性

In [11]:
sysfix = xa.mulfix(status=df, totmoney=14000)
# 做成有14000初始基金的封闭组合
In [12]:
sysfix.bcmkset(xa.indexinfo("SH000300"), start="2017-01-01")  # 设定比较基准为沪深300
# 这一过程会生成计算封闭组合每日净值情况,耗时较长,请耐心等待
In [13]:
sysfix.v_netvalue()
# 吊打300,毕竟马后炮的最强基金
Out[13]:
In [24]:
sysfix.summary()
# 我们看到此时出现了货币基金选项,这是因为默认现金分红会智能处理帮你买入货币基金
Out[24]:

我们可以进一步进行指标分析

In [25]:
sysfix.beta(), sysfix.alpha(), sysfix.sharpe()
Out[25]:
(0.508105417009912, 0.040867579213678853, 0.279802542882795)
In [9]:
sysfix.total_annualized_returns(), sysfix.algorithm_volatility()
Out[9]:
(0.0684, 0.11160584774628288)
In [29]:
sysfix.max_drawdown()
# 最大回撤8%发生在今年,竟然不是18年,是不是说明马后炮组合的优势再减弱?
Out[29]:
(Timestamp('2020-02-25 00:00:00'),
 Timestamp('2020-03-23 00:00:00'),
 -0.08257630349535526)
In [ ]: