Zum Inhalt

TradeWatch Tab Sample

Übersicht

Das TradeWatch Tab Sample Plugin fügt eine neue Registerkarte zur Handelsüberwachung hinzu, die Live-Statistiken und Handelsaktionen für das Symbol im aktiven Chart anzeigt. Es bietet die folgenden Hauptfunktionalitäten:

  • Fügt das Plugin automatisch als neue Registerkarte in der Handelsüberwachung hinzu.
  • Zeigt Live-Handelsstatistiken an.
  • Ermöglicht die Ausführung von Markt-Orders für das aktuelle Chart-Symbol.
  • Aktualisiert sich automatisch, wenn sich das aktive Chart-Symbol ändert.

Das Plugin läuft über die dedizierte Registerkarte der Handelsüberwachung, die den aktiven Chart widerspiegelt. Es bleibt aktiv, während cTrader Windows oder Mac läuft, und gibt automatisch Systemressourcen frei, wenn es gestoppt wird.

Plugin-Erstellung

Erfahren Sie, wie Sie Plugins erstellen, entweder mit C# oder Python, in unseren schrittweisen Anleitungen.

Der Code des TradeWatch Tab Sample Plugins ist in unseren öffentlichen C#- und Python-Repositorys verfügbar. Derselbe Code wird als Vorlage im Algorithmen-Erstellungsassistenten in cTrader Windows oder Mac bereitgestellt, oder Sie können einfach den folgenden Ausschnitt kopieren und verwenden:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using cAlgo.API;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class MyTradeWatchTabSample1 : Plugin
    {
        private SymbolStatsControl _symbolStatsControl;
        private TradeControl _tradeControl;

        protected override void OnStart()
        {
            var tab = TradeWatch.AddTab("Active Chart Symbol Stats");

            var panel = new StackPanel
                {Orientation = Orientation.Vertical, HorizontalAlignment = HorizontalAlignment.Center};

            _symbolStatsControl = new SymbolStatsControl {Margin = 10};
            _tradeControl = new TradeControl {Margin = 10};

            panel.AddChild(_symbolStatsControl);
            panel.AddChild(_tradeControl);

            tab.Child = panel;

            SetSymbolStats();

            _tradeControl.Trade += TradeControlOnTrade;
            ChartManager.ActiveFrameChanged += _ => SetSymbolStats();
        }

        private void TradeControlOnTrade(object sender, TradeEventArgs e)
        {
            ExecuteMarketOrder(e.TradeType, e.SymbolName, e.Volume);
        }

        private void SetSymbolStats()
        {
            if (ChartManager.ActiveFrame is not ChartFrame chartFrame)
                return;

            _tradeControl.Symbol = chartFrame.Symbol;
            _symbolStatsControl.Symbol = chartFrame.Symbol;
        }
    }
}
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
import clr
clr.AddReference("cAlgo.API")

from cAlgo.API import *

class TradeWatchTabSample():
    def on_start(self):
        tab = api.TradeWatch.AddTab("Active Chart Symbol Stats")

        panel = StackPanel()
        panel.Orientation = Orientation.Vertical
        panel.HorizontalAlignment = HorizontalAlignment.Center

        self.symbolStatsControl = SymbolStatsControl()
        self.symbolStatsControl.Margin = Thickness(10)
        self.tradeControl = TradeControl(self.on_trade)
        self.tradeControl.Margin = Thickness(10)

        panel.AddChild(self.symbolStatsControl.content)
        panel.AddChild(self.tradeControl.content)

        tab.Child = panel

        self.set_symbol_stats()

        api.ChartManager.ActiveFrameChanged += lambda _ : self.set_symbol_stats()

    def on_trade(self, args):
        api.ExecuteMarketOrder(args["tradeType"], args["symbolName"], args["volume"])

    def set_symbol_stats(self):
        if api.ChartManager.ActiveFrame is None or isinstance(api.ChartManager.ActiveFrame.__implementation__, ChartFrame) == False:
            return;

        chartFrame = ChartFrame(api.ChartManager.ActiveFrame)
        self.tradeControl.set_symbol(chartFrame.Symbol)
        self.symbolStatsControl.set_symbol(chartFrame.Symbol)


