تخطَّ إلى المحتوى

إضافة الأحداث

تتيح add_events لاستراتيجية AQE الاشتراك في تدفقات إضافية لأحداث بيانات السوق، إلى جانب الإطار الزمني الرئيسي للاستراتيجية. أول تدفق أحداث مدعوم هو EventStreamType::Bar.

يُسجَّل الإطار الزمني الرئيسي للاستراتيجية تلقائيًا دائمًا وفق الإطار الزمني الممرَّر إلى run_backtest(...) أو المضبوط للتشغيل المباشر. لا تستدعِ add_events إلا عندما تحتاج إلى أطر زمنية إضافية للخصائص، مثل 1m أو 15m أو 1h.

سجّل تدفقات الخصائص في on_start:

use aq_engine::core::strategy::{EventStreamType, StrategyContext};
use aq_engine::core::utils::timeframe::{TimeFrame, TimeFrameUnit};
fn on_start(&mut self, ctx: &mut dyn StrategyContext) {
ctx.add_events(
EventStreamType::Bar,
Some(TimeFrame::new(15, TimeFrameUnit::Minute)),
);
}

يطبّق AQE هذا التدفق على كل أصل في نطاق الأصول المحمّل. إذا كانت الاستراتيجية تتداول BTC وETH، فسيُسجَّل تدفق شموع إضافي للخصائص بإطار 15m لكلا الرمزين.

يشير استدعاء ctx.add_events(EventStreamType::Bar, None) إلى الإطار الزمني الرئيسي؛ ويمنع AQE تسجيله مرتين لأنه مسجّل تلقائيًا.

استخدم EventStreamRequest عندما تحتاج إلى خيارات:

use aq_engine::core::strategy::{EventStreamRequest, EventStreamType, StrategyContext};
use aq_engine::core::utils::timeframe::{TimeFrame, TimeFrameUnit};
fn on_start(&mut self, ctx: &mut dyn StrategyContext) {
ctx.add_events_with_options(
EventStreamRequest::bar(Some(TimeFrame::new(1, TimeFrameUnit::Hour)))
.allow_trading(true),
);
}

يتحكم allow_trading في توليد الإشارات التداولية من الاستراتيجية ونموذج ألفا لهذا التدفق:

  • القيمة false هي الافتراضية لتدفقات الخصائص. يحدّث AQE السجل ويستدعي on_bar، لكنه لا يستدعي generate_insights لنموذج ألفا أو generate_insights للاستراتيجية لهذا الحدث الإضافي.
  • تسمح القيمة true بتشغيل generate_insights لنموذج ألفا وgenerate_insights للاستراتيجية لهذا الحدث الإضافي.

يظل تنفيذ أوامر الوسيط متّبعًا للمسار المعتاد. صُمّمت شموع الخصائص لإثراء سياق الاستراتيجية وتوليد الإشارات التداولية؛ ولا ينبغي التعامل معها كتدفق منفصل لتنفيذ أوامر الوسيط.

يحتفظ الإطار الزمني الرئيسي بالرمز الأساسي بوصفه مفتاح السجل:

let main_history = ctx.history().get(symbol);

تستخدم أطر الخصائص الزمنية الصيغة {symbol}:{timeframe}:

let feature_history = ctx.history().get("BTC:15m");
let faster_history = ctx.history().get("BTC:1m");
let hourly_history = ctx.history().get("ETH:1h");

يبقي ذلك بيانات الخصائص منفصلة عن السجل الرئيسي للاستراتيجية. ينبغي للمؤشرات والحالة المخصصة القراءة من المفتاح المطابق للحدث أو الإشارة التي تستخدمها.

استخدم ctx.current_event() داخل on_bar أو نماذج ألفا أو generate_insights لفحص الحدث الذي يعالجه AQE حاليًا:

fn on_bar(&mut self, ctx: &mut dyn StrategyContext, symbol: &str, _bar: &BarData) {
let Some(event) = ctx.current_event() else {
return;
};
let history = ctx.history().get(&event.history_key);
if event.is_feature {
println!(
"feature bar: {} {} history={} allow_trading={}",
event.symbol,
event.timeframe,
event.history_key,
event.allow_trading,
);
} else {
println!("main bar: {symbol}");
}
}

يتضمن StrategyEventContext ما يلي:

  • event_type
  • symbol
  • timeframe
  • history_key
  • is_feature
  • allow_trading
  • timestamp

يظل السياق نشطًا طوال نطاق معالجة الشمعة لهذا الحدث: تحديث السجل، وتحديث المؤشرات، وon_bar، وتوليد الإشارات التداولية من نموذج ألفا والاستراتيجية عندما يُسمح للحدث بتوليد الإشارات التداولية.

متى تستخدم تدفقات الخصائص

Section titled “متى تستخدم تدفقات الخصائص”

استخدم تدفقات الخصائص عندما تحتاج الاستراتيجية إلى بيانات سوق بأكثر من دقة زمنية:

  • استراتيجية يومية تقرأ بنية 15m قبل توليد إشارة؛
  • استراتيجية بإطار 1h تستخدم مرشّحات تقلب أو سيولة بإطار 1m؛
  • إطار زمني رئيسي للتنفيذ مع تأكيد من إطار زمني أعلى.

أبقِ الإطار الزمني الرئيسي مرجع التوقيت الأساسي للتنفيذ. استخدم تدفقات الخصائص للسياق، إلا إذا سمحت لذلك التدفق عمدًا بتوليد الإشارات التداولية.