量化投资:交易模型开发与数据挖掘
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.9 账户相关属性

3.9.1 下单函数

1.order

order表示可以对股票、期货、指数策略进行下单操作。根据指定的参数,进行策略订单委托下单指定股数。订单类型支持市价单或限价单,限价单需设置order_type为’limit',并设置下单价格。示例代码如下:

        stock_account.order(symbol, amount)            # 股票账户下单指定股数
        futures_account.order(symbol, amount, 'open')  # 期货账户委托开仓指定份数
        otc_fund_account.order(symbol, amount)         # 场外账户申购指定份数基金
        index_account.order(symbol, amount, 'open')    # 指数账户委托开仓指定份数

参数说明如下。

· symbol:需要交易的证券代码。

参数类型:str。

· amount:需要交易的证券数量,正数表示买入,负数表示卖出。

参数类型:int。

· price:定义下限价单时指定的下单价格,仅用于分钟线策略。

参数类型:float。

· order_type:下单类型。包括两个值,即’market’表示市价单,'limit’表示限价单。其中限价单仅用于分钟线策略,日线策略下单时可以省略order_type参数。

参数类型:str。

· offset_flag:期货开平仓方向,仅用于期货策略。包括两个值,即’open’表示开仓,'close'表示平仓。

参数类型:str。

返回策略订单的ID,这个ID全局唯一,且包含了时间顺序。

例如,采用日线策略下单,每个交易日买入上证50成分股各100股,代码如下:

        start = '2019-01-01'                    # 回测起始时间
        end = '2019-03-01'                      # 回测结束时间
        universe = DynamicUniverse('SH50')      # 证券池,支持股票、基金、期货
        benchmark = 'HS300'                     # 策略参考基准
        # 策略类型,'d’表示日间策略使用日线回测,'m’表示日内策略使用分钟线回测
        freq = 'd'
        refresh_rate = 1                        # 执行handle_data的时间间隔
        accounts = {
            'stock_account': AccountConfig(account_type='security', capital_base=
    10000000)
        }
        def initialize(context):                # 初始化策略运行环境
            pass
        def handle_data(context):              # 核心策略逻辑
            stock_account = context.get_account('stock_account')
            current_universe = context.get_universe('stock', exclude_halt=True)
            for stk in current_universe:
              stock_account.order(stk, 100)

期货日线策略下单的示例代码如下:

        start = '2018-01-01'                    # 回测起始时间
        end = '2019-01-01'                      # 回测结束时间
        universe = ['CUM0', 'IFM0']             # 证券池,支持股票、基金、期货
        benchmark = 'HS300'                     # 策略参考基准
        # 策略类型,'d’表示日间策略使用日线回测,'m’表示日内策略使用分钟线回测
        freq = 'd'
        refresh_rate = 1                        # 执行handle_data的时间间隔
        accounts = {
            'futures_account': AccountConfig(account_type='futures', capital_base=
    10000000)
        }
        def initialize(context):                # 初始化策略运行环境
            pass
        def handle_data(context):               # 核心策略逻辑
            futures_account = context.get_account('futures_account')
            current_futures = context.get_universe('futures')
            for symbol in current_futures:
              futures_contract = context.get_symbol(symbol)
              futures_account.order(futures_contract, 1, 'open')

