الرئيسية سجل المعايرة إخلاء المسؤولية التوثيق English
Metric Risk · QuantMarketEngine

شو بترث فعلاً

الوثيقة اللي بتجاوب على سؤال: «شو رح ألاقي بأول ساعة، وشو رح يفاجئني؟»

ما في إشي هون اعتراف بعيب. هاي مجموعة الحقائق اللي بتنقرأ كأخطاء عند حدا ما حدا حكاله عنها، مع الإعدادات اللي ما إلها قيمة افتراضية آمنة على جهاز حدا تاني. وكل ادعاء بهاي الصفحة بتقدر تفحصه على المستودع — والقسم الأخير بيقول كيف.

شو بينتقل إلك

المستودع

الكود الكامل وتاريخه بالكامل — مؤلّف واحد، بلا مساهمين خارجيين.

التوثيق

106 ملف markdown، منها تبرير مكتوب لكل ثابت من 166 ثابتاً في المحرّك.

العلامة

الشعار وطقم الأيقونات.

قناة تيليجرام

قناة النشر الحيّة، بتنتقل ملكيتها مع البيع.

الدعم

30 يوم دعم انتقالي.

واللي ما بينتقل: بيانات الاعتماد

مفتاح بيانات السوق وتوكن بوت تيليجرام موجودين في المخزن السرّي لـ .NET، برّا المستودع. وما في إشي غير مبني وراهم — هم حسابات شخصية، وإنت بتوفّر حساباتك إنت. والاتنين مجانيين.

قاعدة البيانات، وشو بتعني لسجلّ الأداء

سجلّ المعايرة هو أقوى ادعاء بالمنتَج — 264 خرقاً للحدّ في 4,975 قراءة مقيَّمة لليورو/دولار، يعني 5.3% مقابل 5% معلنة، بالإضافة لـ 220 من 3,922 للذهب. وهاد السجل عايش في قاعدة البيانات، مش في الكود.

يعني في قرار لازم ينتّخذ صراحةً بدل ما ينفترض:

تستلم القاعدة

بترث الدليل اللي انباعت عليه الصفقة — 8,913 نتيجة مقيَّمة، جاهزة تكمّل تراكم من أول يوم.

تستلمها فاضية

المحرّك هو هو، بس سجلّ الأداء العلني بيبلّش من صفر وبدّه شهور يرجع. وbackfill بيقصّر هاي المدة بتقييم الماضي بتمريرة وحدة — بس الجزء الحيّ من السجل ما بينعاد بناؤه.

ما في جواب غلط هون. في بس جواب لازم ينتّفق عليه. وApiKeys فاضي عند التسليم — أي مفتاح بتصدره بعدها هو بيانات اعتماد آلة تبعك إنت.

إعدادات ما إلها قيمة افتراضية آمنة على بنيتك

المرجع الكامل بيعدّد كل قسم إعدادات بيقراه الكود. وهدول اللي رح يوقّفوك.

ConnectionStrings__Quant

كل مستضيف لازم يسمّي نفس الملف. شوف القسم الجاي — هاد اللي بيكلّف نص يوم.

Admin:Emails

الطريقة الوحيدة اللي بيصير فيها حدا مشغّلاً. بيتشحن فاضي، وهاي الحالة الآمنة: AdminAccess بيفشل مقفولاً، وصفحة الإدارة بتقولك إنها غير مضبوطة بدل ما توهمك إن حسابك ناقصه صلاحية. ضيف عنوانك وسجّل دخول.

DataProtection:KeysDirectory

اللوحة بترفض تقوم في الإنتاج بدونه، عن قصد. وبدونه، مفاتيح الكوكيز بتتولّد لكل عملية، وكل إعادة تشغيل بتسجّل خروج كل المشتركين بلا ما يوضّح السجل ليش. أشّره على وحدة تخزين دائمة.

AlphaVantage__ApiKey

بيانات السوق الحيّة. وبدونه بيرجع لمزوّد CSV مرفق — منيح للتقييم، بس للتطوير مش للإنتاج.

Saas__AdminApiKey

لحد ما ينحط، كل نقطة تشغيل بترد 503.

Stripe__SecretKey · __WebhookSecret · __PriceIds__*

الفوترة مبنية من الطرف للطرف وبتتفعّل لما ينحطوا التلاتة. ولحد ذلك اللوحة بتكتشف ذلك وبتحوّل الترقيات لتفعيل يدوي، وبتقول ذلك للمستخدم.

Email__SmtpHost وباقي Email__*

بدونه، رسائل استعادة كلمة المرور بتصير أسطر في السجل — يعني مسار الاستعادة ما بيعمل إشي بصمت.

Telegram__BotToken

بس إذا بدّك قناة تيليجرام. وكل إشي تاني بيشتغل بدونه.

قاعدتين عن وين بتعيش القيم

