BigQuant使用文档

交易引擎介绍

由anthony_wan创建,最终由small_q 被浏览 462 用户

什么是BigTrader

BigTrader是宽邦科技推出的致力于为用户提供便捷、功能强大的量化策略编写、回测分析、仿真模拟和实盘交易的工具。在量化研究的过程中,量化研究员(宽客)需要在历史数据里回放模拟,验证策略效果,这就是BigTrader交易引擎的应用场景。

交易引擎有哪些优势

  • 回测研究贴近真实 交易,最大程度保证回测的准确性
  • 回测研究、模拟交易、实盘交易为同一套代码,无需做任务修改
  • 交易引擎是一个有体系、结构化的工程框架,能大幅提升策略开发的效率

支持的品种

股票、基金、期货、可转债、指数,未来会支持期权、债券、两融

交易频率

日线、分钟、Tick、逐笔

交易引擎介绍

BigQuant回测引擎为时间驱动回测引擎,当设定好每一根K线后,会根据K线频率读取数据。如当在回测引擎中设置为daily时,回测引擎会按照天从传入数据读取。

回测引擎交易时间图{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}

回测引擎运行逻辑{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}

回测引擎的运行逻辑为每一根K线运行一次,在当前K线进行下单操作时会在下一根K线开始撮合成交。

由于BigQuant模块间传参均使用内置DataSource格式,以下是将**==DataFrame==与DataSource**互转的方式以及读取方式。

\

DataFrame转为DataSource 格式

#创建DataFrame
df = pd.DataFrame([])

#将DataFrame转为DataSource
df = DataSource.write_df(df)

DataSource转为DataFrame 格式

#例如某个模块为m1,将m1的输出转为DataFrame.
#将 m1模块内的data(DataSource)赋值给变量df
df = m1.data

#将DataSource 转为 DataFrame
df = df.read()

\

回测引擎的调取

可视化版本

搜索hftrade, 确认模块版本为 HFTrade.v2, 可直接在该模块内进行代码修改。

可视化版本{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}{w:100}


代码版本

# 交易引擎:初始化函数,只执行一次
def m1_initialize_bigquant_run(context):
    # 加载预测数据
    pass

# 交易引擎:每个单位时间开盘前调用一次。
def m1_before_trading_start_bigquant_run(context, data):
    # 盘前处理,订阅行情等
    pass

# 交易引擎:tick数据处理函数,每个tick执行一次
def m1_handle_tick_bigquant_run(context, tick):
    pass

# 交易引擎:bar数据处理函数,每个时间单位执行一次
def m1_handle_data_bigquant_run(context, data):
    pass

# 交易引擎:成交回报处理函数,每个成交发生时执行一次
def m1_handle_trade_bigquant_run(context, trade):
    pass

# 交易引擎:委托回报处理函数,每个委托变化时执行一次
def m1_handle_order_bigquant_run(context, order):
    pass

# 交易引擎:盘后处理函数,每日盘后执行一次
def m1_after_trading_bigquant_run(context, data):
    pass


m1 = M.hftrade.v2(
    start_date='2023-01-03',
    end_date='2023-01-06',
    initialize=m1_initialize_bigquant_run,
    before_trading_start=m1_before_trading_start_bigquant_run,
    handle_tick=m1_handle_tick_bigquant_run,
    handle_data=m1_handle_data_bigquant_run,
    handle_trade=m1_handle_trade_bigquant_run,
    handle_order=m1_handle_order_bigquant_run,
    after_trading=m1_after_trading_bigquant_run,
    capital_base=1000000,
    frequency='minute',
    price_type='真实价格',
    product_type='股票',
    before_start_days='0',
    volume_limit=1,
    order_price_field_buy='open',
    order_price_field_sell='close',
    benchmark='000300.HIX',
    plot_charts=True,
    disable_cache=False,
    replay_bdb=False,
    show_debug_info=False,
    backtest_only=False
)

Hftrade.v2 回测引擎启动参数

参数 数据类型 参数功能 调用方法
instruments DataSource 回测引擎会自动订阅日期内股票的日线行情,同时会根据日线时间区间运行回测引擎。 context.instruments
options_data DataSource 回测引擎接入options_data后,可从options_data读取预测数据,并且根据该数据进行下单。 context.options
frequency str 可填参数**'daily’’minute’’tick’**,会根据填入的参数更新引擎内置运行时间,以此为依据提取数据,达到切换频率的效果。 data.current_dt