期货分钟线策略下单的示例代码如下:

        import numpy as np
        import pandas as pd
        import talib as ta
        universe = ['RBM0']                     # 策略期货合约
        start = '2018-01-01'                    # 回测起始时间
        end = '2019-02-01'                      # 回测结束时间
        refresh_rate = 5                        # 调仓周期
        # 策略类型,'d’表示日间策略使用日线回测,'m’表示日内策略使用分钟线回测
        freq = 'm'
        max_history_window = (150, 200)
        lfast = 5                               # 入场短均线窗口
        lslow = 20                              # 入场长均线窗口
        sfast = 3                               # 出场短均线窗口
        sslow = 10                              # 出场长均线窗口
        accounts   =   {'futures_account':   AccountConfig(account_type='futures',
    capital_base=1000000)}
        # 初始化虚拟期货账户,一般用于设置计数器、回测辅助变量等
        def initialize(context):
            context.current_bar = 0
            context.symbol = 'RB1605'
        # 回测调仓逻辑,每个调仓周期运行一次,可在此函数内实现信号生产,生成调仓指令
        def handle_data(context):
            futures_account = context.get_account('futures_account')
            symbol = context.get_symbol(universe[0])
            long_position = futures_account.get_positions().get(symbol,
    dict()).get('long_amount', 0)
            if context.mapping_changed(universe[0]):
              symbol_before, symbol_after = context.get_rolling_tuple
    (universe[0])
              if futures_account.get_position(symbol_before):
                  futures_account.switch_position(symbol_before, symbol_after)
            else:
              data = context.history(symbol=symbol, attribute=['closePrice',
    'openPrice', 'lowPrice', 'highPrice'], time_range=20, freq='60m')
              high_price = np.array(data[symbol]['highPrice'], dtype=float)
              low_price = np.array(data[symbol]['lowPrice'], dtype=float)
              open_price = np.array(data[symbol]['openPrice'], dtype=float)
              close_price = np.array(data[symbol]['closePrice'], dtype=float)
              malfast = ta.MA(close_price, lfast)
              malslow = ta.MA(close_price, lslow)
              masfast = ta.MA(close_price, sfast)
              masslow = ta.MA(close_price, sslow)
              if long_position == 0:
                  if malfast[-1] > malslow[-1] and masfast[-1] > masslow[-1] and
    high_price[-1] > high_price[-2]:
                      ids = futures_account.order(symbol, 10, 'open')
              if long_position ! = 0:
                  if masfast[-1] < masslow[-1]:
                      futures_account.order(symbol, -long_position, 'close')
              context.current_bar += 1

2.order_to

order_to仅用于股票策略,根据指定的参数进行策略订单委托下单,将股票仓位调整到指定股数。每次调用handle_data,最多只允许调用一次order_to函数,否则可能会造成下单量计算错误。示例代码如下:

        stock_account.order_to(symbol, amount)  # 股票策略下单到指定股数

参数说明如下。

· symbol:需要交易的证券代码。

参数类型:str。

· amount:调仓后需要达到的目标股数,需要是100的正整数倍或0。

参数类型:int。

· price:定义下限价单时指定的下单价格,仅用于分钟线策略。

参数类型:float。

· order_type:下单类型。包括两个值,即’market’表示市价单,'limit’表示限价单。其中限价单仅用于分钟线策略,日线策略下单时可以省略order_type参数。

参数类型:str。

返回订单的ID,这个ID全局唯一,且包含了时间顺序。