المفاتيح السرّية بتنحط في متغيّرات بيئة أو المخزن السرّي، أبداً مش في appsettings.json. ما في إشي حسّاس مرفوع بهاد المستودع، وبيستاهل تضل هيك.

و .NET بيقرأ المخزن السرّي في بيئة التطوير فقط لمستضيفَي الـ API واللوحة؛ أما مستضيف البوت فبيقراه بأي بيئة. وعلى الخادم، حطّ كل إشي عبر متغيّرات البيئة بدل الاعتماد على المخزن.

الإشي الوحيد اللي بيوقّع الناس

المستضيفات التلاتة لازم تأشّر على نفس ملف SQLite

بيتشحنوا مربوطين بمسار نسبي، وهاد بيمشي لما يشتغلوا من مجلداتهم على جهاز واحد. وعلى الخادم، حطّ التلاتة على مسار مطلق واحد.

وإذا غلط، ما بيطلع خطأ. كل مستضيف بيتعلّق بهدوء بـ quant.db خاص فيه، والتسجيل بيشتغل، وما بتظهر ولا تقرير أبداً، وما في إشي بالسجلات بيبيّن غلط.

ConnectionStrings__Quant=Data Source=/data/quant.db

سلوكيات بتنقرأ كأخطاء إذا ما حدا حكالك

زر «توليد تقرير» بدّه عمليتين، مش وحدة

اللوحة بتخدم الصفحة وبتحجز الشغل. والعملية اللي بتنفّذه خدمة مستضافة جوّا مستضيف البوت. شغّل اللوحة لحالها وكل طلب بينقبل وبينخزّن وما بينفّذ أبداً.

# both, not one
dotnet run --project QuantMarketEngine/src/QuantMarketEngine.Dashboard --urls http://localhost:5199
dotnet run --project QuantMarketEngine/src/QuantMarketEngine.TelegramBot

والتقرير ما بيظهر لحظة ما تضغط الزر. الصفحة بترجع فوراً وبتقول إن الأداة قيد التحليل. والعامل بياخد المهمة وبيصرف خمس لعشر ثواني. بعدها بتعمل تحديث للصفحة — ما في تحديث حيّ والصفحة ما بتستطلع.

واللي بيضغط الزر وبيبقى يحدّق بجدول ما تغيّر رح يستنتج إنه ما عمل إشي. وهاد أكتر انطباع أول وارد يطلع غلط.

«قيد التحليل» ما بيتغيّر

مستضيف البوت مش شغّال.

«الجلسة مسجّلة أصلاً»

قراءة اليوم موجودة؛ ما في إعادة تشغيل.

ما بيظهر إشي ولا رسالة

فحوص ما قبل النشر رفعت مشكلة حرجة — القراءة محجوزة، مش منشورة.

جلسات قديمة بس مش اليوم

خطة هاد الحساب بتؤجّل الوصول لجلسة نفس اليوم. وبتأثّر على التغذية المجدولة بس، مش على جلسة الحساب طلبها بنفسه.

بوابة الموافقة البشرية — الادعاء الدقيق

كل تقرير بينشره المحرّك على جدوله بينتظر إنساناً، والقراءة اللي فحوصها بتقول إنها غير صالحة ما بتنُشر بأي مسار.

ومسار واحد مستثنى عن قصد: التقرير اللي بيطلبه مشترك من صفحة التقارير بينولّد وبينُشر بلا انتظار مشغّل. وهاد قرار مالك، مش سهو — المشترك اللي لازم يستنّى حدا ينتبه ما بيقدر يستخدم الزر. وفحوص ما قبل النشر بتضل تنطبق عليه، فالشمعة القديمة ما بتطلع أبداً على إنها سوق اليوم.

أما التشغيلة المجدولة، والمراقب المدفوع بالأحداث، وزر «Report now» تبع المشغّل — كلهم بيوقفوا عند البوابة.

تصدير الـ PDF بدّه متصفّح على المستضيف

بيطبع عبر Chrome أو Edge بوضع بلا واجهة. وصور Docker ما فيها متصفّح، فالتصدير مطفي في الحاوية الافتراضية لحد ما ينثبّت واحد وينحط PdfExport:BrowserPath. والرابط بيخفي حاله، والنقطة بترد 503، وتصديرات النص والـ JSON ما بتتأثر.

وفي الحاوية ممكن كمان تحتاج PdfExport:NoSandbox=true — صندوق حماية Chrome بدّه صلاحيات نواة الحاوية اللي بتشتغل كـ root عادةً ما بتملكها. وهو مطفي افتراضياً لأن الخيار بيخلّي الميزة تشتغل بكل مكان وبيضعّفها بكل مكان، وهاد قرار المشغّل مش قيمة افتراضية تنورَث.

والـ PDF إنجليزي فقط. العربي بالـ PDF بدّه تخطيطاً ثنائي الاتجاه، والمُصيِّر بيعكس الأرقام داخل نص مختلط عربي/لاتيني. والتقرير العربي بينسلّم كنص بدلاً عن ذلك.

