跳转至

函数定义

本章节我们继续深入到 CtaTemplate 类中封装好的函数,再认识一下 ctaEngine 这个“看不到的”库,在实际编写策略的时候,我们可以使用这些函数来获取到我们想要的数据和信息,根据这些数据和信息来控制买入卖出,达到盈利的目的。

总之 PythonGo 是提供了一个框架,给你把数据准备好,你需要使用这些数据处理后来达到你想要的策略效果,不要被框架受限,你是在写 Python 代码,不是在写“PythonGo 代码”。

输出日志到控制台

函数:output

说明:输出信息到控制台

参数 类型 必填 说明
content str 想输出的文本信息

用法:

self.output("Hello World")

注意事项:控制台目前输出内容有做控制,不建议在控制台输出大量数据。

获取资金账户信息

函数:get_investor_account

说明:获取某个账户的资金情况

参数 类型 必填 说明
investor str 投资者帐号

用法:

# 获取资金账号 123456 的资金信息
self.get_investor_account("123456")

返回结果:

账户数据类,是基础数据结构中的 AccountData,这里展示 JSON 格式方便观看

{
    "gatewayName": "", // Gateway 名称
    "rawData": null, // 原始数据
    "datetime": DateTimeObject, // Python datetime 对象
    "accountID": "123456", // 账户代码
    "vtAccountID": "123456", // 账户在 vt 中的唯一代码,通常是 Gateway 名.账户代码(一般和 accountID 是一样)
    "preBalance": 104729701.23, // 昨日账户结算净值
    "balance": 105440025.05, // 账户净值
    "available": 97564545.05, // 可用资金
    "commission": 556.17864, // 今日手续费
    "margin": 7164600, // 保证金占用
    "closeProfit": 0, // 平仓盈亏
    "positionProfit": 710880 // 持仓盈亏
}

获取账户持仓信息

函数:getInvestorPosition

说明:获取某个账户的持仓情况

参数 类型 必填 说明
investor str 投资者帐号

用法:

ctaTemplate.py
self.getInvestorPosition("123456")

返回结果:

数组(List[dict, ...]),里面的字段是账户的持仓数据类,单个合约持仓返回结果如下:

[
    {
        "BrokerID": "0001", // 经纪公司编号
        "ExchangeID": "CFFEX", // 交易所代码
        "InvestorID": "123456", // 投资者编号
        "InstrumentID": "IC2201", // 合约代码
        "Direction": "多", // 持仓方向:'多' 或 '空'
        "HedgeFlag": "1", // 投机套保方向:1 - 投机,2 - 套利,3 - 套保,4 - 做市商,5 - 备兑
        "Position": 10, // 总持仓量
        "FrozenPosition": 0, // 开仓冻结持仓
        "FrozenClosing": 0, // 平仓冻结持仓
        "YdFrozenClosing": 0, // 昨持仓平仓冻结持仓
        "YdPositionClose": 0, // 昨持仓可平仓数量(包括平仓冻结持仓)
        "OpenVolume": 10, // 今日开仓数量(不包括冻结)
        "CloseVolume": 0, // 今日平仓数量(包括昨持仓的平仓,不包括冻结)
        "StrikeFrozenPosition": 0, // 行权执行冻结
        "AbandonFrozenPosition": 0, // 行权放弃冻结
        "PositionCost": 14358400, // 总持仓成本
        "YdPositionCost": 0, // 初始昨日持仓成本(当日不变)
        "CloseProfit": 0, // 平仓盈亏
        "PositionProfit": 0, // 持仓盈亏
        "OpenAvgPrice": 7179.2, // 开仓均价
        "PositionAvgPrice": 7179.2, // 持仓均价
        "CloseAvailable": 25, // 当前可平
        "PositionClose": 25 // 总持仓可平仓数量(包括平仓冻结持仓)
    }
]

处理账户的持仓情况

弃用提示

该方法将在后续的版本中逐步弃用,请使用最新的 get_position 来获取持仓

函数:manage_position

说明:通过传入 index 来处理指定账户的持仓情况(默认第一个),会自动将所有合约的持仓都设置好

