# 编写程序化策略

# 设计原则

交易策略作为每个交易员的核心资产,应该独立于交易软件的项目代码,另起一个项目管理。这样做一来可以保证策略逻辑的安全性,二来可以保证扩展性。 交易软件的项目代码的迭代,会尽量保证策略的接口API部分不做改变,如有改变,会在版本发布说明重点提出。
这样用户就可以放心地跟进交易软件的版本迭代。

TIP

在阅读以下内容前,读者需要对软件的整体架构有所了解(详情请阅读架构设计);
并且已经知道如何搭建开发环境(详情请阅读如何搭建开发环境);

# 项目架构

交易策略应该另起一个项目管理,如下图
策略开发项目架构

具体操作如下:

  1. 新建一个maven项目
    策略开发新建项目
    选择模板 策略开发项目创建2

创建项目时注意

  1. Group Id 可以随意填写
  2. Artifact Id 必须是 northstar-external 或以其为前缀
  3. Version 必须与 northstar 主项目版本号一致
  4. Package 必须是 org.dromara.northstar.external
  5. 不要勾选交互式创建
  1. 确保新项目的pom.xml文件引入了northstar-api,并且版本号与主程序一致 外置项目依赖设置

# 编程模型

每一个量化交易软件,策略编程模型的设计是最核心的设计之一,因为它体现了该软件的设计哲学,同时直接影响用户的理解难易程度。 模组模型设计

上图概括地描述了在Northstar交易软件上,交易策略是怎么运作的:

  • 交易模组,是程序化策略运行的基本单元,它定义了采用什么样的交易策略执行交易、使用哪个或哪几个账户进行交易、订阅哪个或哪几个合约的数据进行交易;
  • 为了最大程度地简化用户编写策略的复杂度,使用户只需要关注交易策略逻辑本身,模型引入了一个模组上下文的概念。模组上下文定义了一系列操作接口,方便策略逻辑去调用;并且把一系列复杂的、通用的操作封装在策略上下文内部——比如,策略指标的创建与更新、模组账户的持仓与盈亏计算、模组状态的更新与持久化、数据的过滤与分发、账户与策略与合约三者之间的绑定等等。
  • Northstar的编程模型是事件驱动型的,也就是说程序会监听市场的数据,每一个合约的每一个TICK都会触发一次程序的响应,从而执行程序预定义的运行逻辑,最终实现自动交易。因此,用户需要理解相关的API与SPI。

# API与SPI

SPI指的是用户需要实时的数据响应逻辑,比如在策略中,需要实现一个onTick方法的逻辑,模组订阅的每一个市场数据都会触发这个onTick方法的执行,假设我的响应逻辑就是简单地把收到的数据打印到日志,那就可以简单地输出。同理,onBar方法会每个K线触发一次,以下便是简单打印一下K线数据的做法。

    @Override
	public void onBar(BarField bar) {
		log.debug("策略每分钟触发");
	}

	@Override
	public void onMergedBar(BarField bar) {
		log.debug("策略每个K线周期触发,如何策略采用了5分钟K线,则5分钟触发一次");
	}

当然,如果只有SPI,就好比你只能看着行情软件上的数据在不断变动一样。当你需要做出一些操作,你就需要通过调用API来实现发单、撤单等交易操作。
那么,用户站在策略开发层面,会有哪些API的调用需求呢?大致有以下:

  • 发单
  • 撤单
  • 获取当前的订单状态、持仓状态等等

因此,作者定义了一个IModuleStrategyContext来描述用户站在策略层可以调用的所有现成的接口。

# 示例代码

为了让用户更好地理解策略该如何编写,在 northstar-strategy-example 子项目中,作者提供了一些最基本示例策略代码以供参考。

# 开发与调试

由于扩展项目 northstar-external 是外置项目,要想在开发调试环境引入它,就必须先配置好IDE。
以下以eclipse为例(注意,以下动画是循环播放的): 开发调试引入外置项目的设置方法

用调试模式启动 northstar-main 项目,便可对 northstar-external 中的代码进行调试。

# 版本升级易错事项

northstar-external 外置项目所依赖的主项目版本,需要时刻与本地主项目代码同步,否则会出现代码不生效问题。
比如 northstar 主项目版本已经升级到6.0版本,此时 northstar-external 中的 northstar-api 版本也应该是6.0。