Python策略范例3-了解米筐撮合机制

通过期货与股票策略对比,带你了解米筐撮合机制

instrument

可以通过all_instruments函数来获取我们可以市场上所有合约的信息,目前只支持中国市场。

In [ ]:
all_instruments(type=None)

当然,有事我们只需要查询某一类合约的信息,那么只需要传入如下种类的的type参数:

CS
Common Stock, 即股票

ETF
Exchange Traded Fund, 即交易所交易基金

LOF
Listed Open-Ended Fund,即上市型开放式基金

FenjiMu
Fenji Mu Fund, 即分级母基金

FenjiA
Fenji A Fund, 即分级A类基金

FenjiB
Fenji B Funds, 即分级B类基金

INDX
Index, 即指数

Future
Futures,即期货,包含股指、国债和商品期货

获取获取中国市场所有股票信息:

In [1]:
all_instruments('CS').head()#取前5行
Out[1]:
abbrev_symbolboard_typeconcept_namesde_listed_dateexchangeindustry_codeindustry_namelisted_dateorder_book_idround_lotsector_codesector_code_namespecial_typestatussymboltype
0HGGFMainBoard融资融券|业绩预降0000-00-00XSHEC31黑色金属冶炼及压延加工业1997-04-16000709.XSHE100.0Materials原材料NormalActive河钢股份CS
1ZHZBGEM业绩预升|陕甘宁0000-00-00XSHEC38电气机械及器材制造业2010-11-12300140.XSHE100.0Industrials工业NormalActive中环装备CS
2SYDUNKNOWN4G概念|海峡西岸|摘帽概念|宽带提速0000-00-00XSHEC39计算机、通信和其他电子设备制造业2010-06-01002417.XSHE100.0InformationTechnology信息技术NormalActive三元达CS
3XJHUNKNOWNO2O模式|内贸规划0000-00-00XSHEF52零售业2011-03-03002561.XSHE100.0ConsumerDiscretionary非必需消费品NormalActive徐家汇CS
4RSJTUNKNOWN海峡西岸0000-00-00XSHEC36汽车制造业2011-06-28002593.XSHE100.0ConsumerDiscretionary非必需消费品NormalActive日上集团CS

获取获取中国市场所有期货信息:

In [2]:
all_instruments('Future').head()#取前5行
Out[2]:
abbrev_symbolcontract_multiplierde_listed_dateexchangelisted_datemargin_ratematurity_dateorder_book_idproductround_lotsettlement_methodsymboltrading_unittypeunderlying_order_book_idunderlying_symbol
0ZLY130910.02013-09-13DCE2012-09-170.052013-09-13P1309Commodity1.0PhysicalSettlementRequired棕榈油130910FuturenullP
1DE150510.02015-05-15DCE2014-05-190.052015-05-15B1505Commodity1.0PhysicalSettlementRequired豆二150510FuturenullB
2LWG130510.02013-05-15SHFE2012-05-160.072013-05-15RB1305Commodity1.0PhysicalSettlementRequired螺纹钢130510FuturenullRB
3ZLY130510.02013-05-15DCE2012-05-160.052013-05-15P1305Commodity1.0PhysicalSettlementRequired棕榈油130510FuturenullP
4XWB1709500.02017-09-14DCE2016-09-190.202017-09-14FB1709Commodity1.0PhysicalSettlementRequired纤维板1709500FuturenullFB

context

context是储存策略自定义参数、设置、仓位、投资组合信息的全局变量,属性通过点标记(”.”)来取到

例如将查询到的财务数据添加进去context里面保存,并且之后可以在handle_bar里使用,即你的算法策略之后可以使用这些保存在dataframe中的数据:

In [ ]:
context.fundamental_df = fundamental_df

在这里,我们还将介绍一下context的一些有用的属性

now(当前时间)

使用以上的方式就可以在handle_bar中拿到当前的bar的时间,比如day bar的话就是那天的时间,minute bar的话就是这一分钟的时间点。
返回数据类型为datetime.datetime

context.now

portfolio(投资组合信息)

该投资组合在单一股票或期货策略中分别为股票投资组合和期货投资组合。在股票+期货的混合策略中代表汇总之后的总投资组合。

context.portfolio

portfolio还有以下属性

starting_cash
float   初始资金,为子组合初始资金的加总

cash
float   可用资金,为子组合可用资金的加总

total_returns
float   投资组合至今的累积收益率。计算方法是现在的投资组合价值/投资组合的初始资金

daily_returns
float   投资组合每日收益率

daily_pnl
float   当日盈亏,子组合当日盈亏的加总

market_value
float   投资组合当前的市场价值,为子组合市场价值的加总

portfolio_value
float   总权益,为子组合总权益加总

pnl
float   当前投资组合的累计盈亏

start_date
datetime.datetime   策略投资组合的回测/实时模拟交易的开始日期

annualized_returns
float   投资组合的年化收益率