参数 类型 必填 说明
index str 投资者帐号序号

用法

self.manage_position()

注意事项:

通过在 onStart 回调函数中使用该方法可进行持仓信息的初始化,后续在代码中可以使用策略模板处理好的仓位管理获取对应的持仓,具体如下:

self.pos = {} # 总投机持仓
self.tpos0L = {} # 今持多仓
self.tpos0S = {} # 今持空仓
self.ypos0L = {} # 昨持多仓
self.ypos0S = {} # 昨持空仓

由于都是字典类型,可以通过 get 方法取值:

pos = self.pos.get("IC2309")

这样就能获取到当前账户下 IC2309 合约的净投机持仓数量,这里要注意,净多头持仓获取到的数是正值,净空头持仓获取到的数是负值。其次仓位信息是由策略模板自动维护的,主要逻辑是在 onTick 实时行情中里面判断昨仓和今仓,再通过 onTrade 收到的成交回报中计算持仓的新增或减少。您也可以继承后自己再策略里面通过其他方式维护持仓。

获取账户持仓

仅适用于 v1.2023.0829.x 和 v2.2023.0829.x 之后的版本

函数:get_position

参数 类型 必填 说明
instrument str 合约代码
hedgeflag str 投机套保标志:1 投机(默认), 2 套利, 3 套保, 4 做市商, 5 备兑
investor str 资金账号,多账号情况下默认使用第一个帐号

返回:

参数 类型 说明
Position | Position_p Position | Position_p 持仓数据

用法:

position = self.get_position("ag2310")

# 总持仓
position.position

# 净持仓
position.net_position

# 多头总持仓
position.long.position

# 空头今持仓
position.short.td_position_close

# 空头昨持仓
position.short.yd_position_close

# 今日买开数量
position.long.open_volume

# 今日买平数量
position.long.close_volume

# 使用字符串仅获取空头持仓
short_position = self.get_position("ag2310").get_single_position("short")
short_position.position # 空头总持仓

# 获取套保持仓
position = self.get_position("ag2310", hedgeflag="3")
position.long.position # 套保多头总持仓

注意:

  1. 该方法的返回值是 Position | Position_p 类,所有的类属性都是不可修改与赋值的

  2. 如果开始使用该方法,则不再需要自己同步持仓,因为每次获取到的持仓都是最新的

  3. 持仓对应的属性,编辑器会自动补全,还能够显示属性对应的含义,如果需要更详细的信息,看这里

获取某一品种的所有合约

函数:get_InstListByExchAndProduct

参数 类型 必填 说明
exchange str 交易所代码
product str 品种代码

用法:

获取大商所棕榈油品种的所有期货期权合约的合约代码

self.get_InstListByExchAndProduct('DCE', 'p')

返回结果:

{
    '1': ['p2204', 'p2205', 'p2206', 'p2207', 'p2208', 'p2209', 'p2210', 'p2211', 'p2212', 'p2301', 'p2302', 'p2303', 'pMain'],
    '2': ['p2205-C-7400', 'p2205-C-7500', 'p2205-P-5800', 'p2205-P-5900', 'p2205-P-6000', 'p2205-P-6100', ...]
}

其中字典的键所代表的说明:
期货:1
期权:2
交易所套利:3
即期:4
期转现:5
未知类型:6
证券:7
股票期权:8
金交所现货:9
金交所递延:a
金交所远期:b
现货期权:h
外汇:c
TAS 合约:d
金属指数:e

获取上交所 ETF 证券合约代码

self.get_InstListByExchAndProduct('SSE', 'ETF')

注意:

  1. 如果需要获取股票期权合约,则品种代码为 ETF_O
  2. 如果获取不到 ETF 合约,那可能是你登录的环境不支持股票期权

获取合约信息

函数:get_contract

参数 类型 必填 说明
exchange str 交易所代码
symbol str 合约代码

用法:

self.get_contract(exchange="CFFEX", symbol="IC2306")

返回结果:

合约数据类,是基础数据结构中的 ContractData,这里展示 JSON 格式方便观看

