范例
extension范例
策略范例
Python策略范例
源码目录结构:
strategy-python-101/ # 名字随意
├── src/
│ └── python
| └── KungfuStrategy101Python # 必须与package.json中kungfuConfig的key相同
| └── __init__.py # python策略代码,文件名不可更改
└── package.json # 编译配置信息
编译后文件目录结构:
strategy-python-101/
├── src/
│ └── python
| └── KungfuStrategy101Python
| └── __init__.py
├── package.json
├── __pypackages__/ # Python模块库, 自动生成
├── dist/ # 编译打包出来的二进制文件
| └── KungfuStrategy101Python
| └── KungfuStrategy101Python.cp39-win_amd64.pyd # 编译之后的二进制文件
├── pdm.lock # build后下载依赖库自动生成的文件
└── pyproject.toml # build后下载依赖库自动生成的文件
package.json:
{
"name": "@kungfu-trader/examples-strategy-python",
"author": {
"name": "Kungfu Trader",
"email": "info@kungfu.link"
},
"description": "KungFu Strategy 101 - Python Demo",
"license": "Apache-2.0",
"kungfuBuild": {
"python": {
"dependencies": {}
}
},
"kungfuConfig": {
"key": "KungfuStrategy101Python" # key对应的是 策略文件中策略文件(.py文件)所在文件夹的名字 , 这个名字不能有 _ , - . 比如命名不可以是 : kungfu-demo , kungfu_demo
}
}
__init__.py 策略范例 :
1# __init__.py
2
3import random
4from kungfu.wingchun.constants import *
5import kungfu
6
7lf = kungfu.__binding__.longfist
8wc = kungfu.__binding__.wingchun
9yjj = kungfu.__binding__.yijinjing
10
11source = "sim" # 目标交易账户的柜台名称
12account = "fill" # 目标交易账户的账户号, 需添加 sim 柜台的账户号为 fill 的账户
13md_source = "sim" # 目标行情源的柜台名称, 需添加 sim 行情源
14
15
16def pre_start(context):
17 context.log.info("pre start")
18 context.add_account(source, account) # 添加交易账户
19 context.subscribe(md_source, ["600000", "600004", "600009"], Exchange.SSE) # 订阅行情
20 context.subscribe(md_source, ["300033", "300059"], Exchange.SZE) # 订阅行情
21 context.subscribe(md_source, ["rb2401"], Exchange.SHFE) # 订阅行情
22 context.subscribe(md_source, ["sc2401"], Exchange.INE) # 订阅行情
23 # context.subscribe_operator("bar", "123") # 需从算子入口添加bar插件, 并定义bar的id为123
24 context.throttle_insert_order = {}
25
26
27def post_start(context):
28 account_uid = context.get_account_uid(source, account)
29 context.log.info(f"account {source} {account}, account_uid: {account_uid}")
30
31
32def on_quote(context, quote, location, dest):
33 # insert order interval 10s
34 if context.now() - context.throttle_insert_order.get(quote.instrument_id, 0) < 10000000000:
35 return
36 context.throttle_insert_order[quote.instrument_id] = context.now()
37
38 side = random.choice([Side.Buy, Side.Sell])
39 offset = random.choice([Offset.Open, Offset.Close])
40 side = random.choice([Side.Buy, Side.Sell])
41 price = quote.ask_price[0] if side == Side.Buy else quote.bid_price[0]
42 price_type = random.choice([PriceType.Any, PriceType.Limit])
43 volume = 3 if quote.instrument_type == InstrumentType.Future else 300
44 order_id = context.insert_order(
45 quote.instrument_id,
46 quote.exchange_id,
47 source,
48 account,
49 price,
50 volume,
51 price_type,
52 side,
53 offset,
54 )
55 context.log.info(f"insert order: {order_id}")
56
57
58# 监听算子广播信息
59def on_synthetic_data(context, synthetic_dataa, location, dest):
60 context.log.info("on_synthetic_data: {}".format(synthetic_dataa))
61
62
63def on_order(context, order, location, dest):
64 context.log.info(f"on_order: {order}, from {location} to {dest}")
65
66 if not wc.utils.is_final_status(order.status):
67 context.cancel_order(order.order_id)
68
69
70def on_trade(context, trade, location, dest):
71 context.log.info(f"on_trade: {trade}, from {location} to {dest}")
通过主面板的 策略进程->添加->策略路径 选择 KungfuStrategy101Python.cp39-win_amd64.pyd, 点击启动就可以运行Python编译后的策略代码
CPP策略范例
源码目录结构:
strategy-cpp-101/
├── src/
│ └── cpp
| └── strategy.cpp # cpp策略代码
└── package.json # 编译配置信息
编译后文件目录结构:
strategy--101/
├── src/
│ └── cpp
| └── strategy.cpp # cpp策略代码
├── package.json
├── dist/ # 编译打包出来的二进制文件
| └── KungfuStrategy101Cpp
| └── KungfuStrategy101Cpp.cp39-win_amd64.pyd # 编译之后的二进制文件
└── build # build 编译生成中间文件
package.json:
{
"name": "@kungfu-trader/examples-strategy-cpp",
"author": "kungfu-trader",
"description": "KungFu Strategy 101 - C++ Demo",
"license": "Apache-2.0",
"kungfuConfig": {
"key": "KungfuStrategy101Cpp" # 编译之后的二进制文件所在文件夹名
},
"kungfuBuild": { # 打包模块相关
"cpp": {
"target": "bind/python"
}
}
}
1// strategy.cpp
2#include <kungfu/wingchun/extension.h>
3#include <kungfu/wingchun/strategy/context.h>
4#include <kungfu/wingchun/strategy/strategy.h>
5
6using namespace kungfu::longfist::enums;
7using namespace kungfu::longfist::types;
8using namespace kungfu::wingchun::strategy;
9using namespace kungfu::yijinjing::data;
10
11KUNGFU_MAIN_STRATEGY(KungfuStrategy101) {
12public:
13KungfuStrategy101() = default;
14~KungfuStrategy101() = default;
15
16void pre_start(Context_ptr & context) override {
17 SPDLOG_INFO("preparing strategy");
18 SPDLOG_INFO("arguments: {}", context->get_arguments());
19
20 context->add_account("sim", "fill");
21 context->subscribe("sim", {"600000"}, {"SSE"});
22}
23
24void post_start(Context_ptr & context) override { SPDLOG_INFO("strategy started"); }
25
26void on_quote(Context_ptr & context, const Quote "e, const location_ptr &location, uint32_t dest) override {
27 SPDLOG_INFO("Quote: {} location: {}", quote.to_string(), location->to_string());
28 context->insert_order(quote.instrument_id, quote.exchange_id, "sim", "fill", quote.last_price, 200,
29 PriceType::Limit, Side::Buy, Offset::Open);
30}
31
32void on_order(Context_ptr & context, const Order &order, const location_ptr &location, uint32_t dest) override {
33 SPDLOG_INFO("Order: {}", order.to_string());
34}
35
36void on_trade(Context_ptr & context, const Trade &trade, const location_ptr &location, uint32_t dest) override {
37 SPDLOG_INFO("Trade: {}", trade.to_string());
38}
39
40void on_tree(Context_ptr & context, const Tree &tree, const location_ptr &location, uint32_t dest) override {
41 SPDLOG_INFO("on tree: {}", tree.to_string());
42}
43
44void on_synthetic_data(Context_ptr & context, const SyntheticData &synthetic_data, const location_ptr &location,
45 uint32_t dest) override {
46 SPDLOG_INFO("on_synthetic_data: {} ", synthetic_data.to_string());
47}
48
49void on_broker_state_change(Context_ptr & context, const BrokerStateUpdate &broker_state_update,
50 const location_ptr &location) override {
51 SPDLOG_INFO("on broker state changed: {}", broker_state_update.to_string());
52}
53
54void on_operator_state_change(Context_ptr & context, const OperatorStateUpdate &operator_state_update,
55 const location_ptr &location) override {
56 SPDLOG_INFO("on operator state changed: {}", operator_state_update.to_string());
57}
58};
通过主面板的 策略进程->添加->策略路径 选择 KungfuStrategy101Cpp.cp39-win_amd64.pyd, 点击启动就可以运行Python编译后的策略代码
CPP策略可执行程序范例
源码目录结构:
strategy-cpp-101-exe/
├── src/
│ └── cpp
| └── strategy.cpp # cpp策略代码
└── package.json # 编译配置信息
编译后文件目录结构:
strategy-cpp-101-exe/
├── src/
│ └── cpp
| └── strategy.cpp # cpp策略代码
├── package.json
├── dist/ # 编译打包出来的二进制文件
| └── KungfuStrategy101CppExe
| └── KungfuStrategy101CppExe.exe # 可执行文件
└── build # build 编译生成中间文件
package.json:
{
"name": "@kungfu-trader/examples-strategy-cpp",
"author": "kungfu-trader",
"description": "KungFu Strategy 101 - C++ Demo",
"license": "Apache-2.0",
"kungfuConfig": {
"key": "KungfuStrategy101CppExe"
},
"kungfuBuild": {
"cpp": {
"target": "exe"
}
}
}
1// strategy.cpp
2#include <kungfu/wingchun/strategy/context.h>
3#include <kungfu/wingchun/strategy/runner.h>
4#include <kungfu/wingchun/strategy/strategy.h>
5
6using namespace kungfu::longfist::enums;
7using namespace kungfu::longfist::types;
8using namespace kungfu::wingchun::strategy;
9using namespace kungfu::yijinjing::data;
10
11class KungfuStrategy101 : public Strategy {
12public:
13KungfuStrategy101() = default;
14~KungfuStrategy101() = default;
15
16void pre_start(Context_ptr &context) override {
17 SPDLOG_INFO("preparing strategy");
18 SPDLOG_INFO("arguments: {}", context->get_arguments());
19
20 context->add_account("sim", "fill");
21 context->subscribe("sim", {"600000"}, {"SSE"});
22}
23
24void post_start(Context_ptr &context) override { SPDLOG_INFO("strategy started"); }
25
26void on_quote(Context_ptr &context, const Quote "e, const location_ptr &location, uint32_t dest) override {
27 SPDLOG_INFO("Quote: {} location: {}", quote.to_string(), location->to_string());
28 context->insert_order(quote.instrument_id, quote.exchange_id, "sim", "fill", quote.last_price, 200,
29 PriceType::Limit, Side::Buy, Offset::Open);
30}
31
32void on_order(Context_ptr &context, const Order &order, const location_ptr &location, uint32_t dest) override {
33 SPDLOG_INFO("Order: {}", order.to_string());
34}
35
36void on_trade(Context_ptr &context, const Trade &trade, const location_ptr &location, uint32_t dest) override {
37 SPDLOG_INFO("Trade: {}", trade.to_string());
38}
39
40void on_tree(Context_ptr &context, const Tree &tree, const location_ptr &location, uint32_t dest) override {
41 SPDLOG_INFO("on tree: {}", tree.to_string());
42}
43
44void on_synthetic_data(Context_ptr &context, const SyntheticData &synthetic_data, const location_ptr &location,
45 uint32_t dest) override {
46 SPDLOG_INFO("on_synthetic_data: {} ", synthetic_data.to_string());
47}
48
49void on_broker_state_change(Context_ptr &context, const BrokerStateUpdate &broker_state_update,
50 const location_ptr &location) override {
51 SPDLOG_INFO("on broker state changed: {}", broker_state_update.to_string());
52}
53
54void on_operator_state_change(Context_ptr &context, const OperatorStateUpdate &operator_state_update,
55 const location_ptr &location) override {
56 SPDLOG_INFO("on operator state changed: {}", operator_state_update.to_string());
57}
58};
59
60int main(int argc, char **argv) {
61 SPDLOG_INFO("runner1 add strategy1");
62 Runner runner(std::make_shared<locator>(), "CppStrategy", "demo01exe", mode::LIVE, false);
63 SPDLOG_INFO("runner");
64 runner.add_strategy(std::make_shared<KungfuStrategy101>());
65 runner.run();
66 SPDLOG_INFO("Over");
67 return 0;
68}
直接运行 KungfuStrategy101CppExe.exe 程序就可以运行以上策略
小技巧
需要将 {Kungfu安装目录}/resource/kfc/ 目录下的Kungfu.dll放在KungfuStrategy101CppExe.exe同一个目录下, 或者配置系统变量使得程序运行时可以找到动态库Kungfu.dll
尽量使用命令行运行, 鼠标双击运行后在退出时会自动关闭命令行界面, 必须要找到Kungfu运行home目录下找到对应log文件才能查看运行日志