class SymbolStatsControl():
    def __init__(self):
        self.__symbol__ = None
        self.content = StackPanel()
        self.content.Orientation = Orientation.Vertical

        self.symbolNameTextBlock = self.get_text_block()
        self.symbolPriceTextBlock = self.get_text_block()

        self.content.AddChild(self.wrap_in_horizontal_panel(self.symbolNameTextBlock, self.symbolPriceTextBlock))

        grid = Grid(10, 2)

        self.spreadTextBlock = self.get_text_block()

        grid.AddChild(self.get_text_block("Spread"), 0, 0)
        grid.AddChild(self.spreadTextBlock, 0, 1)

        self.unrealizedNetProfitTextBlock = self.get_text_block()

        grid.AddChild(self.get_text_block("Unrealized Net Profit"), 1, 0)
        grid.AddChild(self.unrealizedNetProfitTextBlock, 1, 1)

        self.unrealizedGrossProfitTextBlock = self.get_text_block()

        grid.AddChild(self.get_text_block("Unrealized Gross Profit"), 2, 0)
        grid.AddChild(self.unrealizedGrossProfitTextBlock, 2, 1)

        self.commissionTextBlock = self.get_text_block()

        grid.AddChild(self.get_text_block("Commission"), 3, 0)
        grid.AddChild(self.commissionTextBlock, 3, 1)

        self.content.AddChild(grid);

    def get_text_block(self, text = None):
        textBlock = TextBlock()
        textBlock.Margin = Thickness(3)
        textBlock.FontSize = 20
        textBlock.FontWeight = FontWeight.Bold
        textBlock.FontFamily = "Calibri"
        textBlock.Text = text
        return textBlock

    def wrap_in_horizontal_panel(self, *args):
        panel = StackPanel()
        panel.Orientation = Orientation.Horizontal

        for control in args:
            if control.Margin == Thickness(0):
                control.Margin = 3
            panel.AddChild(control)

        return panel

    def get_symbol(self):
        return self.__symbol__

    def set_symbol(self, symbol):
        if symbol is None or symbol == self.__symbol__:
            return

        self.update(symbol)

    def update(self, newSymbol):
        previousSymbol = self.__symbol__;
        self.__symbol__ = newSymbol;

        self.symbolNameTextBlock.Text = f"{newSymbol.Name} ({newSymbol.Description})"
        self.symbolPriceTextBlock.Text = f"Bid: {newSymbol.Bid}, Ask: {newSymbol.Ask}"
        self.spreadTextBlock.Text = f"{self.get_spread_in_pips(newSymbol)} Pips"
        self.unrealizedNetProfitTextBlock.Text = str(newSymbol.UnrealizedNetProfit)
        self.unrealizedGrossProfitTextBlock.Text = str(newSymbol.UnrealizedGrossProfit)
        self.commissionTextBlock.Text = f"{newSymbol.Commission} {newSymbol.CommissionType}"

        if previousSymbol is not None: 
            previousSymbol.Tick -= self.on_symbol_tick

        newSymbol.Tick += self.on_symbol_tick

    def get_spread_in_pips(self, symbol):
        return (symbol.Spread * pow(10, symbol.Digits)) / (symbol.PipSize / symbol.TickSize);

    def on_symbol_tick(self, args):
        self.symbolPriceTextBlock.Text = f"Bid: {args.Bid}, Ask: {args.Ask}"
        self.spreadTextBlock.Text = f"{self.get_spread_in_pips(args.Symbol)} Pips"
        self.unrealizedNetProfitTextBlock.Text = str(args.Symbol.UnrealizedNetProfit)
        self.unrealizedGrossProfitTextBlock.Text = str(args.Symbol.UnrealizedGrossProfit)

class TradeControl():
    def __init__(self, on_trade):
        self.__symbol__ = None
        self.__on_trade__ = on_trade
        self.content = Grid(10, 2)

        self.volumeTextBox = TextBox()
        self.volumeTextBox.MinWidth = 200
        self.volumeTextBox.FontFamily = "Calibri"
        self.volumeTextBox.FontSize = 20
        self.volumeTextBox.FontWeight = FontWeight.Bold
        self.volumeTextBox.Margin = Thickness(3)

        self.content.AddChild(self.get_text_block("Volume"), 0, 0)
        self.content.AddChild(self.volumeTextBox, 0, 1);

        self.tradeTypeComboBox = ComboBox()
        self.tradeTypeComboBox.MinWidth = 200
        self.tradeTypeComboBox.FontFamily = "Calibri"
        self.tradeTypeComboBox.FontSize = 20
        self.tradeTypeComboBox.FontWeight = FontWeight.Bold
        self.tradeTypeComboBox.Margin = Thickness(3)

        self.tradeTypeComboBox.AddItem("Buy")
        self.tradeTypeComboBox.AddItem("Sell")

        self.tradeTypeComboBox.SelectedItem = "Buy"

        tradeTypeTextBlock = self.get_text_block("Trade Type")

        tradeTypeTextBlock.VerticalAlignment = VerticalAlignment.Center

        self.content.AddChild(tradeTypeTextBlock, 1, 0)
        self.content.AddChild(self.tradeTypeComboBox, 1, 1)

        executeButton = Button()
        executeButton.Text = "Execute"
        executeButton.FontFamily = "Calibri"
        executeButton.BackgroundColor = Color.Red

        executeButton.Click += self.on_execute_button_click

        self.content.AddChild(executeButton, 2, 0, 1, 2);

    def get_text_block(self, text = None):
        textBlock = TextBlock()
        textBlock.Margin = Thickness(3)
        textBlock.FontSize = 20
        textBlock.FontWeight = FontWeight.Bold
        textBlock.FontFamily = "Calibri"
        textBlock.Text = text
        return textBlock

    def get_symbol(self):
        return self.__symbol__

    def set_symbol(self, symbol):
        if symbol is None or symbol == self.__symbol__:
            return

        self.__symbol__ = symbol
        self.volumeTextBox.Text = str(self.__symbol__.VolumeInUnitsMin)

    def on_execute_button_click(self, args):
        if self.__symbol__ is None:
            return;

        volume = float(self.volumeTextBox.Text)
        tradeType = TradeType.Buy if self.tradeTypeComboBox.SelectedItem == "Buy" else TradeType.Sell

        self.__on_trade__({"volume": volume, "tradeType": tradeType, "symbolName": self.__symbol__.Name});