{
    "symbol": "IC2306", // 合约代码
    "exchange": "CFFEX", // 交易所
    "vtSymbol": "IC2306", // 合约代码
    "name": "中证500指数2306", // 合约中文名
    "productClass": null, // 合约类型
    "size": 200.0, // 合约大小(合约乘数)
    "priceTick": 0.2, // 合约最小价格
    "min_limit_order_volume": 1, // 最小下单量
    "expire_date": "20230616", // 合约到期日
    "strikePrice": 0.0, // 期权行权价
    "underlyingSymbol": "IC", // 标的物合约代码
    "optionType": null // 期权类型
}

获取合约持仓成本

弃用提示

该方法将在后续的版本中逐步弃用,请使用最新的 get_position 来获取合约持仓成本

函数:get_investor_cost

参数 类型 必填 说明
symbol str 合约代码
investor str 投资者帐号

用法:

self.get_investor_cost(symbol="IC2306")

返回结果:数组(List[dict, ...]

[
    {
        "symbol": "IC2306", // 合约代码
        "direction": "SHORT", // 持仓方向,SHORT - 空,LONG - 多
        "open_avg_price": 6116.4, // 开仓均价
        "position_avg_price": 6116.4, // 持仓均价
        "position_cost": 4893120.0 // 总持仓成本
    }
]

暂停策略

函数:pause_strategy

说明:在代码里暂停当前策略,等效于客户端点暂停按钮

用法:

self.pause_strategy()

注意事项:不能在 onStartonStop 中使用本方法,否则会进入死循环

错误回报

在策略运行过程中产生的接口调用错误和对应的语法错误将会通过 onErr 函数推送给策略,并且会在控制台显示。

onErr 的回调入参是 Python 字典,其中包括 errCode (错误代码)和 errMsg (具体错误信息)两个键值; errCode 代码包括以下信息:

参数 说明
0001 onTick 触发语法错误
0002 onOrder 触发语法错误
0003 onTrade 触发语法错误
0004 发单撤单错误
0005 onInit 触发语法错误
0006 onStart 触发语法错误
0007 onStop 触发语法错误
0008 onTimer 触发语法错误

注意事项:

  1. 其他报单错误也会通过本回调推送,但是具体错误代码和信息由交易所推送

定时器

弃用提示

定时器将在后续版本逐渐弃用,请改用 utils 库中的 Scheduler 代替

注册定时器

函数:regTimer

参数 类型 必填 说明
tid int 定时器编号(唯一)
mSecs int 定时器触发的毫秒数

用法:

注册一个一秒钟运行一次的定时器,注册成功之后将会触发 onTimer 函数

self.regTimer(tid=1, mSecs=1000)

定时器回调

函数:onTimer

参数 类型 必填 说明
tid int 定时器编号(唯一)

说明:

开启定时器后收到定时推送,接受一个参数 tid 参数为定时器编号

用法:

由于这是一个回调函数,所以是需要你把代码写在函数里,然后根据 tid 来判断并编写处理代码

def onTimer(self, tid: int) -> None:
    """收到定时推送"""
    if tid == 1:
        print("tid = 1")
    elif tid == 2:
        print("tid = 2")

移除定时器

函数:removeTimer

参数 类型 必填 说明
tid int 定时器编号(唯一)

用法:

self.removeTimer(tid=1)

发单方法

平今平昨区别

上期所(SHFE) / 能源中心(INE)

  • 区分平今平昨

  • 以平仓委托,按平仓费率计算手续费

  • 以平今委托,按平今费率计算手续费

中金所(CFFEX) / 郑商所(CZCE) / 大商所(DCE)...

  • 只有平仓委托一种指令,没有平今委托

  • 若是当日先前已有开仓 N 手,不论有多少昨仓,之后的平仓成交 N 手,按平今费率计算手续费

这是交易所的规则,与软件无关

弃用提示

cover, cover_t, cover_y, cover_fak, cover_fok, sell, sell_t, sell_y, sell_fak, sell_fok 方法已经弃用,在新版本中将删除这些方法,请使用最新的 auto_close_position 方法代替

自动平仓

函数:auto_close_position

说明:自动平仓,默认平今优先

参数 类型 必填 说明
price float 报单价格
volume int 报单数量
symbol str 合约代码
exchange str 交易所代码
order_direction str 买卖方向: buy 买入平仓, sell 卖出平仓
shfe_close_first bool 上期平仓优先
hedgeflag str 投机套保方向: 1 投机, 2 套利, 3 套保, 4 做市商, 5 备兑
order_type str 交易指令: 0 GFD, 1 FAK, 2 FOK
memo str 自定义备注,可以通过此参数对应下的单
investor str 投资者帐号

注意事项:

  • 上期所(SHFE)和能源中心(INE)平仓时区分今仓和昨仓

示例:

# 中金所 IC2309 合约以 5890 的价格卖出平仓 10 手
self.auto_close_position(
    price=5890,
    volume=10,
    symbol="IC2309",
    exchange="CFFEX",
    order_direction="sell"
)
# 上期所 ag2306 合约以 3069 的价格买入平仓 10 手(如有今仓优先平今仓)
self.auto_close_position(
    price=3069,
    volume=10,
    symbol="ag2306",
    exchange="SHFE",
    order_direction="buy"
)
# 上期所 ag2306 合约以 3069 的价格卖出平仓 10 手(如有昨仓优先平昨仓)
self.auto_close_position(
    price=3069,
    volume=10,
    symbol="ag2306",
    exchange="SHFE",
    order_direction="sell",
    shfe_close_first=True
)
# 中金所 IC2309 合约以 5890 的价格发送 FAK 指令的卖出平仓 10 手
self.auto_close_position(
    price=5890,
    volume=10,
    symbol="IC2309",
    exchange="CFFEX",
    order_direction="sell",
    order_type="1"
)

FAK 委托指令:当所委托的手数不能全部成交时,将能成交的部分手数全部成交,不能成交的立即撤单。

FAK 买入开仓

函数:buy_fak

说明:买入开仓,使用 FAK 指令

参数 类型 必填 说明
price float 报单价格
volume int 报单数量
symbol str 合约代码
exchange str 交易所代码
memo str 自定义备注,可以通过此参数对应下的单
investor str 投资者帐号

FAK 卖出开仓

函数:short_fak

说明:卖出开仓,使用 FAK 指令

参数 类型 必填 说明
price float 报单价格
volume int 报单数量
symbol str 合约代码
exchange str 交易所代码
memo str 自定义备注,可以通过此参数对应下的单
investor str 投资者帐号

FOK 买入开仓

函数:buy_fok

说明:买入开仓,使用 FOK 指令

参数 类型 必填 说明
price float 报单价格
volume int 报单数量
symbol str 合约代码
exchange str 交易所代码
memo str 自定义备注,可以通过此参数对应下的单
investor str 投资者帐号

FOK 卖出开仓

函数:short_fok

说明:卖出开仓,使用 FOK 指令

参数 类型 必填 说明
price float 报单价格
volume int 报单数量
symbol str 合约代码
exchange str 交易所代码
memo str 自定义备注,可以通过此参数对应下的单
investor str 投资者帐号

发送 FAK 委托指令

函数:sendOrderFAK

说明:高阶下单方法,使用 FAK 委托自行指令

参数 类型 必填 说明
orderType str 报单方向
price float 报单价格
volume int 报单数量
symbol str 合约代码
exchange str 交易所代码
memo str 自定义备注,可以通过此参数对应下的单
investor str 投资者帐号

注意事项:通过传入参数 orderType 的不同,实现平仓,开仓的委托方式,具体如下:

CTAORDER_BUY # 买开
CTAORDER_SELL # 卖平
CTAORDER_SELL_TODAY # 卖平今
CTAORDER_SHORT # 卖开
CTAORDER_COVER # 买平
CTAORDER_COVER_TODAY # 买平今

发送 FOK 委托指令

函数:sendOrderFOK

说明:高阶下单方法,使用 FOK 委托自行指令

参数 类型 必填 说明
orderType str 报单方向
price float 报单价格
volume int 报单数量
symbol str 合约代码
exchange str 交易所代码
memo str 自定义备注,可以通过此参数对应下的单
investor str 投资者帐号

注意事项:通过传入参数 orderType 的不同,实现平仓,开仓的委托方式,具体如下:

CTAORDER_BUY # 买开
CTAORDER_SELL # 卖平
CTAORDER_SELL_TODAY # 卖平今
CTAORDER_SHORT # 卖开
CTAORDER_COVER # 买平
CTAORDER_COVER_TODAY # 买平今

发送市价 FAK 指令

函数:sendOrderMarketFAK

说明:高阶下单方法,使用 FAK 委托指令发送市价委托

注意事项:不需要填写价格参数

参数 类型 必填 说明
orderType str 报单方向
volume int 报单数量
symbol str 合约代码
exchange str 交易所代码
memo str 自定义备注,可以通过此参数对应下的单
investor str 投资者帐号

PythonGoCore

本库属于新版功能,只在新版本存在。本库所有方法均有流控,请注意使用频率。

获取主连合约列表

仅适用于 v1.2023.0724.x 和 v2.2023.0724.x 之后的版本

函数:get_dominant_list

说明:根据交易所代码获取该交易所所有的主连合约

参数 类型 必填 说明
exchange str 交易所代码

示例:

# 获取上期所的主连合约

from core import MarketCenter
from typing import List

market_center = MarketCenter()
dominant_list: List[str] = market_center.get_dominant_list("SHFE")

print(dominant_list)

返回:

['ag2310', 'al2309', 'ao2311', 'au2310', 'br2401', 'bu2311', 'cu2309', 'fu2311', 'hc2310', 'ni2309', 'pb2309', 'rb2310', 'ru2401', 'sn2309', 'sp2401', 'ss2310', 'wr2310', 'zn2309']

查询合约带交易日的交易时段

仅适用于 v1.2023.0609.x 和 v2.2023.0609.x 之后的版本

函数:get_instrument_trade_time

说明:查询某个合约带交易日的交易时段

参数 类型 必填 说明
exchange str 交易所代码
instrument str 合约代码

示例:

# 获取 ag2309 的交易时段
from core import MarketCenter

market_center = MarketCenter()
instrument_trade_time: dict = market_center.get_instrument_trade_time("SHFE", "ag2309")

print(instrument_trade_time)

返回:

{
    "tradingDay":"20230816",
    "sections":[
        {
            "head":"2023-08-15 21:00:00",
            "tail":"2023-08-16 02:30:00"
        },
        {
            "head":"2023-08-16 09:00:00",
            "tail":"2023-08-16 10:15:00"
        },
        {
            "head":"2023-08-16 10:30:00",
            "tail":"2023-08-16 11:30:00"
        },
        {
            "head":"2023-08-16 13:30:00",
            "tail":"2023-08-16 15:00:00"
        }
    ]
}

查询品种的交易时段信息

仅适用于 v1.2023.0609.x 和 v2.2023.0609.x 之后的版本

函数:get_product_trade_time

说明:查询某个品种的交易时段

参数 类型 必填 说明
exchange str 交易所代码
product str 品种代码

示例:

# 获取 ag 的交易时段
from core import MarketCenter

market_center = MarketCenter()
product_trade_time: dict = market_center.get_product_trade_time("SHFE", "ag")

print(product_trade_time)

示例:

{
    "exchange":"SHFE",
    "product":"ag",
    "nextTradingDay":"20230817",
    "sections":[
        {
            "order":0,
            "open":"21:00:00",
            "close":"02:30:00"
        },
        {
            "order":1,
            "open":"09:00:00",
            "close":"10:15:00"
        },
        {
            "order":2,
            "open":"10:30:00",
            "close":"11:30:00"
        },
        {
            "order":3,
            "open":"13:30:00",
            "close":"15:00:00"
        }
    ],
    "timezone":8
}

底层 ctaEngine 接口说明

这里的函数都是 ctaEngine 库的未经过封装的函数,正常来讲,我们直接使用已经封装过的函数即可

订阅合约

函数:ctaEngine.subMarketData

说明:此方法传入的参数为字典类型,以下是字典中所需的字段

参数 类型 必填 说明
sid CtaTemplate 实例化后的父类,self
InstrumentID str 合约代码
ExchangeID str 交易所代码

取消订阅合约

函数:ctaEngine.unsubMarketData

说明:此方法传入的参数为字典类型,以下是字典中所需的字段

参数 类型 必填 说明
sid CtaTemplate 实例化后的父类,self
InstrumentID str 合约代码
ExchangeID str 交易所代码

发送委托

函数:ctaEngine.sendOrder

说明:此方法传入的参数为字典类型,以下是字典中所需的字段

参数 类型 必填 说明
sid int 实例 ID
ordertype str 0 - GFD,1 - FAK,2 - FOK
hedgeflag str 1 - 投机,2 - 套利,3 - 套保,4 - 做市商,5 - 备兑
direction str 0 - 买,1 - 卖
offset str 0 - 开仓,1 - 平仓,3 - 平今仓
price float 报单价格
volume int 报单数量
symbol str 合约代码
exchange str 交易所代码
memo str 自定义备注,可以通过此参数对应下的单
investor str 投资者帐号

撤单

函数:ctaEngine.cancelOrder

参数 类型 必填 说明
vtOrderID int 所有报单方法报单成功后返回的 order_id

获取K线数据

函数:ctaEngine.getKLineData

注意

请不要在 onTick 中调用 loadBar 或者 getKLineData

以上两个方法每天最多调用一百次,超过一百次将会被永久封禁 IP

参数 类型 必填 说明
symbol str 合约代码
exchange str 交易所代码
start_date str K 线开始日期(年月日),例:20220608
days int 天数(从数据开始时间往前算,不超过 30 天)
years int 年数,获取分钟线时应为 0
start_time str K 线开始时间(时分秒),例:09:00:00
k_type int 分钟线(枚举值 1, 5, 15, 30, 60)

调用示例:

分钟线

# 获取 IC2309 从 20230608 往前 10 天的 1 分钟 K线
ctaEngine.getKLineData("IC2309", "CFFEX", "20230608", 10, 0, "09:00:00", 1)
日线
# 获取 IC2309 截止 20230608 过去一年的日线
ctaEngine.getKLineData("IC2309", "CFFEX", "20230608", 0, 1)

获取投资者账户资金情况

函数:ctaEngine.getInvestorAccount

参数 类型 必填 说明
investor str 投资者帐号

调用示例:

# 获取资金账户为 166225 的账户资金情况
ctaEngine.getInvestorAccount("166225")

获取投资者账户持仓情况

函数:ctaEngine.getInvestorPosition

参数 类型 必填 说明
investor str 投资者帐号

调用示例:

# 获取资金账户为 166225 的账户持仓明细
ctaEngine.getInvestorPosition("166225")

获取合约信息

函数:ctaEngine.getInstrument

参数 类型 必填 说明
exchange str 交易所代码
symbol str 合约代码

调用示例:

# 获取 IC2309 合约的合约信息
ctaEngine.getInstrument('CFFEX', 'IC2309')

获取所有投资者账号信息

函数:ctaEngine.getInvestorList

调用示例:

ctaEngine.getInvestorList()

返回结果:

[{"BrokerID": "0001", "InvestorID": "166225", "UserID": "166225"}]

输出信息到控制台

函数:ctaEngine.writeLog

参数 类型 必填 说明
content str 想输出的字符串

调用示例:

# 将 `买入1手` 输出到控制台
ctaEngine.writeLog("买入1手")

获取某一品种的所有合约

函数:ctaEngine.getInstListByExchAndProduct

参数 类型 必填 说明
exchange str 交易所代码
product str 品种代码

调用示例:

# 获取 IC 品种的所有合约
ctaEngine. getInstListByExchAndProduct('CFFEX', 'IC')

注意

本文文档部分地方语句可能有错别字或者语法错误,如发现文档某处出现错误,请电子邮件联系:infinitrader#quantdo.com.cn(# 换成 @)。我们也会尽量将该版文档改版,这需要时间,感谢各位的支持。