深入函数
本章节我们继续深入到 CtaTemplate
类中封装好的函数,再认识一下 ctaEngine
这个“看不到的”库,在实际编写策略的时候,我们可以使用这些函数来获取到我们想要的数据和信息,根据这些数据和信息来控制买入卖出,达到盈利的目的。
总之 PythonGo 是提供了一个框架,给你把数据准备好,你需要使用这些数据处理后来达到你想要的策略效果,不要被框架受限,你是在写 Python 代码,不是在写“PythonGo 代码”。
输出日志到控制台
output
输出函数
def output(content: str) -> None:
"""输出信息到控制台"""
...
含义:输出信息到控制台。
使用条件:控制台目前输出内容有做控制,不建议在控制台输出大量数据。
获取资金账户信息
get_investor_account
获取账户的资金情况
def get_investor_account(investor: str) -> VtAccountData:
"""获取资金"""
...
含义:获取某个账户的资金情况。
返回结果:返回的结果是账户数据类,是基础数据结构中的 VtAccountData
{
"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
获取某个账户的持仓信息
def getInvestorPosition(self, investorID: str) -> List[dict]:
"""获取持仓信息"""
...
返回结果:数组(List[dict, ...]
),里面的字段是账户的持仓数据类,单个合约持仓返回结果如下:
[
{
"BrokerID": "0001", // 经纪商代码
"ExchangeID": "CFFEX", // 交易所代码
"InvestorID": "123456", // 资金账号
"InstrumentID": "IC2201", // 合约代码
"Direction": "多", // 持仓方向:0 - 买,1 - 卖
"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 // 持仓均价
}
]
manage_position
处理账户的持仓情况
def manage_position(self, index: int=1) -> None:
"""处理账户(默认第一个)的持仓情况"""
...
含义:通过传入 index
来处理指定账户的持仓情况(默认第一个)。
注意事项:通过在 onStart
回调函数中使用该方法可进行持仓信息的初始化,后续在代码中可以使用策略模板处理好的仓位管理获取对应的持仓,具体如下:
self.pos = {} # 总投机持仓
self.tpos0L = {} # 今持多仓
self.tpos0S = {} # 今持空仓
self.ypos0L = {} # 昨持多仓
self.ypos0S = {} # 昨持空仓
get
方法取值:
pos = self.pos.get("IC2101")
IC2101
合约的净投机持仓数量,这里要注意,净多头持仓获取到的数是正值,净空头持仓获取到的数是负值。其次仓位信息是由策略模板自动维护的,主要逻辑是在 onTick
实时行情中里面判断昨仓和今仓,再通过 onTrade
收到的成交回报中计算持仓的新增或减少。您也可以继承后自己再策略里面通过其他方式维护持仓。
获取某一品种的所有合约
def get_InstListByExchAndProduct(self, exchange: str, product: str) -> dict:
"""获取某个交易所下某个品种的期货合约和期权合约的合约信息"""
...
示例:获取大商所棕榈油品种的所有期货期权合约的合约代码
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')
注意:
- 如果需要获取股票期权合约,则品种代码为
ETF_O
- 如果获取不到 ETF 合约,那可能是你登录的环境不支持股票期权
错误回报
在策略运行过程中产生的接口调用错误和对应的语法错误将会通过 onErr
函数推送给策略,并且会在控制台显示。
OnErr
的回调参数是 Python 字典,其中包括 errCode (错误代码)和 errMsg (具体错误信息)两个键值; errCode 代码包括以下信息:
参数 | 说明 |
---|---|
0001 | onTick 触发语法错误 |
0002 | onOrder 触发语法错误 |
0003 | onTrade 触发语法错误 |
0004 | 发单撤单错误 |
0005 | onInit 触发语法错误 |
0006 | onStart 触发语法错误 |
0007 | onStop 触发语法错误 |
0008 | onTimer 触发语法错误 |
获取合约信息
get_contract
获取合约信息。
在 ctaTemplate
文件中为 def get_contract(self, exchange, symbol)
含义:获取合约信息。
返回结果:返回的结果是合约数据类,是基础数据结构中的 VtContractData
。
定时器相关函数
regTimer
开启定时器
在 ctaTemplate
文件中为 def regTimer(self, tid, mSecs)
含义:开启设置的定时器,tid
参数为自己定义的定时器编号建议使用数字编号,mSecs
是定时器触发的毫秒数。
onTimer
定时器
在 ctaTemplate
文件中为 def onTimer(self, tid)
含义:开启定时器后收到定时推送;tid
参数为定时器编号。
removeTimer
移除定时器
底层 ctaEngine
接口:ctaEngine.removeTimer(self.sid, self.tid)
含义:sid
为策略编号,基础的策略模板里面有定义;tid
参数为定时器编号,移动对应的定时器。
更多发单方法
在这里我们提供了限价 FAK 委托方式和 FOK 委托方式:
FAK 委托指令:当所委托的手数不能全部成交时,将能成交的部分手数全部成交,不能成交的立即撤单。
buy_fak
买入开仓函数
在 ctaTemplate
文件中为 def buy_fak(price, volume, symbol='', exchange='', stop=False, investor='')
含义:买入开仓,使用 FAK 指令。
注意事项:注意合约,交易和投资者账号所传入参数的要求。
short_fak
卖出开仓函数
在 ctaTemplate
文件中为 def short_fak(price, volume, symbol='', exchange='', stop=False, investor='')
含义:卖出开仓,使用 FAK 指令。
注意事项:注意合约,交易和投资者账号所传入参数的要求。
cover_fak
买平函数
在 ctaTemplate
文件中为 def cover_fak(price, volume, symbol='', exchange='', stop=False, investor='')
含义:买入平仓,使用 FAK 指令。
注意事项:注意合约,交易和投资者账号所传入参数的要求。
sell_fak
卖平函数
在 ctaTemplate
文件中为 def sell_fak(price, volume, symbol='', exchange='', stop=False, investor='')
含义:卖出平仓,使用 FAK 指令。
注意事项:注意合约,交易和投资者账号所传入参数的要求
sendOrderFAK
发送 FAK 委托指令
在 ctaTemplate
文件中为 def sendOrderFAK(orderType, price, volume, symbol='', exchange='', stop=False, investor='')
含义:使用 FAK 委托指令。
注意事项:通过传入参数 orderType
的不同,实现平仓,开仓的委托方式,在 ctaBase
文件中已经定义了 orderType
交易方向类型,如下:
CTAORDER_BUY = "买开"
CTAORDER_SELL = "卖平"
CTAORDER_ SELL _TODAY = "卖平今"
CTAORDER_SHORT = "卖开"
CTAORDER_COVER = "买平"
CTAORDER_COVER_TODAY = "买平今"
FOK 委托指令:当所委托的手数不能全部成交时交易所系统自动撤单,如果能够全部成交则立即成交。
buy_fok
买入开仓函数
在 ctaTemplate
文件中为 def buy_fok(price, volume, symbol='', exchange='', stop=False, investor='')
含义:买入开仓,使用 FOK 指令。
注意事项:注意合约,交易和投资者账号所传入参数的要求。
short_fok
卖出开仓函数
在 ctaTemplate
文件中为 def short_fok(price, volume, symbol='', exchange='', stop=False, investor='')
含义:卖出开仓,使用 FOK 指令。
注意事项:注意合约,交易和投资者账号所传入参数的要求。
cover_fok
买平函数
在 ctaTemplate
文件中为 def cover_fok(price, volume, symbol='', exchange='', stop=False, investor='')
含义:买入平仓,使用 FOK 指令。
注意事项:注意合约,交易和投资者账号所传入参数的要求。
sell_fok
卖平函数
在 ctaTemplate 文件中为 def sell_fok(price, volume, symbol='', exchange='', stop=False, investor='')
含义:卖出平仓,使用 FOK 指令。
注意事项:注意合约,交易和投资者账号所传入参数的要求
sendOrderFOK
发送 FOK 委托指令
在 ctaTemplate
文件中为 def sendOrderFAK(orderType,price, volume, symbol='', exchange='', stop=False, investor='')
含义:使用 FOK 委托指令。
注意事项:通过传入参数 orderType
的不同,实现平仓,开仓的委托方式。
平今和平昨:策略模板 ctaTemplate
文件中处理的 cover
和 sell
函数暂时使用下面的逻辑来自动处理平今平昨:发单手数必须小于等于今仓或者昨仓的一个;优先平今,每次仅处理平今平昨的一个。但这里建议用户自己通过 sendOrder
相关方法去处理平今和平昨。
sendOrderMarketFAK
发送市价 FAK 指令
在 ctaTemplate 文件中为 def sendOrderMarketFAK(orderType, volume, symbol='', exchange='', stop=False, investor='')
含义:使用 FAK 委托指令发送市价委托。
注意事项:不需要填写价格参数,请按照函数要求参数填写对应字段.
-
cover_t
买入平今仓函数在
ctaTemplate
文件中为 def cover_t(price, volume, symbol='', exchange='', stop=False, investor='')含义:买入平今仓。
注意事项:注意合约,交易和投资者账号所传入参数的要求。
-
sell_t
卖出平今仓函数在
ctaTemplate
文件中为 def sell_t(price, volume, symbol='', exchange='', stop=False, investor='')含义:卖出平今仓。
注意事项:注意合约,交易和投资者账号所传入参数的要求。
-
cover_y
买入平昨仓函数在
ctaTemplate
文件中为 def cover_y(price, volume, symbol='', exchange='', stop=False, investor='')含义:买入平昨仓。
注意事项:注意合约,交易和投资者账号所传入参数的要求。
-
sell_y
卖出平昨仓函数在
ctaTemplate
文件中为 def sell_y(price, volume, symbol='', exchange='', stop=False, investor='')含义:卖出平昨仓。
注意事项:注意合约,交易和投资者账号所传入参数的要求。
底层 ctaEngine 接口说明
ctaEngine.subMarketData
订阅合约
需要参数:
参数 | 说明 | 数据类型 |
---|---|---|
sid | 策略ID | int |
InstrumentID | 合约代码 | str |
ExchangeID | 交易所代码 | str |
调用示例:
ctaEngine.subMarketData({'sid': self, 'InstrumentID': "IC2301", 'ExchangeID': "CFFEX"})
ctaEngine.unsubMarketData
取消订阅合约
需要参数:
参数 | 说明 | 数据类型 |
---|---|---|
sid | 策略ID | int |
InstrumentID | 合约代码 | str |
ExchangeID | 交易所代码 | str |
调用示例:
ctaEngine.subMarketData({'sid': self, 'InstrumentID': "IC2301", 'ExchangeID': "CFFEX"})
ctaEngine.sendOrder
发送委托
需要参数:
参数 | 说明 | 数据类型 |
---|---|---|
sid | 策略ID | int |
direction | 持仓方向 | str |
hedgeflag | 委托指令 | str |
offset | 开平方向 | str |
symbol | 合约 | str |
volume | 委托数量 | int |
price | 委托价格 | int or float |
ordertype | 委托类型 | str |
ExchangeID | 交易所代码 | str |
investor | 账户ID | str |
调用示例:参考更多发单方法中 sendOrder
的实现方法 。
注意事项:
参数 | 说明 |
---|---|
hedgeflag | 1 - 投机,2 - 套利,3 - 套保,4 - 做市商,5 - 备兑 |
ordertype | 0 - GFD,1 - FAK,2 - FOK |
direction | 0 - 买,1 - 卖 |
offset | 0 - 开仓,1 - 平仓,3 - 平今仓 |
ctaEngine.cancelOrder
撤单
需要参数:
参数 | 说明 |
---|---|
vtOrderID | ctaEngine.sendOrder 方法发送委托,返回的委托 ID |
调用示例:
ctaEngine.cancelOrder(vtOrderID)
ctaEngine.getKLineData
获取K线数据
需要参数:
参数 | 说明 | 示例 | 数据类型 |
---|---|---|---|
symbol | 合约 | IC2209 | str |
exchange | 交易所 | CFFEX | str |
start_date | 数据开始时间(年月日) | 20220608 | str |
start_time | 数据开始时间(时分秒) | 09:00:00 | str |
days | 天数(从数据开始时间往前算,不超过 30 天) | 10 | int |
years | 年数 | 0 | int |
k_type | 分钟线 | 1 | int(枚举值 1, 5, 15, 30, 60) |
调用示例:
分钟线
ctaEngine.getKLineData("IC2209", "CFFEX", "20220608", 10, 0, "09:00:00", 1)
# 获取 IC2209 从 20220608 往前 10 天的 1 分钟 K线
ctaEngine.getKLineData("IC2209", "CFFEX", "20220608", 0, 1)
# 获取 IC2209 截止 20220608 过去一年的日线
ctaEngine.getInvestorAccount
获取投资者账户资金情况
需要参数:
参数 | 说明 | 数据类型 |
---|---|---|
investor | 投资者账户 | str |
调用示例:
ctaEngine.getInvestorAccount("166225") # 获取资金账户为 166225 的账户资金情况
ctaEngine.getInvestorPosition
获取投资者账户持仓情况
需要参数:
参数 | 说明 | 数据类型 |
---|---|---|
investor | 投资者账户 | str |
调用示例:
ctaEngine.getInvestorPosition("166225") # 获取资金账户为 166225 的账户持仓明细
ctaEngine.getInstrument
获取合约信息
需要参数:
参数 | 说明 | 数据类型 |
---|---|---|
exchange | 交易所 | str |
symbol | 合约 | str |
调用示例:
ctaEngine.getInstrument('CFFEX', 'IC2101') # 获取IC2101合约的合约信息
ctaEngine.getInvestorList
获取所有投资者账号
需要参数:
参数 | 说明 | 数据类型 |
---|---|---|
exchange | 交易所 | str |
symbol | 合约 | str |
调用示例:
ctaEngine.getInvestorList() # 获取当前登录的所有投资者账号
ctaEngine.writeLog
输出信息到控制台
调用示例:
ctaEngine.writeLog("买入1手") # 将 `买入1手` 输出到控制台
ctaEngine.getInstListByExchAndProduct
获取某一品种的所有合约
需要参数:
参数 | 说明 | 数据类型 |
---|---|---|
exchange | 交易所 | str |
Product | 品种 | str |
调用示例:
ctaEngine. getInstListByExchAndProduct('CFFEX', 'IC') # 获取 IC 品种的所有合约信息
注意
本文文档是基于以前的文档重新排版的,部分地方语句可能有错别字或者语法错误,如发现文档某处出现错误,请电子邮件联系:infinitrader#quantdo.com.cn(# 换成 @)。我们也会尽量将该版文档改版,这需要时间,感谢各位的支持。