تجربة VonmoTrade. الجزء 4: الرسوم البيانية التجارية


في المقالات السابقة ، اكتشفنا كيف يتم إنشاء أوامر التجارة ومعالجتها. سيكون موضوع هذه المقالة قضايا معالجة وتخزين المعلومات اللازمة للأدوات الرسومية لتحليل السوق - الرسوم البيانية للسهم.


قبل البدء ، أريد أن أصنع استطرادا صغيرا. بالنسبة لمشاريع Vonmo الداخلية ، يتم استخدام نظام تسمية الكلمات V + المعتاد ، والذي يصف بإيجاز وظائف المشروع. اكتشفت اليوم أن VTrade هي شركة موجودة. من أجل تجنب الالتباس ، قمت بإعادة تسمية التجربة إلى VonmoTrade.


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


  1. الخطية.
  2. الشوط الاول.

الرسوم البيانية الخطية


جدول أبسط وأكثر مفهومة دون إعداد. يعرض اعتماد سعر الأداة المالية في الوقت المحدد.



الميزة الرئيسية لهذا النوع من الرسم البياني هي البساطة. العيب الرئيسي يتبع منه - محتوى المعلومات منخفضة.


إذا كان الرسم البياني يستند إلى بيانات أولية ، فسيتم أخذ سعر الإغلاق الأخير. ولكن عادةً ما يتم بناء الرسوم البيانية على أساس البيانات المجمعة. في هذه الحالة ، يتم أخذ سعر الإغلاق لكل فاصل. نظرًا لأننا نتجاهل كل ما حدث في الفاصل الزمني ونأخذ سعر إغلاق الفاصل فقط ، ولهذا السبب ، يتم فقد محتوى المعلومات.


دقة الرسومات


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


لذلك ، يتم تخفيف البيانات عن طريق تقسيم المحور الزمني إلى فواصل زمنية وتجميع الأسعار في هذه الفواصل الزمنية.
الدقة - حجم الفاصل الأولي لتقسيم محور الوقت: الثانية والدقيقة والساعة واليوم وما إلى ذلك.


الحانات


تتعلق المخططات الفاصلة. لزيادة محتوى المعلومات ، من الضروري لكل فترة زمنية عرض معلومات السعر في بداية ونهاية الفاصل ، وكذلك الحد الأقصى والحد الأدنى للسعر. يسمى عرض الرسوم البيانية لهذه المجموعة بشريط. النظر في مخطط شريط واحد:



يشكل تسلسل الأشرطة مخططًا:



الشموع اليابانية


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



شكل تسلسل الشموع رسم بياني:



OHLCV التدوين


في المقالة الأخيرة ، اكتشفنا مخطط تخزين البيانات للرسم البياني في postgresql وقمنا بإنشاء جدول لمصدر البيانات الذي سيخزن البيانات المجمعة:


CREATE TABLE df ( t timestamp without time zone NOT NULL, r df_resolution NOT NULL DEFAULT '1m'::df_resolution, o numeric(64,32), h numeric(64,32), l numeric(64,32), c numeric(64,32), v numeric(64,32), CONSTRAINT df_pk PRIMARY KEY (t, r) ) 

لا تتطلب الحقول توضيحًا ، إلا أن الحقل r هو دقة السلسلة. هناك تعدادات في postgresql ، من المناسب استخدامها عندما تكون مجموعة من القيم للحقل معروفة مسبقًا. من خلال التعدادات ، نحدد نوعًا جديدًا لقرارات الرسم البياني المسموح بها. فليكن مسلسلًا من دقيقة واحدة إلى شهر واحد:


 CREATE TYPE df_resolution AS ENUM ('1m', '3m', '5m', '15m', '30m', '45m', '1h', '2h', '4h', '6h', '8h', '12h', '1d', '3d', '1w', '1M'); 

