コンテンツにスキップ

プラグインコードサンプル

このページでは、cTraderでの手動またはアルゴリズム取引のためのツールを含む、ネイティブプラグインを作成するためのいくつかのPythonおよびC#コード例を提供します。

プラグインサンプルリポジトリ

さまざまなUI領域や機能のための実行可能なテンプレートを含む包括的なプラグインコードサンプルは、GitHubの別々のPythonおよびC#リポジトリで利用可能です。

ヒント

C#およびPythonプラグインでカスタマイズ可能なパラメータを使用して、より高い柔軟性を実現してください。 C#プラグインのカスタマイズ可能なパラメータは、通常のC#コードで宣言されますが、Pythonプラグインでは、カスタマイズ可能なパラメータを.csファイルで宣言する必要があります。

チャートフレームにウェブサイトを表示する

以下のプラグインは、cTraderストアのウェブサイトを別のチャートフレーム内に表示します。

 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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class ForumExample : Plugin
    {
        private WebView _cTraderWebView;

        protected override void OnStart()
        {
            _cTraderWebView = new WebView();
            _cTraderWebView.Loaded += DisplayForum;

            var webViewFrame = ChartManager.AddCustomFrame("Forum");
            webViewFrame.Child = _cTraderWebView;
            webViewFrame.ChartContainer.Mode = ChartMode.Multi;
            webViewFrame.Attach();
        }


        private void DisplayForum(WebViewLoadedEventArgs args)
        {
            _cTraderWebView.NavigateAsync("https://ctrader.com/forum");
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import clr
clr.AddReference("cAlgo.API")

from cAlgo.API import *

class ForumExample():
    def on_start(self):
        self.cTraderWebView = WebView()
        self.cTraderWebView.Loaded += self.display_forum

        webViewFrame = api.ChartManager.AddCustomFrame("Forum")
        webViewFrame.Child = self.cTraderWebView
        webViewFrame.ChartContainer.Mode = ChartMode.Multi
        webViewFrame.Attach()

    def display_forum(self, args):
        self.cTraderWebView.NavigateAsync("https://ctrader.com/forum")

ローカルストレージに情報を書き込む

以下のプラグインは、1分ごとにアカウントの総損益(P&L)をローカルストレージ機能を使用してファイルに保存し、現在のタイムスタンプをファイル名とします。 また、同じ情報をアクティブ通貨ペアパネル(ASP)の別セクションに表示します。

 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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class GrossPnL : Plugin
    {
        private TextBlock _textBlock = new TextBlock
        {
            Text = "Starting...",
            FontSize = 15,
            FontWeight = FontWeight.ExtraBold,
            TextAlignment = TextAlignment.Center,
            Padding = new Thickness(5, 5, 5, 5),
        };

        protected override void OnStart()
        {
            var aspBlock = Asp.SymbolTab.AddBlock("Gross P&L");
            aspBlock.Child = _textBlock;
            Timer.Start(TimeSpan.FromMinutes(1));
        }

        protected override void OnTimer()
        {
            var timestamp = Server.TimeInUtc;

            string result = timestamp.ToString("HH mm ss");

            LocalStorage.SetString($"{result}", $"{Account.UnrealizedGrossProfit}", LocalStorageScope.Device);

            _textBlock.Text = $"{result}: {Account.UnrealizedGrossProfit}";
        }

    }
}
 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
import clr
clr.AddReference("cAlgo.API")

from cAlgo.API import *

class GrossPnL():
    def on_start(self):
        self.textBlock = TextBlock()
        self.textBlock.Text = "Starting..."
        self.textBlock.FontSize = 15
        self.textBlock.FontWeight = FontWeight.ExtraBold
        self.textBlock.TextAlignment = TextAlignment.Center
        self.textBlock.Padding = Thickness(5, 5, 5, 5)

        aspBlock = api.Asp.SymbolTab.AddBlock("Gross P&L")
        aspBlock.Child = self.textBlock

        api.Timer.Start(60)

    def on_timer(self):
        timestamp = api.Server.TimeInUtc

        result = timestamp.ToString("HH mm ss")

        api.LocalStorage.SetString(result, f"{api.Account.UnrealizedGrossProfit}", LocalStorageScope.Device)

        self.textBlock.Text = f"{result}: {api.Account.UnrealizedGrossProfit}"

カスタムコントロールを持つ別ウィンドウを表示する

以下のプラグインは、デタッチされたウィンドウにカスタムボタンを追加します。 クリックすると、このコントロールは、すべてのオープンポジションに利食いレベルを追加しますが、以前に設定された利食いがない場合のみです。

 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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class ProtectionPlugin : Plugin
    {

        private Button _buttonAddTakeProfit;
        private Window _window;

        protected override void OnStart()
        {
            _buttonAddTakeProfit = new Button
            {
                BackgroundColor = Color.SeaGreen,
                Height = 50,
                Text = "Add Take Profit"
            };

            _buttonAddTakeProfit.Click += AddTakeProfit;
            _window = new Window
            {
                Height = 150,
                Width = 150,
                Padding = new Thickness(5, 10, 10, 5),
            };

            _window.Child = _buttonAddTakeProfit;
            _window.Show();
        }

        private void AddTakeProfit(ButtonClickEventArgs args)
        {
            foreach (var position in Positions)
            {
                if (position.TakeProfit is null)
                {
                    position.ModifyTakeProfitPips(20);
                }
            }
        }
    }
}
 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