\

回测引擎主要函数介绍

回测引擎内置了几类主要函数,会按照顺序依次运行。用户可通过可视化或代码方式对函数内容进行更改,最终实现通过回测引擎达到回测的目的。以下是各类函数的运行逻辑。

\

函数名称 函数英文名 运行逻辑
初始化函数 initialize_bigquant_run 启动回测引擎时运行,只运行一次
盘前处理函数 before_trading_start_bigquant_run 每日开盘前运行一次
K线处理函数 handle_data_bigquant_run 每根K线运行一次
tick处理函数 handle_tick_bigquant_run 每个tick运行一次,仅在频率为’tick’时生效,股票一般3s一次,期货一般 500ms 一次
盘后处理函数 after_trading_bigquant_run 盘后运行

\

重要函数用法示例

\

初始化函数

初始化函数主要用于设置回测引擎的实例参数,通过实例参数可以在之后的模块中实现交易中的需求。

以下是一个示例,假如我们传入context.options是一个字典,字典中data对应着DataSource文件,这时我们可通过下列方法将数据存入回测引擎并设置交易周期。


# m7_ 为模块编号前缀
def m7_initialize_bigquant_run(context):
    #=========================== 加载预测数据  ===================================
    #传入的options是一个字典,字典中'data'对应着DataSource文件,我们可将DataSource文件转为DataFrame中并存入回测引擎

    context.ranker_prediction = context.options['data'].read_df()
    context.ranker_prediction.set_index('date',inplace=True)  #用日期作为索引,可提高之后数据读写速度

    #=======================================功能设置
    #设置最大买入股票为5只
    context.buy_bum = 5

    #T+1 交易
    context.set_stock_t1(1)


\

盘前处理函数

盘前处理函数通常用于订阅数据,回测引擎内置自动订阅股票日线数据。当我们需要使用股票分钟数据,或期货数据,期货分钟数据等。我们需要提前订阅行情,来实现最终的下单以及收益的计算。


以下是我们订阅股票分钟行情的示例

def m7_before_trading_start_bigquant_run(context, data):
    
    #订阅股票分钟数据
    #获取全部需要订阅的股票代码
    instrument = context.instrument   
    
    #订阅分钟行情
    context.subscribe_bar(instrument, '1m')
    

context.subscribe_bar(instruments: List[str], frequency: str) 实例方法参数

参数 是否必选 内容
instrument 必选 标的代码的列表
frequency 默认为 ‘1d’ 可通过更改参数选择不同的行情进行订阅,可选 ‘1d’ , ‘1m’

\

K线处理函数

K线处理函数会在每根K线运行一次,通常我们会在该函数内进行K线数据读取,并且下单。

以下是一个我们使用该函数进行数据并下单的示例。

\

def m7_handle_data_bigquant_run(context, data):
    """
    context: StrategyContext 是交易引擎策略上下文对象,提供下单、获取资金持仓等对象接口
    data: BarDatas 是K线集合对象,提供了访问当前时间,K线价格等接口
    """

    #创建买入列表
    buy_list = []  


    #==================== 数据准备

    #获取当前时间 pydatetime 类型
    time = data.current_dt 
    #将时间格式转为年月日
    date = data.current_dt.date()

    #读取预测数据,根据时间进行索引,再将索引重置。
    try:
        today_data  = context.ranker_prediction.loc[date,:]
        today_data.reset_index(inplace=True)
    except:
        return

    #假如我们需要选择最小市值的n只股票,n已在初始化模块中设置,以下是实现方法。
    #获得当日目标持仓
    buy_num = context.buy_num

    today_data = today_data.sort_values(by='市值',ascending=True)
    buy_list = today_data.instrument.tolist()[:buy_num]

    #获取目前持仓列表
    holding_list = list(context.get_positions().keys()) 

    #先卖出已持仓股票不在目标持仓中的
    for ins in holding_list:
        if ins not in buy_list:
            context.order_target(ins, 0)
  

    #买入目标持仓中,未持仓的股票
    for ins in buy_list:
        if ins not in holding_list:
            context.order_percent(ins, 0.02)



\

实例方法介绍

\

【查询】实例方法

\

单只标的持仓信息查询 context.get_position(instrument: str, direction = Direction.NONE)

当查询单只标的持仓信息时,可使用 context.get_position() 来获取该标的信息。

