范例

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 &quote, 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 &quote, 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 程序就可以运行以上策略

小技巧

  1. 需要将 {Kungfu安装目录}/resource/kfc/ 目录下的Kungfu.dll放在KungfuStrategy101CppExe.exe同一个目录下, 或者配置系统变量使得程序运行时可以找到动态库Kungfu.dll

  2. 尽量使用命令行运行, 鼠标双击运行后在退出时会自动关闭命令行界面, 必须要找到Kungfu运行home目录下找到对应log文件才能查看运行日志