import clr
clr.AddReference("cAlgo.API")

from cAlgo.API import *

class ProtectionPlugin():
    def on_start(self):
        self.buttonAddTakeProfit = Button()
        self.buttonAddTakeProfit.BackgroundColor = Color.SeaGreen
        self.buttonAddTakeProfit.Height = 50
        self.buttonAddTakeProfit.Text = "Add Take Profit"

        self.buttonAddTakeProfit.Click += self.On_add_take_profit_click

        self.window = Window()
        self.window.Height = 150
        self.window.Width = 150
        self.window.Padding = Thickness(5, 10, 10, 5)

        self.window.Child = self.buttonAddTakeProfit
        self.window.Show()

    def On_add_take_profit_click(self, args):
        for position in api.Positions:
            if position.TakeProfit is None:
                position.ModifyTakeProfitPips(20)

トレードウォッチディスプレイにバー価格に関する情報を表示する

このプラグインは、ビルドされるとトレードウォッチパネルに新しいタブを追加します。 このタブには、m1時間枠と「USDJPY」通貨ペアの最後に知られたバー価格に関する情報を表示する2×2のグリッドが含まれています。

 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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class BarInfo : Plugin
    {
        private Grid _grid;
        private TextBlock _lowBlock;
        private TextBlock _highBlock;
        private TextBlock _closeBlock;
        private TextBlock _openBlock;
        private Bars _bars;

        protected override void OnStart()
        {
            _bars = MarketData.GetBars(TimeFrame.Minute, "USDJPY");
            _grid = new Grid(2, 2)
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                ShowGridLines = true,
                Height = 150,
                Width = 150,
            };

            _lowBlock = new TextBlock
            {
                Text = $"Low: {_bars.LowPrices.LastValue}",
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
            };

            _highBlock = new TextBlock
            {
                Text = $"High: {_bars.HighPrices.LastValue}",
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
            };

            _closeBlock = new TextBlock
            {
                Text = $"Low: {_bars.ClosePrices.LastValue}",
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
            };

            _openBlock = new TextBlock
            {
                Text = $"Open: {_bars.OpenPrices.LastValue}",
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
            };

            _grid.AddChild(_lowBlock, 0, 0);
            _grid.AddChild(_highBlock, 0, 1);
            _grid.AddChild(_openBlock, 1, 0);
            _grid.AddChild(_closeBlock, 1, 1);

            var TradeWatchTab = TradeWatch.AddTab("Bar Info");
            TradeWatchTab.Child = _grid;
            TradeWatchTab.IsSelected = true;
            _bars.Tick += OnBarsTick;
        }

        private void OnBarsTick(BarsTickEventArgs args)
        {
            _lowBlock.Text = _bars.LowPrices.LastValue.ToString();
            _highBlock.Text = _bars.HighPrices.LastValue.ToString();
            _openBlock.Text = _bars.HighPrices.LastValue.ToString();
            _closeBlock.Text = _bars.HighPrices.LastValue.ToString();
        }
    }
}
 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
import clr
clr.AddReference("cAlgo.API")

from cAlgo.API import *