positions
dict    一个包含所有仓位的字典,以order_book_id作为键,position对象作为值

stock_portfolio(股票投资组合信息)

获取股票投资组合信息。

在单独股票类型策略中,内容与portfolio一致,都代表当前投资组合;在期货+股票混合策略中代表股票子组合;在单独期货策略中,不能被访问。

In [ ]:
context.stock_portfolio

stock_portfolio还有以下属性

starting_cash
float   回测或实盘交易给算法策略设置的初始资金
cash
float   可用资金
total_returns
float   投资组合至今的累积收益率。计算方法是现在的投资组合价值/投资组合的初始资金
daily_returns
float   当前最新一天的每日收益
daily_pnl
float   当日盈亏,当日投资组合总权益-昨日投资组合总权益
market_value
float   投资组合当前所有证券仓位的市值的加总
portfolio_value
float   总权益,包含市场价值和剩余现金
pnl
float   当前投资组合的累计盈亏
start_date
datetime.datetime   策略投资组合的回测/实时模拟交易的开始日期
annualized_returns
float   投资组合的年化收益率
positions
dict    一个包含所有证券仓位的字典,以order_book_id作为键,position对象作为值
dividend_receivable
float   投资组合在分红现金收到账面之前的应收分红部分

future_portfolio(期货投资组合信息)

获取期货投资组合信息。
在单独期货类型策略中,内容与portfolio一致,都代表当前投资组合;在期货+股票混合策略中代表期货子组合;在单独股票策略中,不能被访问。

In [ ]:
context.future_portfolio
starting_cash
float   初始资金
cash
float   可用资金
frozen_cash
float   冻结资金
total_returns
float   投资组合至今的累积收益率,当前总权益/初始资金
daily_returns
float   当日收益率 = 当日收益 / 昨日总权益
market_value
float   投资组合当前所有期货仓位的名义市值的加总
pnl
float   累计盈亏,当前投资组合总权益-初始资金
daily_pnl
float   当日盈亏,当日浮动盈亏 + 当日平仓盈亏 - 当日费用
daily_holding_pnl
float   当日浮动盈亏
daily_realized_pnl
float   当日平仓盈亏
portfolio_value
float   总权益,昨日总权益+当日盈亏
transaction_cost
float   总费用
start_date
Date    回测开始日期
annualized_returns
float   投资组合的年化收益率
positions
dict    一个包含期货仓位的字典,以order_book_id作为键,position对象作为值
margin
float   已占用保证金

run_info(策略运行信息)

In [ ]:
context.run_info
run_id
str 标识策略每次运行的唯一id
run_type
RUN_TYPE    RUN_TYPE.BACKTEST表示当前策略在进行回测,RUN_TYPE.PAPER_TRADING表示当前策略在进行实盘模拟
start_date
datetime.date   策略的开始日期
end_date
datetime.date   策略的结束日期
frequency
str 策略频率,'1d'或'1m'
stock_starting_cash
float   股票账户初始资金
future_starting_cash
float   期货账户初始资金
slippage
float   滑点水平
margin_multiplier
float   保证金倍率
commission_multiplier
float   佣金倍率
benchmark
str 基准合约代码
matching_type
MATCHING_TYPE   撮合方式,MATCHING_TYPE.NEXT_BAR_OPEN代表以下一bar开盘价撮合,MATCHING_TYPE.CURRENT_BAR_CLOSE代表以当前bar收盘价撮合

universe(策略合约池)

In [ ]:
context.universe

在运行update_universe,subscribe或者unsubscribe的时候,合约池会被更新。
需要注意,合约池内合约的交易时间(包含股票的策略默认会在股票交易时段触发)是handle_bar被触发的依据。

subscribe(订阅)

鉴于不同合约交易时间的不同(例如股票没有夜间交易,期货一些品种有夜盘交易),您在编写策略的时候需要注意策略的有效运行时间。比如在2015年12月之前,中金所股指期货的交易时间段是09:15~11:30, 13:00~15:15,比A股市场多出了30分钟。在这个时候进行混合回测的时候就需要通过订阅的方式让策略引擎’知道’handle_bar是要在每天09:16产生第一个bar数据,而不是股票的09:31。

如果您创建的是单一的期货策略,则必须在策略初始化的时候订阅(subscribe)有效期货合约。由于期货有到期日,所以您需要保证在回测期间,始终都有正在交易的合约被订阅。

In [ ]:
subscribe(order_book_id)

订阅合约行情。该操作会导致合约池内合约的增加,从而影响handle_bar中处理bar数据的数量。
需要注意,用户在初次编写策略时候需要首先订阅合约行情,否则handle_bar不会被触发。

In [ ]:
unsubscribe(order_book_id)

取消订阅合约行情。取消订阅会导致合约池内合约的减少,如果当前合约池中没有任何合约,则策略直接退出。

bar

包含股票、期货数据