Anpassungsoptionen

Dieses Plugin verknüpft den Echtzeit-Chart-Kontext mit der Trade-Ausführung über das Panel Handelsüberwachung. Die folgende Tabelle beschreibt seine Hauptkomponenten und deren Funktionen:

Parameter Beschreibung Mögliche Werte
TradeWatch.AddTab Registerkartenkonfiguration für das Panel Handelsüberwachung. Active chart symbol stats
StackPanel.Orientation Definiert die Stapelrichtung der UI-Elemente. Vertical oder horizontal
HorizontalAlignment Definiert die horizontale Ausrichtung des Panels in der Registerkarte. Center, left, right, usw.
SymbolStatsControl.Margin Legt den Rand um das Symbolstatistik-Kontrollelement fest. 10, 12, 14, usw.
TradeControl.Margin Legt den Rand um das Trade-Kontrollelement fest. 10, 12, 14, usw.
SymbolStatsControl.Symbol Bindet das Symbolstatistik-Steuerelement an ein bestimmtes Chart-Symbol. chartframe.symbol, eurusd, gbpjpy, etc.
TradeControl.Symbol Verknüpft TradeControl mit einem Symbol für Handelsaktionen. chartframe.symbol, eurusd, gbpjpy, etc.
ChartManager.ActiveFrameChanged Ereignis, das Symbolstatistik-Aktualisierungen auslöst, wenn sich der Chart-Frame ändert. _ => setsymbolstats()
TradeControl.Trade Ereignis, das ausgelöst wird, wenn eine Handelsaktion über das Bedienfeld durchgeführt wird. tradecontrolontrade oder null
ExecuteMarketOrder Führt eine Transaktion aus, wenn aufgerufen. e.tradetype, e.symbolname, e.volume

Anwendungsfälle

Das TradeWatch Tab Sample-Plugin bietet eine unkomplizierte Möglichkeit, cTrader zu erweitern, indem es den Echtzeit-Chart-Kontext mit der Handelsausführung verknüpft. Es unterstützt praktische Anwendungen, die Handelsabläufe optimieren. Nachfolgend finden Sie praktische Anwendungsfälle, die zeigen, wie das Plugin das Handelserlebnis verbessern kann.

Anwendungsfall Szenario Wert
Symbolsperre Legen Sie fest, dass die Plugin-Registerkarte immer ein festes Symbol wie EURUSD anzeigt, anstatt sich bei jedem Chartwechsel zu aktualisieren. Hilft Ihnen, ein Instrument konsistent zu verfolgen und zu handeln, unabhängig vom Chart-Kontext.
Chart-verknüpftes Handelspanel Halten Sie das Plugin mit dem aktiven Chart-Symbol synchronisiert, um immer relevante Statistiken und Handelsoptionen anzuzeigen. Ermöglicht es Ihnen, schnell auf Chart-Analysen zu reagieren, ohne Tools oder Panels zu wechseln.
Transaktion mit festem Volumen Passen Sie das Standardvolumen im Order-Handler auf eine feste oder bevorzugte Lot-Größe an. Vereinfacht die Ausführung, indem die Notwendigkeit entfällt, das Volumen jedes Mal anzupassen.
Schnellaktions-Terminal Positionieren Sie die Steuerelemente horizontal neu und richten Sie sie mittig aus, um ein optimiertes Handelspanel zu erhalten. Ermöglicht schnelleren Zugriff auf Statistiken und Handels-Buttons in kompakten Setups.

Zusammenfassung

TradeWatch Tab Sample vereinfacht Handelsabläufe, indem es Echtzeitstatistiken und Handelssteuerelemente in einer eigenen Registerkarte innerhalb der Handelsüberwachung kombiniert. Es wird automatisch mit dem aktiven Chart aktualisiert, und sein Layout, Symbolverhalten und Handelseinstellungen können an verschiedene Handelsstile oder Schwerpunktbereiche angepasst werden.

Weitere Entwicklungsdetails finden Sie in unserer Plugin-Dokumentation.