API文档 ========== 快速上手 ----------- 策略逻辑简介 ~~~~~~~~~~~~~~ 功夫系统上的策略在策略连接行情交易柜台,发送订阅请求以后,通过以下回调函数给用户发送消息,用户在不同的回调函数中调用功能函数实现获取行情,下单,时间回调等逻辑。详细数据定义和接口函数定义可查看后文,以下为一个策略示例 **注意 : 策略应和功夫安装目录在一个盘符下面,策略文件路径最好不要有空格** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: # -*- coding: UTF-8 -*- import kungfu.yijinjing.time as kft from kungfu.wingchun.constants import * # 期货 # SOURCE = "ctp" # ACCOUNT = "089270" # tickers = ["rb2001","rb2003"] # VOLUME = 2 # EXCHANGE = Exchange.SHFE #股票 SOURCE = "xtp" ACCOUNT = "15040910" tickers = ["600000","600001"] VOLUME = 200 EXCHANGE = Exchange.SSE # 启动前回调,添加交易账户,订阅行情,策略初始化计算等 def pre_start(context): context.add_account(SOURCE, ACCOUNT, 100000.0) context.subscribe(SOURCE, tickers, EXCHANGE) # context.subscribe("bar", tickers, EXCHANGE) # context.subscribe_all(SOURCE) context.ordered = False # 启动准备工作完成后回调,策略只能在本函数回调以后才能进行获取持仓和报单 def post_start(context): context.log.warning("post_start") log_book(context,None) # context.req_history_order(ACCOUNT) # context.req_history_trade(ACCOUNT) # 收到快照行情时回调,行情信息通过quote对象获取 def on_quote(context, quote): # context.log.info("[on_quote] {}".format(quote)) if quote.instrument_id in tickers: # 如果没有报单则报单 if not context.ordered: order_id = context.insert_order(quote.instrument_id, EXCHANGE, ACCOUNT, quote.last_price, VOLUME, PriceType.Limit, Side.Buy, Offset.Open) # order_id = context.insert_order(quote.instrument_id, EXCHANGE, ACCOUNT, quote.last_price, VOLUME, PriceType.Any, Side.Buy, Offset.Open)#上期所不支持市价单 if order_id > 0: context.ordered = True context.log.info("[order] (rid){} (ticker){}".format(order_id, quote.instrument_id)) # 通过添加时间回调,在三秒以后撤单 context.add_timer(context.now() + 3 * 1000000000, lambda ctx, event: cancel_order(ctx, order_id)) # 收到k线行情时回调,行情信息通过bar对象获取 def on_bar(context, bar): context.log.warning("[on_bar] {}".format(bar)) # 收到订单状态回报时回调 def on_order(context, order): context.log.info("[on_order] {}".format(order)) # 收到成交信息回报时回调 def on_trade(context, trade): context.log.info("[on_trade] {}".format(trade)) # 策略释放资源前回调,仍然可以获取持仓和报单 def pre_stop(context): context.log.info("[befor strategy stop]") # 策略释放资源后回调 def post_stop(context): context.log.info("[befor process stop]") ## 自定义函数 # 自定义持仓和资金日志输出函数 def log_book(context, event): context.log.warning("[avail]{}".format(context.book.asset.avail)) context.log.warning("[acc_avail]{}".format(context.get_account_book(SOURCE, ACCOUNT).asset.avail)) book = context.book asset = book.asset context.log.warning( "[strategy capital] (avail){} (margin){} (market_value){} (initial_equity){} (dynamic_equity){} (static_equity){} (realized_pnl){} (unrealized_pnl){}".format( asset.avail, asset.margin, asset.market_value, asset.initial_equity, asset.dynamic_equity, asset.static_equity, asset.realized_pnl, asset.unrealized_pnl)) book = context.get_account_book(SOURCE, ACCOUNT) asset = book.asset context.log.warning( "[account capital] (avail){} (margin){} (market_value){} (initial_equity){} (dynamic_equity){} (static_equity){} (realized_pnl){} (unrealized_pnl){}".format( asset.avail, asset.margin, asset.market_value, asset.initial_equity, asset.dynamic_equity, asset.static_equity, asset.realized_pnl, asset.unrealized_pnl)) context.logger.warning("acc_pos") for key in book.long_positions: log_stock_pos(context, book.long_positions[key]) # log_future_pos(context, pos) context.logger.warning("str_pos") for key in context.book.long_positions: log_stock_pos(context, context.book.long_positions[key]) # log_future_pos(context, pos) # 自定义期货持仓数据日志输出函数 def log_future_pos(context, pos): context.log.info( "(instrument_id){} (instrument_type){} (exchange_id){}(direction){} (volume){} (yesterday_volume){} (last_price){} (settlement_price){} (pre_settlement_price){} (avg_open_price){} (position_cost_price){} (margin){} (position_pnl){} (realized_pnl){} (unrealized_pnl){} ".format( pos.instrument_id, pos.instrument_type, pos.exchange_id, pos.direction, pos.volume, pos.yesterday_volume, pos.last_price, pos.settlement_price, pos.pre_settlement_price, pos.avg_open_price, pos.position_cost_price, pos.margin, pos.position_pnl, pos.realized_pnl, pos.unrealized_pnl)) # 自定义股票持仓数据日志输出函数 def log_stock_pos(context, pos): context.log.info( "(instrument_id){} (instrument_type){} (exchange_id){} (direction){} (volume){} (yesterday_volume){} (last_price){} (pre_close_price){} (close_price){} (avg_open_price){} (position_cost_price){} (realized_pnl){} (unrealized_pnl){} ".format( pos.instrument_id, pos.instrument_type, pos.exchange_id, pos.direction, pos.volume, pos.yesterday_volume, pos.last_price, pos.pre_close_price, pos.close_price, pos.avg_open_price, pos.position_cost_price, pos.realized_pnl, pos.unrealized_pnl)) # 自定义撤单回调函数 def cancel_order(context, order_id): action_id = context.cancel_order(order_id) if action_id > 0: context.log.info("[cancel order] (action_id){} (rid){} ".format(action_id, order_id)) 函数定义 ----------- 基本方法 ~~~~~~~~~~~~~~ pre_start ^^^^^^^^^^^^^ **启动前调用函数,在策略启动前调用,用于完成添加交易账户,订阅行情,策略初始化计算等** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - context - python对象 - 策略的全局变量,通过点标记(”.”)来获取其属性。 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: def pre_start(context): context.add_account(source, account, 100000.0) context.subscribe(source, tickers, exchange) context.count = 0 post_start ^^^^^^^^^^^^^^^^^ **启动后调用函数,策略连接上行情交易柜台后调用,本函数回调后,策略可以执行添加时间回调、获取策略持仓、报单等操作** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - context - python对象 - 策略的全局变量,通过点标记(”.”)来获取其属性。 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: def post_start(context): context.log.info("[log] {}".format("post_start")) context.add_timer(context.now() + 1*1000000000, lambda ctx, event: call(ctx, "test log1", "test log2")) context.add_timer(context.now() + 2*1000000000, log_pos) pre_stop ^^^^^^^^^^^^^^^^^ **退出前方法** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - context - python对象 - 策略的全局变量,通过点标记(”.”)来获取其属性。 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: # 退出前函数 def pre_stop(context): context.log.info("strategy will stop") post_stop ^^^^^^^^^^^^^^^^^ **退出前方法** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - context - python对象 - 策略的全局变量,通过点标记(”.”)来获取其属性。 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: # 退出前函数 def post_stop(context): context.log.info("process will stop") on_quote ^^^^^^^^^^^^^^^^^ **行情数据的推送会自动触发该方法的调用。** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - context - python对象 - 策略的全局变量,通过点标记(”.”)来获取其属性 * - quote - :ref:`Quote对象 ` - 行情数据 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: def on_quote(context, quote): context.log.info('[on_quote] {}, {}, {}'.format( quote.instrument_id, quote.last_price, quote.volume)) on_transaction ^^^^^^^^^^^^^^^^^ **逐笔成交行情数据的推送会自动触发该方法的调用** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - context - python对象 - 策略的全局变量,通过点标记(”.”)来获取其属性 * - transaction - :ref:`Transaction对象 ` - 逐笔成交行情数据 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: def on_transaction(context, transaction): context.log.info('[on_transaction] {}'.format(transaction)) on_entrust ^^^^^^^^^^^^^^^^^ **逐笔委托行情数据的推送会自动触发该方法的调用** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - context - python对象 - 策略的全局变量,通过点标记(”.”)来获取其属性 * - entrust - :ref:`Entrust对象 ` - 逐笔委托行情数据 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: def on_entrust(context, entrust): context.log.info('[on_entrust] {}'.format( entrust)) on_bar ^^^^^^^^^^^^^^^^^ **BAR行情数据的推送会自动触发该方法的调用** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - context - python对象 - 策略的全局变量,通过点标记(”.”)来获取其属性 * - bar - :ref:`Bar对象 ` - bar 行情数据 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: def on_bar(context, bar): context.log.warning("[on_bar] {}".format(bar)) on_order ^^^^^^^^^^^^^^^^^ **订单信息的更新会自动触发该方法的调用** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - context - python对象 - 策略的全局变量,通过点标记(”.”)来获取其属性 * - order - :ref:`Order对象 ` - 订单信息更新数据 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: def on_order(context, order): context.log.info('[on_order] {}, {}, {}'.format( order.order_id, order.status, order.volume)) on_trade ^^^^^^^^^^^^^^^^^ **策略订单成交信息的更新会自动触发该方法的调用** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - context - python对象 - 策略的全局变量,通过点标记(”.”)来获取其属性 * - trade - :ref:`Trade对象 ` - 订单成交更新数据 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: def on_trade(context, trade): context.log.info('[on_trade] {}, {}, {}'.format(trade.order_id, trade.volume, trade.price)) 行情交易函数 ~~~~~~~~~~~~~~ context.add_account ^^^^^^^^^^^^^^^^^^^^^^^^^ **添加交易柜台,策略需要先添加账户,才能使用该账户报单** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - source_id - str - 行情柜台ID * - account_id - str - 账户ID * - cash_limit - float - 策略首次运行时才设置初始资金 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - result - bool - 无 范例:: # 添加柜台、账户以及初始资金 context.add_account(source_id, account_id, cash_limit) context.subscribe ^^^^^^^^^^^^^^^^^^^^^^^^^ **订阅行情** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - source_id - str - 行情柜台ID * - instrument - list - 代码列表 * - exchange_id - :ref:`Exchange对象 ` - 交易所ID * - is_level2 - bool - 是否Level2 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: # 向source柜台的exchange_id交易所订阅了instruments列表中的合约的行情 context.subscribe(source, instruments, exchange_id, is_level2=False) #订阅bar行情,推送调用on_bar函数 context.subscribe("bar", instruments, exchange_id) context.subscribe_all ^^^^^^^^^^^^^^^^^^^^^^^^^ **订阅全市场行情** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - source - str - 行情柜台ID * - MarketType - :ref:`MarketType ` - 权限订阅数据类型(可选参数) * - SubscribeSecuDataType - :ref:`SubscribeSecuDataType ` - 证券数据类型(可选参数) * - SubscribeCategoryType - :ref:`SubscribeCategoryType ` - 证券品种类型(可选参数) 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: # 订阅source柜台全市场标的(不带可选参数) context.subscribe_all(source) #订阅某个柜台中某个交易所的某个品种(带可选参数) context.subscribe_all(source, MarketType.kSSE, SubscribeCategoryType.kStock, SubscribeSecuDataType.kSnapshot) #可选参数 SubscribeSecuDataType,SubscribeCategoryType可以多选 context.subscribe_all(source, MarketType.kSSE, SubscribeCategoryType.kStock | SubscribeCategoryType.kFund | SubscribeCategoryType.kOthers, SubscribeSecuDataType.kSnapshot | SubscribeSecuDataType.kTickExecution | SubscribeSecuDataType.kOrderQueue) context.insert_order ^^^^^^^^^^^^^^^^^^^^^^^^^ **报单函数** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - instrument_id - str - 合约ID * - exchange_id - str - 交易所ID * - account_id - str - 交易账号 * - limit_price - float - 价格 * - volume - int - 数量 * - priceType - :ref:`PriceType ` - 报单类型 * - side - :ref:`Side ` - 买卖方向 * - offset - :ref:`Offset ` - 开平方向 * - hedgeFlag - :ref:`HedgeFlag ` - 投机套保标识 (Python策略可以不填默认是投机 , c++策略需要填写) 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - order_id - long - 订单ID 范例 - 通过交易账户acc_1以12.0元的价格买200股浦发银行: :: context.insert_order("600000", Exchange.SSE, "acc_1", 12.0, 200, PriceType.Limit, Side.Buy, Offset.Open) - 通过交易账户acc_2以3500元的价格开仓买入2手上期所rb1906合约: :: context.insert_order("rb1906", Exchange.SHFE, "acc_2", 3500.0, 2, PriceType.Limit, Side.Buy, Offset.Open) **注(期权):当买卖方向为:Lock(锁仓)、Unlock(解锁)、Exec(行权)、Drop(放弃行权)时,设定的price(委托价)以及offset(开平方向)都不生效** ontext.cancel_order ^^^^^^^^^^^^^^^^^^^^^^^^^ **撤单函数** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - order_id - long - 订单ID 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - action_id - long - 订单操作 范例:: # 通过context.insert_order函数进行下单,同时用order_id记录下单的订单ID号, # 下单完成后,为了保证后续可能会出现的撤单操作能够正常执行,这里需要等待一段时间 order_id = context.insert_order(quote.instrument_id, exchange, account, quote.last_price - 10, volume, PriceType.Limit, Side.Buy, Offset.Open) if order_id > 0: context.log.info("[order] (rid){} (ticker){}".format(order_id, quote.instrument_id)) context.add_timer(context.now() + 1*1000000000, lambda ctx, event: cancel_order(ctx, order_id)) context.order_id = order_id # 将order_id传入cancel_order进行撤单操作,同时打印相关日志 def cancel_order(context,order_id): action_id = context.cancel_order(order_id) if action_id > 0: context.log.info("[cancel order] (action_id){} (rid){} ".format(action_id, order_id)) 投资组合相关功能 ~~~~~~~~~~~~~~~~~~~~~ 盈亏及持仓 ~~~~~~~~~~~~~~~~~~~~~ 功夫系统支持实时维护策略收益及持仓及对应的历史记录,针对不同的应用场景,提供共计四种不同的维护收益及持仓的模式。对于任一策略,具体采用的模式由两个 API 决定:context.hold_book() 及 context.hold_positions(),使用者需要在策略的 pre_start() 方法里决定是否调用这两个方法,系统在 pre_start() 处理完成时会根据是否调用这两个方法对应出的共计四种状态来设置维护收益及持仓的结果。 context.hold_book() ^^^^^^^^^^^^^^^^^^^^^^^^^ **保持策略运行历史上的交易过的标的。缺省设置即没有调用此方法时,系统只会维护当前策略代码中通过 subscribe 方法订阅过的标的;当调用此方法后,系统会在策略启动后,根据该同名策略在历史上的交易情况,构造一份包含所有该同名策略所交易过标的,及当前策略代码中通过 subscribe 订阅的标的的账目。注意此方法仅影响标的列表,对于每个标的的具体持仓数值,是由 hold_positions() 方法来决定。** 范例:: # 历史曾执行过订阅某些标的 # context.subscribe(source, ['600000', '600001']) # 当前代码中重置了 subscribe,且没有调用 context.hold_book(),则该策略只会收到新订阅的标的行情,且账目收益及持仓中只包含新订阅的标的 context.subscribe(source, ['600002', '600003']) # 如果调用 hold_book,则该策略订阅行情列表中会自动包含历史记录中有的标的 #,且账目收益及持仓中也会包含对应标的的数据 context.hold_book() context.hold_positions() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **保持账目中每一标的的历史持仓。缺省设置即没有调用此方法时,系统会通过同步柜台查询到的持仓数据来构建策略账目,每次策略启动后,账目中所有标的的持仓都会同步为最新的柜台账户对应的持仓;当调用此方法后,系统会使用功夫内部记录的历史数据来恢复策略的账目持仓。缺省设置保证了策略账目中的持仓数据是绝对准确的,但无法反映功夫运行期间内的策略历史交易情况;如果需要获取之前运行策略时产生的历史持仓记录,则需要通过调用该方法来使系统使用本地存储的历史记录,在这种情况下,当因为各种因素(例如在功夫系统外使用别的软件对同一账户手动交易)都会使得功夫内部维护的持仓记录产生偏差,(例如同一账户下对应的不同策略持仓汇总之和不等于账户总持仓),当发生此类偏差时,建议使用缺省模式来从账户持仓恢复策略持仓。** 范例:: # 策略账目所包含的持仓标的列表取决于是否调用context.hold_book(),但每个标的的具体持仓数值则由context.hold_positions()来决定, # 当缺省即没有调用该方法时,策略启动后的账目中的标的持仓等于所对应账户下的标的持仓: context.subscribe(source, ['600000', '600001']) # 当调用 hold_positions() 方法后,策略启动后的账目中标的持仓等于上次运行策略结束时所对应的标的持仓: context.hold_positions() context.book ^^^^^^^^^^^^^^^^^^^^^^^^^ **策略的投资组合** .. list-table:: :width: 600px * - 类型 * - :ref:`book对象 ` 范例:: #获取策略的投资组合,并打印相关参数 book = context.book context.log.warning("[strategy capital] (avail){} (margin){}".format(book.asset.avail, book.asset.margin)) context.get_account_book(SOURCE, ACCOUNT) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **账户的投资组合** .. list-table:: :width: 600px * - 类型 * - :ref:`book对象 ` 范例:: #获取账户的投资组合,并打印相关参数 book = context.get_account_book(SOURCE, ACCOUNT) context.log.warning("[account capital] (avail){} (margin){} ".format(book.asset.avail, book.asset.margin)) 辅助函数 ~~~~~~~~~~~~~~~~~~~~~ context.log.info ^^^^^^^^^^^^^^^^^^^^^^^^^ **输出INFO级别 Log 信息** .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - msg - str - Log信息 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: context.log.info(msg) context.log.warning ^^^^^^^^^^^^^^^^^^^^^^^^^ **输出WARN级别Log信息** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - msg - str - Log信息 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: context.log.warning(msg) context.log.error ^^^^^^^^^^^^^^^^^^^^^^^^^ **输出ERROR级别Log信息** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - msg - str - Log信息 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: context.log.error(msg) context.add_timer ^^^^^^^^^^^^^^^^^^^^^^^^^ **注册时间回调函数** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - nano - long - 触发回调的纳秒时间戳 * - callback - object - 回调函数 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: # 通过时间回调函数,在1s后撤去订单号为order_id的报单 context.add_timer(context.now() + 1*1000000000, lambda ctx, event: cancel_order(ctx, order_id)) context.add_time_interval ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **时间间隔回调函数** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - nano - long - 触发回调的纳秒时间戳 * - callback - object - 回调函数 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - 无 - 无 - 无 范例:: # 通过时间间隔回调函数,每过60s,调用一次func函数 context.add_time_interval(60 * 1000000000, lambda ctx, event: func(ctx)) 常量定义 ------------- Source柜台 ~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 值 - 说明 * - CTP - “ctp“ - CTP柜台 * - XTP - “xtp“ - XTP柜台 * - SIM - “sim“ - SIM柜台 柜台使用方法 :: # 案例示范 from kungfu.wingchun.constants import Source SOURCE = Source.XTP # SOURCE = "xtp" ACCOUNT = "1111111" def pre_start(context): # 添加账户柜台信息 context.add_account(SOURCE, ACCOUNT, 100000.0) .. _Exchange对象: Exchange交易所 ~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 值 - 说明 * - SSE - “SSE” - 上交所 * - SZE - “SZE” - 深交所 * - SHFE - “SHFE” - 上期所 * - DCE - “DCE” - 大商所 * - CZCE - “CZCE” - 郑商所 * - CFFEX - “CFFEX” - 中金所 * - INE - “INE” - 能源中心 交易所使用方法 :: # 案例示范 from kungfu.wingchun.constants import Exchange EXCHANGE = Exchange.SZE EXCHANGE_2 = Exchange.SSE def pre_start(context): # 订阅某些深交所股票的行情 context.subscribe(SOURCE, tickers, EXCHANGE) # 订阅某些上交所股票的行情 context.subscribe(SOURCE, tickers_2, EXCHANGE_2) .. _InstrumentType对象: InstrumentType 代码类型 ~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 说明 * - Unknown - 未知 * - Stock - 股票 * - Future - 期货 * - Bond - 债券 * - StockOption - 股票期权 * - Fund - 基金 * - TechStock - 科创板股票 * - Index - 指数 * - Repo - 回购 合约类型判断方法 :: # 案例示范 from kungfu.wingchun.constants import InstrumentType positions = context.get_account_book(SOURCE, ACCOUNT) for key in positions.long_positions: pos = positions.long_positions[key] if pos.instrument_type == InstrumentType.Stock: context.log.info("这个ticker的合约类型是股票类型") elif pos.instrument_type == InstrumentType.Future: context.log.info("这个ticker的合约类型是期货类型") elif pos.instrument_type == InstrumentType.Bond: context.log.info("这个ticker的合约类型是债券类型") .. _PriceType对象: PriceType 报单类型 ~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 说明 * - Limit - 限价,通用 * - Any - 市价,通用,对于股票上海为最优五档剩余撤销,深圳为即时成交剩余撤销 * - FakBest5 - 上海深圳最优五档即时成交剩余撤销,不需要报价 * - ForwardBest - 仅深圳本方方最优价格申报, 不需要报价 * - ReverseBest - 上海最优五档即时成交剩余转限价,深圳对手方最优价格申报,不需要报价 * - Fak - 股票(仅深圳)即时成交剩余撤销,不需要报价;期货即时成交剩余撤销,需要报价 * - Fok - 股票(仅深圳)市价全额成交或者撤销,不需要报价;期货全部或撤销,需要报价 报单类型使用方法 :: # 案例示范 from kungfu.wingchun.constants import PriceType, Side, Offset context.insert_order("600000", Exchange.SSE, "acc_1", 12.0, 200, PriceType.Limit, Side.Buy, Offset.Open) # 通过交易账户acc_1以12.0元的限价价格买开200股浦发银行 .. _Side对象: Side 买卖 ~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 说明 * - Buy - 买 * - Sell - 卖 * - Lock - 锁仓 * - Unlock - 解锁 * - Exec - 行权 * - Drop - 放弃行权 * - MarginTrade - 融资买入 * - ShortSell - 融券卖出 * - RepayMargin - 卖券还款 * - RepayStock - 买券还券 买卖方向使用方法 :: # 案例示范 from kungfu.wingchun.constants import PriceType, Side, Offset context.insert_order("600000", Exchange.SSE, "acc_1", 12.0, 200, PriceType.Limit, Side.Buy, Offset.Open) # 通过交易账户acc_1以12.0元的限价价格买开200股浦发银行 .. _Offset对象: Offset 开平 ~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 说明 * - Open - 开 * - Close - 平 * - CloseToday - 平今 * - CloseYesterday - 平昨 买卖方向使用方法 :: # 案例示范 from kungfu.wingchun.constants import PriceType, Side, Offset context.insert_order("600000", Exchange.SSE, "acc_1", 12.0, 200, PriceType.Limit, Side.Buy, Offset.Open) # 通过交易账户acc_1以12.0元的限价价格买开200股浦发银行 .. _HedgeFlag对象: HedgeFlag 投机套保标识 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 说明 * - Speculation - 投机 **注意 : Python策略中insert_order可以不写这个参数,因为已经默认是投机.c++策略中需要填写** .. _Direction: Direction 多空 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 说明 * - Long - 多 * - Short - 空 持仓方向使用方法 :: # 案例示范 from kungfu.wingchun.constants import Direction positions = context.get_account_book(SOURCE, ACCOUNT) for key in positions.long_positions: pos = positions.long_positions[key] if pos.direction == Direction .Long: context.log.info("这个ticker的持仓方向 : 多") elif pos.direction == Direction .Short: context.log.info("这个ticker的持仓方向 : 空") .. _OrderStatus: OrderStatus 委托状态 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 说明 * - Unknown - 未知 * - Submitted - 已提交 * - Pending - 等待 * - Cancelled - 已撤单 * - Error - 错误 * - Filled - 已成交 * - PartialFilledNotActive - 部分成交不在队列中(部成部撤) * - PartialFilledActive - 部分成交还在队列中 订单状态获取 :: # 案例示范 from kungfu.wingchun.constants import OrderStatus def on_order(context, order): if order.status == OrderStatus.Submitted: context.log.warning("此时的订单状态为 : 已提交") elif order.status == OrderStatus.Pending: context.log.warning("此时的订单状态为 : 等待中") elif order.status == OrderStatus.Filled: context.log.warning("此时的订单状态为 : 已成交") .. _MarketType对象: MarketType 权限订阅数据类型 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 说明 * - kNone - 表示全市场 * - kNEEQ - 北交所 * - kSHFE - 上期所 * - kCFFEX - 中金所 * - kDCE - 大商所 * - kCZCE - 郑商所 * - kINE - 上期能源 * - kSSE - 上交所 * - kSZSE - 深交所 * - kMax - 市场类型最大值 **注意 : 暂时不支持直连港交所, 港交所行情数据通过深交所和上交所的港股通获取, 市场类型为kSZSE/kSSE** .. _SubscribeSecuDataType对象: SubscribeSecuDataType 证券数据类型 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 说明 * - kNone - 订阅全部证券数据类别 * - kSnapshot - 订阅快照数据类别 * - kTickExecution - 订阅逐笔成交数据 * - kTickOrder - 订阅逐笔委托数据 * - kOrderQueue - 订阅委托队列数据 .. _SubscribeCategoryType对象: SubscribeCategoryType 证券品种类型 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 说明 * - kNone - 订阅全部证券品种类别 * - kStock - 订阅股票证券品种类别 * - kFund - 订阅基金证券品种类别 * - kBond - 订阅债券证券品种类别 * - kIndex - 订阅指数证券品种类别 * - kHKT - 订阅港股通证券品种类别 * - kOption - 订阅期权证券品种类别 * - kFutureOption - 订阅期货/期货期权证券品种类别 * - kOthers - 订阅其他证券品种类别 .. _ExecType: ExecType 标识 ~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 说明 * - Unknown - 未知 * - Cancel - 撤单 * - Trade - 成交 .. _BsFlag: BsFlag 标识 ~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 说明 * - Unknown - 未知 * - Buy - 买 * - Sell - 卖 数据结构 ----------- .. _Quote对象: Quote 行情信息 ~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 类型 - 说明 * - source_id - str - 柜台ID * - trading_day - str - 交易日 * - data_time - long - 数据生成时间 * - instrument_id - str - 合约ID * - exchange_id - str - 交易所 * - instrument_type - str - 合约类型 * - pre_close_price - float - 昨收价 * - pre_settlement_price - float - 昨结价 * - last_price - float - 最新价 * - volume - int - 数量 * - turnover - float - 成交金额 * - pre_open_interest - float - 昨持仓量 * - open_interest - float - 持仓量 * - open_price - float - 今开盘 * - high_price - float - 最高价 * - low_price - float - 最低价 * - upper_limit_price - float - 涨停板价 * - lower_limit_price - float - 跌停板价 * - close_price - float - 收盘价 * - settlement_price - float - 结算价 * - bid_price - list of float - 申买价 * - ask_price - list of float - 申卖价 * - bid_volume - list of float - 申买量 * - ask_volume - list of float - 申卖量 * - iopv - float - 基金实时参考净值 * - trading_phase_code - str - 交易 .. _Entrust对象: Entrust 逐笔委托 ~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 类型 - 说明 * - source_id - str - 柜台ID * - trading_day - str - 交易日 * - data_time - long - 数据生成时间 * - instrument_id - str - 合约ID * - exchange_id - str - 交易所 * - instrument_type - str - 合约类型 * - price - float - 委托价格 * - volume - int - 委托量 * - side - Side - 委托方向 * - price_type - PriceType - 订单价格类型(市价、限价、本方最优) * - main_seq - long - 主序号 * - seq - long - 子序号 * - biz_index - int - 业务序号 .. _Transaction对象: Transaction 逐笔成交 ~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 类型 - 说明 * - source_id - str - 柜台ID * - trading_day - str - 交易日 * - data_time - long - 数据生成时间 * - instrument_id - str - 合约ID * - exchange_id - str - 交易所 * - instrument_type - str - 合约类型 * - price - float - 成交价 * - volume - int - 成交量 * - bid_no - long - 买方订单号 * - ask_no - long - 卖方订单号 * - exec_type - :ref:`ExecType ` - SZ: 成交标识 * - bs_flag - :ref:`BsFlag ` - SH: 内外盘标识 * - main_seq - long - 主序号 * - seq - long - 子序号 * - biz_index - int - 业务序号 .. _Order对象: Order 订单回报 ~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 类型 - 说明 * - order_id - long - 订单ID * - insert_time - long - 订单写入时间 * - update_time - long - 订单更新时间 * - trading_day - str - 交易日 * - instrument_id - str - 合约ID * - exchange_id - str - 交易所ID * - account_id - str - 账号ID * - client_id - str - Client ID * - instrument_type - str - 合约类型 * - limit_price - float - 价格 * - frozen_price - float - 冻结价格(市价单冻结价格为0.0) * - volume - int - 数量 * - volume_traded - int - 成交数量 * - volume_left - int - 剩余数量 * - tax - float - 税 * - commission - float - 手续费 * - status - :ref:`OrderStatus ` - 订单状态 * - error_id - int - 错误ID * - error_msg - str - 错误信息 * - parent_id - int - 母订单ID * - side - str - 买卖方向 * - offset - str - 开平方向 * - price_type - str - 价格类型 * - volume_condition - str - 成交量类型 * - time_condition - str - 成交时间类型 .. _Trade对象: Trade 订单成交 ~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 类型 - 说明 * - order_id - long - 订单ID * - parent_order_id - long - 母订单ID * - trade_id - long - 成交ID * - trade_time - long - 成交时间(时间戳时间) * - trading_day - str - 成交时间(年月日) * - instrument_id - str - 合约ID * - exchange_id - str - 交易所ID * - account_id - str - 账号ID * - client_id - str - Client ID * - instrument_type - str - 合约类型 * - side - str - 买卖方向 * - offset - str - 开平方向 * - price - float - 成交价格 * - volume - int - 成交量 * - tax - float - 税 * - commission - float - 手续费 * - close_today_volume - int - 今日收盘成交量 * - hedge_flag - int - 投机套保标识 .. _Bar对象: Bar k线行情 ~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 类型 - 说明 * - trading_day - str - 交易日 * - instrument_id - str - 合约代码 * - exchange_id - str - 交易所代码 * - start_time - int - 开始时间 * - end_time - int - 结束时间 * - open - double - 开始价格 * - close - double - 结束价格 * - low - double - 最低价格 * - high - double - 最高价格 * - volume - int - 区间交易量 * - start_volume - int - 初始交易量 * - tick_count - int - 区间有效tick Utils ~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 类型 - 说明 * - hash_instrument - long - 持仓列表中的key值 * - is_valid_price - bool - 判断当前价格是否为有效价格 * - is_final_status - str - 判断当前状态是否为最终状态 * - get_instrument_type - :ref:`InstrumentType ` - 获取类型 Utils范例 :: # 案例示范 from pykungfu import wingchun as wc wc.utils.hash_instrument(exchange_id, instrument_id) wc.utils.is_valid_price(quote.last_price) wc.utils.is_final_status(order.status) wc.utils.get_instrument_type(exchange_id, instrument_id) .. _book对象: Book 投资组合 ~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :width: 600px * - 属性 - 类型 - 说明 * - asset - :ref:`asset ` - 投资组合资金信息 * - asset_margin - :ref:`asset_margin ` - 两融相关信息 * - long_positions - List of Position - 投资组合的持仓列表,对应多头仓位 * - short_positions - List of Position - 投资组合的持仓列表,对应空头仓位 * - has_long_position - bool - 判断是否为多头仓位 * - has_short_position - bool - 判断是否为空头仓位 * - has_position - bool - 判断是否有仓位 * - get_long_position - dict - 多头持仓信息 * - get_short_position - dict - 空头持仓信息 * - has_position_for - bool - 判断是否有持仓 获取投资组合持仓列表范例 :: # 通过context.log.info打印组合投资的多头持仓列表 positions = context.get_account_book(SOURCE, ACCOUNT).long_positions for key in positions: pos = positions[key] context.log.info("(instrument_id){} (direction){} (volume){} (yesterday_volume){} ".format(pos.instrument_id, pos.direction, pos.volume, pos.yesterday_volume) :: # 通过context.log.info打印持仓列表 context.book = context.get_account_book(SOURCE, ACCOUNT) context.book.asset_margin context.book.has_long_position(exchange_id, instrument_id) context.book.has_position(exchange_id, instrument_id) context.book.get_long_position(exchange_id, instrument_id) context.book.has_position_for(quote) # context.book.has_position_for(order) # context.book.has_position_for(trade) .. _asset: Book.asset 投资组合资金信息 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. list-table:: :width: 600px * - 属性 - 类型 - 说明 * - avail - float - 可用资金 * - margin - float - 保证金(期货) * - market_value - float - 市值 * - initial_equity - float - 初始权益 * - dynamic_equity - float - 动态权益 * - static_equity - float - 静态权益 * - realized_pnl - float - 已实现盈亏 * - unrealized_pnl - float - 未实现盈亏 * - accumulated_fee - float - 累计手续费 * - intraday_fee - float - 当日手续费 * - frozen_cash - float - 冻结资金 * - frozen_margin - float - 冻结保证金 * - frozen_fee - float - 冻结手续费 * - position_pnl - float - 持仓盈亏 * - close_pnl - float - 平仓盈亏 .. _asset_margin: Book.asset_margin 两融相关信息 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. list-table:: :width: 600px * - 属性 - 类型 - 说明 * - total_asset - float - 总资产 * - avail_margin - float - 可用保证金 * - cash_margin - float - 融资占用保证金 * - short_margin - float - 融券占用保证金 * - margin - float - 总占用保证金 * - cash_debt - float - 融资负债 * - short_cash - float - 融券卖出金额 * - short_market_value - float - 融券卖出证券市值 * - margin_market_value - float - 融资买入证券市值 * - margin_interest - float - 融资融券利息 * - margin_fee - float - 融资融券费用 * - settlement - float - 融资融券清算资金 * - credit - float - 信贷额度 * - collateral_ratio - float - 担保比例 **投资组合持仓明细** 参数 .. list-table:: :width: 600px * - 参数 - 类型 - 说明 * - instrument_id - str - 合约ID * - exchange_id - :ref:`Exchange ` - 交易所ID * - direction - :ref:`Direction ` - 持仓方向 返回 .. list-table:: :width: 600px * - 返回 - 类型 - 说明 * - position - Position对象 - 账户持仓明细 范例 :: book = context.get_account_book(SOURCE, ACCOUNT) context.log.info("[pos]{}".format(book.get_position( Direction.Long,Exchange.SSE,"600000").volume)) Position 持仓信息 ~~~~~~~~~~~~~~~~~~~~~ 期货持仓 .. list-table:: :width: 600px * - 属性 - 类型 - 说明 * - account_id - str - 账户ID * - instrument_id - str - 合约ID * - instrument_type - :ref:`InstrumentType ` - 合约类型 * - exchange_id - str - 交易所 * - direction - :ref:`Direction ` - 方向 * - volume - int - 总仓 * - yesterday_volume - int - 昨仓 * - frozen_total - int - 冻结数量 * - frozen_yesterday - int - 冻结昨仓 * - last_price - float - 最新价 * - settlement_price - float - 结算价 * - pre_settlement_price - float - 昨结价 * - avg_open_price - float - 开仓均价 * - position_cost_price - float - 持仓成本 * - margin - float - 保证金 * - position_pnl - float - 持仓盈亏 * - close_pnl - float - 平仓盈亏 * - realized_pnl - float - 已实现盈亏 * - unrealized_pnl - float - 未实现盈亏 * - trading_day - float - 交易日 * - update_time - float - 订单更新时间 * - source_id - float - 行情柜台ID * - client_id - str - Client ID 股票持仓 .. list-table:: :width: 600px * - 属性 - 类型 - 说明 * - account_id - str - 账户ID * - instrument_id - str - 合约ID * - instrument_type - :ref:`InstrumentType ` - 合约类型 * - exchange_id - str - 交易所 * - direction - :ref:`Direction ` - 方向 * - volume - int - 总仓 * - yesterday_volume - int - 昨仓 * - frozen_total - int - 冻结数量 * - frozen_yesterday - int - 冻结昨仓 * - last_price - float - 最新价 * - pre_close_price - float - 昨收价 * - close_price - float - 收盘价 * - avg_open_price - float - 开仓均价 * - position_cost_price - float - 持仓成本 * - realized_pnl - float - 已实现盈亏 * - unrealized_pnl - float - 未实现盈亏 * - trading_day - float - 交易日 * - update_time - float - 订单更新时间 * - source_id - float - 行情柜台ID * - client_id - str - Client ID 功夫自带python库(pipfile) -------------------------------------- :: url = "http://mirrors.aliyun.com/pypi/simple/" verify_ssl = false name = "pypi" [packages] conan = "==1.22" pywin32 = {version = "==227",sys_platform = "== 'win32'"} pyinstaller = "==3.6" click = "==7.1.1" tabulate = "==0.8.6" prompt_toolkit = "==1.0.14" PyInquirer = "==1.0.3" psutil = "==5.7.0" chinesecalendar = "==1.4.0" zhdate = "==0.1" schema = "==0.7.1" rx = "==3.0.1" numpy = "==1.16.4" pandas = "==0.24.2" statsmodels = "==0.10.1" sortedcontainers = "==2.1.0" recordclass = "==0.12.0.1" dotted_dict = "==1.1.2" plotly = "==4.0.0" tushare = "==1.2.39" [dev-packages] clang-format = "==9.0.0"