من المهم تحقيق توازن بين أداء نظام القرص والمعالج والتكلفة الإجمالية للملكية. يحدد النظام حاليًا 16 قرارًا. حلان واضحان:


  • يمكننا حساب وتخزين جميع القرارات في قاعدة البيانات. الخيار مناسب لأنه عندما لا ننفق أخذ العينات الطاقة على تجميع الفواصل الزمنية ، تكون جميع البيانات جاهزة فورًا للإخراج. في غضون شهر ، سيتم إنشاء ما يزيد قليلاً عن 72 ألف سجل لأداة واحدة. يبدو الأمر بسيطًا ومريحًا ، لكن مثل هذا الجدول سيتغير كثيرًا ، حيث أنه بالنسبة لكل تحديث للسعر ، تحتاج إلى إنشاء أو تحديث 16 إدخالًا في الجدول وإعادة إنشاء الفهرس. في postgresql ، قد يكون هناك مشكلة مع جمع القمامة.
  • خيار آخر هو تخزين دقة أساسية واحدة. عند الاختيار من الدقة الأساسية ، يجب بناء القرارات المطلوبة. على سبيل المثال ، عند تخزين دقة الوضوح كقاعدة شهرية ، سيتم إنشاء 43 ألف سجل لكل أداة. وبالتالي ، بالمقارنة مع الإصدار السابق ، يتم تقليل حجم التسجيل والنفقات العامة بنسبة 40٪. ومع ذلك ، فإن حمل المعالج يتزايد.

كما ذكر أعلاه ، من المهم أن تجد التوازن. لذلك ، لا يتمثل خيار التسوية في تخزين دقة أساسية واحدة ، ولكن عدة خيارات: دقيقة واحدة ، ساعة واحدة ، يوم واحد. باستخدام هذا المخطط ، سيتم إنشاء 44.6 ألف سجل لكل أداة شهريًا. سيكون تحسين حجم التسجيل 36٪ ، لكن الحمل على المعالج سيكون مقبولًا. على سبيل المثال ، لإنشاء فواصل زمنية أسبوعية بدلاً من قراءة وتجميع 10،080 سجلًا في حالة دقة أساسية دقيقة ، نحتاج إلى القراءة من القرص وتجميع البيانات بدقة 7 أيام فقط.


OHLCV التخزين


بطبيعتها ، OHLCV هي سلسلة زمنية. كما تعلم ، فإن قاعدة البيانات العلائقية ليست مناسبة لتخزين ومعالجة هذه البيانات. لحل هذه المشكلات ، يستخدم المشروع ملحق Timescale .


يعمل مقياس الوقت على تحسين أداء عمليات الإدراج والتحديث ، ويسمح لك بتكوين التقسيم ، ويوفر وظائف تحليلية مُحسَّنة خصيصًا للعمل مع السلاسل الزمنية.


لإنشاء وتحديث الأشرطة ، نحتاج فقط إلى وظائف قياسية:


  • date_trunc('minute' | 'hour' | 'day', transaction_ts) - للعثور على بداية الفاصل الزمني للدقيقة والساعة واليوم ، على التوالي.
  • greatest least لتحديد الحد الأقصى والحد الأدنى للأسعار.

بفضل واجهة برمجة التطبيقات ، يتم تنفيذ طلب تحديث واحد فقط لكل معاملة.
حصلت على هذا النوع من SQL لإصلاح تغييرات السوق في القرارات الأساسية:


 FOR i IN 1 .. array_upper(storage_resolutions, 1) LOOP resolution = storage_resolutions[i]; IF resolution = '1m' THEN SELECT DATE_TRUNC('minute', ts) INTO bar_start; ELSIF resolution = '1h' THEN SELECT DATE_TRUNC('hour', ts) INTO bar_start; ELSIF resolution = '1d' THEN SELECT DATE_TRUNC('day', ts) INTO bar_start; END IF; EXECUTE format( 'INSERT INTO %I (t,r,o,h,l,c,v) VALUES (%L,%L,%L::numeric,%L::numeric,%L::numeric,%L::numeric,%L::numeric) ON CONFLICT (t,r) DO UPDATE SET h = GREATEST(%Ih, %L::numeric), l = LEAST(%Il, %L::numeric), c = %L::numeric, v = %Iv + %L::numeric;', df_table, bar_start, resolution, price, price, price, price, volume, df_table, price, df_table, price, price, df_table, volume ); END LOOP; 

