
Kami terus berbicara tentang membuat robot perdagangan menggunakan platform
StockSharp .
Artikel pertama membahas tentang pembuatan proyek dan menggambar elemen-elemen utama dari sistem perdagangan. Dalam materi akhir siklus, kami akan langsung menerapkan strategi perdagangan.
Membuat panel portofolio
Dengan analogi dengan bilah alat, buat panel log. Untuk melakukan ini, tambahkan UserControl lain ke folder XAML. Beri nama PortfolioGridControl. Tambahkan elemen PortfolioGrid ke sana.
<UserControl x:Class="ShellNew.XAML.PortfolioGridControl" 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:PortfolioGrid x:Name="PortfolioGrid" /> </UserControl>
Dalam konstruktor PortofolioGridControl, kita perlu berlangganan ke acara kemunculan portofolio baru dan acara kemunculan posisi baru di Connector.
public PortfolioGridControl() { InitializeComponent(); MainWindow.Instance.Connector.NewPortfolio += PortfolioGrid.Portfolios.Add; MainWindow.Instance.Connector.NewPosition += PortfolioGrid.Positions.Add; }
Jadi, ketika membuat portofolio baru, itu akan muncul di panel portofolio, dan ketika posisi baru muncul di panel portofolio, itu akan diperbarui.
Di bagian tengah MainWindow, tambahkan panel PortfolioGridControl yang dibuat:
<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>
Jalankan untuk memeriksa:

Kami memiliki tab dengan portofolio.
Membuat panel pesanan
Bilah pesanan di S # .API memiliki kemampuan untuk melakukan pemesanan, menarik pesanan, dan mendaftar ulang. Dengan analogi dengan bilah alat, buat panel pesanan, tambahkan UserControl lain ke folder XAML. Beri nama OrderGridControl. Tambahkan elemen OrderGrid ke dalamnya:
<UserControl x:Class="ShellNew.XAML.OrderGridControl" 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:OrderGrid x:Name="OrderGrid" /> </UserControl>
OrderGrid memiliki acara pendaftaran OrderRegistering, acara registrasi ulang OrderReRegistering, dan acara pembatalan OrderCanceling.
Mari kita buat penangan mereka:
<UserControl x:Class="ShellNew.XAML.OrderGridControl" 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:OrderGrid x:Name="OrderGrid" OrderRegistering="OrderGrid_OnOrderRegistering" OrderReRegistering="OrderGrid_OnOrderReRegistering" OrderCanceling="OrderGrid_OnOrderCanceling" /> </UserControl>
Dalam penangan event pendaftaran permintaan, kami membuat jendela OrderWindow di mana Anda perlu menentukan sumber data untuk instrumen, portofolio, dan data pasar. Dalam kasus kami, semuanya akan menjadi Connector.
Lalu kami memanggil OrderWindow dengan metode ShowModal. Jika tombol OK ditekan di jendela ini, maka melalui konektor kami mendaftar menggunakan metode RegisterOrder:
private void OrderGrid_OnOrderRegistering() { var newOrder = new OrderWindow { Title = "Order registering", Order = new Order(), SecurityProvider = MainWindow.Instance.Connector, MarketDataProvider = MainWindow.Instance.Connector, Portfolios = new PortfolioDataSource(MainWindow.Instance.Connector), }; if (newOrder.ShowModal(this)) MainWindow.Instance.Connector.RegisterOrder(newOrder.Order); }
Dalam event handler pendaftaran ulang acara, kami melakukan semuanya dengan cara yang sama. Hanya dalam kasus ini, objek Order datang ke acara - ini adalah pesanan yang perlu didaftarkan ulang. Oleh karena itu, di OrderWindow, kami menentukan
Order = order.ReRegisterClone(newVolume: order.Balance)
untuk mengisi bidang jendela OrderWindow.
Lalu kami memanggil OrderWindow dengan metode ShowModal. Jika tombol OK diklik di jendela ini, maka kami akan mendaftar ulang aplikasi melalui konektor menggunakan metode ReRegisterClone. Kami mentransfer ke sana aplikasi lama, yang harus dibatalkan, dan yang baru, yang harus ditetapkan.
private void OrderGrid_OnOrderReRegistering(Order order) { var window = new OrderWindow { Title = "Order re-registering", SecurityProvider = MainWindow.Instance.Connector, MarketDataProvider = MainWindow.Instance.Connector, Portfolios = new PortfolioDataSource(MainWindow.Instance.Connector), Order = order.ReRegisterClone(newVolume: order.Balance) }; if (window.ShowModal(this)) MainWindow.Instance.Connector.ReRegisterOrder(order, window.Order); }
Dalam penangan peristiwa pembatalan permintaan, panggil saja metode CancelOrder dan kirimkan pesanan kepadanya, yang harus dibatalkan:
private void OrderGrid_OnOrderCanceling(Order order) { MainWindow.Instance.Connector.CancelOrder(order); }
Agar pesanan ditampilkan di OrderGrid, Anda harus berlangganan ke acara kemunculan pesanan baru dan acara kesalahan pendaftaran di konstruktor OrderGridControl, dan kemudian mentransfer acara ini ke OrderGrid:
public OrderGridControl() { InitializeComponent(); MainWindow.Instance.Connector.NewOrder += OrderGrid.Orders.Add; MainWindow.Instance.Connector.OrderRegisterFailed += OrderGrid.AddRegistrationFail; }
Di bagian tengah MainWindow, tambahkan panel OrderGridControl yang dibuat:
<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>
Jalankan untuk memeriksa:

