# 功夫开发的技术体系
- 使用 kungfu 来开发策略可以使用 python 或者 C++编程语言任意一种。两种语言的策略编写方式有一点差别,可参考Demo 代码。 其中 Python 版本是3.7.9,C++ 版本是17。
- kungfu 内置 RQData 金融数据 API 以及 ta-lib 库,也可根据需要来获取 tushare 等资讯数据。
- 策略平台合成 Bar 行情,客户可以自主选择 Bar 行情合成频率。
- 通过与“客户端组件开发”可以实现功夫策略与客户端组件实时双向通信。
# 视频讲解
跟随视频 (opens new window)一步步构建属于自己的策略吧。
# 策略 Demo 代码
# (一)Python 语言策略 Demo
# 策略 Demo1:
import sys
import json
from functools import partial
import kungfu.yijinjing.time as kft
import kungfu.wingchun.utils as wc_utils
from kungfu.wingchun.constants import *
import pyyjj
#如果需要米筐数据,需要引入rqdatac
#import rqdatac as rq
#from rqdatac import*
source = Source.XTP
exchange_sse = Exchange.SSE
exchange_sze = Exchange.SZE
account_str = "15003934"
# 静态行情整个交易日都不会变,启动策略时取到所有证券的静态数据后,需要时直接使用
# 而不需要用一次查一次,性能很差(因为需要读写文件)
# key的格式是:证券代码.证券市场;比如:600000.SSE和000001.SZE
quotes={}
def test_timer(context, event):
context.log.info('test timer')
def test_timer_with_parameter_x(context, event, x):
context.log.info('test timer, x={}'.format(x))
def test_time_interval(context, event):
context.log.info('test time interval')
def test_time_interval_with_parameter_y(context, event, y):
context.log.info('test time interval, y={}'.format(y))
def cancel_order(context, event, order_id):
if order_id in context.book._orders and context.book._orders[order_id].active:
context.cancel_order(order_id)
def print_books(context):
if context.all_books_ready():
strategy_book = context.book #策略的资金与持仓
context.log.info("strategy available cash:{}".format(strategy_book.avail))
context.log.info("strategy position as follow :")
for position in strategy_book.positions:
context.log.info("account instrument_id:{}, volume:{},account sellable volume:{},account avg_open_price :{}".format(position.instrument_id , position.volume - position.frozen_total , position.yesterday_volume - position.frozen_yesterday ,position.avg_open_price ))
account_book = context.get_account_book(source, account_str ) #某资金账户的资金与持仓
context.log.warning("[account available cash]:{}".format( account_book.avail))
pos_es = account_book.positions
for pos in pos_es:
context.log.info("account instrument_id:{}, volume:{},account sellable volume:{},account avg_open_price :{}".format(pos.instrument_id ,pos.volume - pos.frozen_total , pos.yesterday_volume - pos.frozen_yesterday ,pos.avg_open_price ))
else:
context.log.warning("book is not ready,please wait one more moment!")
#启动前
def pre_start(context):
context.log.info("pre run strategy")
context.book_ready_flag = False #该变量为自定义的全局变量,用于标记策略是否已经拿到策略自己以及所使用账号的持仓;策略在使用资金账户之前要先通过context.add_account添加资金账户。
context.add_account(source, account_str, 100000000.0)
# 查询新发行的债
# 备注:context.query_bondIPO_infolist 函数从2.1.1版本开始支持
context.query_bondIPO_infolist(account_str)
#登录xtp算法交易服务器
#备注:1.context.login_algo_server()函数从2.0.12版本开始支持
# 2.参数需要根据实际情况填写
#context.login_algo_server(source, account_str, "algo_user", "algo_password")
context.subscribe(source, ["600000", "601988"], exchange_sse)
# 订阅逆回购品种
#context.subscribe_market_data(Source.XTP, ["204001"], exchange_sse)
#获取沪深交易所全量静态行情
# 静态行情数量大于零,说明获取成功
global quotes
quotes=context.getAllStaticQuote()
context.log.info('static quotes num: {}.'.format(len(quotes)))
quote = quotes['600000.SSE']
context.log.info('quotes[600000.SSE]={}'.format(quote))
context.log.info('instrument_id={}, exchange_id={}, upper_limit_price={}, lower_limit_price={}, '.format(quote.instrument_id, quote.exchange_id, quote.upper_limit_price, quote.lower_limit_price))
#遍历quotes
#for key in quotes:
# quote = quotes[key]
# context.log.info("key={}, instrument_id={}, exchange_id={}".format(key, quote.instrument_id, quote.exchange_id))
#getAllStaticQuote()函数的使用方法,详见“kungfu SDK API 文档”
#获取新三板/北交所全量静态行情
# 静态行情数量大于零,说明获取成功
# 备注:context.getAllNQStaticQuote()函数从 2.1.3 版本开始支持
global nq_quotes
nq_quotes=context.getAllNQStaticQuote()
context.log.info('nq static quotes num: {}.'.format(len(nq_quotes)))
# 加载自定义库文件,库文件需跟当前策略文件放在同一目录下
# luck_package.py为自定义库文件的名字,可以根据实际情况自行替换和修改
# 该功能要求系统版本大于等于2.0.8
# cust_lib = context.import_local_lib('luck_package.py')
# result = cust_lib.test()
#获取参数配置文件路径的参考代码
#path = context.getParamFileDir()
#config_file = os.path.join(path, "param.csv")
# 订阅买一卖一队列行情
#备注:context.subscribe_bid1_ask1()函数从2.0.11版本开始支持
#context.subscribe_bid1_ask1(Source.XTP, ["600000", "601988"], exchange_sse)
#context.subscribe_tick_by_tick(source, ["600000", "601988"], exchange_sse)
#context.subscribe_order_book(source, ["600000", "601988"], exchange_sse)
#context.subscribe('bar', ["600000", "601988", "601600", "600589"], Exchange.SSE)#订阅bar行情
#context.add_timer(pyyjj.now_in_nano()+100, partial(test_timer))
#context.add_timer(pyyjj.now_in_nano()+100, partial(test_timer_with_parameter_x, x=1)) #带参数x的定时函数
#context.add_time_interval(kft.NANO_PER_SECOND, partial(test_time_interval)) #kft.NANO_PER_SECOND是一个系统定义的数值常量,为1000000000,单位是纳秒,也即1秒钟;
#客户可根据实际需要,自行对该值进行替换
#context.add_time_interval(kft.NANO_PER_SECOND, partial(test_time_interval_with_parameter_y, y=1)) #带参数y的定时函数
#调用米筐数据的样例
#rq.init("username","password",('IP地址',端口))
#rqt = rq.get_price('000001.XSHE','2020-9-28','2020-9-28','tick')
#context.log.info(rqt.shape)
#信用账户查询相关示例
#请求查询信用账户特有信息
#备注:context.query_credit_fund_info()函数从2.0.8版本开始支持
#context.query_credit_fund_info(source, account_str)
#融资融券业务中请求现金直接还款
#备注:context.credit_cash_repay()函数从2.0.8版本开始支持
#context.credit_cash_repay(source, account_str, 50000.00)
#请求查询信用账户可融券头寸信息
#备注:context.query_credit_ticker_assign_info()函数从2.0.11版本开始支持
#context.query_credit_ticker_assign_info(source, account_str, "600000", exchange_sse)
#请求查询信用账户负债合约信息
#备注:context.query_credit_debt_info()函数从2.0.11版本开始支持
#context.query_credit_debt_info(source, account_str)
#请求查询信用账户指定证券负债未还信息
#备注:context.query_credit_ticker_debt_info()函数从2.0.11版本开始支持
#context.query_credit_ticker_debt_info(source, account_str, "600000", exchange_sse)
#请求查询信用账户待还资金信息
#备注:context.query_credit_asset_debt_info()函数从2.0.11版本开始支持
#context.query_credit_asset_debt_info(source, account_str)
#请求债转股信息
#备注:context.query_bondswapstock_info()函数从2.1.2版本开始支持
#查询所有的债转股信息
context.query_bondswapstock_info(account_str)
#查询单支债转股信息
#context.query_bondswapstock_info(account_str, "110001", exchange_sse)
#启动后
def post_start(context):
print_books(context)
pass
#策略退出前,可在此做一些回收工作
def pre_stop(context):
context.log.info("strategy pre_stop.")
#退出后
def post_stop(context):
pass
#bar 分钟级别行情回调
def on_bar(context, bar):
if not context.book_ready_flag: #此判断逻辑非必须,如果策略不关心策略或者账户资金与持仓,直接注掉该if语句块即可。
context.logger.warning("book has not been ready")
return
context.logger.info("bar received: [instrument_id]{} [exchange_id]{}".format(bar.instrument_id, bar.exchange_id))
pass
#行情数据更新回调
def on_quote(context, quote):
if not context.book_ready_flag: #此判断逻辑非必须,如果策略不关心策略或者账户资金与持仓,直接注掉该if语句块即可。
context.logger.warning("book has not been ready")
return
context.log.info("quote received: [time]{} [instrument_id]{} [last_price]{}".format(quote.data_time, quote.instrument_id, quote.last_price))
#一般来说可以在此处进行逻辑判断,符合下单条件下单即可。
order_id = context.insert_order(quote.instrument_id, quote.exchange_id, account_str , quote.ask_price[0], 200, PriceType.Limit, Side.Buy, Offset.Open, HedgeFlag.Speculation)
#信用交易示例
#担保品买入
#order_id = context.insert_order(quote.instrument_id, quote.exchange_id, account, quote.ask_price[0],
# 200, PriceType.Limit, Side.Buy, Offset.Open, HedgeFlag.Speculation, BusinessType.MARGIN)
#担保品卖出
#order_id = context.insert_order(quote.instrument_id, quote.exchange_id, account, quote.bid_price[0],
# 200, PriceType.Limit, Side.Sell, Offset.Open, HedgeFlag.Speculation, BusinessType.MARGIN)
#融资买入
#order_id = context.insert_order(quote.instrument_id, quote.exchange_id, account, quote.bid_price[0],
# 200, PriceType.Limit, Side.MarginTrade, Offset.Open, HedgeFlag.Speculation, BusinessType.MARGIN)
#卖券还款
#order_id = context.insert_order(quote.instrument_id, quote.exchange_id, account, quote.ask_price[0],
# 200, PriceType.Limit, Side.RepayMargin, Offset.Open, HedgeFlag.Speculation, BusinessType.MARGIN)
#融券卖出
#order_id = context.insert_order(quote.instrument_id, quote.exchange_id, account, quote.ask_price[0],
# 200, PriceType.Limit, Side.ShortSell, Offset.Open, HedgeFlag.Speculation, BusinessType.MARGIN)
#买券还券
#order_id = context.insert_order(quote.instrument_id, quote.exchange_id, account, quote.ask_price[0],
# 200, PriceType.Limit, Side.RepayStock, Offset.Open, HedgeFlag.Speculation, BusinessType.MARGIN)
#现券还券
#order_id = context.insert_order(quote.instrument_id, quote.exchange_id, account, quote.ask_price[0],
# 200, PriceType.Limit, Side.StockRepayStock, Offset.Open, HedgeFlag.Speculation, BusinessType.MARGIN)
#逆回购下单 入参注意事项:
#1.交易方向为卖即Side.Sell
#2.价格类型为限价即PriceType.Limit
#3.业务类型为回购业务即BusinessType.REPO
#4.交易数量:根据最新调整,沪深交易所逆回购一手均为10张
#if(quote.instrument_id == "204001" and quote.exchange_id == exchange_sse):
# order_id = context.insert_order(quote.instrument_id, quote.exchange_id, account_xtp, quote.bid_price[0], 10, PriceType.Limit, Side.Sell, Offset.Open, HedgeFlag.Speculation, BusinessType.REPO)
#elif (quote.instrument_id == "131810" and quote.exchange_id == exchange_sze):
# order_id = context.insert_order(quote.instrument_id, quote.exchange_id, account_xtp, quote.bid_price[0], 10, PriceType.Limit, Side.Sell, Offset.Open, HedgeFlag.Speculation, BusinessType.REPO)
#下单后一段时间通过定时函数进行撤单
#if order_id>0:
# context.add_timer(pyyjj.now_in_nano()+kft.NANO_PER_SECOND, partial(cancel_order, order_id = order_id))
#策略向客户端发送自定义字符串。
#context.send_msg("insert_order({},{})".format(quote.instrument_id, quote.exchange_id))
#策略用户在双中心间进行资金划转(从远端节点转入到本节点200元)。
#account_str是当前下单用的资金账户;“123456”是账户的密码,需根据实际情况设定
#context.fund_transfer(account_str, “123456”, FundTransferType.FundInterTransferIn 200.0)
#策略用户查询双中心间资金划转情况。
#account_str是当前下单用的资金账户;“123456”是账户的密码,需根据实际情况设定
#context.query_other_server_fund(account_str, “123456”, FundQueryType.FundQueryInternal)
#订单簿数据更新回调
def on_order_book(context, order_book):
context.log.info('order_book received: [instrument_id]{} [exchange_id]{}'.format(order_book.instrument_id, order_book.exchange_id))
pass
#买一卖一队列数据更新回调
#备注:on_bid1ask1(context, b1a1)函数从2.0.11版本开始支持
def on_bid1ask1(context, b1a1):
context.log.info('bid1ask1 received: [instrument_id]{} [exchange_id]{}'.format(b1a1.instrument_id, b1a1.exchange_id))
pass
#逐笔成交更新回调
def on_transaction(context, transaction):
context.log.info("{} {}".format(transaction.instrument_id, transaction.exchange_id))
pass
#逐笔委托更新回调
def on_entrust(context, entrust):
context.log.info("{} {}".format(entrust.instrument_id, entrust.exchange_id))
pass
#订单信息更新回调
def on_order(context, order):
context.log.info('order received: [instrument_id]{} [volume]{} [price]{}'.format(order.instrument_id, order.volume, order.limit_price))
#订单成交回报回调
def on_trade(context, trade):
context.log.info('trade received: {} [trade_id]{} [volume]{} [price]{}'.format(kft.strftime(trade.trade_time), trade.order_id, trade.volume, trade.price))
#订单操作错误回调 撤单反馈信息回调
def on_order_action_error(context, error):
context.log.info('order_action_error received: [order_id]{} [error_id]{}'.format(error.order_id, error.error_id))
pass
# #撤单反馈信息回调
# def on_cancelorder_feedback(context, cofeedback):
# context.log.info('cancelorder_feedback received: [feedback_type]{} [order_id]{}'.format(cofeedback.feedback_type, cofeedback.order_id))
# pass
#资金账户信息更新回调
#备注:on_asset(context, asset)函数从2.0.11版本开始支持
def on_asset(context, asset):
context.log.info('asset received: [source_id]{} [account_id]{}'.format(asset.source_id, asset.account_id))
pass
#接收前端发送回来的客户自定义消息
def on_client_msg(context, msg):
context.log.info('on_client_msg received: {}'.format(msg))
#msg类型为字符串,内容是客户自定义的json结构字符串,比如:“{\"A\"=1,\"B\"=2,\"C\"=3,}”
#可通过如下语句解析:
#j = json.loads(msg)
#A = j["A"]
#B = j["B"]
#C = j["C"]
#context.log.info('A: {}, B: {}, C: {} '.format(A, B, C))
pass
#融资融券特有帐户数据回调
#备注:on_query_credit_fund_info(context, crdfundinfo)函数从2.0.8版本开始支持
def on_query_credit_fund_info(context, crdfundinfo):
context.log.info('crdfundinfo received: [all_asset]{} [all_debt]{}'.format(crdfundinfo.all_asset, crdfundinfo.all_debt))
pass
#融资融券业务中现金直接还款的响应回调
#备注:on_credit_cash_repay(context, crd_cash_repay_info)函数从2.0.8版本开始支持
def on_credit_cash_repay(context, crd_cash_repay_info):
context.log.info('crd_cash_repay_info received: [request_amount]{} [cash_repay_amount]{}'.format(crd_cash_repay_info.request_amount, crd_cash_repay_info.cash_repay_amount))
pass
#信用账户可融券头寸信息更新回调
#备注:on_query_credit_ticker_assign_info(context, crd_position_stk_info)函数从2.0.11版本开始支持
def on_query_credit_ticker_assign_info(context, crd_position_stk_info):
context.log.info('credit_ticker_assign_info received: [instrument_id]{} [exchange_id]{}'.format(crd_position_stk_info.instrument_id, crd_position_stk_info.exchange_id))
pass
#信用账户负债信息更新回调
#备注:on_query_credit_debt_info(context, crd_debt_info)函数从2.0.11版本开始支持
def on_query_credit_debt_info(context, crd_debt_info):
context.log.info('credit_debt_info received: [instrument_id]{} [exchange_id]{}'.format(crd_debt_info.instrument_id, crd_debt_info.exchange_id))
pass
#信用账户指定证券负债未还信息更新回调
#备注:on_query_credit_ticker_debt_info(context, crd_debt_stk_info)函数从2.0.11版本开始支持
def on_query_credit_ticker_debt_info(context, crd_debt_stk_info):
context.log.info('credit_ticker_debt_info received: [instrument_id]{} [exchange_id]{}'.format(crd_debt_stk_info.instrument_id, crd_debt_stk_info.exchange_id))
pass
#信用账户待还资金信息更新回调
#备注:on_query_credit_asset_debt_info(context, remain_amount)函数从2.0.11版本开始支持
def on_query_credit_asset_debt_info(context, remain_amount):
context.log.info('credit_asset_debt_info received: [remain_amount]{}'.format(remain_amount))
pass
#资金划转结果回调
def on_fund_transfer(context, feedback):
context.log.info('on_fund_transfer received: [feedback]{}'.format(feedback))
pass
#资金查询结果回调
def on_query_other_server_fund(context, feedback):
context.log.info('on_query_other_server_fund received: [feedback]{}'.format(feedback))
pass
#xtp算法交易服务器登录反馈信息回调
#备注:1.on_login_algo_server(context, success)函数从2.0.12版本开始支持
# 2.参数需要根据实际情况填写
def on_login_algo_server(context, success):
context.log.info('login_algo_server result is: {} '.format(success))
if success:
strategy_param = {}
strategy_param["buyDateTime"] = ["09:30", "09:40"]
strategy_param["stop_selling_while_buy_overflow"] = False
strategy_param["cancel_overflow_order_after_clear_time"] = True
strategy_param["start_time"] = "09:30:00"
strategy_param["end_time"] = "09:40:00"
strategy_param["trade_list"] = []
trade0 = {}
trade0["market"] = "SZ"
trade0["clientStrategyId"] = "202010200902"
trade0["quantity"] = 20000
trade0["side"] = "BUY"
trade0["ticker"] = "002513"
trade1 = {}
trade1["market"] = "SZ"
trade1["clientStrategyId"] = "202010200902"
trade1["quantity"] = 20000
trade1["side"] = "BUY"
trade1["ticker"] = "001914"
strategy_param["trade_list"].append(trade0)
strategy_param["trade_list"].append(trade1)
strategy_param["business_type"] = "CASH"
context.create_algo_strategy(account_str, 2001, 202010200902, json.dumps(strategy_param))
#备注:变量strategy_param的数据格式,由context.create_algo_strategy()函数的第二个参数来决定,具体细节需咨询算法交易相关人员
pass
#xtp算法交易创建策略反馈信息回调
#备注: on_create_algo_strategy(context, algo_strategy_info)函数从2.0.12版本开始支持
def on_create_algo_strategy(context, algo_strategy_info):
context.log.info('algo_strategy_info received: {} '.format(algo_strategy_info))
context.start_algo_strategy(account_xtp, algo_strategy_info.xtp_strategy_id)
pass
#xtp算法交易查询策略反馈信息回调
#备注: on_query_algo_strategy(context, algo_strategy_info)函数从2.0.12版本开始支持
def on_query_algo_strategy(context, algo_strategy_info):
context.log.info('algo_strategy_info received: {} '.format(algo_strategy_info))
pass
#xtp算法交易开始运行策略反馈信息回调
#备注: on_start_algo_strategy(context, algo_strategy_info)函数从2.0.12版本开始支持
def on_start_algo_strategy(context, algo_strategy_info):
context.log.info('algo_strategy_info received: {} '.format(algo_strategy_info))
pass
#xtp算法交易停止运行策略反馈信息回调
#备注: on_stop_algo_strategy(context, algo_strategy_info)函数从2.0.12版本开始支持
def on_stop_algo_strategy(context, algo_strategy_info):
context.log.info('algo_strategy_info received: {} '.format(algo_strategy_info))
pass
#xtp算法交易销毁策略反馈信息回调
#备注: on_destroy_algo_strategy(context, algo_strategy_info)函数从2.0.12版本开始支持
def on_destroy_algo_strategy(context, algo_strategy_info):
context.log.info('algo_strategy_info received: {} '.format(algo_strategy_info))
pass
#xtp算法交易策略信息更新回调
#备注:on_algo_strategy_info(context, algo_strategy_info)函数从2.0.12版本开始支持
def on_algo_strategy_info(context, algo_strategy_info):
context.log.info('algo_strategy_info received: {} '.format(algo_strategy_info))
pass
#xtp算法交易运行时策略状态更新回调
#备注: on_algo_strategy_state_report(context, algo_strategy_state_report)函数从2.0.12版本开始支持
def on_algo_strategy_state_report(context, algo_strategy_state_report):
context.log.info('algo_strategy_state_report received: {} '.format(algo_strategy_state_report))
pass
#接收查询到的新债信息
# 备注:on_query_bondIPO_info函数从2.1.1版本开始支持
def on_query_bondIPO_info(context, IPOInfo):
if 0 == IPOInfo.error_id:
context.log.info('bond ipo info: {}'.format(IPOInfo))
else:
context.log.warn('error bond ipo info: {}'.format(IPOInfo))
pass
#完成接收查询到的新债信息
# 备注:on_query_bondIPO_end函数从2.1.1版本开始支持
def on_query_bondIPO_end(context):
context.log.info('bond ipo collected finish.')
pass
#接收查询到的债转股信息
def on_query_bondswapstock_info(context, swap_info):
if 0 == swap_info.error_id:
context.log.info('bond swap stock info: {}'.format(swap_info))
else:
context.log.warn('error bond swap stock info: {}'.format(swap_info))
pass
#完成接收查询到的债转股信息
def on_query_bondswapstock_end(context):
context.log.info('bond swap stock collected finish.')
pass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
# 策略 Demo2:
import sys
import time
import json
import kungfu.yijinjing.time as kft
import kungfu.wingchun.utils as wc_utils
from kungfu.wingchun.constants import *
import pyyjj
#如果需要米筐数据,需要引入rqdatac
#import rqdatac as rq
#from rqdatac import*
source = Source.XTP
exchange = Exchange.SSE
def info_bar(context, bar) :
context.log.info("Bar data, code: " + bar.code
+ ", bar data, trading_day: " + bar.trading_day
+ ", source_id: " + bar.source_id
+ ", instrument_id: " + bar.instrument_id
+ ", exchange_id: " + bar.exchange_id
+ ", start_time: " + str(bar.start_time)
+ ", end_time: " + str(bar.end_time)
+ ", time_interval: " + str(bar.time_interval)
+ ", period: " + bar.period
+ ", open: " + str(bar.open)
+ ", close: " + str(bar.close)
+ ", low: " + str(bar.low)
+ ", high: " + str(bar.high)
+ ", volume: " + str(bar.volume)
+ ", start_volume: " + str(bar.start_volume)
+ ", turnover: " + str(bar.turnover)
+ ", start_turnover: " + str(bar.start_turnover)
)
def info_quote(context, quote) :
context.log.info("Quote data, source_id: " + quote.source_id
+ ", trading_day: " + str(quote.trading_day)
+ ", data_time: " + str(quote.data_time)
+ ", instrument_id: " + str(quote.instrument_id)
+ ", exchange_id: " + str(quote.exchange_id)
+ ", instrument_type: " + str(quote.instrument_type)
# + ", kungfu_time_flag: " + str(quote.kungfu_time_flag)
+ ", pre_close_price: " + str(quote.pre_close_price)
+ ", pre_settlement_price: " + str(quote.pre_settlement_price)
+ ", last_price: " + str(quote.last_price)
+ ", volume: " + str(quote.volume)
+ ", turnover: " + str(quote.turnover)
+ ", pre_open_interest: " + str(quote.pre_open_interest)
+ ", open_interest: " + str(quote.open_interest)
+ ", open_price: " + str(quote.open_price)
+ ", high_price: " + str(quote.high_price)
+ ", low_price: " + str(quote.low_price)
+ ", upper_limit_price: " + str(quote.upper_limit_price)
+ ", lower_limit_price: " + str(quote.lower_limit_price)
+ ", close_price: " + str(quote.close_price)
+ ", settlement_price: " + str(quote.settlement_price)
+ ", iopv: " + str(quote.iopv)
+ ", pre_iopv: " + str(quote.pre_iopv)
+ ", ticker_status: " + str(quote.ticker_status)
)
def on_quote(context, quote) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} called".format(func_name))
info_quote(context, quote)
def info_data_frame(context, msg, data) :
context.log.info(msg)
for row in data.itertuples() :
context.log.info("{} : {}".format(msg, row))
def info_numpy(context, msg, data) :
context.log.info(msg)
for row in data :
context.log.info("{} : {}".format(msg, row))
#bar 分钟级别行情回调
def on_bar(context, bar) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} called".format(func_name))
info_bar(context, bar)
bar_callback_called_times = 0
def bar_callback(context, bar):
func_name = sys._getframe().f_code.co_name
context.log.info("{} called".format(func_name))
info_bar(context, func_name, bar)
def test_sub_bar(context) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} start".format(func_name))
codes1 = ["000001.SZ", "600000.SSE"]
failed_codes = context.subscribe_bar(codes1, "3m", bar_callback)
context.log.info("call {} done, failed_codes: {}".format(func_name, failed_codes))
codes2 = ["000002.SZ", "600004.SSE"]
failed_codes = context.subscribe_bar(codes2, "2m")
context.log.info("call {} done, failed_codes: {}".format(func_name, failed_codes))
def on_indicator(context, indicator_type, indicator:dict) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} called, indicator type: {}, indicator data: {}".format(func_name, indicator_type, json.dumps(indicator)))
def indicator_callback(context, indicator_type, indicator:dict) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} called, indicator type: {}, indicator data: {}".format(func_name, indicator_type, json.dumps(indicator)))
def test_sub_indicator(context) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} start".format(func_name))
codes1 = ["512160.SSE", "159631.SZ"]
failed_codes = context.subscribe_indicator("etf", codes1, indicator_callback)
context.log.info("call {} done, failed_codes: {}".format(func_name, failed_codes))
codes2 = ["561130.SSE", "159523.SZ"]
failed_codes = context.subscribe_indicator("etf", codes2)
def test_query_bar_today(context) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} start".format(func_name))
### 此处可以传两种形式的 code,即长码和短码,同时支持大小写
codes = ["000002.SZ", "600000.SSE"]
today_bar_data_map = context.query_bar_today(codes, "30m")
for code, bars in today_bar_data_map.items() :
context.log.info("{}, map code: {}".format(func_name, code))
for bar in bars :
info_bar(context, bar)
context.log.info("{} end".format(func_name))
def today_bar_callback(context, today_bar_data_mp, query_id) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} called, query_id: {}".format(func_name, query_id))
for code, bars in today_bar_data_mp.items() : ### 这里的 code 和调用 query_bar_today_async 时传入的 codes 相同
context.log.info("map code: {}".format(code))
for bar in bars :
info_bar(context, bar)
def test_query_bar_today_async(context) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} start".format(func_name))
### 此处可以传两种形式的 code,即长码和短码,同时支持大小写
codes = ["000002.SZ", "600000.SSE"]
context.query_bar_today_async(codes, today_bar_callback, "60m", 22)
context.log.info("{} end".format(func_name))
def test_query_market_data(context) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} start".format(func_name))
params = {
"code": "000001.SZ", # 证券代码 SZ:深证 SH:上海 String(必填)
"start_date": "2024-01-12 10:00:00", # 开始日期 String(必填) 开始日期 格式yyyy-MM-dd hh:mm:ss
"end_date": "2024-01-12 10:10:00" # 结束日期 String(必填) 结束日期 格式yyyy-MM-dd hh:mm:ss
}
quotes = context.query_market_data(params)
if len(quotes) > 0 :
for quote in quotes :
info_quote(context, quote)
def query_market_data_callback(context, quotes, query_id) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} called, query_id: {}".format(func_name, query_id))
if len(quotes) > 0 :
for quote in quotes :
info_quote(context, quote)
def test_query_market_data_async(context) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} start".format(func_name))
params = {
"code": "000001.SZ", # 证券代码 SZ:深证 SH:上海 String(必填)
"start_date": "2024-01-12 10:00:00", # 开始日期 String(必填) 开始日期 格式yyyy-MM-dd hh:mm:ss
"end_date": "2024-01-12 10:10:00" # 结束日期 String(必填) 结束日期 格式yyyy-MM-dd hh:mm:ss
}
context.query_market_data_async(params, query_market_data_callback, 23)
def test_query_bar(context) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} start".format(func_name))
params = {
# "code": "", # String(必填) 证券代码 SZ:深证 SH:上海
"instrument": "000002",
"exchange_id": "SZE",
"start_date": "2024-01-24 10:00:00", # String(必填) 开始日期
"end_date": "2024-01-24 11:00:00", # String(必填) 结束日期
"period": "15m", # #String(选填) 频次 仅支持1m 5m 15m 30m 60m 1d 1w 默认1d,(m代表分钟,d代表天,w代表周),注意:查询1d的则开始、截止时间需要将00:00:00包住,查询1w的则开始、截止时间需要将周五的00:00:00包住
"adjust_type": "pre" # String(选填) 复权方式 none:不复权 pre:前复权 post:后复权 默认前复权
}
bars = context.query_bar(params)
if len(bars) > 0 :
for bar in bars :
info_bar(context, bar)
def query_bar_callback(context, bar_list, query_id) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} called, query_id: {}".format(func_name, query_id))
if len(bar_list) > 0 :
for bar in bar_list :
info_bar(context, bar)
def test_query_bar_async(context) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} start".format(func_name))
params = {
"code": "000001.SZ", # String(必填) 证券代码 SZ:深证 SH:上海
"instrument_id" : "600000",
"exchange_id" : "SSE",
"start_date": "2024-01-23 10:00:00", # String(必填) 开始日期
"end_date": "2024-01-24 10:00:00", # String(必填) 结束日期
"period": "60m", # String(选填) 频次 仅支持1m 15m 30m 60m 1d 1w 默认1d
"adjust_type": "pre" # String(选填) 复权方式 none:不复权 pre:前复权 post:后复权 默认前复权
}
bars = context.query_bar_async(params, query_bar_callback, 24)
context.log.info("call query_bar_async done")
# 查询历史 bar 数据
def test_query_data(context) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} start".format(func_name))
out_format = OutFormat.List
method = "bar" # String(必填)
### 以下参数中如果传了 code 则可以不传 instrument_id 和 exchange_id,如果传了 instrument_id 和 exchange_id,如果同时传了,则使用 code
params = {
"code": "000001.SZ", # 证券代码 SZ:深证 SH:上海
"instrument_id" : "600000",
"exchange_id" : "SSE",
"start_date": "2013-01-04", # String(必填) 开始日期
"end_date": "2013-01-08", # String(必填) 结束日期
"period": "1d", # String(选填) 频次 仅支持1m 15m 30m 60m 1d 1w 默认1d
"adjust_type": "pre" # String(选填) 复权方式 none:不复权 pre:前复权 post:后复权 默认前复权
}
result = context.query_data(method, params, out_format)
###
''' result 的类型为 dict,查询结果 result 如下所示, data 的格式由 out_format 指定
{
"code": 200
"msg": ""
"data" : [
{}, ### 此处的格式由 out_format 指定
{},
.....
]
}
'''
code = result.get("code")
msg = result.get("msg")
context.log.info("code: " + str(code) + ", msg: " + msg) ### 当 code 为 200 时表示请求正常,其他值均为异常
if code == 200 :
for bar in result.get("data") :
context.log.info("{} : {}".format(func_name, json.dumps(bar)))
context.log.info("{} end".format(func_name))
def query_data_async_callback_list(context, result, query_id) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} called, query_id: {}".format(func_name, query_id))
code = result.get("code")
msg = result.get("msg")
context.log.info("code: " + str(code) + ", msg: " + msg) ### 当 code 为 200 时表示请求正常,其他值均为异常
context.log.info("{} called, data: {}".format(func_name, json.dumps(result.get("data"))))
def test_query_data_async(context) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} start".format(func_name))
out_format = OutFormat.List
method = "bar" # String(必填) method方法:固定值
params = {
"code": "000001.SZ", # String(必填) 证券代码 SZ:深证 SH:上海
"start_date": "2013-01-04", # String(必填) 开始日期
"end_date": "2013-01-08", # String(必填) 结束日期
"period": "1d", # String(选填) 频次 仅支持1m 15m 30m 60m 1d 1w 默认1d
"adjust_type": "pre" # String(选填) 复权方式 none:不复权 pre:前复权 post:后复权 默认前复权
}
context.query_data_async(method, params, query_data_async_callback_list, out_format, 25)
# 同步分页查询历史 bar 数据
def test_query_data_page(context) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} start".format(func_name))
out_format = OutFormat.List
page_size = 100
current_page = 1
method = "bar" # String(必填) method方法:固定值
params = {
"code": "000001.SZ", # String(必填) 证券代码 SZ:深证 SH:上海
"start_date": "2013-01-04", # String(必填) 开始日期
"end_date": "2014-01-04", # String(必填) 结束日期
"period": "1d", # String(选填) 频次 仅支持1m 15m 30m 60m 1d 1w 默认1d
"adjust_type": "pre", # String(选填) 复权方式 none:不复权 pre:前复权 post:后复权 默认前复权
"page_size": page_size,
"current_page": current_page
}
data_page_info = context.query_data_page(method, params, out_format)
context.log.info("{}, currentPage: {}, totalPage: {}, pageSize: {}, totalCount: {}".format(func_name, data_page_info.currentPage, data_page_info.totalPage, data_page_info.pageSize, data_page_info.totalCount))
code = data_page_info.data.get("code")
msg = data_page_info.data.get("msg")
context.log.info("data code: " + str(code) + ", msg: " + msg)
if code == 200 :
if (len(data_page_info.data.get("data")) > 0) :
for bar in data_page_info.data.get("data") :
context.log.info("{}, bar data: {}".format(func_name, json.dumps(bar)))
else :
context.log.info("{}, data is empty".format(func_name))
context.log.info("{} end".format(func_name))
def query_data_page_async_callback_list(context, data_page_info, query_id) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} called, query_id:{}".format(func_name, query_id))
context.log.info("{}, currentPage: {}, totalPage: {}, pageSize: {}, totalCount: {}".format(func_name, data_page_info.currentPage, data_page_info.totalPage, data_page_info.pageSize, data_page_info.totalCount))
code = data_page_info.data.get("code")
msg = data_page_info.data.get("msg")
context.log.info("data code: " + str(code) + ", msg: " + msg)
if code == 200 :
if (len(data_page_info.data.get("data")) > 0) :
for bar in data_page_info.data.get("data") :
context.log.info("{}, bar data: {}".format(func_name, json.dumps(bar)))
else :
context.log.info("{}, data is empty".format(func_name))
context.log.info("{} end".format(func_name))
def test_query_data_page_async(context) :
func_name = sys._getframe().f_code.co_name
context.log.info("{} start".format(func_name))
page_size = 100
current_page = 1
out_format = OutFormat.List
method = "bar" # String(必填) method方法:固定值
params = {
"code": "000001.SZ", # String(必填) 证券代码 SZ:深证 SH:上海
"start_date": "2013-01-04", # String(必填) 开始日期
"end_date": "2013-01-08", # String(必填) 结束日期
"period": "1d", # String(选填) 频次 仅支持1m 15m 30m 60m 1d 1w 默认1d
"adjust_type": "pre", # String(选填) 复权方式 none:不复权 pre:前复权 post:后复权 默认前复权
"page_size": page_size,
"current_page": current_page
}
context.query_data_page_async(method, params, query_data_page_async_callback_list, out_format, 345)
#启动前
def pre_start(context):
context.log.info("pre_start called")
context.send_msg("call send_msg")
#策略退出前,可在此做一些回收工作
def pre_stop(context):
context.log.info("pre_stop called")
context.log.info("strategy pre_stop.")
#退出后
def post_stop(context):
context.log.info("post_stop called")
pass
#启动后
def post_start(context):
context.log.info("post_start called")
test_query_bar_today(context)
test_query_bar_today_async(context)
test_query_bar(context)
test_query_bar_async(context)
test_query_market_data(context)
test_query_market_data_async(context)
test_query_data(context)
test_query_data_async(context)
test_query_data_page(context)
test_query_data_page_async(context)
test_sub_indicator(context)
test_sub_bar(context)
pass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
备注:“策略 Demo2”,从 2.1.2 版本开始支持
# 支持 Python 工具库:
| 工具库 | 版本号 |
|---|---|
| numpy | 1.16.4 |
| pandas | 0.24.2 |
| statsmodels | 0.10.1 |
| xlrd | 0.9.3 |
| openpyxl | 2.6.4 |
| rqdatac | 2.9.37 |
| ta-lib | 0.4.19 |
| scipy | 1.5.4 |
# (二)C++ 语言策略 Demo
# 策略 Demo1:
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <kungfu/yijinjing/common.h>
#include <kungfu/yijinjing/log/setup.h>
#include <kungfu/wingchun/strategy/context.h>
#include <kungfu/wingchun/strategy/strategy.h>
namespace py = pybind11;
using namespace kungfu;
using namespace kungfu::wingchun;
using namespace kungfu::wingchun::strategy;
#define ACCOUNT_ID "53191001503"
class DemoStrategy : public Strategy
{
public:
DemoStrategy(yijinjing::data::location_ptr home)
{
yijinjing::log::copy_log_settings(home, home->name);
};
void test_timer(yijinjing::event_ptr event, Context_ptr context)
{
return;
}
void test_time_interval(Context_ptr context, yijinjing::event_ptr event)
{
return;
}
void cancel_order(yijinjing::event_ptr event, Context_ptr context, uint64_t order_id)
{
context->cancel_order(order_id);
}
// 启动前
void pre_start(Context_ptr context) override
{
SPDLOG_INFO("cpp demo pre start");
// 获取配置文件的路径
std::string path = getParamFileDir();
SPDLOG_INFO("path: {}", path);
std::vector<std::string> tickers;
tickers.push_back("600000");
tickers.push_back("601988");
context->add_account(SOURCE_XTP, ACCOUNT_ID, 100000000.0);
// 查询新发行的债
// 备注:context->query_bondIPO_infolist 函数从2.1.1版本开始支持
context->query_bondIPO_infolist(ACCOUNT_ID);
//请求登录xtp算法交易服务器
//备注:context->login_algo_server()函数从2.0.12版本开始支持
//备注:参数中的"username"和"password",需要根据实际情况填写
//context->login_algo_server(SOURCE_XTP, ACCOUNT_ID, "username", "password")
context->subscribe(SOURCE_XTP, tickers, EXCHANGE_SSE);
context->subscribe_tick_by_tick(SOURCE_XTP, tickers, EXCHANGE_SSE);
context->subscribe_order_book(SOURCE_XTP, tickers, EXCHANGE_SSE);
// 订阅买一卖一队列行情
// 备注:context->subscribe_bid1_ask1()函数从2.0.11版本开始支持
//context->subscribe_bid1_ask1(SOURCE_XTP, tickers, EXCHANGE_SSE)
auto f1 = std::bind(&DemoStrategy::test_timer, this, std::placeholders::_1, context);
context->add_timer(yijinjing::time::now_in_nano() + yijinjing::time_unit::NANOSECONDS_PER_SECOND * 5, f1);
// 静态行情数量大于零,说明获取成功
quotes = context->getAllStaticQuote();
SPDLOG_INFO("load status quote num: {}.", quotes.size());
// 信用账户查询相关示例
// 请求查询信用账户特有信息
// 备注:context->query_credit_fund_info()函数从2.0.8版本开始支持
context->query_credit_fund_info(SOURCE_XTP, ACCOUNT_ID)
// 融资融券业务中请求现金直接还款
// 备注:context->credit_cash_repay()函数从2.0.8版本开始支持
context->credit_cash_repay(SOURCE_XTP, ACCOUNT_ID, 50000.00)
// 请求查询信用账户可融券头寸信息
// 备注:context->query_credit_ticker_assign_info()函数从2.0.11版本开始支持
//context->query_credit_ticker_assign_info(SOURCE_XTP, ACCOUNT_ID, "600000", EXCHANGE_SSE);
// 请求查询信用账户负债合约信息
// 备注:context->query_credit_debt_info()函数从2.0.11版本开始支持
//context->query_credit_debt_info(SOURCE_XTP, ACCOUNT_ID);
// 请求查询信用账户指定证券负债未还信息
// 备注:context->query_credit_ticker_debt_info()函数从2.0.11版本开始支持
//context->query_credit_ticker_debt_info(SOURCE_XTP, ACCOUNT_ID, "600000", EXCHANGE_SSE);
// 请求查询信用账户待还资金信息
// 备注:context->query_credit_asset_debt_info()函数从2.0.11版本开始支持
//context->query_credit_asset_debt_info(SOURCE_XTP, ACCOUNT_ID);
// 请求债转股信息
// 备注:context->query_bondswapstock_info()函数从2.1.2版本开始支持
// 查询所有的债转股信息
context->query_bondswapstock_info(ACCOUNT_ID);
// 查询单支债转股信息
// context->query_bondswapstock_info(ACCOUNT_ID, "110001", EXCHANGE_SSE);
auto f4= std::bind(&DemoStrategy::test_time_interval, this, context, std::placeholders::_1);
context->add_time_interval(yijinjing::time_unit::NANOSECONDS_PER_SECOND, f4);//NANOSECONDS_PER_SECOND是一个系统定义的数值常量,为1000000000,单位是纳秒,也即1秒钟;
//客户可根据实际需要,自行对该值进行替换
SPDLOG_INFO("account_cash_limit: {}", context->get_account_cash_limit(ACCOUNT_ID));
}
// 启动后
void post_start(Context_ptr context) override
{
SPDLOG_INFO("cpp demo post start");
}
// 策略退出前,可在此做一些回收工作
void pre_stop(Context_ptr context) override
{
SPDLOG_INFO("cpp demo pre stop");
}
// 退出后
void post_stop(Context_ptr context) override
{
SPDLOG_INFO("cpp demo post stop");
}
void on_trading_day(Context_ptr context, int64_t daytime) override
{
SPDLOG_INFO("cpp demo on trading day");
}
// bar 分钟级别行情回调
void on_bar(Context_ptr context, const wingchun::msg::data::Bar &bar) override
{
SPDLOG_INFO("cpp demo on bar");
}
// 行情数据更新回调
void on_quote(Context_ptr context, const wingchun::msg::data::Quote "e) override
{
SPDLOG_INFO("cpp demo on quote");
uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.ask_price[0],
200, PriceType::Limit, Side::Buy, Offset::Open, HedgeFlag::Speculation);
//信用交易示例
//普通买入
//uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.ask_price[0],
// 200, PriceType::Limit, Side::Buy, Offset::Open, HedgeFlag::Speculation, BusinessType::MARGIN);
//普通卖出
//uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.bid_price[0],
// 200, PriceType::Limit, Side::Sell, Offset::Open, HedgeFlag::Speculation, BusinessType::MARGIN);
//融资买入
//uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.bid_price[0],
// 200, PriceType::Limit, Side::MarginTrade, Offset::Open, HedgeFlag::Speculation, BusinessType::MARGIN);
//卖券还款
//uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.ask_price[0],
// 200, PriceType::Limit, Side::RepayMargin, Offset::Open, HedgeFlag::Speculation, BusinessType::MARGIN);
//融券卖出
//uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.ask_price[0],
// 200, PriceType::Limit, Side::ShortSell, Offset::Open, HedgeFlag::Speculation, BusinessType::MARGIN);
//买券还券
//uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.ask_price[0],
// 200, PriceType::Limit, Side::RepayStock, Offset::Open, HedgeFlag::Speculation, BusinessType::MARGIN);
//现券还券
//uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.ask_price[0],
// 200, PriceType::Limit, Side::StockRepayStock, Offset::Open, HedgeFlag::Speculation, BusinessType::MARGIN);
char msg[1024];
sprintf(msg, "insert_order(%s,%s)", quote.instrument_id, quote.exchange_id);
context->send_msg(msg);
if (order_id > 0)
{
auto f = std::bind(&DemoStrategy::cancel_order, this, std::placeholders::_1, context, order_id);
context->add_timer(yijinjing::time::now_in_nano() + yijinjing::time_unit::NANOSECONDS_PER_SECOND, f);
}
SPDLOG_INFO("quote received: [time]{} [instrument_id]{} [last_price]{}, msg: {}.",
yijinjing::time::strftime(quote.data_time), quote.instrument_id, quote.last_price,msg);
//策略用户在双中心间进行资金划转(从远端节点转入到本节点200元)。
//ACCOUNT_ID是当前下单用的资金账户;“123456”是账户的密码,需根据实际情况设定
//context->fund_transfer(ACCOUNT_ID, “123456”, FUND_TRANSFER_TYPE::FUND_TRANSFER_IN, 200.0);
//策略用户查询双中心间资金划转情况。
//ACCOUNT_ID是当前下单用的资金账户;“123456”是账户的密码,需根据实际情况设定
//context->query_other_server_fund(ACCOUNT_ID, “123456”, FUND_QUERY_TYPE::FUND_QUERY_INTERNAL) ;
}
// 买一卖一队列行情数据更新回调
// 备注:on_bid1ask1()函数从2.0.11版本开始支持
void on_bid1ask1(Context_ptr context, const msg::data::Bid1Ask1 &b1a1) override
{
SPDLOG_INFO("cpp demo on Bid1Ask1");
}
// 逐笔成交更新回调
void on_transaction(Context_ptr context, const wingchun::msg::data::Transaction &transaction) override
{
SPDLOG_INFO("cpp demo on transaction");
}
// 逐笔委托更新回调
void on_entrust(Context_ptr context, const wingchun::msg::data::Entrust &entrust) override
{
SPDLOG_INFO("cpp demo on entrust");
}
// 订单信息更新回调
void on_order(Context_ptr context, const wingchun::msg::data::Order &order) override
{
SPDLOG_INFO("cpp demo on order");
}
// 订单成交回报回调
void on_trade(Context_ptr context, const wingchun::msg::data::Trade &trade) override
{
SPDLOG_INFO("cpp demo on trade");
}
// 订单操作错误回调 撤单反馈信息回调
void on_order_action_error(Context_ptr context, const wingchun::msg::data::OrderActionError &error) override
{
SPDLOG_INFO("cpp demo on order action error");
}
// 订单簿数据更新回调
void on_order_book(Context_ptr context, const wingchun::msg::data::OrderBook& order_book) override
{
SPDLOG_INFO("cpp demo on order book");
}
// // 撤单反馈信息回调
// void on_cancelorder_feedback(Context_ptr context, const wingchun::msg::data::CancelOrderFeedBack &cofeedback) override
// {
// SPDLOG_INFO("cpp demo on cancelorder feedback");
// }
// 资金账户响应回调
// 备注:on_asset()函数从2.0.11版本开始支持
void on_asset(Context_ptr context, const msg::data::Asset& asset) override
{
SPDLOG_INFO("cpp demo on asset");
}
// 接收前端发送回来的客户自定义消息
void on_client_msg(Context_ptr context, const std::string &msg) override
{
SPDLOG_INFO("cpp demo on client msg");
}
// 融资融券特有帐户数据回调
// 备注:on_query_credit_fund_info()函数从2.0.8版本开始支持
void on_query_credit_fund_info(Context_ptr context, const msg::data::CreditFundInfo &crdfundinfo) override
{
SPDLOG_INFO("cpp demo on on_query_credit_fund_info");
}
// 融资融券业务中现金直接还款的响应回调
// 备注:on_credit_cash_repay()函数从2.0.8版本开始支持
void on_credit_cash_repay(Context_ptr context, const msg::data::CreditCashRepayRsp& cash_repay_rsp) override
{
SPDLOG_INFO("cpp demo on on_credit_cash_repay");
}
// 请求查询信用账户可融券头寸信息的响应回调
// 备注:on_query_credit_ticker_assign_info()函数从2.0.11版本开始支持
void on_query_credit_ticker_assign_info(Context_ptr context, const msg::data::CrdPositionStkInfo &crd_position_stk_info) override
{
SPDLOG_INFO("cpp demo on query_credit_ticker_assign_info");
}
// 请求查询信用账户负债信息的响应回调
// 备注:on_query_credit_debt_info()函数从2.0.11版本开始支持
void on_query_credit_debt_info(Context_ptr context, const msg::data::CrdDebtInfo &crd_debt_info) override
{
SPDLOG_INFO("cpp demo on query_credit_debt_info");
}
// 请求查询信用账户指定证券负债未还信息响应回调
// 备注:on_query_credit_ticker_debt_info()函数从2.0.11版本开始支持
void on_query_credit_ticker_debt_info(Context_ptr context, const msg::data::CrdDebtStockInfo &crd_debt_stk_info) override
{
SPDLOG_INFO("cpp demo on query_credit_ticker_debt_info");
}
// 请求查询信用账户待还资金的响应回调
// 备注:on_query_credit_asset_debt_info()函数从2.0.11版本开始支持
void on_query_credit_asset_debt_info(Context_ptr context, const double &remain_amount) override
{
SPDLOG_INFO("cpp demo on query_credit_asset_debt_info");
}
// 资金划转结果回调
void on_fund_transfer(Context_ptr context, const msg::data::FundTransferFeedBack &feedback) override
{
SPDLOG_INFO("cpp demo on fund_transfer");
}
// 资金查询结果回调
void on_query_other_server_fund(Context_ptr context, const msg::data::FundQueryFeedBack &feedback) override
{
SPDLOG_INFO("cpp demo on query_other_server_fund");
}
// xtp算法交易策略信息响应回调
// 备注: on_algo_strategy_info()函数从2.0.12版本开始支持
void on_algo_strategy_info(Context_ptr context, const msg::data::AlgoStrategyInfo& algo_strategy_info) override
{
SPDLOG_INFO("cpp demo on algo_strategy_info");
}
// xtp算法交易运行时策略状态结构体响应回调
// 备注: on_algo_strategy_state_report()函数从2.0.12版本开始支持
void on_algo_strategy_state_report(Context_ptr context, const msg::data::AlgoStrategyStateReport& algo_strategy_state_report) override
{
SPDLOG_INFO("cpp demo on algo_strategy_state_report");
}
// xtp算法交易创建策略反馈信息响应回调
// 备注: on_create_algo_strategy()函数从2.0.12版本开始支持
void on_create_algo_strategy(Context_ptr context, const msg::data::AlgoStrategyInfo& algo_strategy_info) override
{
SPDLOG_INFO("cpp demo on create_algo_strategy");
context->start_algo_strategy(ACCOUNT_ID, algo_strategy_info.xtp_strategy_id);
}
// xtp算法交易查询策略反馈信息响应回调
// 备注: on_query_algo_strategy()函数从2.0.12版本开始支持
void on_query_algo_strategy(Context_ptr context, const msg::data::AlgoStrategyInfo& algo_strategy_info) override
{
SPDLOG_INFO("cpp demo on query_algo_strategy");
}
// xtp算法交易开始运行策略反馈信息响应回调
// 备注: on_start_algo_strategy()函数从2.0.12版本开始支持
void on_start_algo_strategy(Context_ptr context, const msg::data::AlgoStrategyInfo& algo_strategy_info) override
{
SPDLOG_INFO("cpp demo on start_algo_strategy");
}
// xtp算法交易停止运行策略反馈信息响应回调
// 备注: on_stop_algo_strategy()函数从2.0.12版本开始支持
void on_stop_algo_strategy(Context_ptr context, const msg::data::AlgoStrategyInfo& algo_strategy_info) override
{
SPDLOG_INFO("cpp demo on stop_algo_strategy");
}
// xtp算法交易销毁策略反馈信息响应回调
// 备注: on_destroy_algo_strategy()函数从2.0.12版本开始支持
void on_destroy_algo_strategy(Context_ptr context, const msg::data::AlgoStrategyInfo& algo_strategy_info) override
{
SPDLOG_INFO("cpp demo on destroy_algo_strategy");
}
// 登录xtp算法交易服务器反馈信息响应回调
// 备注: on_login_algo_server()函数从2.0.12版本开始支持
void on_login_algo_server(Context_ptr context, bool success) override
{
SPDLOG_INFO("cpp demo on login_algo_server");
if(success)
{
nlohmann::json strategy_param;
std::vector<std::string> buyDateTime;
buyDateTime.push_back("09:30");
buyDateTime.push_back("09:40");
strategy_param["buyDateTime"] = buyDateTime;
strategy_param["stop_selling_while_buy_overflow"] = false;
strategy_param["cancel_overflow_order_after_clear_time"] = true;
strategy_param["start_time"] = "09:30:00";
strategy_param["end_time"] = "09:40:00";
nlohmann::json trade0;
trade0["market"] = "SZ";
trade0["clientStrategyId"] = "202010200902";
trade0["quantity"] = 20000;
trade0["side"] = "BUY";
trade0["ticker"] = "002513";
nlohmann::json trade1;
trade1["market"] = "SZ";
trade1["clientStrategyId"] = "202010200902";
trade1["quantity"] = 20000;
trade1["side"] = "BUY";
trade1["ticker"] = "001914";
std::vector<nlohmann::json> trade_list;
trade_list.push_back(trade0);
trade_list.push_back(trade1);
strategy_param["trade_list"] = trade_list;
strategy_param["business_type"] = "CASH";
context->create_algo_strategy(ACCOUNT_ID, 2001, 202010140939, strategy_param.dump());
//备注:变量strategy_param的数据格式,由context->create_algo_strategy()函数的第二个参数来决定,具体细节需咨询算法交易相关人员
}
}
// 查询新发行的债信息响应回调
// 备注: on_query_bondIPO_info函数从2.1.1版本开始支持
void on_query_bondIPO_info(Context_ptr context, const wingchun::msg::data::IPOTickerInfo &IPOInfo) override
{
if(0 == IPOInfo.error_id)
{
SPDLOG_INFO("bond ipo info: {}", wingchun::msg::data::to_string(IPOInfo));
}
else
{
// 查询失败
SPDLOG_WARN("error bond ipo info: {}", wingchun::msg::data::to_string(IPOInfo));
}
}
// 查询新发行的债信息推送结束响应回调
// 备注: on_query_bondIPO_end函数从2.1.1版本开始支持
void on_query_bondIPO_end(Context_ptr context) override
{
// 查询结果推送完成
SPDLOG_INFO("collect finish.");
}
// 查询债转股信息响应回调
// 备注: on_query_bondswapstock_info函数从2.1.2版本开始支持
void on_query_bondswapstock_info(Context_ptr context, const wingchun::msg::data::QueryBondSwapStockRsp &swap_info)
{
if(0 == swap_info.error_id)
{
SPDLOG_INFO("bond swap stock info: {}", wingchun::msg::data::to_string(swap_info));
}
else
{
// 查询失败
SPDLOG_WARN("error bond swap stock info: {}", wingchun::msg::data::to_string(swap_info));
}
}
// 查询债转股信息响应结束回调
// 备注: on_query_bondswapstock_end函数从2.1.2版本开始支持
void on_query_bondswapstock_end(Context_ptr context)
{
// 查询结果推送完成
SPDLOG_INFO("collect finish.");
}
// 获取编译策略的kungfu版本号,本函数不允许修改。
virtual const std::string getCompileVersion() const override
{
std::ostringstream ver;
#ifdef ALPHAX_VERSION
ver<<ALPHAX_VERSION;
#else
ver<<DEFAULT_COMPILE_VERSION;
#endif
SPDLOG_INFO("Version: {}.", ver.str());
return ver.str();
}
private:
// 静态行情整个交易日都不会变,启动策略时取到所有证券的静态数据后,需要时直接使用
// 而不需要用一次查一次,性能很差(因为需要读写文件)
// key的格式是:证券代码.证券市场;比如:600000.SSE和000001.SZE
std::map<std::string, QuoteStaticFullInfo> quotes;
};
PYBIND11_MODULE(PY_MODULE, m)
{
py::class_<DemoStrategy, Strategy, std::shared_ptr<DemoStrategy>>(m, "Strategy")
.def(py::init<yijinjing::data::location_ptr>())
.def("pre_start", &DemoStrategy::pre_start)
.def("post_start", &DemoStrategy::post_start)
.def("pre_stop", &DemoStrategy::pre_stop)
.def("post_stop", &DemoStrategy::post_stop)
.def("on_trading_day", &DemoStrategy::on_trading_day)
.def("on_quote", &DemoStrategy::on_quote)
.def("on_bid1ask1", &DemoStrategy::on_bid1ask1) // 备注:on_bid1ask1()函数从2.0.11版本开始支持
.def("on_bar", &DemoStrategy::on_bar)
.def("on_entrust", &DemoStrategy::on_entrust)
.def("on_transaction", &DemoStrategy::on_transaction)
.def("on_order", &DemoStrategy::on_order)
.def("on_order_action_error", &DemoStrategy::on_order_action_error)
.def("on_trade", &DemoStrategy::on_trade)
.def("on_order_book", &DemoStrategy::on_order_book)
.def("on_asset", &DemoStrategy::on_asset) // 备注:on_asset()函数从2.0.11版本开始支持
.def("on_client_msg", &DemoStrategy::on_client_msg)
.def("on_query_credit_fund_info", &DemoStrategy::on_query_credit_fund_info) // on_query_credit_fund_info()函数从2.0.8版本开始支持
.def("on_credit_cash_repay", &DemoStrategy::on_credit_cash_repay) // on_credit_cash_repay()函数从2.0.8版本开始支持
.def("on_query_credit_ticker_assign_info", &DemoStrategy::on_query_credit_ticker_assign_info) // 备注:on_query_credit_ticker_assign_info()函数从2.0.11版本开始支持
.def("on_query_credit_debt_info", &DemoStrategy::on_query_credit_debt_info) // 备注:on_query_credit_debt_info()函数从2.0.11版本开始支持
.def("on_query_credit_ticker_debt_info", &DemoStrategy::on_query_credit_ticker_debt_info) // 备注:on_query_credit_ticker_debt_info()函数从2.0.11版本开始支持
.def("on_query_credit_asset_debt_info", &DemoStrategy::on_query_credit_asset_debt_info) // 备注:on_query_credit_asset_debt_info()函数从2.0.11版本开始支持
.def("on_fund_transfer", &DemoStrategy::on_fund_transfer)
.def("on_query_other_server_fund", &DemoStrategy::on_query_other_server_fund)
.def("on_algo_strategy_info", &DemoStrategy::on_algo_strategy_info) // 备注:on_algo_strategy_info()函数从2.0.12版本开始支持
.def("on_algo_strategy_state_report", &DemoStrategy::on_algo_strategy_state_report) // 备注: on_algo_strategy_state_report()函数从2.0.12版本开始支持
.def("on_create_algo_strategy", &DemoStrategy::on_create_algo_strategy) // 备注: on_create_algo_strategy()函数从2.0.12版本开始支持
.def("on_query_algo_strategy", &DemoStrategy::on_query_algo_strategy) // 备注: on_query_algo_strategy()函数从2.0.12版本开始支持
.def("on_start_algo_strategy", &DemoStrategy::on_start_algo_strategy) // 备注: on_start_algo_strategy()函数从2.0.12版本开始支持
.def("on_stop_algo_strategy", &DemoStrategy::on_stop_algo_strategy) // 备注: on_stop_algo_strategy()函数从2.0.12版本开始支持
.def("on_destroy_algo_strategy", &DemoStrategy::on_destroy_algo_strategy) // 备注: on_destroy_algo_strategy()函数从2.0.12版本开始支持
.def("on_login_algo_server", &DemoStrategy::on_login_algo_server) // 备注: on_login_algo_server()函数从2.0.12版本开始支持
.def("on_query_bondIPO_info", &DemoStrategy::on_query_bondIPO_info)// 备注: on_query_bondIPO_info()函数从2.1.1版本开始支持
.def("on_query_bondIPO_end", &DemoStrategy::on_query_bondIPO_end)// 备注: on_query_bondIPO_end()函数从2.1.1版本开始支持
.def("on_query_bondswapstock_info", &DemoStrategy::on_query_bondswapstock_info)// 备注: on_query_bondswapstock_info()函数从2.1.2版本开始支持
.def("on_query_bondswapstock_end", &DemoStrategy::on_query_bondswapstock_end)// 备注: on_query_bondswapstock_end()函数从2.1.2版本开始支持
.def("getCompileVersion", &DemoStrategy::getCompileVersion);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
# 策略 Demo2:
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <kungfu/yijinjing/common.h>
#include <kungfu/yijinjing/log/setup.h>
#include <kungfu/wingchun/strategy/context.h>
#include <kungfu/wingchun/strategy/strategy.h>
namespace py = pybind11;
using namespace kungfu;
using namespace kungfu::wingchun;
using namespace kungfu::wingchun::strategy;
#define ACCOUNT_ID "15003941"
class DemoStrategy : public StrategyWithBook
{
public:
DemoStrategy(yijinjing::data::location_ptr home):StrategyWithBook(home), count_(0)
{
yijinjing::log::copy_log_settings(home, home->name);
};
void test_timer(yijinjing::event_ptr event, Context_ptr context)
{
return;
}
void test_time_interval(Context_ptr context, yijinjing::event_ptr event)
{
//注意:book和position数据,是异步更新,而非实时更新
auto book1 = get_book();
SPDLOG_INFO("Strategy available cash:{}", book1->get_available_cash());
SPDLOG_INFO("Strategy Book: {}", book1->event()->as_dict().dump());
auto pos_uids1 = book1->get_position_uids();
SPDLOG_INFO("Strategy position as follow :");
for(auto& pos_id: pos_uids1)
{
auto pos = book1->get_position(pos_id);
SPDLOG_INFO("instrument_id:{}, volume:{}, sellable volume:{}, avg_open_price :{}", pos->instrument_id_ , pos->volume_ - pos->frozen_total_, pos->yesterday_volume_ - pos->frozen_yesterday_, pos->avg_open_price_);
SPDLOG_INFO("Strategy Position: {}", pos->event()->as_dict().dump());
}
auto book2 = get_account_book(SOURCE_XTP, ACCOUNT_ID);
SPDLOG_INFO("Account available cash:{}", book2->get_available_cash());
SPDLOG_INFO("Account Book: {}", book2->event()->as_dict().dump());
auto pos_uids2 = book2->get_position_uids();
SPDLOG_INFO("Account position as follow :");
for(auto& pos_id: pos_uids2)
{
auto pos = book2->get_position(pos_id);
SPDLOG_INFO("instrument_id:{}, volume:{}, sellable volume:{}, avg_open_price :{}", pos->instrument_id_ , pos->volume_ - pos->frozen_total_, pos->yesterday_volume_ - pos->frozen_yesterday_, pos->avg_open_price_);
SPDLOG_INFO("Account Position: {}", pos->event()->as_dict().dump());
}
return;
}
void cancel_order(yijinjing::event_ptr event, Context_ptr context, uint64_t order_id)
{
context->cancel_order(order_id);
}
// 启动前
void pre_start(Context_ptr context) override
{
SPDLOG_INFO("cpp demo pre start");
StrategyWithBook::pre_start(context);
// 获取配置文件的路径
std::string path = getParamFileDir();
SPDLOG_INFO("path: {}", path);
std::vector<std::string> tickers;
tickers.push_back("600000");
tickers.push_back("601988");
add_account(context, SOURCE_XTP, ACCOUNT_ID, 100000000.0);
// 查询新发行的债
// 备注:context->query_bondIPO_infolist 函数从2.1.1版本开始支持
context->query_bondIPO_infolist(ACCOUNT_ID);
//请求登录xtp算法交易服务器
//备注:context->login_algo_server()函数从2.0.12版本开始支持
//备注:参数中的"username"和"password",需要根据实际情况填写
//context->login_algo_server(SOURCE_XTP, ACCOUNT_ID, "username", "password")
// context->subscribe(SOURCE_XTP, tickers, EXCHANGE_SSE);
context->subscribe_market_data(SOURCE_XTP, tickers, EXCHANGE_SSE);
// context->subscribe_tick_by_tick(SOURCE_XTP, tickers, EXCHANGE_SSE);
// context->subscribe_order_book(SOURCE_XTP, tickers, EXCHANGE_SSE);
// 订阅买一卖一队列行情
// 备注:context->subscribe_bid1_ask1()函数从2.0.11版本开始支持
//context->subscribe_bid1_ask1(SOURCE_XTP, tickers, EXCHANGE_SSE)
auto f1 = std::bind(&DemoStrategy::test_timer, this, std::placeholders::_1, context);
context->add_timer(yijinjing::time::now_in_nano() + yijinjing::time_unit::NANOSECONDS_PER_SECOND * 5, f1);
// 静态行情数量大于零,说明获取成功
// quotes = context->getAllStaticQuote();
// SPDLOG_INFO("load status quote num: {}.", quotes.size());
// 信用账户查询相关示例
// 请求查询信用账户特有信息
// 备注:context->query_credit_fund_info()函数从2.0.8版本开始支持
context->query_credit_fund_info(SOURCE_XTP, ACCOUNT_ID)
// 融资融券业务中请求现金直接还款
// 备注:context->credit_cash_repay()函数从2.0.8版本开始支持
// context->credit_cash_repay(SOURCE_XTP, ACCOUNT_ID, 50000.00)
// 请求查询信用账户可融券头寸信息
// 备注:context->query_credit_ticker_assign_info()函数从2.0.11版本开始支持
//context->query_credit_ticker_assign_info(SOURCE_XTP, ACCOUNT_ID, "600000", EXCHANGE_SSE);
// 请求查询信用账户负债合约信息
// 备注:context->query_credit_debt_info()函数从2.0.11版本开始支持
//context->query_credit_debt_info(SOURCE_XTP, ACCOUNT_ID);
// 请求查询信用账户指定证券负债未还信息
// 备注:context->query_credit_ticker_debt_info()函数从2.0.11版本开始支持
//context->query_credit_ticker_debt_info(SOURCE_XTP, ACCOUNT_ID, "600000", EXCHANGE_SSE);
// 请求查询信用账户待还资金信息
// 备注:context->query_credit_asset_debt_info()函数从2.0.11版本开始支持
//context->query_credit_asset_debt_info(SOURCE_XTP, ACCOUNT_ID);
// 请求债转股信息
// 备注:context->query_bondswapstock_info()函数从2.1.2版本开始支持
// 查询所有的债转股信息
context->query_bondswapstock_info(ACCOUNT_ID);
// 查询单支债转股信息
// context->query_bondswapstock_info(ACCOUNT_ID, "110001", EXCHANGE_SSE);
auto f4= std::bind(&DemoStrategy::test_time_interval, this, context, std::placeholders::_1);
context->add_time_interval(yijinjing::time_unit::NANOSECONDS_PER_SECOND*30, f4);//NANOSECONDS_PER_SECOND是一个系统定义的数值常量,为1000000000,单位是纳秒,也即1秒钟;
//客户可根据实际需要,自行对该值进行替换
SPDLOG_INFO("account_cash_limit: {}", context->get_account_cash_limit(ACCOUNT_ID));
}
// 启动后
void post_start(Context_ptr context) override
{
SPDLOG_INFO("cpp demo post start");
}
// 策略退出前,可在此做一些回收工作
void pre_stop(Context_ptr context) override
{
SPDLOG_INFO("cpp demo pre stop");
}
// 退出后
void post_stop(Context_ptr context) override
{
SPDLOG_INFO("cpp demo post stop");
}
void on_trading_day(Context_ptr context, int64_t daytime) override
{
SPDLOG_INFO("cpp demo on trading day");
}
// bar 分钟级别行情回调
void on_bar(Context_ptr context, const wingchun::msg::data::Bar &bar) override
{
SPDLOG_INFO("cpp demo on bar");
}
// 行情数据更新回调
void on_quote(Context_ptr context, const wingchun::msg::data::Quote "e) override
{
if(count_>=5)
return;
SPDLOG_INFO("cpp demo on quote");
uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.ask_price[0],
200, PriceType::Limit, Side::Buy, Offset::Open, HedgeFlag::Speculation);
//信用交易示例
//普通买入
//uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.ask_price[0],
// 200, PriceType::Limit, Side::Buy, Offset::Open, HedgeFlag::Speculation, BusinessType::MARGIN);
//普通卖出
//uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.bid_price[0],
// 200, PriceType::Limit, Side::Sell, Offset::Open, HedgeFlag::Speculation, BusinessType::MARGIN);
//融资买入
//uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.bid_price[0],
// 200, PriceType::Limit, Side::MarginTrade, Offset::Open, HedgeFlag::Speculation, BusinessType::MARGIN);
//卖券还款
//uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.ask_price[0],
// 200, PriceType::Limit, Side::RepayMargin, Offset::Open, HedgeFlag::Speculation, BusinessType::MARGIN);
//融券卖出
//uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.ask_price[0],
// 200, PriceType::Limit, Side::ShortSell, Offset::Open, HedgeFlag::Speculation, BusinessType::MARGIN);
//买券还券
//uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.ask_price[0],
// 200, PriceType::Limit, Side::RepayStock, Offset::Open, HedgeFlag::Speculation, BusinessType::MARGIN);
//现券还券
//uint64_t order_id = context->insert_order(quote.instrument_id, quote.exchange_id, ACCOUNT_ID, quote.ask_price[0],
// 200, PriceType::Limit, Side::StockRepayStock, Offset::Open, HedgeFlag::Speculation, BusinessType::MARGIN);
char msg[1024];
sprintf(msg, "insert_order(%s,%s)", quote.instrument_id, quote.exchange_id);
context->send_msg(msg);
if (order_id > 0)
{
auto f = std::bind(&DemoStrategy::cancel_order, this, std::placeholders::_1, context, order_id);
context->add_timer(yijinjing::time::now_in_nano() + yijinjing::time_unit::NANOSECONDS_PER_SECOND, f);
count_++;
}
SPDLOG_INFO("quote received: [time]{} [instrument_id]{} [last_price]{}, msg: {}.",
yijinjing::time::strftime(quote.data_time), quote.instrument_id, quote.last_price,msg);
//策略用户在双中心间进行资金划转(从远端节点转入到本节点200元)。
//ACCOUNT_ID是当前下单用的资金账户;“123456”是账户的密码,需根据实际情况设定
//context->fund_transfer(ACCOUNT_ID, “123456”, FUND_TRANSFER_TYPE::FUND_TRANSFER_IN, 200.0);
//策略用户查询双中心间资金划转情况。
//ACCOUNT_ID是当前下单用的资金账户;“123456”是账户的密码,需根据实际情况设定
//context->query_other_server_fund(ACCOUNT_ID, “123456”, FUND_QUERY_TYPE::FUND_QUERY_INTERNAL) ;
}
// 买一卖一队列行情数据更新回调
// 备注:on_bid1ask1()函数从2.0.11版本开始支持
void on_bid1ask1(Context_ptr context, const msg::data::Bid1Ask1 &b1a1) override
{
SPDLOG_INFO("cpp demo on Bid1Ask1");
}
// 逐笔成交更新回调
void on_transaction(Context_ptr context, const wingchun::msg::data::Transaction &transaction) override
{
SPDLOG_INFO("cpp demo on transaction");
}
// 逐笔委托更新回调
void on_entrust(Context_ptr context, const wingchun::msg::data::Entrust &entrust) override
{
SPDLOG_INFO("cpp demo on entrust");
}
// 订单信息更新回调
void on_order(Context_ptr context, const wingchun::msg::data::Order &order) override
{
SPDLOG_INFO("cpp demo on order");
}
// 订单成交回报回调
void on_trade(Context_ptr context, const wingchun::msg::data::Trade &trade) override
{
SPDLOG_INFO("cpp demo on trade");
}
// 订单操作错误回调
void on_order_action_error(Context_ptr context, const wingchun::msg::data::OrderActionError &error) override
{
SPDLOG_INFO("cpp demo on order action error");
}
// 订单簿数据更新回调
void on_order_book(Context_ptr context, const wingchun::msg::data::OrderBook& order_book) override
{
SPDLOG_INFO("cpp demo on order book");
}
// // 撤单反馈信息回调
// void on_cancelorder_feedback(Context_ptr context, const wingchun::msg::data::CancelOrderFeedBack &cofeedback) override
// {
// SPDLOG_INFO("cpp demo on cancelorder feedback");
// }
// 资金账户响应回调
// 备注:on_asset()函数从2.0.11版本开始支持
void on_asset(Context_ptr context, const msg::data::Asset& asset) override
{
SPDLOG_INFO("cpp demo on asset");
}
// 接收前端发送回来的客户自定义消息
void on_client_msg(Context_ptr context, const std::string &msg) override
{
SPDLOG_INFO("cpp demo on client msg");
}
// 融资融券特有帐户数据回调
// 备注:on_query_credit_fund_info()函数从2.0.8版本开始支持
void on_query_credit_fund_info(Context_ptr context, const msg::data::CreditFundInfo &crdfundinfo) override
{
SPDLOG_INFO("cpp demo on on_query_credit_fund_info");
}
// 融资融券业务中现金直接还款的响应回调
// 备注:on_credit_cash_repay()函数从2.0.8版本开始支持
void on_credit_cash_repay(Context_ptr context, const msg::data::CreditCashRepayRsp& cash_repay_rsp) override
{
SPDLOG_INFO("cpp demo on on_credit_cash_repay");
}
// 请求查询信用账户可融券头寸信息的响应回调
// 备注:on_query_credit_ticker_assign_info()函数从2.0.11版本开始支持
void on_query_credit_ticker_assign_info(Context_ptr context, const msg::data::CrdPositionStkInfo &crd_position_stk_info) override
{
SPDLOG_INFO("cpp demo on query_credit_ticker_assign_info");
}
// 请求查询信用账户负债信息的响应回调
// 备注:on_query_credit_debt_info()函数从2.0.11版本开始支持
void on_query_credit_debt_info(Context_ptr context, const msg::data::CrdDebtInfo &crd_debt_info) override
{
SPDLOG_INFO("cpp demo on query_credit_debt_info");
}
// 请求查询信用账户指定证券负债未还信息响应回调
// 备注:on_query_credit_ticker_debt_info()函数从2.0.11版本开始支持
void on_query_credit_ticker_debt_info(Context_ptr context, const msg::data::CrdDebtStockInfo &crd_debt_stk_info) override
{
SPDLOG_INFO("cpp demo on query_credit_ticker_debt_info");
}
// 请求查询信用账户待还资金的响应回调
// 备注:on_query_credit_asset_debt_info()函数从2.0.11版本开始支持
void on_query_credit_asset_debt_info(Context_ptr context, const double &remain_amount) override
{
SPDLOG_INFO("cpp demo on query_credit_asset_debt_info");
}
// 资金划转结果回调
void on_fund_transfer(Context_ptr context, const msg::data::FundTransferFeedBack &feedback) override
{
SPDLOG_INFO("cpp demo on fund_transfer");
}
// 资金查询结果回调
void on_query_other_server_fund(Context_ptr context, const msg::data::FundQueryFeedBack &feedback) override
{
SPDLOG_INFO("cpp demo on query_other_server_fund");
}
// xtp算法交易策略信息响应回调
// 备注: on_algo_strategy_info()函数从2.0.12版本开始支持
void on_algo_strategy_info(Context_ptr context, const msg::data::AlgoStrategyInfo& algo_strategy_info) override
{
SPDLOG_INFO("cpp demo on algo_strategy_info");
}
// xtp算法交易运行时策略状态结构体响应回调
// 备注: on_algo_strategy_state_report()函数从2.0.12版本开始支持
void on_algo_strategy_state_report(Context_ptr context, const msg::data::AlgoStrategyStateReport& algo_strategy_state_report) override
{
SPDLOG_INFO("cpp demo on algo_strategy_state_report");
}
// xtp算法交易创建策略反馈信息响应回调
// 备注: on_create_algo_strategy()函数从2.0.12版本开始支持
void on_create_algo_strategy(Context_ptr context, const msg::data::AlgoStrategyInfo& algo_strategy_info) override
{
SPDLOG_INFO("cpp demo on create_algo_strategy");
context->start_algo_strategy(ACCOUNT_ID, algo_strategy_info.xtp_strategy_id);
}
// xtp算法交易查询策略反馈信息响应回调
// 备注: on_query_algo_strategy()函数从2.0.12版本开始支持
void on_query_algo_strategy(Context_ptr context, const msg::data::AlgoStrategyInfo& algo_strategy_info) override
{
SPDLOG_INFO("cpp demo on query_algo_strategy");
}
// xtp算法交易开始运行策略反馈信息响应回调
// 备注: on_start_algo_strategy()函数从2.0.12版本开始支持
void on_start_algo_strategy(Context_ptr context, const msg::data::AlgoStrategyInfo& algo_strategy_info) override
{
SPDLOG_INFO("cpp demo on start_algo_strategy");
}
// xtp算法交易停止运行策略反馈信息响应回调
// 备注: on_stop_algo_strategy()函数从2.0.12版本开始支持
void on_stop_algo_strategy(Context_ptr context, const msg::data::AlgoStrategyInfo& algo_strategy_info) override
{
SPDLOG_INFO("cpp demo on stop_algo_strategy");
}
// xtp算法交易销毁策略反馈信息响应回调
// 备注: on_destroy_algo_strategy()函数从2.0.12版本开始支持
void on_destroy_algo_strategy(Context_ptr context, const msg::data::AlgoStrategyInfo& algo_strategy_info) override
{
SPDLOG_INFO("cpp demo on destroy_algo_strategy");
}
// 登录xtp算法交易服务器反馈信息响应回调
// 备注: on_login_algo_server()函数从2.0.12版本开始支持
void on_login_algo_server(Context_ptr context, bool success) override
{
SPDLOG_INFO("cpp demo on login_algo_server");
if(success)
{
context->create_algo_strategy(ACCOUNT_ID, 2001, 202010140939, "{\"buyDateTime\":[\"09:50\",\"10:00\"],\"stop_selling_while_buy_overflow\":false,\"cancel_overflow_order_after_clear_time\":true,\"start_time\":\"09:50:00\",\"end_time\":\"10:00:00\",\"trade_list\":[{\"market\":\"SZ\",\"clientStrategyId\":\"202010140939\",\"quantity\":20000,\"side\":\"BUY\",\"ticker\":\"002513\"},{\"market\":\"SZ\",\"clientStrategyId\":\"202010140939\",\"quantity\":20000,\"side\":\"BUY\",\"ticker\":\"001914\"}],\"business_type\":\"CASH\"}");
}
}
// 查询新发行的债信息响应回调
// 备注: on_query_bondIPO_info函数从2.1.1版本开始支持
void on_query_bondIPO_info(Context_ptr context, const wingchun::msg::data::IPOTickerInfo &IPOInfo) override
{
if(0 == IPOInfo.error_id)
{
SPDLOG_INFO("bond ipo info: {}", wingchun::msg::data::to_string(IPOInfo));
}
else
{
// 查询失败
SPDLOG_WARN("error bond ipo info: {}", wingchun::msg::data::to_string(IPOInfo));
}
}
// 查询新发行的债信息推送结束响应回调
// 备注: on_query_bondIPO_end函数从2.1.1版本开始支持
void on_query_bondIPO_end(Context_ptr context) override
{
// 查询结果推送完成
SPDLOG_INFO("collect finish.");
}
// 查询债转股信息响应回调
// 备注: on_query_bondswapstock_info函数从2.1.2版本开始支持
void on_query_bondswapstock_info(Context_ptr context, const wingchun::msg::data::QueryBondSwapStockRsp &swap_info)
{
if(0 == swap_info.error_id)
{
SPDLOG_INFO("bond swap stock info: {}", wingchun::msg::data::to_string(swap_info));
}
else
{
// 查询失败
SPDLOG_WARN("error bond swap stock info: {}", wingchun::msg::data::to_string(swap_info));
}
}
// 查询债转股信息响应结束回调
// 备注: on_query_bondswapstock_end函数从2.1.2版本开始支持
void on_query_bondswapstock_end(Context_ptr context)
{
// 查询结果推送完成
SPDLOG_INFO("collect finish.");
}
// 获取编译策略的kungfu版本号,本函数不允许修改。
virtual const std::string getCompileVersion() const override
{
std::ostringstream ver;
#ifdef ALPHAX_VERSION
ver<<ALPHAX_VERSION;
#else
ver<<DEFAULT_COMPILE_VERSION;
#endif
SPDLOG_INFO("Version: {}.", ver.str());
return ver.str();
}
private:
// 静态行情整个交易日都不会变,启动策略时取到所有证券的静态数据后,需要时直接使用
// 而不需要用一次查一次,性能很差(因为需要读写文件)
// add by zz on 20210112
std::unordered_map<std::string, QuoteStaticFullInfo> quotes;
uint64_t count_;
};
PYBIND11_MODULE(PY_MODULE, m)
{
py::class_<DemoStrategy, Strategy, std::shared_ptr<DemoStrategy>>(m, "Strategy")
.def(py::init<yijinjing::data::location_ptr>())
.def("pre_start", &DemoStrategy::pre_start)
.def("post_start", &DemoStrategy::post_start)
.def("pre_stop", &DemoStrategy::pre_stop)
.def("post_stop", &DemoStrategy::post_stop)
.def("on_trading_day", &DemoStrategy::on_trading_day)
.def("on_quote", &DemoStrategy::on_quote)
.def("on_bid1ask1", &DemoStrategy::on_bid1ask1) // 备注:on_bid1ask1()函数从2.0.11版本开始支持
.def("on_bar", &DemoStrategy::on_bar)
.def("on_entrust", &DemoStrategy::on_entrust)
.def("on_transaction", &DemoStrategy::on_transaction)
.def("on_order", &DemoStrategy::on_order)
.def("on_order_action_error", &DemoStrategy::on_order_action_error)
.def("on_trade", &DemoStrategy::on_trade)
.def("on_order_book", &DemoStrategy::on_order_book)
.def("on_asset", &DemoStrategy::on_asset) // 备注:on_asset()函数从2.0.11版本开始支持
.def("on_client_msg", &DemoStrategy::on_client_msg)
.def("on_query_credit_fund_info", &DemoStrategy::on_query_credit_fund_info) // on_query_credit_fund_info()函数从2.0.8版本开始支持
.def("on_credit_cash_repay", &DemoStrategy::on_credit_cash_repay) // on_credit_cash_repay()函数从2.0.8版本开始支持
.def("on_query_credit_ticker_assign_info", &DemoStrategy::on_query_credit_ticker_assign_info) // 备注:on_query_credit_ticker_assign_info()函数从2.0.11版本开始支持
.def("on_query_credit_debt_info", &DemoStrategy::on_query_credit_debt_info) // 备注:on_query_credit_debt_info()函数从2.0.11版本开始支持
.def("on_query_credit_ticker_debt_info", &DemoStrategy::on_query_credit_ticker_debt_info) // 备注:on_query_credit_ticker_debt_info()函数从2.0.11版本开始支持
.def("on_query_credit_asset_debt_info", &DemoStrategy::on_query_credit_asset_debt_info) // 备注:on_query_credit_asset_debt_info()函数从2.0.11版本开始支持
.def("on_fund_transfer", &DemoStrategy::on_fund_transfer)
.def("on_query_other_server_fund", &DemoStrategy::on_query_other_server_fund)
.def("on_algo_strategy_info", &DemoStrategy::on_algo_strategy_info) // on_algo_strategy_info()函数从2.0.12版本开始支持
.def("on_algo_strategy_state_report", &DemoStrategy::on_algo_strategy_state_report) // 备注: on_algo_strategy_state_report()函数从2.0.12版本开始支持
.def("on_create_algo_strategy", &DemoStrategy::on_create_algo_strategy) // 备注: on_create_algo_strategy()函数从2.0.12版本开始支持
.def("on_query_algo_strategy", &DemoStrategy::on_query_algo_strategy) // 备注: on_query_algo_strategy()函数从2.0.12版本开始支持
.def("on_start_algo_strategy", &DemoStrategy::on_start_algo_strategy) // 备注: on_start_algo_strategy()函数从2.0.12版本开始支持
.def("on_stop_algo_strategy", &DemoStrategy::on_stop_algo_strategy) // 备注: on_stop_algo_strategy()函数从2.0.12版本开始支持
.def("on_destroy_algo_strategy", &DemoStrategy::on_destroy_algo_strategy) // 备注: on_destroy_algo_strategy()函数从2.0.12版本开始支持
.def("on_login_algo_server", &DemoStrategy::on_login_algo_server) // 备注: on_login_algo_server()函数从2.0.12版本开始支持
.def("on_query_bondIPO_info", &DemoStrategy::on_query_bondIPO_info)// 备注: on_query_bondIPO_info()函数从2.1.1版本开始支持
.def("on_query_bondIPO_end", &DemoStrategy::on_query_bondIPO_end)// 备注: on_query_bondIPO_end()函数从2.1.1版本开始支持
.def("on_query_bondswapstock_info", &DemoStrategy::on_query_bondswapstock_info)// 备注: on_query_bondswapstock_info()函数从2.1.2版本开始支持
.def("on_query_bondswapstock_end", &DemoStrategy::on_query_bondswapstock_end)// 备注: on_query_bondswapstock_end()函数从2.1.2版本开始支持
.def("getCompileVersion", &DemoStrategy::getCompileVersion);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
备注:“策略 Demo2”,从 2.0.11 版本开始支持
# 策略 Demo3:
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <kungfu/yijinjing/common.h>
#include <kungfu/yijinjing/log/setup.h>
#include <kungfu/wingchun/strategy/context.h>
#include <kungfu/wingchun/strategy/strategy.h>
#include <thread_pool.h>
namespace py = pybind11;
using std::placeholders::_1;
using std::placeholders::_2;
using std::placeholders::_3;
using namespace kungfu;
using namespace kungfu::wingchun;
using namespace kungfu::wingchun::strategy;
std::string info_bar(const wingchun::msg::data::Bar& bar) {
nlohmann::json bar_json;
wingchun::msg::data::to_json(bar_json, bar);
return safe_dump(bar_json);
}
std::string info_quote(const wingchun::msg::data::Quote& quote) {
nlohmann::json quote_json;
wingchun::msg::data::to_json(quote_json, quote);
return safe_dump(quote_json);
}
void today_bar_callback(Context_ptr context, const std::map<std::string, std::vector<wingchun::msg::data::Bar>>& bar_map) {
SPDLOG_INFO("{} called", __func__);
for (const auto& item : bar_map) {
SPDLOG_INFO("code: {}", item.first);
for (const wingchun::msg::data::Bar& bar : item.second) {
SPDLOG_INFO("code: {}, open: {}, close: {}", bar.code, bar.open, bar.close);
}
}
}
class DemoStrategy : public StrategyWithBook
{
public:
DemoStrategy(yijinjing::data::location_ptr home):StrategyWithBook(home), count_(0)
{
yijinjing::log::copy_log_settings(home, home->name);
};
// bar 分钟级别行情回调
void on_bar(Context_ptr context, const wingchun::msg::data::Bar &bar) override
{
SPDLOG_INFO("{} called, data: {}", __func__, info_bar(bar));
}
void on_indicator(Context_ptr context, const std::string& type, const nlohmann::json& indicator) override {
SPDLOG_INFO("{} called, type: {}, data: {}", __func__, type, safe_dump(indicator));
}
// 启动前
void pre_start(Context_ptr context) override
{
SPDLOG_INFO("pre run strategy");
StrategyWithBook::pre_start(context);
}
// 启动后
void post_start(Context_ptr context) override
{
SPDLOG_INFO("cpp demo post start");
test(context);
}
std::string info_bar(const wingchun::msg::data::Bar& bar) {
std::ostringstream ostr;
ostr << "Bar data, trading_day: " << bar.trading_day
<< ", source_id: " << bar.source_id
<< ", instrument_id: " << bar.instrument_id
<< ", exchange_id: " << bar.exchange_id
<< ", code: " << bar.code
<< ", type: " << bar.type
<< ", start_time: " << bar.start_time
<< ", end_time: " << bar.end_time
<< ", time_interval: " << bar.time_interval
<< ", open: " << bar.open
<< ", close: " << bar.close
<< ", low: " << bar.low
<< ", high: " << bar.high
<< ", volume: " << bar.volume
<< ", start_volume: " << bar.start_volume
<< ", turnover: " << bar.turnover
<< ", start_turnover: " << bar.start_turnover
<< ", period: " << bar.period;
return ostr.str();
}
std::string info_quote(const wingchun::msg::data::Quote& quote) {
std::ostringstream ostr;
ostr << "Quote data, source_id: " << quote.source_id
<< ", trading_day: " << quote.trading_day
<< ", data_time: " << quote.data_time
<< ", instrument_id: " << quote.instrument_id
<< ", exchange_id: " << quote.exchange_id
<< ", instrument_type: " << int(quote.instrument_type)
<< ", kungfu_time_flag: " << quote.kungfu_time_flag
<< ", pre_close_price: " << quote.pre_close_price
<< ", pre_settlement_price: " << quote.pre_settlement_price
<< ", last_price: " << quote.last_price
<< ", volume: " << quote.volume
<< ", turnover: " << quote.turnover
<< ", pre_open_interest: " << quote.pre_open_interest
<< ", open_interest: " << quote.open_interest
<< ", open_price: " << quote.open_price
<< ", high_price: " << quote.high_price
<< ", low_price: " << quote.low_price
<< ", upper_limit_price: " << quote.upper_limit_price
<< ", lower_limit_price: " << quote.lower_limit_price
<< ", close_price: " << quote.close_price
<< ", settlement_price: " << quote.settlement_price
<< ", iopv: " << quote.iopv
<< ", pre_iopv: " << quote.pre_iopv
<< ", ticker_status: " << quote.ticker_status
<< ", total_bid_volume: " << quote.total_bid_volume
<< ", total_ask_volume: " << quote.total_ask_volume
<< ", ma_bid_price: " << quote.ma_bid_price
<< ", ma_ask_price: " << quote.ma_ask_price
<< ", bid_price: ";
for (double price : quote.bid_price) {
ostr << price << ",";
}
ostr << " ask_price: ";
for (double price : quote.ask_price) {
ostr << price << ",";
}
ostr << " bid_volume: ";
for (int64_t volume : quote.bid_volume) {
ostr << volume << ",";
}
ostr << " ask_volume: ";
for (int64_t volume : quote.ask_volume) {
ostr << volume << ",";
}
// return ostr.str().pop_back();
return ostr.str();
}
void test_query_bar_today(Context_ptr context) {
SPDLOG_INFO("{} start", __func__);
std::vector<std::string> codes = {"600000.SSE", "000002.SZ"};
std::map<std::string, std::vector<wingchun::msg::data::Bar>> today_bar = context->query_bar_today(codes, "5m");
for (auto& kv : today_bar) {
for (auto& bar : kv.second) {
SPDLOG_INFO("{}", info_bar(bar));
}
}
SPDLOG_INFO("{} end", __func__);
}
void today_bar_callback(Context_ptr context, const std::map<std::string, std::vector<wingchun::msg::data::Bar>>& bar_map, uint64_t query_id) {
SPDLOG_INFO("{} called, query id: {}", __func__, query_id);
for (const auto& item : bar_map) {
SPDLOG_INFO("code: {}", item.first);
for (const wingchun::msg::data::Bar& bar : item.second) {
SPDLOG_INFO("{}", info_bar(bar));
}
}
}
void test_query_bar_today_async(Context_ptr context) {
SPDLOG_INFO("{} start", __func__);
std::vector<std::string> codes = {"600000.SSE", "000002.SZ"};
context->query_bar_today_async(codes, std::bind(&DemoStrategy::today_bar_callback, this, _1, _2, _3), "2m", 51);
// context->query_bar_today_async(codes, today_bar_callback, "2m");
}
void test_query_bar(Context_ptr context) {
SPDLOG_INFO("{} start", __func__);
nlohmann::json params = {
{"code", "000001.SZ"},
{"start_date", "2013-01-04"},
{"end_date", "2014-01-04"},
{"period", "1d"},
{"adjust_type", "pre"}
};
std::vector<wingchun::msg::data::Bar> bars = context->query_bar(params);
for (const auto bar : bars) {
SPDLOG_INFO("{}", info_bar(bar));
}
}
void query_bar_callback(Context_ptr context, const std::vector<wingchun::msg::data::Bar>& bars, uint64_t query_id) {
SPDLOG_INFO("{} called, query_id: {}", __func__, query_id);
for (const auto bar : bars) {
SPDLOG_INFO("receive bar: {}", info_bar(bar));
}
}
void test_query_bar_async(Context_ptr context) {
SPDLOG_INFO("{} start", __func__);
nlohmann::json params = {
{"code", "000001.SZ"},
{"start_date", "2013-01-04"},
{"end_date", "2014-01-04"},
{"period", "1d"},
{"adjust_type", "pre"}
};
context->query_bar_async(params, std::bind(&DemoStrategy::query_bar_callback, this, _1, _2, _3), 52);
}
void test_query_market_data(Context_ptr context) {
SPDLOG_INFO("{} start", __func__);
nlohmann::json params = {
{"code", "000001.SZ"},
{"start_date", "2013-01-04"},
{"end_date", "2014-01-04"}
};
std::vector<wingchun::msg::data::Quote> quotes = context->query_market_data(params);
for (const auto quote : quotes) {
SPDLOG_INFO("quote data: {}", info_quote(quote));
}
}
void query_market_data_callback(Context_ptr context, const std::vector<wingchun::msg::data::Quote>& quotes, uint64_t query_id) {
SPDLOG_INFO("{} called, query id: {}", __func__, query_id);
for (const auto quote : quotes) {
SPDLOG_INFO("{}", info_quote(quote));
}
}
void test_query_market_data_async(Context_ptr context) {
SPDLOG_INFO("{} start", __func__);
nlohmann::json params = {
{"code", "000001.SZ"},
{"start_date", "2014-01-04"},
{"end_date", "2014-01-08"}
};
context->query_market_data_async(params, std::bind(&DemoStrategy::query_market_data_callback, this, _1, _2, _3), 53);
}
void test_query_data(Context_ptr context) {
SPDLOG_INFO("{} start", __func__);
std::string method = "bar";
nlohmann::json params = {
{"code", "000001.SZ"},
{"start_date", "2014-01-04"},
{"end_date", "2014-02-04"},
{"period", "1d"},
{"adjust_type", "pre"}
};
nlohmann::json result = context->query_data(method, params);
int code = result["code"];
std::string msg = result["msg"].get<std::string>();
SPDLOG_INFO("query data, code: {}, msg: {}", code, msg);
if (code == 200) {
for (const auto& bar : result["data"]) {
SPDLOG_INFO("Bar data: {}", safe_dump(bar));
}
}
SPDLOG_INFO("{} end", __func__);
}
void query_data_callback(Context_ptr context, nlohmann::json result, uint64_t query_id) {
SPDLOG_INFO("{} called", __func__);
int code = result["code"];
std::string msg = result["msg"].get<std::string>();
SPDLOG_INFO("query data, code: {}, msg: {}", code, msg);
if (code == 200) {
for (const auto& data : result["data"]) {
SPDLOG_INFO("data: {}", safe_dump(data));
}
}
}
void test_query_data_async(Context_ptr context) {
SPDLOG_INFO("{} start", __func__);
std::string method = "market_data";
nlohmann::json params = {
{"code", "000001.SZ"},
{"start_date", "2013-01-04"},
{"end_date", "2014-01-04"}
};
context->query_data_async(method, params, std::bind(&DemoStrategy::query_data_callback, this, _1, _2, _3), 54);
SPDLOG_INFO("{} end", __func__);
}
void test_query_data_page(Context_ptr context) {
SPDLOG_INFO("{} start", __func__);
std::string method = "bar";
int page_size = 100;
int current_page = 1;
nlohmann::json params = {
{"code", "000001.SZ"},
{"start_date", "2014-01-04"},
{"end_date", "2014-02-04"},
{"period", "1d"},
{"adjust_type", "pre"},
{"page_size", 100},
{"current_page", 1}
};
wingchun::msg::data::DataPageInfo data_page_info = context->query_data_page(method, params);
SPDLOG_INFO("{}, currentPage: {}, totalPage: {}, pageSize: {}, totalCount: {}", __func__, data_page_info.currentPage, data_page_info.totalPage, data_page_info.pageSize, data_page_info.totalCount);
int code = data_page_info.data["code"];
std::string msg = data_page_info.data["msg"].get<std::string>();
SPDLOG_INFO("code: {}, msg: {}", code, msg);
for (const auto& bar : data_page_info.data["data"]) {
SPDLOG_INFO("{}, bar data: {}", __func__, safe_dump(bar));
}
SPDLOG_INFO("{} end", __func__);
}
void query_data_page_callback(Context_ptr context, const DataPageInfo& data_page_info, uint64_t query_id) {
SPDLOG_INFO("{}, query id: {}, currentPage: {}, totalPage: {}, pageSize: {}, totalCount: {}", __func__, query_id, data_page_info.currentPage, data_page_info.totalPage, data_page_info.pageSize, data_page_info.totalCount);
int code = data_page_info.data["code"];
std::string msg = data_page_info.data["msg"].get<std::string>();
SPDLOG_INFO("code: {}, msg: {}", code, msg);
for (const auto& bar : data_page_info.data["data"]) {
SPDLOG_INFO("{}, bar data: {}", __func__, safe_dump(bar));
}
}
void test_query_data_page_async(Context_ptr context) {
SPDLOG_INFO("{} start", __func__);
std::string method = "bar";
int page_size = 100;
int current_page = 1;
nlohmann::json params = {
{"code", "000001.SZ"},
{"start_date", "2014-01-04"},
{"end_date", "2014-02-04"},
{"period", "1d"},
{"adjust_type", "pre"},
{"page_size", 100},
{"current_page", 1}
};
context->query_data_page_async(method, params, std::bind(&DemoStrategy::query_data_page_callback, this, _1, _2,_3), 55);
SPDLOG_INFO("{} end", __func__);
}
void indicator_callback(Context_ptr context, const std::string& indicator_type, const nlohmann::json& indicator) {
SPDLOG_INFO("indicator type: {}, data: {}", indicator_type, safe_dump(indicator));
}
void test_sub_indicator(Context_ptr context) {
SPDLOG_INFO("{} start", __func__);
std::vector<std::string> codes = {"512160.SSE", "159631.SZ"};
std::vector<std::string> failed_codes;
failed_codes = context->subscribe_indicator("etf", codes, std::bind(&DemoStrategy::indicator_callback, this, _1, _2, _3));
// 或者使用如下订阅方式, indicator 通过 on_indicator 接收
// failed_codes = context->subscribe_indicator("etf", codes);
SPDLOG_INFO("failed codes: {}", safe_dump(nlohmann::json(failed_codes)));
SPDLOG_INFO("{} end", __func__);
}
void bar_callback(Context_ptr context, const wingchun::msg::data::Bar &bar)
{
SPDLOG_INFO("{} called, data: {}", __func__, info_bar(bar));
}
void test_sub_bar(Context_ptr context) {
SPDLOG_INFO("{} start", __func__);
std::vector<std::string> codes = {"000002.SZ", "600004.SSE"};
std::vector<std::string> failed_codes;
failed_codes = context->subscribe_bar(codes, "2m", std::bind(&DemoStrategy::bar_callback, this, _1, _2));
// 或者使用如下方式订阅, Bar 通过 on_bar 接收
// failed_codes = context->subscribe_bar(codes, "2m", std::bind(&DemoStrategy::bar_callback, this, _1, _2));
SPDLOG_INFO("failed codes: {}", safe_dump(nlohmann::json(failed_codes)));
SPDLOG_INFO("{} end", __func__);
}
void test(Context_ptr context) {
// test_query_bar_today(context);
// test_query_bar_today_async(context);
// test_query_bar(context);
// test_query_bar_async(context);
// test_query_market_data(context);
// test_query_market_data_async(context);
// test_query_data(context);
// test_query_data_async(context);
// test_query_data_page(context);
// test_query_data_page_async(context);
test_sub_indicator(context);
test_sub_bar(context);
}
// 获取编译策略的kungfu版本号,本函数不允许修改。
virtual const std::string getCompileVersion() const override
{
std::ostringstream ver;
#ifdef ALPHAX_VERSION
ver<<ALPHAX_VERSION;
#else
ver<<DEFAULT_COMPILE_VERSION;
#endif
SPDLOG_INFO("Version: {}.", ver.str());
return ver.str();
}
private:
// 静态行情整个交易日都不会变,启动策略时取到所有证券的静态数据后,需要时直接使用
// 而不需要用一次查一次,性能很差(因为需要读写文件)
// add by zz on 20210112
std::unordered_map<std::string, QuoteStaticFullInfo> quotes;
uint64_t count_;
};
PYBIND11_MODULE(PY_MODULE, m)
{
py::class_<DemoStrategy, Strategy, std::shared_ptr<DemoStrategy>>(m, "Strategy")
.def(py::init<yijinjing::data::location_ptr>())
.def("pre_start", &DemoStrategy::pre_start)
.def("post_start", &DemoStrategy::post_start)
.def("pre_stop", &DemoStrategy::pre_stop)
.def("post_stop", &DemoStrategy::post_stop)
.def("on_trading_day", &DemoStrategy::on_trading_day)
.def("on_quote", &DemoStrategy::on_quote)
.def("on_bar", &DemoStrategy::on_bar)
.def("on_entrust", &DemoStrategy::on_entrust)
.def("on_transaction", &DemoStrategy::on_transaction)
.def("on_order", &DemoStrategy::on_order)
.def("on_order_action_error", &DemoStrategy::on_order_action_error)
.def("on_trade", &DemoStrategy::on_trade)
.def("on_order_book", &DemoStrategy::on_order_book)
.def("on_cancelorder_feedback", &DemoStrategy::on_cancelorder_feedback)
.def("on_client_msg", &DemoStrategy::on_client_msg)
.def("on_query_bondIPO_info", &DemoStrategy::on_query_bondIPO_info)
.def("on_query_bondIPO_end", &DemoStrategy::on_query_bondIPO_end)
.def("on_query_bondswapstock_info", &DemoStrategy::on_query_bondswapstock_info)
.def("on_query_bondswapstock_end", &DemoStrategy::on_query_bondswapstock_end)
.def("getCompileVersion", &DemoStrategy::getCompileVersion);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
备注:“策略 Demo3”,从 2.1.2 版本开始支持