例如,初始持仓1000股浦发银行,目标持仓100股浦发银行的代码如下:

        start = '2019-01-01'                # 回测起始时间
        end = '2019-01-05'                  # 回测结束时间
        universe = ['600000.XSHG']          # 证券池,支持股票、基金、期货
        benchmark = 'HS300'                 # 策略参考基准
        # 策略类型,'d’表示日间策略使用日线回测,'m’表示日内策略使用分钟线回测
        freq = 'd'
        refresh_rate = 1                    # 执行handle_data的时间间隔
        accounts = {
            'stock_account': AccountConfig(account_type='security', capital_base=
    10000000, position_base = {'600000.XSHG':1000}, cost_base = {'600000.
    XSHG':10.05})
        }
        def initialize(context):            # 初始化策略运行环境
            pass
        def handle_data(context):           # 核心策略逻辑
            stock_account = context.get_account('stock_account')
            current_universe = context.get_universe('stock', exclude_halt=True)
            for stk in current_universe:
              stock_account.order_to(stk, 100)
            print stock_account.get_orders()

查看下单明细:

        [Order(order_id: 2019-01-02-0000001, order_time: 2019-01-02 09:30, symbol:
    600000.XSHG, direction: -1, order_amount: 900, state: ORDER_SUBMITTED,
    filled_time: , filled_amount: 0, transact_price: 0.0000, slippage: 0.0000,
    commission: 0.0000)]

3.order_pct

order_pct仅用于股票策略,根据当前账户总资产,进行策略订单委托下单到指定百分比的股票仓位。示例代码如下:

        stock_account.order_pct(symbol, pct)  # 股票策略下单指定百分比

例如,1000000元总资产(含股票和现金),下单20%,表示下单1000000元总资产的20%。

参数说明如下。

· symbol:需要交易的证券代码,必须包含后缀,其中上证证券的后缀为.XSHG,深证证券的后缀为.XSHE。

参数类型:str。

· pct:每次下单的交易额占总资产的百分比,取值范围为-1~1,负值代表卖出,正值代表买入。

参数类型:float。

返回订单的ID,这个ID全局唯一,且包含了时间顺序。

示例代码如下:

        start = '2019-01-01'                    # 回测起始时间
        end = '2019-06-01'                      # 回测结束时间
        universe = DynamicUniverse('SH50')      # 证券池,支持股票、基金、期货
        benchmark = 'HS300'                     # 策略参考基准
        # 策略类型,'d’表示日间策略使用日线回测,'m’表示日内策略使用分钟线回测
        freq = 'd'
        refresh_rate = 1                        # 执行handle_data的时间间隔
        accounts = {
            'stock_account': AccountConfig(account_type='security', capital_base=
    10000000)
        }
        def initialize(context):                # 初始化策略运行环境
            pass
        def handle_data(context):               # 核心策略逻辑
            stock_account = context.get_account('stock_account')
            current_universe = context.get_universe('stock', exclude_halt=True)
            for stk in current_universe:
              stock_account.order_pct(stk, 0.1)

4.order_pct_to

order_pct_to仅用于股票策略,根据当前账户总资产,进行策略订单委托下单到指定目标百分比的股票仓位,示例代码如下:

        stock_account.order_pct_to(symbol, pct)  # 股票策略下单到指定百分比

例如,1000000元总资产(含股票和现金),下单到20%,系统会根据持仓自动进行计算并下单。

参数说明如下。

· symbol:需要交易的证券代码,必须包含后缀,其中上证证券的后缀为.XSHG,深证证券的后缀为.XSHE。

参数类型:str。

· pct:交易下单后证券持仓占账户总资产的目标百分比,范围为0~1。

参数类型:float。

返回订单的ID,这个ID全局唯一,且包含了时间顺序。

示例代码如下:

        start = '2019-01-01'                    # 回测起始时间
        end = '2019-06-01'                      # 回测结束时间
        universe = DynamicUniverse('SH50')      # 证券池,支持股票、基金、期货
        benchmark = 'HS300'                     # 策略参考基准
        # 策略类型,'d’表示日间策略使用日线回测,'m’表示日内策略使用分钟线回测
        freq = 'd'
        refresh_rate = 1                        # 执行handle_data的时间间隔
        accounts = {
            'stock_account': AccountConfig(account_type='security', capital_base=
    10000000)
        }
        def initialize(context):                # 初始化策略运行环境
            pass
        def handle_data(context):               # 核心策略逻辑
            stock_account = context.get_account('stock_account')
            current_universe = context.get_universe('stock', exclude_halt=True)
            for stk in current_universe:
              stock_account.order_pct_to(stk, 0.1)

5.close_all_positions

close_all_positions表示卖出当前所有持仓,期货平仓时包含多头持仓和空头持仓,示例代码如下:

        close_all_positions(symbol)

参数说明如下。

· symbol:需要全部卖出的证券代码,必须包含后缀,其中上证证券的后缀为.XSHG,深证证券的后缀为.XSHE,如果该参数为空,表示清仓。

参数类型:str或list。

返回order_id,这个ID全局唯一,且包含了时间顺序。

示例代码如下:

        # 平掉所有持仓
        account.close_all_positions()
        # 平掉指定标的持仓
        account.close_all_positions('IF1601')

6.cancel_order

cancel_order表示根据订单ID,撤销未成交或部分成交的订单,示例代码如下:

        cancel_order(order_id)

参数:order_id,订单的唯一指定ID。

返回布尔值,表示是否成功发出撤单指令。

示例代码如下:

        start = '2019-01-01'                # 回测起始时间
        end = '2019-01-07'                  # 回测结束时间
        benchmark = 'HS300'                 # 策略参考基准
        universe = ['000001.XSHE']          # 证券池,支持股票和基金
        capital_base = 10000000             # 起始资金
        # 策略类型,'d’表示日间策略使用日线回测,'m’表示日内策略使用分钟线回测
        freq = 'm'
        # 调仓频率,表示执行handle_data的时间间隔,若freq = 'd’则表示时间间隔的单位为交易
    日,若freq = 'm’则表示时间间隔为分钟
        refresh_rate = (2, 1)
        def initialize(account):
            stock_account.record_orders = []
        def handle_data(account):
            if stock_account.universe:
              if '13:14' == stock_account.current_minute:
                  del stock_account.record_orders[:]
                  for stk in stock_account.universe:
                      price = stock_account.referencePrice[stk] * 0.99
                      order_id = order(stk, 500, price=price, otype='limit')
                      stock_account.record_orders.append(order_id)
              elif '13:15' == stock_account.current_minute:
                  for order_id in stock_account.record_orders:
                    _order = get_order(order_id)
                    assert _order.state == OrderState.OPEN
        #               assert _order.state=="ToFill"
                    success = cancel_order(order_id)
              elif '13:16' == stock_account.current_minute:
        #           print stock_account.blotter[0].state
                  assert stock_account.blotter[0].state == OrderState.CANCELED
                  assert stock_account.cash == 10000000

3.9.2 获取账户信息

1.get_order

get_order表示根据订单ID获取已委托的订单对象,示例代码如下:

        account.get_order(order_id)

参数为order_id:订单的唯一指定ID。在调用下单函数时生成,可以由FuturesOrder. order_id属性获得。

参数类型:str。

返回order_id对应的对象。

不同资产对象支持的参数如表3-17所示。

表3-17

订单状态及其描述如表3-18所示。

表3-18

示例代码如下:

        start = '2019-01-01'                    # 回测起始时间
        end = '2019-01-05'                      # 回测结束时间
        universe = DynamicUniverse('SH50')      # 证券池,支持股票、基金、期货
        benchmark = 'HS300'                     # 策略参考基准
        # 策略类型,'d’表示日间策略使用日线回测,'m’表示日内策略使用分钟线回测
        freq = 'd'
        refresh_rate = 1                        # 执行handle_data的时间间隔
        accounts = {
            'stock_account': AccountConfig(account_type='security', capital_base=
    10000000)
        }
        def initialize(context):       # 初始化策略运行环境
            pass
        def handle_data(context):      # 核心策略逻辑
            stock_account = context.get_account('stock_account')
            current_universe = context.get_universe('stock', exclude_halt=True)
            for stk in current_universe:
              order_id = stock_account.order(stk, 100)
              print stock_account.get_order(order_id)

部分输出结果如下:

        Order(order_id: 2019-01-02-0000050, order_time: 2019-01-02 09:30, symbol:
        Order(order_id: 2019-01-02-0000051, order_time: 2019-01-02 09:30, symbol:
        Order(order_id: 2019-01-02-0000052, order_time: 2019-01-02 09:30, symbol:
        Order(order_id: 2019-01-02-0000053, order_time: 2019-01-02 09:30, symbol:
        Order(order_id: 2019-01-02-0000054, order_time: 2019-01-02 09:30, symbol:
        Order(order_id: 2019-01-02-0000055, order_time: 2019-01-02 09:30, symbol:

2.get_orders

get_orders用于获取满足条件的一系列订单实例,示例代码如下:

        account.get_orders(state, symbol)

参数说明如下。

· state:所需订单的状态。

参数类型:str。

· symbol:所需订单的证券限制,即定义之后只会返回symbol范围内的证券的订单,可以为字符串或列表,如’000001.XSHE’或['000001.XSHE', '600000.XSHG'];还可以设置为空,代表所有证券。

参数类型:str或list。

返回满足条件的订单列表。

示例代码如下:

        start = '2019-01-01'                    # 回测起始时间
        end = '2019-01-05'                      # 回测结束时间
        universe = DynamicUniverse('SH50')      # 证券池,支持股票、基金、期货
        benchmark = 'HS300'                     # 策略参考基准
        # 策略类型,'d’表示日间策略使用日线回测,'m’表示日内策略使用分钟线回测
        freq = 'd'
        refresh_rate = 1            # 执行handle_data的时间间隔
        accounts = {
            'stock_account': AccountConfig(account_type='security', capital_base=
    10000000)
        }
        def initialize(context):   # 初始化策略运行环境
            pass
        def handle_data(context):  # 核心策略逻辑
            stock_account = context.get_account('stock_account')
            current_universe = context.get_universe('stock', exclude_halt=True)
            for stk in current_universe:
              order_id = stock_account.order(stk, 100)
              print stock_account.get_orders()

3.get_position

get_position用于获取指定资产的持仓情况,示例代码如下:

        account.get_position(symbol)

参数:symbol,表示资产ID。

参数类型:str。

返回指定资产的持仓信息。

不同资产对象支持的参数如表3-19所示。

表3-19

示例代码如下:

        start = '2018-01-01'                        # 回测起始时间
        end = '2019-01-01'                          # 回测结束时间
        universe = ['000001.XSHE', '601318.XSHG']   # 证券池,支持股票、基金、期货
        benchmark = 'HS300'                         # 策略参考基准
        # 策略类型,'d’表示日间策略使用日线回测,'m’表示日内策略使用分钟线回测
        freq = 'd'
        refresh_rate = 1                            # 执行handle_data的时间间隔
        accounts = {
            'stock_account': AccountConfig(account_type='security', capital_base=
    10000000)
        }
        def initialize(context):                    # 初始化策略运行环境
            pass
        def handle_data(context):                   # 核心策略逻辑
            stock_account = context.get_account('stock_account')
            current_universe = context.get_universe('stock', exclude_halt=False)
            for stk in universe:
              stock_account.order(stk, 100)
            print stock_account.get_position('601318.XSHG')

输出的部分结果如下:

        Position(symbol: 601318.XSHG, amount: 100, available_amount: 100 ...)
        Position(symbol: 601318.XSHG, amount: 200, available_amount: 200 ...)
        Position(symbol: 601318.XSHG, amount: 300, available_amount: 300 ...)
        Position(symbol: 601318.XSHG, amount: 400, available_amount: 400 ...)
        Position(symbol: 601318.XSHG, amount: 500, available_amount: 500 ...)
        Position(symbol: 601318.XSHG, amount: 600, available_amount: 600 ...)

4.get_positions

get_positions用于获取所有账户持仓,示例代码如下:

        account.get_positions(exclude_halt=False)

参数为exclude_halt:是否移除持仓中停牌的资产。

返回类型:dict。key为证券代码,value为持仓对象。

示例代码如下:

        start = '2018-01-01'                        # 回测起始时间
        end = '2019-01-01'                          # 回测结束时间
        universe = ['000001.XSHE', '601318.XSHG']   # 证券池,支持股票、基金、期货
        benchmark = 'HS300'                         # 策略参考基准
        # 策略类型,'d’表示日间策略使用日线回测,'m’表示日内策略使用分钟线回测
        freq = 'd'
        refresh_rate = 1                            # 执行handle_data的时间间隔
        accounts = {
            'stock_account': AccountConfig(account_type='security', capital_base=
    10000000)
        }
        def initialize(context):                    # 初始化策略运行环境
            pass
        def handle_data(context):                   # 核心策略逻辑
            stock_account = context.get_account('stock_account')
            current_universe = context.get_universe('stock', exclude_halt=False)
            for stk in universe:
              stock_account.order(stk, 100)
            print stock_account.get_positions()

输出的部分结果如下:

        {'000001.XSHE': Position(symbol: 000001.XSHE, amount: 100 ...}
        {'000001.XSHE': Position(symbol: 000001.XSHE, amount: 200 ...}
        {'000001.XSHE': Position(symbol: 000001.XSHE, amount: 300 ...}
        {'000001.XSHE': Position(symbol: 000001.XSHE, amount: 400 ...}
        {'000001.XSHE': Position(symbol: 000001.XSHE, amount: 500 ...}
        {'000001.XSHE': Position(symbol: 000001.XSHE, amount: 600 ...}

3.10 策略结果展示

1.bt

bt的含义:回测报告,格式为pandas.DataFrame。其包括日期、现金头寸、证券头寸、投资组合价值、参考指数收益率、交易指令明细表等6列,以及用户在observe中定义的其他列。

时间从开始日期及需要获取的最长历史窗口后开始计算。

用法:策略运行完成后,可以在code单元中输入bt,运行后查看结果。

2.bt_by_account

bt_by_account的含义:回测报告,格式为dict。其包括日期、现金头寸、证券头寸、投资组合价值、参考指数收益率、交易指令明细表等6列,以及用户在observe中定义的其他列。

时间从开始日期及需要获取的最长历史窗口后开始计算。

用法:策略运行完成后,可以在code单元中输入bt_by_account,运行后查看结果。

3.perf

perf是指根据回测记录计算各项风险收益指标,类型为dict, key为指标名称,value为指标的值,有些类型为float或list。参数及其描述如表3-20所示。

表3-20

用法:策略运行完成后,可以在code单元中输入perf,运行后查看结果。