order_book_id
str 股票代码
symbol
str 合约简称
datetime
datetime.datetime   时间戳
open
float   开盘价
close
float   收盘价
high
float   最高价
low
float   最低价
volume
float   成交量
total_turnover
float   成交额
prev_close
float   昨日收盘价
limit_up
float   涨停价
limit_down
float   跌停价
isnan
bool    当前bar数据是否有行情。例如,获取已经到期的合约数据,isnan此时为True
suspended
bool    是否全天停牌
prev_settlement
float   昨结算(期货日线数据专用)
settlement
float   结算(期货日线数据专用)

通过bar_dict[order_book_id] 可以拿到某个证券的bar信息,key为order_book_id,value为bar数据。当前合约池内所有合约的bar数据信息都会更新在bar_dict里面

分钟回测有多精准?一起看看snapshot

$$\ $$

current.snapshot() 可以返回当前市场快照数据。
$$\ $$

  • 调用 logger.info(current_snapshot(context.f1)),打印context.f1(主力合约)在策略(分钟级)当前时间的数据:
    • 2014-01-02 09:29:00.00 INFO Snapshot(order_book_id: ‘IF1401’, datetime: datetime.datetime(2014, 1, 2, 9, 29), open: 2340.0, high: 2342.4, low: 2330.2, last: 2340.4, volume: 31768, total_turnover: 22278751740, prev_close: 2345.0, open_interest: 96452, prev_settlement: 2348.4)
      $$\ $$
  • 我们也可以直接将current_snapshot(context.f1)打印出来:
    • 2014-01-02 09:29:00.00 INFO Snapshot(order_book_id: ‘IF1401’, datetime: datetime.datetime(2014, 1, 2, 9, 29), open: 2340.0, high: 2342.4, low: 2330.2, last: 2340.4, volume: 31768, total_turnover: 22278751740, prev_close: 2345.0, open_interest: 96452, prev_settlement: 2348.4)

效果相同。

订单到底该如何下,下了之后如何管理

$$\ $$

我们已经了解了股票策略中的订单管理的方式,但是在期货策略中,管理订单的函数有所不同,分别是:

  • buy_open(id_or_ins, amount, style=MarketOrder()) —— 买开仓
  • buy_close(id_or_ins, amount, style=MarketOrder()) —— 平多仓
  • sell_open(id_or_ins, amount, style=MarketOrder()) —— 卖开仓
  • sell_close(id_or_ins, amount, style=MarketOrder()) —— 平空仓

平仓和反向开仓有什么区别呢?在实盘中,证券交易所处理订单的逻辑是优先平仓再处理开仓的,并且反向开仓相同手数,虽然实际上已经锁仓了但是依然占用保证金。因此二者并非等价。

天天都要下单,我们的资产组合里到底有什么?

  • context.portfolio
  • context.stock_portfolio
  • context.future_portfolio

投资组合信息包含以下字段:

  • starting_cash —— 初始资金
  • cash —— 当前持有现金
  • total_returns —— 投资组合累积收益率
  • daily_returns —— 投资组合每日收益率
  • daily_pnl —— 当日盈亏
  • market_value —— 投资组合当前的市场价值
  • portfolio_value —— 总权益,为子组合总权益加总
  • pnl —— 当前投资组合的累计盈亏
  • start_date —— 策略投资组合的回测/实时模拟交易的开始日期
  • annualized_returns —— 投资组合的年化收益率
  • positions —— 一个包含所有仓位的字典,以order_book_id作为键,position对象作为值

以上三个函数都可以获取投资组合中的信息。那么它们有什么区别呢?

  • context.stock_portfolio 中储存股票投资组合信息
  • context.future_portfolio 中储存期货投资组合信息
  • context.portfolio 中保存股票和期货的投资组合信息,在单一股票策略或期货策略里分别与context.stock_portfolio或context.future_portfolio无异,但在混合策略中是二者的总和。

我们如何记录我们的仓位 — portfolio对象

context.portfolio 中有存储仓位信息,这让仓位管理变的异常轻松。

股票和期货分别对应不同的position对象,详情查阅API接口:https://www.ricequant.com/api/python/chn

In [ ]:
# 读仓位信息,以期货投资组合的可平空仓量为例
context.future_portfolio.positions['stock_id'].closable_sell_quantity

 

Python策略范例系列目录:

1. Python策略范例1-一步一步找Alpha
2. Python策略范例2-一个简单的技术指标策略
当前阅读> 3. Python策略范例3-了解米筐撮合机制
4. Python策略范例4-策略怎么样,米筐来分析
5. Python策略范例5-股息率策略
6. Python策略范例6-海龟交易的Python完全版
7. Python策略范例7-Dual Thrust 交易策略
8. Python策略范例8-止损/止盈的七种方法
9. Python策略范例9-我有一个策略想法,如何一步步转化成策略代码?
10. Python策略范例10-参数优化框架