شاشات اللوحة إنجليزية، والمحتوى لأ

تحميلات التقارير على المنصة إنجليزية بالتصميم. والعربي لسّه بينتَج بكل مكان تاني — على القرص، وعلى تيليجرام، وعلى الموقع العام، ومن الـ API بـ ?lang=ar. والعرض بلغتين من محرّك واحد هو أحد ملامح المشتري المستهدف، مش إشي انشال.

سياسة الأمان بتمنع كل JavaScript

script-src 'none' صحيحة اليوم لأن اللوحة Blazor مُصيَّرة على الخادم بلا أي JavaScript. وإضافة @rendermode InteractiveServer لأي مكوّن رح تكسر السياسة لحد ما تتوسّع. وهاد مكتوب في الوسيط ومغطّى باختبار، فبتعرف عند البناء مش في الإنتاج.

الحدود المعروفة، بصراحة

  • لا عملاء ولا إيرادات. هاد بيع أصل.
  • تكامل الفوترة ما عالج معاملة حقيقية أبداً. Checkout المستضاف عند Stripe، وبوابة الفوترة المستضافة، وwebhook بتحقق توقيع — كلهم مبنيين خلف واجهة مزوّد، وبيانات البطاقة ما بتمرّ على المنصة. والفجوة بطاقة حيّة، مش كود.
  • الفضة بتشتغل على المحرّك بس لسّه غير مقيَّمة. تغذيتها ما بتحمل مدى داخل اليوم، فعدة قراءات بتنحجب عن قصد بدل ما تنقدَّر، ومعايرتها لسّه بتقرأ «العيّنة صغيرة». والذهب بيشارك نفس شكل التغذية وبيستقر عند جودة FAIR. وهاد حدّ بيانات مش حدّ محرّك — تاريخ أكتر ما بيحرّكه؛ مزوّد بحركة داخل اليوم هو اللي بيحرّكه.
  • مخروط الاحتمالات أضعف سطح، والتقرير بيقول هاد بنفسه. الحافة السفلية لليورو/دولار عند 20 يوم بتسجّل 6.3% مقابل 5%؛ وحواف الذهب العليا أسوأ. أما مخاطرة اليوم الواحد — الرقم الرئيسي — فبتجتاز على الاتنين.
  • تلات أقسام بتتشحن معطّلة: التحليل الأساسي، والمشغّل المدفوع بالأحداث، وأجزاء من التقويم الاقتصادي. والتلاتة قيم إعدادات مش كود ناقص. والتقويم حامل حالياً 14 إصداراً لبنوك مركزية وبيانات أمريكية لحد 17 ديسمبر 2026، وبعدها بيسكت لحد ما تنمدّد القائمة.
  • 38 من 166 ثابتاً في المحرّك بلا تبرير مكتوب. مفهرَسين على هالأساس، والعدد منشور مش مخفيّ، وولا واحد فيهم بيوصل للصفحة اللي بيشوفها العميل. والـ 128 الباقيين حاملين اشتقاقهم أو قياسهم.

ساعتك الأولى — كيف بتفحص كل هاد بنفسك

ما في إشي فوق بيطلب منك تصدّقه. هاي الأوامر بتشتغل على المستودع اللي بتستلمه.

سجلّ الأداء، مقروء من قاعدة البيانات مباشرة

cd QuantMarketEngine/src/QuantMarketEngine.TelegramBot && python -c "
import sqlite3
c=sqlite3.connect('quant.db')
for s, in c.execute('select distinct Symbol from AnalysisOutcomes order by Symbol'):
    t=c.execute('select count(*) from AnalysisOutcomes where Symbol=?',(s,)).fetchone()[0]
    b=c.execute('select count(*) from AnalysisOutcomes where Symbol=? and VaRBreached=1',(s,)).fetchone()[0]
    if t>=200: print(f'{s}: {b}/{t} = {b/t*100:.1f}%')
"

مجموعة الاختبارات

cd QuantMarketEngine && dotnet test --nologo -v q

حجم اللي بتشتريه

اجمع المجاميع بدل ما تاخد آخر سطر — وإلا wc المُقسَّم على دفعات رح يبلّغك عن دفعة وحدة وكأنها المستودع كله.

git rev-list --count HEAD && git ls-files '*.cs' '*.razor' | xargs wc -l | grep -w total | awk '{s+=$1} END {print s}'

ثغرات الحزم

cd QuantMarketEngine && dotnet list package --vulnerable --include-transitive

المحرّك، بلا أي حساب بأي مكان

مزوّد الـ CSV المرفق والشموع التاريخية بيجوا مع المستودع، فالمحرّك بيولّد تقارير حقيقية بلا إنترنت قبل ما تسجّل عند أي مزوّد بيانات.

cd QuantMarketEngine/src/QuantMarketEngine.TelegramBot
dotnet run -- report        # writes 5 files per symbol into reports/
dotnet run -- audit         # the calibration cards — the engine grading itself