用Stop函数停止一个策略单元后无法触发公式的OnExit

Stop函数的帮助文档地址: https://tbq3.tbquant.net/helper?product_id=991&keyword=1122&content_id=1094&type=article#stop-%E5%81%9C%E6%AD%A2%E4%BA%A4%E6%98%93%E5%8D%95%E5%85%83

试了一下Stop帮助文档中的代码如下:

Events
    OnInit()
    {
        Print("OnInit");
    }

    OnReady()
    {
        Print("OnReady");
    }
    
    OnBar(ArrayRef<Integer> indexs)
    {
        Print("OnBar,CurrentBar:" + Text(CurrentBar));
        if(CurrentBar == 10)
        {
            Print("Stop Begin");
            Stop();
            Print("Stop End");
        }
    }
    
    OnExit()
    {
        Print(" ------ OnExit");
    }

在一个图表上加载了100根K线,第一次运行结果如下:

然后点击了刷新按钮,公式会先输出OnExit,然后继续运行

请问这是怎么回事,如何解决?

OnExit()函数,为什么在停止策略后没有触发?
OnExit()触发场景问题
onexit为何无法使用Print2Quote
TBQ有锁定策略单元运行的代码函数吗?
用buy函数无法触发onorder,onfill等类似事件么?
如在何不停止策略单元的情况下修改参数
一个策略单元,插入多个公式
策略停止后重启问题
TBQuant升级后公式无法编译
一个策略单元中两个公式会相互影响?

在开拓者量化软件(TradeBlazer)中,使用 Stop 函数停止一个策略单元后,确实不会触发 OnExit 事件。这是因为 Stop 函数是强制停止策略单元的运行,而 OnExit 事件通常是在策略正常结束时触发的。

如果你希望在停止策略单元时执行一些清理操作或记录日志,可以通过以下方法实现:



1. 手动调用清理函数

在调用 Stop 函数之前,手动执行清理操作。

示例代码:

pascal

复制

// 自定义清理函数
Function CleanUp()
Begin
    // 执行清理操作,例如记录日志、保存数据等
    FileAppend("C:\\Logs\\strategy_log.txt", "策略单元已停止,时间: " + Text(DateTime) + "\n");
End;

// 停止策略单元
If (ConditionToStop) Then
Begin
    CleanUp(); // 手动调用清理函数
    Stop; // 停止策略单元
End;


2. 使用全局变量标记停止状态

通过全局变量标记策略单元的停止状态,并在 OnBar 或其他事件中检查该状态,执行清理操作。

示例代码:

pascal

复制

Vars:
    Bool isStopped(False); // 标记策略单元是否已停止

// 自定义清理函数
Function CleanUp()
Begin
    // 执行清理操作
    FileAppend("C:\\Logs\\strategy_log.txt", "策略单元已停止,时间: " + Text(DateTime) + "\n");
End;

// OnBar事件
OnBar(ArrayRef<Integer> indexs)
Begin
    // 检查是否需要停止
    If (ConditionToStop And Not isStopped) Then
    Begin
        CleanUp(); // 执行清理操作
        isStopped = True; // 标记为已停止
        Stop; // 停止策略单元
    End;

    // 正常策略逻辑
    If (Not isStopped) Then
    Begin
        // 策略逻辑代码
    End;
End;


3.使用OnExit 事件

如果希望保留 OnExit 事件的功能,可以避免使用 Stop 函数,而是通过设置标志位让策略自然结束。

示例代码:

pascal

复制

Vars:
    Bool isStopped(False); // 标记策略单元是否已停止

// OnBar事件
OnBar(ArrayRef<Integer> indexs)
Begin
    // 检查是否需要停止
    If (ConditionToStop And Not isStopped) Then
    Begin
        isStopped = True; // 标记为已停止
    End;

    // 正常策略逻辑
    If (Not isStopped) Then
    Begin
        // 策略逻辑代码
    End;
End;

// OnExit事件
OnExit()
Begin
    // 执行清理操作
    FileAppend("C:\\Logs\\strategy_log.txt", "策略单元已停止,时间: " + Text(DateTime) + "\n");
End;


4. 注意事项

  • Stop 函数的作用:Stop 是强制停止策略单元,不会触发 OnExit 事件。
  • 清理操作的时机:在调用 Stop 之前,确保所有必要的清理操作已经完成。
  • 日志记录:建议将停止策略单元的时间和原因记录到日志中,便于后续分析。


总结

如果你希望在停止策略单元时执行清理操作,可以通过手动调用清理函数或使用全局变量标记停止状态来实现。如果必须使用 OnExit 事件,可以避免使用 Stop 函数,而是通过设置标志位让策略自然结束。根据你的需求选择合适的方法即可。

回答的驴头不对马嘴

已注意到这个问题。

已提交研发同事测试。

可能需要节后才能答复了。

祝新年快乐

没关系,这个不着急,祝新年快乐