
في مدونتنا ، نكتب الكثير عن التقنيات والأدوات المفيدة المتعلقة بتداول الأسهم. أحدها هو منصة
StockSharp المجانية ، والتي يمكن استخدامها في التطوير المهني لمحطات التداول والروبوتات التجارية في C #. في هذه المقالة ، سنعرض كيفية استخدام الإطار الرسومي المضمن في S # .API من أجل إنشاء محطة تداول مع القدرة على تشغيل استراتيجيات حسابية.
ما هو المطلوب
- Visual Studio 2017 (مجتمع ، نسخة مجانية) ، سنقوم ببرمجته.
- الاتصال بالتداول في البورصة ، في الأمثلة الواردة في هذا النص ، يتم استخدام واجهة SMARTcom من ITI Capital .
إنشاء المشروع
قم بإنشاء تطبيق WPF جديد في Visual Studio:

ثم تحتاج إلى إضافة مكتبة S # .API. يمكنك معرفة كيفية القيام بذلك
في الوثائق . الخيار الأفضل هو التثبيت باستخدام Nuget.
نظرًا لأن جميع عناصر الرسوم البيانية S # .API تعتمد على DevExpress ، وأن مكتبات DevExpress تأتي مع S # .API ، فسيكون من الغباء عدم استخدامها. دعنا نذهب إلى محرر النوافذ MainWindow.xaml:

استبدال النافذة بـ DXWindow ، سنحتاج إلى ذلك لاستخدام أنظمة ألوان مختلفة:

سوف يقدم لنا Visual Studio نفسه إدراج المكتبات اللازمة.
سنقوم بتقسيم النافذة إلى ثلاثة أجزاء - في الجزء العلوي ، سيكون هناك شريط به أزرار لإعداد التوصيلات والاتصالات ، في الجزء السفلي ستكون هناك نافذة بها سجلات ، وفي الوسط جميع اللوحات الأخرى. أسهل طريقة لكسر نافذة هي مع Devout's LayoutControl.
في الأجزاء الثلاثة الناتجة ، سنضيف العناصر التي نحتاجها.
<dx:DXWindow x:Class="ShellNew.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <dxlc:LayoutControl Padding="0" Name="LayoutControlRoot" Orientation="Vertical"> <dxlc:LayoutGroup HorizontalAlignment="Stretch" Height="25"> </dxlc:LayoutGroup> <dxlc:LayoutGroup HorizontalAlignment="Stretch" > </dxlc:LayoutGroup> <dxlc:LayoutGroup HorizontalAlignment="Stretch" > </dxlc:LayoutGroup> </dxlc:LayoutControl> </dx:DXWindow>
تكوين اتصال للموصل
أضف زرين ، أحدهما هو زر إعدادات الاتصال ، والثاني هو زر الاتصال. للقيام بذلك ، استخدم زر SimpleButton من DevExpress. ستكون الأزرار موجودة في الجزء العلوي من التطبيق. في كل زر نضع الصور المألوفة من
S # .Designer و
S # .Data و
S # .Terminal .
<dx:DXWindow x:Class="ShellNew.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol" xmlns:xaml="http://schemas.stocksharp.com/xaml" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <dxlc:LayoutControl Padding="0" Name="LayoutControlRoot" Orientation="Vertical"> <dxlc:LayoutGroup HorizontalAlignment="Stretch" Height="25"> <!-- --> <dxlc:LayoutItem Width="40"> <dx:SimpleButton x:Name="SettingsButton" Click="SettingsButton_Click" > <Image Source="{xaml:ThemedIcons Key=Settings}" Width="16" /> </dx:SimpleButton> </dxlc:LayoutItem> <dxlc:LayoutItem Width="40"> <dx:SimpleButton x:Name="ConnectButton" Click="ConnectButton_Click" > <Image Source="{xaml:ThemedIcons Key=Connect}" Width="16" /> </dx:SimpleButton> </dxlc:LayoutItem> </dxlc:LayoutGroup> <dxlc:LayoutGroup HorizontalAlignment="Stretch" View="Tabs"> <!-- --> </dxlc:LayoutGroup> <dxlc:LayoutGroup HorizontalAlignment="Stretch" > <!-- --> </dxlc:LayoutGroup> </dxlc:LayoutControl> </dx:DXWindow>
في الزاوية اليمنى العليا من نموذج الشاشة ، سنرى الصورة التالية:

انقر نقرًا مزدوجًا فوق كل زر لإنشاء معالجات الأحداث للنقر فوق الزر. في رمز MainWindow ، يجب أن تعلن الموصل ، وكذلك اسم الموقع والملف الذي سيتم تخزين إعدادات الموصل فيه.
public readonly Connector Connector; private const string _dir = "Data"; private static readonly string _settingsFile = $@"{_dir}\connection.xml";
في معالج الأحداث للنقر على زر إعدادات الموصل ، سنفتح نافذة تكوين الموصل ونحفظه في ملف.
private void SettingsButton_Click(object sender, RoutedEventArgs e) { if (Connector.Configure(this)) { new XmlSerializer<SettingsStorage>().Serialize(Connector.Save(), _settingsFile); } }
في المُنشئ ، سوف نتحقق مما إذا كان هناك دليل وملف به إعدادات الموصل ، وإذا كان هناك دليل ، فسنقوم بتحميله في الموصل:
تحتوي معظم كائنات S # .API على أساليب حفظ وتحميل يمكن استخدامها لحفظ هذا الكائن وتحميله من ملف XML.
في معالج الأسلوب بالنقر على زر الاتصال ، نقوم بتوصيل الموصل.
private void ConnectButton_Click(object sender, RoutedEventArgs e) { Connector.Connect(); }
الآن يمكنك تشغيل البرنامج والتحقق منه.
وضع سمة الظلام
يفضل العديد من المتداولين السمات الداكنة على تطبيقات التداول. لذلك ، نجعل فورا موضوع البرنامج مظلمة. لتحتاج إلى العثور على ملف App.xaml:

واستبدل التطبيق بالتخطيط: ExtendedBaseApplication فيه ، وسوف يعرضنا Visual Studio نفسه لإدراج المكتبات اللازمة.
<charting:ExtendedBaseApplication x:Class="ShellNew.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:charting="http://schemas.stocksharp.com/xaml" StartupUri="MainWindow.xaml"> </charting:ExtendedBaseApplication>
وفي ملف App.xaml.cs تحتاج إلى حذف ": التطبيق".
namespace ShellNew {
في مُنشئ MainWindow ، اكتب
ApplicationThemeHelper.ApplicationThemeName = Theme.VS2017DarkName;
كود كامل في الوقت الحالي:
public partial class MainWindow { public readonly Connector Connector; private const string _dir = "Data"; private static readonly string _settingsFile = $@"{_dir}\connection.xml"; public MainWindow() {
تشغيل للتحقق من الموضوع المظلم:

إنشاء شريط الأدوات
أضف مجلدًا حيث سنخزن جميع عناصر التحكم التي أنشأناها ، وسميها XAML. قم بإضافة UserControll الأول الخاص بنا ، وقم بتسميته اسم SecurityGridControl.

نضيف عنصر SecurityPicker واحدًا إليه. سيعرض الأدوات المتاحة. عن طريق القياس مع النافذة الرئيسية ، سنستخدم LayoutControl من DevExpress.
<UserControl x:Class="ShellNew.XAML.SecurityGridControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:xaml="http://schemas.stocksharp.com/xaml" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <xaml:SecurityPicker x:Name="SecPicker" /> </UserControl>
دعنا نذهب إلى مصمم الإطار الرئيسي وتغيير الجزء المركزي إلى عرض الإشارات المرجعية. في إحدى الإشارات المرجعية ، سنضع جهاز التحكم الذي أنشأناه بواسطة SecurityPicker:
<dxlc:LayoutGroup HorizontalAlignment="Stretch" View="Tabs"> <!-- --> <dxlc:LayoutGroup Header="Securities"> <myxaml:SecurityGridControl x:Name="SecurityPanel" /> </dxlc:LayoutGroup> </dxlc:LayoutGroup>
الآن بعد أن أصبح لدينا شريط الأدوات ، نحتاج إلى إعطائه مصدر بيانات ، في حالتنا هو موصل. يمكنك ببساطة
MainWindow
SecurityPanel.SecPicker.SecurityProvider = Connector;
في منشئ
MainWindow
SecurityPanel.SecPicker.SecurityProvider = Connector;
MainWindow
SecurityPanel.SecPicker.SecurityProvider = Connector;
.
ولكن يجب ألا تسد MainWindow برمز لا ينطبق عليه. لذلك ، سنقوم بإنشاء متغير ثابت Instance وتعيين MainWindow إليه في مُنشئ MainWindow:
… public static MainWindow Instance; … Instance = this; …
الآن ، في أي مكان في برنامجنا ، يمكننا الوصول إلى خصائص MainWindow من خلال رمز MainWindow.Instance.XXX.
في مُنشئ SecurityGridControl ، وبهذه الطريقة نحدد الرابط كمصدر للبيانات:
public SecurityGridControl() { InitializeComponent(); SecPicker.SecurityProvider = MainWindow.Instance.Connector; }
تشغيل للتحقق:

مضيفا تسجيل
يجب التحكم في البرنامج أو الموصل أو الروبوت. لهذا ، S # .API لديه فئة LogManager خاصة. يستقبل هذا الفصل الرسائل من المصادر ويمررها إلى المستمعين. في حالتنا ، ستكون المصادر هي الموصل ، الاستراتيجيات ، إلخ ، وسيكون المستمع ملفًا ولوحة سجل.
في رمز MainWindow ، نعلن عن كائن LogManager والمكان الذي سيتم تخزينه فيه:
public readonly LogManager LogManager; private static readonly string _logsDir = $@"{_dir}\Logs\";
في مُنشئ MainWindow ، قم بإنشاء LogManager ، واضبط ملف مصدر الإصغاء و الموصل عليه:
عن طريق القياس مع شريط الأدوات ، قم بإنشاء لوحة سجل في مجلد XAML ، وقم بإضافة UserControl آخر. اعطائها اسم MonitorControl. أضف عنصر الشاشة إليه.
<UserControl x:Class="ShellNew.XAML.MonitorControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:xaml="http://schemas.stocksharp.com/xaml" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <xaml:Monitor x:Name="Monitor" /> </UserControl>
في مُنشئ MonitorControl ، قم بتعيين LogManager على Monitor كمستمع:
public MonitorControl() { InitializeComponent(); MainWindow.Instance.LogManager.Listeners.Add(new GuiLogListener(Monitor)); }
إضافة MonitorControl التي تم إنشاؤها إلى أسفل MainWindow:
<dxlc:LayoutGroup HorizontalAlignment="Stretch" dxlc:LayoutControl.AllowVerticalSizing="True"> <!-- --> <myxaml:MonitorControl x:Name="MonitorControl" /> </dxlc:LayoutGroup>
تشغيل للتحقق:

إنشاء لوحة زجاجية
عن طريق القياس مع اللوحات السابقة ، قم بإنشاء لوحة زجاجية ، وقم بإضافة UserControl آخر إلى مجلد XAML. اعطائها اسم MarketDepthControl.
في MainWindow استخدمنا بالفعل LayoutControl ، في هذا التحكم سوف نستخدم LayoutControl أيضًا. نقسم اللوحة إلى جزأين أفقيًا:
<UserControl x:Class="ShellNew.XAML.MarketDepthControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol" mc:Ignorable="d"> <dxlc:LayoutControl Padding="0" Name="LayoutControlRoot" Orientation="Horizontal"> <dxlc:LayoutGroup> <!--Left--> </dxlc:LayoutGroup> <dxlc:LayoutGroup Orientation="Vertical" dxlc:LayoutControl.AllowHorizontalSizing="True"> <!--Rigth--> </dxlc:LayoutGroup> </dxlc:LayoutControl> </UserControl>
أضف SecurityPicker إلى الجانب الأيسر - قابلناه عندما أنشأنا شريط الأدوات.
<dxlc:LayoutGroup> <xaml:SecurityPicker x:Name="SecPicker" SecuritySelected="SecPicker_SecuritySelected" /> </dxlc:LayoutGroup> . : <dxlc:LayoutGroup Orientation="Vertical" dxlc:LayoutControl.AllowHorizontalSizing="True"> <dxlc:LayoutItem VerticalAlignment="Stretch"> <xaml:MarketDepthControl x:Name="MarketDepth" MaxHeight="2000" SelectionChanged="MarketDepth_SelectionChanged" /> </dxlc:LayoutItem> </dxlc:LayoutGroup>
يحتاج MarketDepthControl إلى تعيين بعض القيمة MaxHeight ، وإلا لن يتم تشغيل التطبيق.
تحت الزجاج ، سنضع عناصر مهمة الحافظة والسعر وحجم الطلب:
<dxlc:LayoutItem Label="Portfolio" Height="20"> <xaml:PortfolioComboBox x:Name="PortfolioComboBox" /> </dxlc:LayoutItem> <dxlc:LayoutItem Label="Price" Height="20"> <dxe:SpinEdit MinValue="0" Name="SpinEditPrice" /> </dxlc:LayoutItem> <dxlc:LayoutItem Label="Volume" Height="20"> <dxe:SpinEdit MinValue="0" Name="SpinEditVolume" /> </dxlc:LayoutItem>
تجدر الإشارة إلى خاصية تسمية LayoutItem ، فهي تسمح لك بتعيين النص أمام العنصر. بالإضافة إلى عنصر SpinEdit من DevExpress والذي يعد ملائماً لضبط القيم العددية. هذه العناصر تبدو كما يلي:

أدناه سنضع أزرار البيع والشراء:
<dxlc:LayoutGroup Orientation="Horizontal" Height="20" VerticalAlignment="Stretch"> <dxlc:LayoutItem VerticalAlignment="Stretch"> <dx:SimpleButton Content="Buy" x:Name="BuyButton" Click="BuyButton_Click" /> </dxlc:LayoutItem> <dxlc:LayoutItem VerticalAlignment="Stretch"> <dx:SimpleButton Content="Sell" x:Name="SelltButton" Click="SelltButton_Click" /> </dxlc:LayoutItem> </dxlc:LayoutGroup>
كود كامل:
<UserControl x:Class="ShellNew.XAML.MarketDepthControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol" xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" xmlns:xaml="http://schemas.stocksharp.com/xaml" xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors" mc:Ignorable="d"> <dxlc:LayoutControl Padding="0" Name="LayoutControlRoot" Orientation="Horizontal"> <dxlc:LayoutGroup> <xaml:SecurityPicker x:Name="SecPicker" SecuritySelected="SecPicker_SecuritySelected" /> </dxlc:LayoutGroup> <dxlc:LayoutGroup Orientation="Vertical" dxlc:LayoutControl.AllowHorizontalSizing="True"> <dxlc:LayoutItem VerticalAlignment="Stretch"> <xaml:MarketDepthControl x:Name="MarketDepth" MaxHeight="2000" SelectionChanged="MarketDepth_SelectionChanged" /> </dxlc:LayoutItem> <dxlc:LayoutItem Label="Portfolio" Height="20"> <xaml:PortfolioComboBox x:Name="PortfolioComboBox" /> </dxlc:LayoutItem> <dxlc:LayoutItem Label="Price" Height="20"> <dxe:SpinEdit MinValue="0" Name="SpinEditPrice" /> </dxlc:LayoutItem> <dxlc:LayoutItem Label="Volume" Height="20"> <dxe:SpinEdit MinValue="0" Name="SpinEditVolume" /> </dxlc:LayoutItem> <dxlc:LayoutGroup Orientation="Horizontal" Height="20" VerticalAlignment="Stretch"> <dxlc:LayoutItem VerticalAlignment="Stretch"> <dx:SimpleButton Content="Buy" x:Name="BuyButton" Click="BuyButton_Click" /> </dxlc:LayoutItem> <dxlc:LayoutItem VerticalAlignment="Stretch"> <dx:SimpleButton Content="Sell" x:Name="SelltButton" Click="SelltButton_Click" /> </dxlc:LayoutItem> </dxlc:LayoutGroup> </dxlc:LayoutGroup> </dxlc:LayoutControl> </UserControl>
في مُنشئ MarketDepthControl ، قم بتعيين مصدر الأدوات الخاصة بـ SecurityPicker ومصدر الحقائب الخاصة بـ PortfolioComboBox ، وفي حالتنا ، سيكون الرابط:
public MarketDepthControl() { InitializeComponent(); SecPicker.SecurityProvider = MainWindow.Instance.Connector; PortfolioComboBox.Portfolios = new PortfolioDataSource(MainWindow.Instance.Connector); }
إنشاء معالج حدث تحديد أداة في SecurityPicker. في ذلك ، نتحقق مما إذا كانت الأداة المستلمة لا تساوي الصفر. إذا كان لا يساوي الصفر ، فنحن نحفظ الأداة المستلمة في متغير محلي ، وسيكون ذلك مفيدًا لنا عند تحديث الزجاج. ثم نقوم بتنظيف وتسجيل الأداة المستلمة في الموصل لاستلام كوب باستخدام أسلوب RegisterMarketDepth. باستخدام أسلوب GetMarketDepth ، نحصل على الزجاج الحالي للأداة من أجل تحديث MarketDepthControl به.
private Security _selectedSecurity; private void SecPicker_SecuritySelected(Security security) { if (security == null) return; _selectedSecurity = security; MainWindow.Instance.Connector.RegisterMarketDepth(_selectedSecurity); var marketDepth = MainWindow.Instance.Connector.GetMarketDepth(_selectedSecurity); MarketDepth.UpdateDepth(marketDepth); }
لكي يتم تحديث الزجاج باستمرار في مُنشئ MarketDepthControl ، نحن نشترك في حدث تغيير الزجاج MarketDepthChanged على الموصل. في معالج هذا الحدث ، سوف نتحقق من الأداة التي ينتمي إليها الزجاج المستلم ، وإذا كان ينتمي إلى الأداة المحددة في SecurityPicker ، فإننا نقوم بتحديثها: MarketDepthControl.
public MarketDepthControl() { InitializeComponent(); SecPicker.SecurityProvider = MainWindow.Instance.Connector; PortfolioComboBox.Portfolios = new PortfolioDataSource(MainWindow.Instance.Connector); MainWindow.Instance.Connector.MarketDepthChanged += Connector_MarketDepthChanged; } private void Connector_MarketDepthChanged(MarketDepth marketDepth) { if (_selectedSecurity == null || marketDepth.Security != _selectedSecurity) return; MarketDepth.UpdateDepth(marketDepth); }
في الجزء الرئيسي من MainWindow ، أضف لوحة MarketDepthControl التي تم إنشاؤها:
<dxlc:LayoutGroup HorizontalAlignment="Stretch" View="Tabs"> <!-- --> <dxlc:LayoutGroup Header="Securities"> <myxaml:SecurityGridControl x:Name="SecurityPanel" /> </dxlc:LayoutGroup> <dxlc:LayoutGroup Header="Portfolios"> <myxaml:PortfolioGridControl x:Name="PortfolioGridControl" /> </dxlc:LayoutGroup> <dxlc:LayoutGroup Header="Orders"> <myxaml:OrderGridControl x:Name="OrderGridControl" /> </dxlc:LayoutGroup> <dxlc:LayoutGroup Header="MyTrades"> <myxaml:MyTradeGridControl x:Name="MyTradeGridControl" /> </dxlc:LayoutGroup> <dxlc:LayoutGroup Header="MarketDepth"> <myxaml:MarketDepthControl x:Name="MarketDepthControl" /> </dxlc:LayoutGroup> </dxlc:LayoutGroup>
في هذه المرحلة ، يمكنك تشغيل البرنامج والتحقق من تشغيل تحديث النظارات.
قم بإنشاء معالج أحداث للنقر فوق أزرار البيع والشراء. في كل معالج نقوم بإنشاء طلب ، نشير فيه إلى الأداة المحددة في SecurityPicker ، والمحفظة المحددة في PortfolioComboBox ، والحجم والسعر من SpinEdit المقابل. تسجيل التطبيق في رابط باستخدام الأسلوب RegisterOrder.
private void BuyButton_Click(object sender, RoutedEventArgs e) { Order order = new Order() { Security = _selectedSecurity, Portfolio = PortfolioComboBox.SelectedPortfolio, Volume = SpinEditVolume.Value, Price = SpinEditPrice.Value, Direction = StockSharp.Messages.Sides.Buy, }; MainWindow.Instance.Connector.RegisterOrder(order); } private void SelltButton_Click(object sender, RoutedEventArgs e) { Order order = new Order() { Security = _selectedSecurity, Portfolio = PortfolioComboBox.SelectedPortfolio, Volume = SpinEditVolume.Value, Price = SpinEditPrice.Value, Direction = StockSharp.Messages.Sides.Sell, }; MainWindow.Instance.Connector.RegisterOrder(order); }
كل المعالجات تختلف فقط في اتجاه التطبيق.
دعنا نجعل قيمة SpinEditPrice تتغير حسب سعر الاقتباس المحدد عند اختيار علامات الاقتباس في كوب. للقيام بذلك ، قم بإنشاء معالج حدث SelectionChanged لـ MarketDepthControl. حيث سنقوم بتحديث قيمة SpinEditPrice بسعر الاقتباس المحدد إذا كان السعر المحدد لا يساوي الصفر.
private void MarketDepth_SelectionChanged(object sender, GridSelectionChangedEventArgs e) { if (MarketDepth.SelectedQuote == null) return; SpinEditPrice.Value = MarketDepth.SelectedQuote.Price; }
تشغيل للتحقق:

حفظ بيانات السوق
لحفظ المحافظ والأدوات والمنصات ، نحتاج إلى فئة CsvEntityRegistry. من الضروري إعادة موقع تخزين الكيان واستدعاء طريقة التهيئة لتحميلها.
_csvEntityRegistry = new CsvEntityRegistry(_csvEntityRegistryDir); _csvEntityRegistry.Init();
لحفظ الشموع والصفقات ، إلخ. نحن بحاجة إلى StorageRegistry:
_storageRegistry = new StorageRegistry { DefaultDrive = new LocalMarketDataDrive(_storageRegistryDir), };
نحتاج أيضًا إلى سجل SnapshotRegistry لمتاجر اللقطات:
_snapshotRegistry = new SnapshotRegistry(_snapshotRegistryDir);
كل هذا نمرر إلى الرابط عندما يتم إنشاؤه:
Connector = new Connector(_csvEntityRegistry, _storageRegistry, _snapshotRegistry) { IsRestoreSubscriptionOnReconnect = true, StorageAdapter = { DaysLoad = TimeSpan.FromDays(3) }, }; Connector.LookupAll();
هنا أشرنا أيضًا إلى أن الموصل سوف يعيد الاتصال عندما يتم قطع الاتصال ، وأيضًا يشير إلى عدد أيام السجل المطلوب تنزيلها. سلسلة رابط. LookupAll () ؛ يطلب البيانات المتاحة:
بعد تحميل التطبيق ، والانتقال إلى مجلد البيانات ، سنرى ظهور مجلدات جديدة:

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