استراتيجية فارغة
ابدأ بأبسط بنية ممكنة للاستراتيجية. فهي توفّر نقاط الاستدعاء اللازمة للتشغيل، دون إضافة نماذج ألفا أو مراحل معالجة في هذه الخطوة.
use aq_engine::core::broker::data_feeds::yahoo::YahooFinanceDataFeed;use aq_engine::core::broker::paper_broker::PaperBroker;use aq_engine::core::broker::types::{AccountType, Asset, BarData};use aq_engine::core::broker::UnifiedBroker;use aq_engine::core::insight::Insight;use aq_engine::core::strategy::{ EventStreamType, Strategy, StrategyContext, StrategyMode, StrategyState,};use aq_engine::core::utils::timeframe::{TimeFrame, TimeFrameUnit};use chrono::{Duration, Utc};use std::collections::HashSet;
pub struct BlankStrategy;
impl Strategy for BlankStrategy { fn on_start(&mut self, ctx: &mut dyn StrategyContext) { // The main strategy timeframe is registered automatically. // This adds a feature bar stream for every symbol in the universe. ctx.add_events( EventStreamType::Bar, Some(TimeFrame::new(15, TimeFrameUnit::Minute)), ); }
fn init(&mut self, _ctx: &mut dyn StrategyContext, _asset: &Asset) {}
fn universe(&self, _ctx: &mut dyn StrategyContext) -> HashSet<String> { HashSet::from([String::from("AAPL")]) }
fn on_bar(&mut self, _ctx: &mut dyn StrategyContext, _symbol: &str, _bar: &BarData) {}
fn generate_insights(&mut self, _ctx: &mut dyn StrategyContext, _symbol: &str) {}
fn insight_pipeline(&mut self, _ctx: &mut dyn StrategyContext, _insight: &Insight) {}
fn on_teardown(&mut self, _ctx: &mut dyn StrategyContext) {}}
let execution = PaperBroker::new(AccountType::Paper, 100_000.0, 1);let data = YahooFinanceDataFeed::new();let broker = UnifiedBroker::new_backtest(execution, data);
let timeframe = TimeFrame::new(1, TimeFrameUnit::Day);let strategy = BlankStrategy;
let mut state = StrategyState::new( "blank-strategy".to_string(), "1.0.0".to_string(), strategy, broker, StrategyMode::Backtest, timeframe.clone(),);
let start = Utc::now() - Duration::days(30);let end = Utc::now();
let results = state.run_backtest(start, end, timeframe).await?;results.print_metrics();يعرض هذا المثال الأولي أصغر مسار متكامل: تعريف استراتيجية، وربط وسيط تجريبي ومصدر بيانات، وتشغيل الاختبار التاريخي، وفحص المقاييس الناتجة. يسجّل استدعاء add_events إطارًا زمنيًا إضافيًا للخصائص؛ ويظل الإطار الزمني الرئيسي للاستراتيجية يعمل تلقائيًا.
توليد إشارة تداولية
Section titled “توليد إشارة تداولية”تُنشئ الإشارة التداولية عادةً داخل نموذج ألفا أو داخل generate_insights()، ثم يتولى مسار معالجة الإشارات التداولية تحديد حجمها وإضافة ضوابط المخاطر وإرسالها.
use aq_engine::core::broker::types::OrderSide;use aq_engine::core::insight::{types::StrategyType, Insight};
fn generate_insights(&mut self, ctx: &mut dyn StrategyContext, symbol: &str) { let mut insight = Insight::new( OrderSide::Buy, symbol.to_string(), StrategyType::Testing, ctx.timeframe().clone(), 80, None, );
insight .set_limit_price(Some(200.0)) .set_take_profit_levels(Some(vec![206.0])) .set_stop_loss(Some(197.5)) .set_period_unfilled(Some(5)) .set_period_till_tp(Some(12));
ctx.add_insight(insight);}للاطلاع على نموذج الإشارات التداولية كاملًا، راجع الإشارات التداولية. ولتحديد الحجم والتحقق والإرسال، راجع مسارات معالجة الإشارات التداولية.
نستخدم ملفات تعريف الارتباط والتخزين الضروريين لتسجيل الدخول وحماية الحساب وحفظ تفضيلات المظهر وهذا الإشعار، ولجمع مقاييس PostHog الداخلية اللازمة لقياس الاستخدام وجودة الجلسات والموثوقية. لا نستخدم ملفات تعريف ارتباط إعلانية.