Membuat Panel Transaksi Anda Sendiri
Dengan analogi dengan bilah alat, buat panel dari transaksi kita sendiri. Di folder XAML, tambahkan UserControl lain. Beri nama MyTradeGridControl. Tambahkan elemen MyTradeGrid ke dalamnya:
<UserControl x:Class="ShellNew.XAML.MyTradeGridControl" 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:MyTradeGrid x:Name="MyTradeGrid" /> </UserControl>
Dalam konstruktor MyTradeGridControl, kita perlu berlangganan ke acara kemunculan transaksi baru sendiri dan mentransfernya ke MyTradeGrid:
public MyTradeGridControl() { InitializeComponent(); MainWindow.Instance.Connector.NewMyTrade += MyTradeGrid.Trades.Add; }
Di bagian tengah MainWindow, tambahkan panel OrderGridControl yang dibuat:
<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>
Jalankan untuk memeriksa:

Membuat panel dengan strategi
Kami akan membuat panel strategi dengan cara yang sama seperti semua panel sebelumnya. Di folder XAML, tambahkan UserControl lain. Beri nama StrategyControl. Menggunakan LayoutControl, kami membagi layar menjadi dua bagian. Di sebelah kiri akan ada tab dengan grafik kandil dan tab dengan statistik strategi:
<dxlc:LayoutGroup Orientation="Vertical"> <dxlc:LayoutGroup View="Tabs" Name="StatistisAndChartLayoutGroup"> <dxlc:LayoutGroup Header="Chart"> <xaml:Chart x:Name="Chart" /> </dxlc:LayoutGroup> <dxlc:LayoutGroup Header="Statistic"> <dxlc:LayoutItem VerticalAlignment="Stretch" dxlc:LayoutControl.AllowHorizontalSizing="True" > <xaml:StatisticParameterGrid x:Name="StatisticParameterGrid" MaxHeight="2000"/> </dxlc:LayoutItem> <dxlc:LayoutItem VerticalAlignment="Stretch" > <xaml:EquityCurveChart x:Name="EquityCurveChart" /> </dxlc:LayoutItem> </dxlc:LayoutGroup> </dxlc:LayoutGroup> </dxlc:LayoutGroup>
Di sini, StatisticParameterGrid digunakan untuk menampilkan statistik strategi, dan EquityCurveChart digunakan untuk menampilkan grafik untung dan rugi. StatisticParameterGrid perlu menetapkan beberapa nilai MaxHeight, jika tidak aplikasi tidak akan mulai.
Sisi kanan akan mengonfigurasi properti strategi di PropertyGridEx. Tombol untuk memulai dan menghentikan strategi juga akan ditemukan:
<dxlc:LayoutGroup View="Group" dxlc:LayoutControl.AllowHorizontalSizing="True" dxlc:DockLayoutControl.Dock="Right" Orientation="Vertical"> <dxlc:LayoutItem VerticalAlignment="Stretch"> <xaml:PropertyGridEx x:Name="PropertyGridEx" /> </dxlc:LayoutItem> <dxlc:LayoutItem VerticalAlignment="Stretch" Height="20"> <dx:SimpleButton x:Name="StartStrategyButton" Content="Start strategy" ToolTip="Start strategy" Click="StartStrategyButton_Click" /> </dxlc:LayoutItem> <dxlc:LayoutItem VerticalAlignment="Stretch" Height="20"> <dx:SimpleButton x:Name="StopStrategyButton" Content="Stop strategy" ToolTip="Stop strategy" Click="StopStrategyButton_Click" /> </dxlc:LayoutItem> </dxlc:LayoutGroup>
Kode lengkap:
<UserControl x:Class="ShellNew.XAML.StrategyControl" 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:xaml="http://schemas.stocksharp.com/xaml" xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" mc:Ignorable="d"> <dxlc:LayoutControl> <dxlc:LayoutGroup Orientation="Vertical"> <dxlc:LayoutGroup View="Tabs" Name="StatistisAndChartLayoutGroup"> <dxlc:LayoutGroup Header="Chart"> <xaml:Chart x:Name="Chart" /> </dxlc:LayoutGroup> <dxlc:LayoutGroup Header="Statistic"> <dxlc:LayoutItem VerticalAlignment="Stretch" dxlc:LayoutControl.AllowHorizontalSizing="True" > <xaml:StatisticParameterGrid x:Name="StatisticParameterGrid" MaxHeight="2000"/> </dxlc:LayoutItem> <dxlc:LayoutItem VerticalAlignment="Stretch" > <xaml:EquityCurveChart x:Name="EquityCurveChart" /> </dxlc:LayoutItem> </dxlc:LayoutGroup> </dxlc:LayoutGroup> </dxlc:LayoutGroup> <dxlc:LayoutGroup View="Group" dxlc:LayoutControl.AllowHorizontalSizing="True" dxlc:DockLayoutControl.Dock="Right" Orientation="Vertical"> <dxlc:LayoutItem VerticalAlignment="Stretch"> <xaml:PropertyGridEx x:Name="PropertyGridEx" /> </dxlc:LayoutItem> <dxlc:LayoutItem VerticalAlignment="Stretch" Height="20"> <dx:SimpleButton x:Name="StartStrategyButton" Content="Start strategy" ToolTip="Start strategy" Click="StartStrategyButton_Click" /> </dxlc:LayoutItem> <dxlc:LayoutItem VerticalAlignment="Stretch" Height="20"> <dx:SimpleButton x:Name="StopStrategyButton" Content="Stop strategy" ToolTip="Stop strategy" Click="StopStrategyButton_Click" /> </dxlc:LayoutItem> </dxlc:LayoutGroup> </dxlc:LayoutControl> </UserControl>
Di konstruktor StrategyControl, atur Connector sebagai sumber data untuk PropertyGridEx, di hampir setiap kontrol kami melakukan tindakan serupa:
public StrategyControl() { InitializeComponent(); PropertyGridEx.SecurityProvider = MainWindow.Instance.Connector; PropertyGridEx.Portfolios = new PortfolioDataSource(MainWindow.Instance.Connector); }
Kita perlu entah bagaimana mentransfer strategi ke kendali kita. Untuk melakukan ini, buat metode BindStraregy di StrategyControl, yang akan mengambil strategi, menyimpan tautan ke dalamnya dalam variabel lokal, dan juga mengatur strategi di PropertyGridEx dan StatisticParameterGrid.
Menggunakan metode SetChart, kami mentransfer grafik lilin Chart ke strategi, setelah itu, Anda bisa mendapatkan strategi Chart menggunakan metode GetChart. Kami juga mengatur Konektor untuk strategi.
private Strategy _strategy; public void BindStraregy(Strategy strategy) { _strategy = strategy; PropertyGridEx.SelectedObject = strategy; StatisticParameterGrid.Parameters. AddRange(_strategy.StatisticManager.Parameters); _strategy.SetChart(Chart); _strategy.Connector = MainWindow.Instance.Connector; }
Ketika bekerja dengan jadwal untung dan rugi, harus dicatat bahwa strategi itu akan mulai dan berhenti, mungkin beberapa kali, puisi itu harus dibersihkan dengan setiap peluncuran strategi. Untuk ini, kita akan membuat metode ResetEquityCurveChart di mana kita pertama kali akan menghapus EquityCurveChart. Setelah itu kita perlu membuat elemen grafik untuk EquityCurveChart, mereka dapat menentukan nama, warna dan jenis garis.
Setelah itu, kami berlangganan acara perubahan PnL dari strategi dan dalam penangan acara ini menarik nilai baru pada bagan untung / rugi EquityCurveChart:
private void ResetEquityCurveChart() { EquityCurveChart.Clear(); var pnl = EquityCurveChart. CreateCurve("PNL", Colors.Green, ChartIndicatorDrawStyles.Area); var unrealizedPnL = EquityCurveChart. CreateCurve("unrealizedPnL", Colors.Black, ChartIndicatorDrawStyles.Line); var commissionCurve = EquityCurveChart .CreateCurve("commissionCurve", Colors.Red, ChartIndicatorDrawStyles.Line); _strategy.PnLChanged += () => { var data = new ChartDrawData(); data.Group(_strategy.CurrentTime) .Add(pnl, _strategy.PnL) .Add(unrealizedPnL, _strategy.PnLManager.UnrealizedPnL ?? 0) .Add(commissionCurve, _strategy.Commission ?? 0); EquityCurveChart.Draw(data); }; }
Pada pengendali event untuk mengklik tombol Start, kami akan memanggil metode ini. Dan kami juga akan mengatur ulang status strategi dan menjalankannya:
private void StartStrategyButton_Click(object sender, RoutedEventArgs e) { ResetEquityCurveChart(); _strategy.Reset(); _strategy.Start(); }
Dalam pengendali event untuk mengklik tombol Stop, kami akan menghentikan strateginya.
private void StopStrategyButton_Click (pengirim objek, RoutedEventArgs e):
{ _strategy.Stop(); }
Di bagian tengah MainWindow, tambahkan panel StrategyControl yang dibuat:
<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 Header="SimpleStrategyControl"> <myxaml:StrategyControl x:Name="SimpleStrategyControl" /> </dxlc:LayoutGroup> </dxlc:LayoutGroup>
Penciptaan strategi
Misalnya, pertimbangkan untuk membuat strategi kandil sederhana. Dia akan membeli jika lilin tumbuh (hijau) dan menjual jika lilin berkurang (merah).
Mari kita buat folder lain di proyek - kita akan menyimpan semua strategi kita di dalamnya. Di folder ini, buat kelas baru, sebut saja SimpleStrategy. Semua strategi S # harus diwarisi dari kelas dasar strategi Strategi.
public class SimpleStrategy : Strategy {}
Karena strategi kami menggunakan lilin, kami akan membuat properti publik CandleSeries dan dalam konstruktor strategi kami, kami akan menetapkannya ke nilai default.
public class SimpleStrategy : Strategy { public CandleSeries Series { get; set; } public SimpleStrategy() { Series = new CandleSeries(typeof(TimeFrameCandle), new Security(), TimeSpan.FromSeconds(15)) { BuildCandlesMode = MarketDataBuildModes.Build }; } }
Di sini kami menunjukkan bahwa lilin di CandleSeries adalah TimeFrameCandle, dengan interval 15 detik (TimeSpan.FromSeconds (15)). Untuk CandleSeries, Anda dapat menentukan mode pembuatan lilin BuildCandlesMode. Kami mengindikasikan bahwa lilin akan dibangun (MarketDataBuildModes.Build). Secara default, mereka akan dibangun dari kutu, tetapi Anda dapat menentukan tipe data lainnya.
Karena kami menjadikan CandleSeries sebagai properti publik, CandleSeries dapat dikustomisasi lebih lanjut dari PropertyGridEx yang dijelaskan dalam paragraf sebelumnya. Semua strategi memiliki metode yang dapat ditimpa, kita perlu mengganti metode OnStarted. Disebut sebelum memulai strategi dan memungkinkan Anda untuk mengaturnya sebagai kondisi awal.
protected override void OnStarted() { _connector = (Connector)Connector; Series.Security = Security; _connector .WhenCandlesFinished(Series) .Do(ProcessCandle) .Apply(this); _connector.SubscribeCandles(Series); base.OnStarted(); }
Di sini, untuk CandleSeries, kami mendefinisikan alat yang ditentukan dalam PropertyGridEx. Kemudian buat aturan untuk memproses lilin yang sudah jadi. Dalam aturan, tentukan metode yang akan memproses setiap lilin jadi - dalam kasus kami, ini adalah metode ProcessCandle. Ini akan dijelaskan nanti. Setelah semuanya diatur, kami berlangganan tampilan lilin di CandleSeries di konektor melalui metode SubscribeCandles. Dalam kasus kami, metode ProcessCandle berisi logika utama strategi:
private void ProcessCandle(Candle candle) { if (!IsRealTime(candle)) return; if (candle.OpenPrice < candle.ClosePrice && Position <= 0) { RegisterOrder(this.BuyAtMarket(Volume + Math.Abs(Position))); } else if (candle.OpenPrice > candle.ClosePrice && Position >= 0) { RegisterOrder(this.SellAtMarket(Volume + Math.Abs(Position))); } }
Pertama-tama, kita perlu menentukan apakah lilin sedang dibangun secara real time atau historis. Jika lilin itu historis, maka kita abaikan saja. Tidak semua strategi memerlukan ini, misalnya, strategi berdasarkan kacamata tidak memerlukan ini, karena kacamata selalu berjalan secara real time. Tidak ada cara universal untuk menentukan apakah lilin itu "real time" atau historis, dan dalam setiap strategi masalah ini harus diselesaikan secara independen, tergantung pada persyaratan. Dalam hal ini, kami hanya akan membandingkan waktu lilin ditutup dengan waktu di konektor dan jika tidak melebihi kelambatan tertentu, maka lilin akan memiliki status waktu-nyata.
private bool IsRealTime(Candle candle) { return (Connector.CurrentTime - candle.CloseTime).TotalSeconds < 10; }
Selanjutnya, kita melihat jenis lilin apa itu, dan apa posisi strategi saat ini. Jika lilin tumbuh, maka dengan posisi sama dengan 0, kami akan membuka posisi dengan urutan pasar untuk volume yang ditentukan oleh kami di PropertyGridEx. Jika lilin tumbuh dan posisinya kurang dari 0, maka kami "membalikkan" posisinya:
if (candle.OpenPrice < candle.ClosePrice && Position <= 0) { RegisterOrder(this.BuyAtMarket(Volume + Math.Abs(Position))); }
Kami melakukan yang sebaliknya untuk lilin yang memudar:
else if (candle.OpenPrice > candle.ClosePrice && Position >= 0) { RegisterOrder(this.SellAtMarket(Volume + Math.Abs(Position))); }
Saat ini, strategi kami siap untuk bekerja. Itu harus diteruskan ke SimpleStrategyControl, yang kami buat pada paragraf sebelumnya menggunakan metode BindStraregy. Kami melakukan ini di konstruktor MainWindow segera setelah menginisialisasi komponen MainWindow.
SimpleStrategyControl.BindStraregy(new SimpleStrategy());
Jalankan untuk memeriksa:


Strateginya berhasil, kesepakatan dibuat, tetapi sejauh ini tidak ada lilin dan kesepakatan pada grafik.
Menambahkan lilin dan penawaran ke bagan dari strategi
Di bagian tentang panel strategi menggunakan metode SetChart, kami mengkhianati bagan lilin Chart ke dalam strategi. Dalam metode strategi OnStarted, kami memeriksa apakah Bagan diatur untuk strategi dan jika sudah diatur, maka kami menginisialisasi bagan, dan juga berlangganan ke peristiwa kemunculan transaksi baru sendiri dan perubahan lilin.
protected override void OnStarted() { _connector = (Connector)Connector; if (this.GetChart() is Chart chart) { InitChart(chart); NewMyTrade += DrawMyTrade; _connector.CandleSeriesProcessing += CandleSeriesProcessing; } Series.Security = Security; _connector .WhenCandlesFinished(Series) .Do(ProcessCandle) .Apply(this); _connector.SubscribeCandles(Series); base.OnStarted(); }
Metode inisialisasi bagan InitChart:
private ChartCandleElement _chartCandleElement; private ChartTradeElement _tradesElem; private Chart _chart; private void InitChart(Chart chart) { _chart = chart; _chart.GuiSync(() => { _chart.ClearAreas(); var candlesArea = new ChartArea(); _chart.AddArea(candlesArea); _chartCandleElement = new ChartCandleElement(); _chart.AddElement(candlesArea, _chartCandleElement); _tradesElem = new ChartTradeElement { FullTitle = "Trade" }; _chart.AddElement(candlesArea, _tradesElem); }); }
Di sini kita menyimpan tautan ke Bagan dalam variabel lokal. Kami membersihkan jadwalnya. Kami juga membuat dan mentransfer ke elemen bagan bagan untuk lilin dan penawaran. Konstruksi _chart.GuiSync (() => {...}); diperlukan untuk menginisialisasi jadwal di utas utama.
CandleSeriesProcessing chart untuk menggambar lilin pada grafik:
private void CandleSeriesProcessing(CandleSeries candleSeries, Candle candle) { var data = new ChartDrawData(); data.Group(candle.OpenTime) .Add(_chartCandleElement, candle); _chart.Draw(data); }
Di sini kita mendapatkan lilin dari acara CandleSeriesProcessing konektor, buat ChartDrawData untuk menampilkannya pada grafik. Kami menunjukkan data waktu. Grup (lilin. Buka Waktu), menunjukkan bahwa lilin harus ditambahkan ke elemen lilin dari bagan. Tambahkan (_chartCandleElement, lilin); Dan kami menunjukkan bahwa gambar perlu menggambar data baru.
Kami melakukan tindakan serupa untuk transaksi:
public void DrawMyTrade(MyTrade myTrade) { var data = new ChartDrawData(); data.Group(myTrade.Trade.Time) .Add(_tradesElem, myTrade); _chart.Draw(data); }
Jalankan untuk memeriksa:

Kesimpulan singkat
Untuk membuat aplikasi yang terlihat rumit dan profesional, Anda tidak perlu menghabiskan banyak waktu. Selama beberapa jam kami telah membuat aplikasi lengkap dengan kemampuan untuk mengkonfigurasi, menampilkan perdagangan langsung dan perdagangan algoritmik.
Jangan takut untuk mencoba dan membuat program perdagangan Anda sendiri. Kami harap artikel ini akan membantu Anda untuk merasa nyaman dalam hal ini.
Penulis : Ivan Zalutsky