实例参数 参数类型 是否必填 参数描述
instrument str 查询传入参数标的的持仓信息

示例

def m7_handle_data_bigquant_run(context, data):
    
    instrument = '000001.SZA'

    #获取股票持仓信息
    pos = context.get_position(instrument)

    print(pos)

通过以上代码,将返回一个字典,该字典数据格式如下。

StockPosition(bkt000,002875.SZA,LONG,current_qty:2100,avail_qty:0,cost_price:9.44,last_price:9.44,margin:0.0)
返回值 返回值含义 获取方式
current_qty 当前持仓 context.get_position(ins).current_qty
avail_qty 可用持仓 context.get_position(ins).avail_qty
cost_price 持仓成本 context.get_position(ins).cost_price
last_price 最新价格 context.get_position(ins).last_price
margin 保证金占用 context.get_position(ins).margin
last_sale_date 最后交易日 context.get_position(ins).last_sale_date


\

多只标的持仓信息查询 context.get_positions()

当查询多只标的持仓信息时可以使用 context.get_positions()来获取标的的信息。

实例参数 参数类型 是否必须 参数描述
instrument list 标的的列表
direction str 可通过 direction=Direction.LONG/SHORT进行持仓方向过滤

示例

def m7_handle_data_bigquant_run(context, data):
    
    instruments = ['000001.SZA','000002.SZA']

    #获取股票持仓信息
    pos = context.get_positions(instruments)

    print(pos)

通过以上代码,可以获得一个如下字典:

{'603176.SHA': StockPosition(bkt000,603176.SHA,LONG,current_qty:0,avail_qty:0,cost_price:0.0,last_price:2.97,margin:0.0), 
'600768.SHA': StockPosition(bkt000,600768.SHA,LONG,current_qty:2000,avail_qty:0,cost_price:9.72,last_price:9.57,margin:0.0)}
 
返回值 返回值含义 获取方式 (注: instrument为股票代码,instrument_list为股票代码列表)
keys() 全部持仓列表 context.get_positions(instrument_list).keys()
current_qty 持仓数量 context.get_positions(instrument_list).instrument.current_qty
avail_qty 可用持仓 context.get_positions(instrument_list).instrument.avil_qty
cost_price 持仓成本 context.get_positions(instrument_list).instrument.cost_price
last_price 最新价格 context.get_positions(instrument_list).instrument.last_price
last_sale_date 最后交易日 context.get_positions(instrument_list).instrument.last_sale_date



\

查询当前日期 data.current_dt

可以通过下列方法获取当前日期,主要用于从引擎中提取当日数据使用.

通常我们在初始化时将全部数据读取进入引擎,并将index转为日期形式,在每日k线处理函数运行时,获取当前日期。通过当前日期从全部数据中获取当日数据。


以下是一个示例


#初始化模块中将全部数据
def m7_initialize_bigquant_run(context):
    #=========================== 加载预测数据  ===================================
    #传入的options是一个字典,字典中'data'对应着DataSource文件,我们可将DataSource文件转为DataFrame中并存入回测引擎
    
    #将全部数据存入 all_data.并重新设定索引
    context.all_data = context.options['data'].read_df()
    context.all_data.set_index('date',inplace=True)  #用日期作为索引,可提高之后数据读写速度



def m7_handle_data_bigquant_run(context, data):

    #获取当前时间 pydatetime
    time = data.current_dt 
    #将时间格式转为年月日
    date = data.current_dt.date()

    #读取数据,根据时间进行索引,再将索引重置。
    try:
        today_data  = context.all_data.loc[date,:]
        today_data.reset_index(inplace=True)
    except:
        return


\

查询当前账户投资组合信息 context.portfolio

可以通过使用 context.portfolio查询当前账户信息

实例方法 返回值含义 获取方式
positions_value 持仓市值 context.portfolio.positions_value
portfolio_value 总资产(资金+持仓市值) context.portfolio.portfolio_value
cash 可用资金 context.portfolio.cash
actual_cash 实际资金 context.portfolio.actual_cash


\

查询当前标的价格 data.history( )

可通过使用 data.history( ) 获取股票当前价格

实例参数

参数 类型 是否必须 参数含义
instrument str 需要获取的代码
fields list[str] 需要获取的字段,如 [“close“, “volume“]
bar_count int 需要的Bar条数
frequency str 默认 ‘1d’ 可选 ‘1d’ ‘1m’ ,按照该频率返回数据