عند أخذ العينات ، لتجميع الفواصل الزمنية ، نحتاج إلى الوظائف التالية:


  • time_bucket - لاقتحام الفواصل الزمنية
  • first - للعثور على سعر الافتتاح - O
  • max - أعلى سعر للفاصل الزمني - H
  • min - أقل سعر للفاصل الزمني - L
  • last - للعثور على سعر الإغلاق - C
  • sum - للعثور على حجم التداول - V

المشكلة الوحيدة الموجودة عند استخدام Timescale هي حدود وظيفة time_bucket . يسمح لك بالعمل فقط على فترات أقل من شهر. لإنشاء دقة شهرية ، يجب استخدام دالة date_trunc القياسية.


API


لعرض الرسوم البيانية على العميل ، سنستخدم الرسوم البيانية خفيفة الوزن من Tradingview. تتيح لك المكتبة تخصيص مظهر الرسوم البيانية تمامًا وهي ملائمة للاستخدام. حصلت على الرسوم البيانية التالية:



نظرًا لأن الجزء الرئيسي من التفاعل بين المتصفح والنظام الأساسي يتم عبر websocket ، فلا توجد مشاكل في التفاعل.


مصدر البيانات


يجب أن يقوم مصدر البيانات للمخططات (تغذية البيانات) بإرجاع الجزء الضروري من السلسلة الزمنية في الدقة المطلوبة. في الوقت نفسه ، لتوفير حركة المرور وتقليل وقت المعالجة على العميل ، يجب على الخادم حزمة النقاط.


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


النظر في مثال لطلب آخر 50 دقيقة ل USDGBP ، مع الاشتراك التلقائي لرسم التحديثات:


 { "m":"market", "c":"get_chart", "v":{ "charts":[ { "ticker":"USDGBP", "resolution":"1h", "from":0, "cnt":50, "send_updates":true } ] } } 

يمكنك بالطبع طلب نطاق زمني (من ، إلى) ، ولكن نظرًا لأن الفاصل الزمني لكل شريط معروف ، فإن واجهة برمجة التطبيقات التوضيحية التي تشير إلى اللحظة وعدد الأشرطة تبدو أكثر ملاءمةً لي.
ستستجيب خلاصة البيانات لهذا الطلب بطريقة مماثلة:


 { "m":"market", "c":"chart", "v":{ "bar_fields":[ "t","uts","o","h","l","c","v" ], "items":[ { "ticker":"USDGBP", "resolution":"1h", "bars":[ [ "2019-12-13 13:00:00",1576242000,"0.75236800", "0.76926400","0.75236800","0.76926400","138.10000000" ], .... ] } ] } } 

يحتوي حقل bar_fields على معلومات حول مواضع العناصر. التحسين الإضافي هو وضع هذا الحقل في تكوين العميل الذي يتلقاه من الخادم في وقت التمهيد.


وبالتالي ، يتلقى العميل الجزء الضروري من البيانات التاريخية ويبني الحالة الأولية للرسم البياني. إذا تغيرت الحالة ، يتلقى تحديثًا يؤثر فقط على الشريط الأخير.


 { "m":"market", "c":"chart_tick", "v":{ "ticker":"USDGBP", "resolution":"1h", "items":{ "v":"140.600", "ut":1576242000, "t":"2019-12-13T13:00:00", "o":"0.752368", "l":"0.752368", "h":"0.770531", "c":"0.770531" } } } 

النتيجة الأولية


خلال سلسلة المقالات ، قمنا بتحليل نظرية وممارسة بناء التبادل. حان الوقت لوضع النظام معًا.


في المقالة التالية ، سنتناول تطوير واجهات المستخدم الرسومية: واجهة المستخدم للخدمة لإدارة النظام الأساسي وواجهة المستخدم للمستخدمين النهائيين. كما سيتم تقديم نسخة تجريبية من Vonmo Trade.

Source: https://habr.com/ru/post/ar483308/


All Articles