持久化数据
c++ gmsdk 需要升级到 3.9.8 版本及以上版本
gmsdk 提供一组持久化数据 key-value 接口,供策略在运行期间读写自定义数据(如:股票池、实时动态参数、策略级持仓记录等)。接口通用约定如下:
① 调用时机:允许在策略运行(init 初始化策略 + run 运行策略)和数据研究场景调用,非策略运行期间调用将被拒绝;
② 策略隔离:每个策略运行时可绑定并使用 1 个 bucket,对应 1 个持久化数据文件;
③ 模式切换:同一个策略,1 个 bucket 对应的持久化数据文件不区分回测(MODE_BACKTEST)与实时(MODE_LIVE)模式,策略切换运行模式 bucket 不变会访问同一个持久化数据;
④ 返回约定:写操作类接口统一返回 status,status = 0 表示成功,非 0 表示失败(错误码定义见 gmsdk 全局错误码表)。
ERR_PERSIST_INIT_ERROR 71001 // Persist组件初始化失败
ERR_PERSIST_NOT_INIT 71002 // Persist组件未初始化
ERR_PERSIST_KEY_ERROR 71003 // KEY太长或为空
ERR_PERSIST_STSTEM_ERROR 71004 // Persist系统错误
ERR_PERSIST_USING 71005 // bucket正在使用中,无法删除
ERR_PERSIST_INIT_ALREADY 71006 // Persist组件已初始化,不能再初始化别的bucket
persist_init - 初始化持久化数据
初始化指定bucket,限定一个策略运行周期只能操作一个持久化数据。
函数原型:
int persist_init(const char *bucket, bool async = true)
参数:
| 参数名 | 类型 | 中文名称 | 必填 | 默认值 | 参数用法说明 |
|---|---|---|---|---|---|
| bucket | str | 持久化数据标识(命名空间) | Y | 无 | 用于定位当前策略的持久化数据文件;初始化成功后,当前策略运行周期内绑定并使用该 bucket,后续 set/get/delete/clear 方法无需再指定 bucket |
| is_async | bool | 是否异步持久化 | N | true | 异步持久化(默认true) async=true时,持久化为异步操作,persist_set会立即返回,数据延时几毫秒写入到硬盘中(实际取决于电脑硬件性能),这种场景适用于盘中交易时随时写入大量数据,如记录实时的行情,持仓变化,资金变化,不至于persist_set操作时间长而行情与回报延时处理。 async=false时,持久化为同步操作,persist_set会确保数据已经写入到硬盘中才返回,数据较多时总耗时会较长。这种场景适用于写入数据少,或写入数据后进程需要立即退出的场景。策略非实时模式(回测模式与数据查询模式)时请设置为false. |
返回值:int
| 类型 | 中文名称 | 说明 |
|---|---|---|
| int | 状态码 | 0 表示初始化成功;非 0 表示失败,对应错误码 |
示例:
const char* bucket = "strategy_demo"; // 持久化数据标识,同一策略全局唯一
int status = persist_init(bucket);
if (status == 0)
printf("初始化成功");
else
printf("初始化失败, 错误码:%d", status);
注意:
1. persist_init 必须在策略运行期间调用(init 策略初始化阶段),且每个策略运行周期内只允许初始化 1 个 bucket;重复初始化同一 bucket 幂等返回成功,初始化不同 bucket 会报错。
2. persist_init 成功后,才能调用后续 persist_set / persist_get / persist_delete / persist_clear 方法,且这些方法无需再指定 bucket。
3. 同一持久化数据文件可被多个策略访问,但在同一时间只能被一个策略进程访问读写,后访问的策略会在初始化时报错并被拒绝访问。
persist_set - 写入持久化数据
向当前绑定的 bucket 写入数据。
函数原型:
int persist_set(const char *key, const char *value)
参数:
| 参数名 | 类型 | 中文名称 | 必填 | 默认值 | 参数用法说明 |
|---|---|---|---|---|---|
| key | str | 数据键 | Y | 无 | 同一 bucket 下唯一;长度限制 512 |
| value | str | 字符串数据值 | Y | 无 |
返回值:int
| 类型 | 中文名称 | 说明 |
|---|---|---|
| int | 状态码 | 0 表示写入成功;非 0 表示失败,对应错误码 |
示例:
const char *key = "stock_pool" # 数据键,长度不超过 512
const char *value = "SHSE.600519,SZSE.000001" # 字符串数据值
int status = persist_set(key, value);
if (status == 0)
printf("写入成功");
else
printf("写入失败, 错误码:%d", status);
注意:
1. 首次向当前绑定的 bucket 写入数据,会新创建该 bucket 的持久化数据文件。
2. 向当前绑定的 bucket 再次写入数据时,若指定 key 已存在会覆盖写入,若指定 key 不存在会创建新的数据键并写入数据值。
persist_get - 读取持久化数据
从当前绑定的 bucket 读取数据。
函数原型:
const char* persist_get(const char *key)
参数:
| 参数名 | 类型 | 中文名称 | 必填 | 默认值 | 参数用法说明 |
|---|---|---|---|---|---|
| key | str | 数据键 | Y | 无 | 同一 bucket 下唯一;长度限制 512 |
返回值:str | NULL
| 类型 | 中文名称 | 说明 |
|---|---|---|
| str 指针 | 字符串数据值 | key 存在时返回对应的字符串数据值, 如果key不存在,则返回NULL。使用时应该先判断是否为NULL,非NULL时再拷贝其值。不建议只保存指针值,指针值会在该key被删除或重新赋值之后失效 |
示例:
const char* value = persist_get("stock_pool");
if(value != NULL)
{
std::string svalue = value; //建议拷贝其值,以防指针失效
printf("读取成功:%s", svalue.c_str());
}
else:
printf("该 key 不存在");
persist_delete - 删除持久化数据中指定的key-value数据
删除当前绑定 bucket 中指定 key-value 的数据。
函数原型:
int persist_delete(const char *key)
参数:
| 参数名 | 类型 | 中文名称 | 必填 | 默认值 | 参数用法说明 |
|---|---|---|---|---|---|
| key | str | 数据键 | Y | 无 | key 不存在时视为删除成功(幂等处理),返回 0 |
返回值:int
| 类型 | 中文名称 | 说明 |
|---|---|---|
| int | 状态码 | 0 表示写入成功;非 0 表示失败,对应错误码 |
示例:
int status = persist_delete("stock_pool");
if (status == 0)
printf("删除成功");
注意:
1. 此接口只能删除当前绑定 bucket 中的 key,不会删除其他 bucket 中的 key; 删除在当前 bucket 中不存在的 key(其他 bucket 的 key),也会返回 status = 0.
persist_clear - 清空持久化的全部key-value数据
清空当前绑定 bucket 中全部 key-value 的数据。
函数原型:
int persist_clear()
返回值:int
| 类型 | 中文名称 | 说明 |
|---|---|---|
| int | 状态码 | 0 表示删除成功;非 0 表示失败,对应错误码 |
示例:
int status = persist_clear();
if (status == 0)
printf("清空成功");
persist_delete_bucket - 删除持久化数据 bucket
删除非当前绑定的持久化数据 bucket。
函数原型:
int persist_delete_bucket(const char *bucket)
参数:
| 参数名 | 类型 | 中文名称 | 必填 | 默认值 | 参数用法说明 |
|---|---|---|---|---|---|
| bucket | str | 持久化数据标识(命名空间) | Y | 无 | 只能删除非当前策略运行周期内通过 persist_init 绑定的 bucket 对应的持久化数据文件;数据文件为空或不存在时视为删除成功(幂等处理)。 |
返回值:int
| 类型 | 中文名称 | 说明 |
|---|---|---|
| int | 状态码 | 0 表示清空成功;非 0 表示失败,对应错误码 |
示例:
int status = persist_delete_bucket("other_strategy_bucket");
if (status == 0)
printf("删除成功");
注意:
1. 删除非当前绑定的 bucket,将删除对应的持久化数据文件;删除后该 bucket 不存在,策略重启后重新初始化 persist_init 绑定该 bucket 并用 persist_set 重新写入数据时,会重新创建该 bucket 的持久化数据文件。
persist_get_all_buckets - 查询持久化数据 bucket 列表
查询当前已创建的全部持久化数据标识(bucket),用于盘点本地持久化数据文件(单个策略可创建多个 bucket,单次运行进程内读写时绑定并使用其中一个)。
函数原型:
DataArray<PersistBucketName>* persist_get_all_buckets()
返回值:
| 类型 | 中文名称 | 说明 |
|---|---|---|
| DataArray |
持久化数据标识列表 | 本策略已创建的全部持久化数据标识;没有任何持久化数据时返回空列表 |
示例:
auto ids = persist_get_all_buckets();
if (ids->status() == 0)
{
for (int i = 0; i < ids->count(); i++)
{
cout << ids->at(i) << std::endl;
}
}
else
{
cout << "persist_get_all_buckets fail: " << ids->status() << std::endl;
}
ids->release();
注意:
1. 查询接口只读取本地持久化数据目录的元数据(标识列表),不读写具体数据文件内容,不受"单次运行进程内最多只能读写 1 个持久化数据 bucket"限制。
2. 调用时机:仅策略运行期间可调用,可在persist_init()初始化前被调用。
persist_get_all_keys - 查询当前绑定 bucket 所有 key
查询当前绑定的 bucket 下已保存的全部数据键(key),用于盘点该持久化数据文件中的数据健。
函数原型:
DataArray<PersistKey>* persist_get_all_keys()
返回值:
| 类型 | 中文名称 | 说明 |
|---|---|---|
| DataArray |
数据键列表 | 当前绑定的 bucket 下已保存的全部数据键 |
示例:
auto akey = persist_get_all_keys();
if (akey->status() == 0)
{
for (int i = 0; i < akey->count(); i++)
{
std::cout << akey->at(i) << std::endl;
}
}
akey->release();
注意:
1. 查询接口只读取元数据(键名列表),不读取数据值。
2. 调用时机与策略隔离规则与其他接口一致:仅策略运行期间可调用,需在 persist_init() 初始化后调用,查询当前绑定 bucket 的 key。