class BarInfo():
    def on_start(self):
        tradeWatchTab = api.TradeWatch.AddTab("Bar Info")
        tradeWatchTab.IsSelected = True

        grid = Grid(2, 2)
        grid.HorizontalAlignment = HorizontalAlignment.Center
        grid.VerticalAlignment = VerticalAlignment.Center
        grid.ShowGridLines = True
        grid.Height = 150
        grid.Width = 150

        self.bars = api.MarketData.GetBars(TimeFrame.Minute, "USDJPY")

        self.lowBlock = self.get_text_block(f"Low: {self.bars.LowPrices.LastValue}")
        self.highBlock = self.get_text_block(f"High: {self.bars.HighPrices.LastValue}")
        self.openBlock = self.get_text_block(f"Open: {self.bars.OpenPrices.LastValue}")
        self.closeBlock = self.get_text_block(f"Close: {self.bars.ClosePrices.LastValue}")

        grid.AddChild(self.lowBlock, 0, 0)
        grid.AddChild(self.highBlock, 0, 1)
        grid.AddChild(self.openBlock, 1, 0)
        grid.AddChild(self.closeBlock, 1, 1)

        tradeWatchTab.Child = grid

        self.bars.Tick += self.on_bars_Tick

    def on_bars_Tick(self, args):
        self.lowBlock.Text = f"Low: {self.bars.LowPrices.LastValue}"
        self.highBlock.Text = f"High: {self.bars.HighPrices.LastValue}"
        self.openBlock.Text = f"Open: {self.bars.OpenPrices.LastValue}"
        self.closeBlock.Text = f"Close: {self.bars.ClosePrices.LastValue}"

    def get_text_block(self, text):
        textblock = TextBlock()
        textblock.Text = text
        textblock.HorizontalAlignment = HorizontalAlignment.Center
        textblock.VerticalAlignment = VerticalAlignment.Center
        return textblock

アクティブフレームの変更に反応する

以下のプラグインは、現在アクティブなChartFrameを検出します。 ASP内のカスタムブロックで、このプラグインは、このChartFrameが開かれている通貨ペアの現在の価格と約1か月前の価格とのパーセンテージ差を表示します。

 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
using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class ActiveFrameChangedSample : Plugin
    {

        // Declaring the necessary UI elements
        private Grid _grid;
        private TextBlock _percentageTextBlock;
        private Frame _activeFrame;

        protected override void OnStart()
        {
            // Initialising the grid and the TextBlock
            // displaying the percentage difference
            _grid = new Grid(1, 1);
            _percentageTextBlock = new TextBlock
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                Text = "Monthly change: ",
            };

            _grid.AddChild(_percentageTextBlock, 0, 0);

            // Initialising a new block inside the ASP
            // and adding the grid as a child
            var block = Asp.SymbolTab.AddBlock("Monthly Change Plugin");

            block.Child = _grid;

            // Attaching a custom handler to the
            // ActiveFrameChanged event
            ChartManager.ActiveFrameChanged += ChartManager_ActiveFrameChanged;
        }

        private void ChartManager_ActiveFrameChanged(ActiveFrameChangedEventArgs obj)
        {
            if (obj.NewFrame is ChartFrame)
            {
                // Casting the Frame into a ChartFrame
                var newChartFrame = obj.NewFrame as ChartFrame;

                // Attaining market data for the symbol for which
                // the currently active ChartFrame is opened
                var dailySeries = MarketData.GetBars(TimeFrame.Daily, newChartFrame.Symbol.Name);

                // Calculating the monthly change and displaying it
                // inside the TextBlock
                double monthlyChange = (newChartFrame.Symbol.Bid - dailySeries.ClosePrices[dailySeries.ClosePrices.Count - 30]) / 100;
                _percentageTextBlock.Text = $"Monthly change: {monthlyChange}";
            }
        }
    }
}
 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
import clr
clr.AddReference("cAlgo.API")

from cAlgo.API import *

class ActiveFrameChangedSample():
    def on_start(self):
        # Initialising the grid and the TextBlock displaying the percentage difference
        grid = Grid(1, 1)
        self.percentageTextBlock = TextBlock()
        self.percentageTextBlock.HorizontalAlignment = HorizontalAlignment.Center
        self.percentageTextBlock.VerticalAlignment = VerticalAlignment.Center
        self.percentageTextBlock.Text = "Monthly change: "

        grid.AddChild(self.percentageTextBlock, 0, 0)

        # Initialising a new block inside the ASP and adding the grid as a child
        block = api.Asp.SymbolTab.AddBlock("Monthly Change Plugin")
        block.Child = grid

        # Attaching an event handler to the ActiveFrameChanged event
        api.ChartManager.ActiveFrameChanged += self.on_chart_manager_active_frame_changed

    def on_chart_manager_active_frame_changed(self, args):
        if args.NewFrame is None or isinstance(args.NewFrame.__implementation__, ChartFrame) == False:
            return

        newChartFrame = ChartFrame(args.NewFrame)

        # Attaining market data for the symbol for which the currently active ChartFrame is opened
        dailySeries = api.MarketData.GetBars(TimeFrame.Daily, newChartFrame.Symbol.Name)

        # Calculating the monthly change and displaying it inside the TextBlock
        monthlyChange = (newChartFrame.Symbol.Bid - dailySeries.ClosePrices[dailySeries.ClosePrices.Count - 30]) / 100
        self.percentageTextBlock.Text = f"Monthly change: {monthlyChange}"

Image title