第 35/36 课 · 约 45 分钟
综合项目:事件驱动的 DAS 价差观察器
实现初始化、采样、迟滞、手动报告与停止控制。
项目规格
前置知识:Timer、状态机与行情校验。观察一个已加载股票,统计进入假设价差条件的次数,不产生买卖方向、入场或出场决定。生命周期分为初始化、安装回调、检查、停止四个操作。重置阈值低于触发阈值,形成迟滞,减少单一边界附近的重复报告。
初始化:Timer 停用时运行
$feSpreadWatch = NewUserObj();
$feSpreadWatch.symbol = "MSFT";
$feSpreadWatch.trigger = 0.08;
$feSpreadWatch.reset = 0.05;
$feSpreadWatch.enabled = 1;
$feSpreadWatch.latched = 0;
$feSpreadWatch.valid = 0;
$feSpreadWatch.reports = 0;
$feSpreadWatch.lastSecond = GetSecond();
$feSpreadWatch.spread = 0;
Timer Event 回调
if ($feSpreadWatch.enabled == 0) {
return;
}
$feSpreadWatch.valid = 0;
$feWatchQuote = GetQuoteObj($feSpreadWatch.symbol);
$feWatchBid = $feWatchQuote.BID;
$feWatchAsk = $feWatchQuote.ASK;
if ($feWatchBid <= 0) {
return;
}
if ($feWatchAsk < $feWatchBid) {
return;
}
$feWatchNow = GetSecond();
if ($feWatchNow < $feSpreadWatch.lastSecond) {
$feSpreadWatch.enabled = 0;
return;
}
$feSpreadWatch.spread = $feWatchAsk - $feWatchBid;
$feSpreadWatch.lastSecond = $feWatchNow;
$feSpreadWatch.valid = 1;
if ($feSpreadWatch.spread > $feSpreadWatch.trigger) {
if ($feSpreadWatch.latched == 0) {
$feSpreadWatch.latched = 1;
$feSpreadWatch.reports = $feSpreadWatch.reports + 1;
}
}
if ($feSpreadWatch.spread < $feSpreadWatch.reset) {
$feSpreadWatch.latched = 0;
}
手动检查与停止
$feSpreadWatch.ShowObject();
$feSpreadWatch.enabled = 0;
解释恢复规则
无效数值会使 valid=0,不伪造新价差。旧 spread 作为历史状态保留,因此读取者必须检查 valid。时间回退时停用并要求重新初始化。等于任一阈值保持原标记。本例初始化 latched=0,所以启动时已经高于触发值会计一次;若不希望这样,应增加首次基准状态。例子没有捕获对象查找错误,先加载并确认股票仍是前提。
确定性的验收序列
接入真实行情前,在测试副本中将 Bid 固定为 20,通过 Ask 依次产生 0.04、0.09、0.10、0.06、0.04、0.09 价差。只初始化一次,每个样本执行一次回调,报告数预期为 0、1、1、1、1、2。0.06 不重置,因为重置要求小于 0.05。再测试零 Bid、颠倒报价和时间回退;模型正确后再恢复行情读取。
扩展练习与参考解答
增加 lastReportSecond。参考解答:初始化为零,只在 0→1 分支更新,不在每次有效采样时更新。确认变量提醒机制后,可把独立事件计数连接到只显示消息的 Alert。卸载时先停用 DAS Timer 回调,再清理状态。