以下是一个实例,在回测引擎中获取当日股票分钟数据

def m7_handle_data_bigquant_run(context, data):

    #获取股票代码
    instrument = '000001.SZA'
    now_time = context.current_df  

    #获取该股票截止至当前分钟的全部日内分钟数据
    df = data.history(instrument, ["close", "volume"], 30, '1m')


\

【下单】实例方法

按照数量下单 context.order( )

可通过 context.order( ) 方式进行按数量下单

order(instrument, volume, price=0, offset=Offset.NONE, **kwargs)

实例参数 参数类型 是否必选 参数含义
instrument str 需要交易的代码
volume int 需要交易的数量,>0表示买入,<0表示卖出
price float 交易的价格,默认为0表示市价单
order_type OrderType 默认为MARKET市价单 下单类型 LIMIT:限价单 MARKET:市价单
offset Offset 开平方向,默认为None OPEN:开仓 CLOSE:平仓 CLOSETODAY平今


以下是一个使用context.order( )下单的示例。

def m7_handle_data_bigquant_run(context, data):

    #获取股票代码
    instrument = '000001.SZA'

    #获取当前价格
    price = data.current(instrument, "close")

    #获取当前账户现金
    cash = context.portfolio.cash

    #计算买入数量
    buy_num = cash//price

    #买入
    context.order(instrument, buy_num)


\

按照目标持仓金额下单 context.order_value()

可通过 context.order_value( ) 方式进行按目标持仓金额下单。


order_value(instrument, value, price=0, **kwargs)

实例参数

参数类型 是否必选 参数含义
instrument str 需要买入的代码
value int 需要买入的金额
price float 交易的价格,默认为0表示市价单
order_type OrderType 默认为MARKET市价单 下单类型 LIMIT:限价单 MARKET:市价单


以下是一个使用 context.order_value( ) 下单的示例。

def m7_handle_data_bigquant_run(context, data):

    #获取股票代码
    instrument = '000001.SZA'

    #获取当前价格
    price = data.current(instrument, "close")

    #获取当前账户现金
    cash = context.portfolio.cash

    #计算要买入的现金,假如在这里为半仓买入
    buy_cash = cash * 0.5

    #买入
    context.order(instrument, buy_cash)


\

按照目标持仓百分比下单 context.order_percent( )

当买入某只标的是,如希望最终可以按照某百分比持仓。可通过 context.order_percent( ) 方式进行按目标持仓百分比下单,通常用于买单

order_percent(instrument, percent, price=0, **kwargs)

实例参数

参数类型 是否必选 参数含义
instrument str 需要买入的标的代码
percent int 目标持仓百分比
price float 交易的价格,默认为0表示市价单
order_type OrderType 默认为MARKET市价单 下单类型 LIMIT:限价单 MARKET:市价单


以下是一个使用 context.order_percent( ) 下单的示例。

def m7_handle_data_bigquant_run(context, data):

    #获取股票代码
    instrument = '000001.SZA'

    #买入50%仓位
    context.order_percent(instrument, 0.5)

\

按照目标持仓数量下单 context.order_target( )

如希望将持仓变动到某个固定数量时可通过 context.order_target( )实现,通常用于清空某只标的。


order_target(symbol, target, price=0, order_type=OrderType.LIMIT)

实例参数

参数类型 是否必选 参数含义
instrument str 需要买入的标的代码
target int 目标持仓数量
price float 交易的价格,默认为0表示市价单
order_type OrderType 默认为MARKET市价单 下单类型 LIMIT:限价单 MARKET:市价单


以下是一个使用 context.order_target( ) 平仓的示例。

def m7_handle_data_bigquant_run(context, data):

    #获取全部持仓股票代码
    holding_list = list(context.get_positions().keys())

    #全部平仓
    for ins in holding_list:
        context.order_target(ins,0)

\

【其他】实例方法

\

行情订阅 context.subscribe_bar()

订阅K行情后,可在K线处理函数中使用 data.history 的方式获取行情数据

实例参数 数据类型 是否必须 参数含义
instrument list[str] 需要订阅的标的代码
frequency str 否 默认’1m’ 需要订阅的频率,通常为 ‘1d’ ‘1m’


{{heading_numbering_zhCN}}

标签

量化策略实盘交易交易引擎
{link}