コンテンツにスキップ

コントロール

コントロールは、cBot、インジケーター、プラグインを含む特定のインタラクションを可能にします。 以下のガイドを使用して、チャート上に直接基本的および高度なUIコントロールを簡単に作成できます。

ボタン、テキストブロック、テキストボックス、形状などの人気のあるコントロールを表すいくつかの組み込みクラスがあります。 ただし、カスタムコントロールを作成することもできます。

次の例を考えてみてください。

 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
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter(DefaultValue = "Click Me")]
        public string Text { get; set; }

        [Parameter(DefaultValue = HorizontalAlignment.Center)]
        public HorizontalAlignment HorizontalAlignment { get; set; }

        [Parameter(DefaultValue = VerticalAlignment.Center)]
        public VerticalAlignment VerticalAlignment { get; set; }

        protected override void Initialize()
        {
            var button = new Button
            {
                Text = Text,
                HorizontalAlignment = HorizontalAlignment,
                VerticalAlignment = VerticalAlignment
            };

            button.Click += Button_Click;

            Chart.AddControl(button);
        }

        private void Button_Click(ButtonClickEventArgs obj)
        {
            obj.Button.Text = "You clicked me, thanks";
        }

        public override void Calculate(int index)
        {
        }
    }
}

上記のインジケーターをビルドしてインスタンスを作成すると、チャートの中央に灰色の Click me ボタンが表示されます。

コントロールとチャートオブジェクトの違い

以前のセクション では、すでにチャートオブジェクトについて説明しました。 コントロールは、ユーザーがcBotやインジケーターとインタラクションすることを可能にします。 逆に、チャートオブジェクトは、取引チャートや分離されたインジケーター出力ウィンドウに何かを描画する機会を提供します。

チャートコントロールは ControlBase クラスから派生し、チャートオブジェクトは ChartObject クラスから派生します。

チャートコントロールは、異なる配置オプションを使用して静的に配置されます。 チャートオブジェクトも同じ方法で配置できますが、特定のXおよびY座標に応じて動的に位置を変更することもできます。

同様に、チャートオブジェクトと同様に、チャートコントロールはメインチャートとインジケーター出力ウィンドウ(存在する場合)の両方に追加できます。 このような配置の例を以下に示します:

 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
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = false, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter(DefaultValue = "Click Me")]
        public string Text { get; set; }

        [Parameter(DefaultValue = HorizontalAlignment.Center)]
        public HorizontalAlignment HorizontalAlignment { get; set; }

        [Parameter(DefaultValue = VerticalAlignment.Center)]
        public VerticalAlignment VerticalAlignment { get; set; }

        protected override void Initialize()
        {
            var button = new Button
            {
                Text = Text,
                HorizontalAlignment = HorizontalAlignment,
                VerticalAlignment = VerticalAlignment
            };

            button.Click += Button_Click;

            IndicatorArea.AddControl(button);
        }

        private void Button_Click(ButtonClickEventArgs obj)
        {
            obj.Button.Text = "You clicked me, thanks";
        }

        public override void Calculate(int index)
        {
        }
    }
}

インジケーターインスタンスを作成した後、インジケーター出力ウィンドウに Click me ボタンが表示されます。

ColorPicker

ColorPicker コントロールは、トレーダーがcTraderの主要な要素やオブジェクトの好みの色を選択できるようにします。 例えば、開発者は、トレンドラインを描画するcBotに ColorPicker コントロールを統合して、ユーザーが各トレンドラインの好みの色を選択できるようにすることができます。 この設定により、トレーダーはさまざまなトレンドラインタイプを簡単に区別できます。

チャートにインジケーターを追加するプラグインも ColorPicker コントロールを実装できます。この機能により、ユーザーは異なるインジケーターラインの色を選択できます。

ユーザーが色の四角をクリックすると、カラーセレクターが表示されます。 ユーザーは標準色とカスタム色の間で選択できます。

コードサンプル:

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

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class ColorPickerTest : Plugin
    {
        protected override void OnStart()
        {
            var aspBlock = Asp.SymbolTab.AddBlock("Color Picker");

            var colorPicker = new ColorPicker {IsStretched = true, SelectedColor = Color.Red, Height = 20, Width = 20, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center};

            aspBlock.Child = colorPicker;

            colorPicker.SelectedColorChanged += colorPicker_SelectedColorChanged;

        }

        private void colorPicker_SelectedColorChanged(ColorPickerSelectedColorChangedEventArgs obj)
        {
            Print($"colorPicker_SelectedColorChanged, NewSelectedColor: {obj.NewSelectedColor} | PreviousSelectedColor: {obj.PreviousSelectedColor}");
        }

        protected override void OnStop()
        {
            // Handle Plugin stop here
        }
    }        
}

Image title

DropZone

DropZone コントロールは、トレーダーがcBot、インジケーター、またはプラグインを含むドラッグアンドドロップアクションを実行できるようにします。 このコントロールをアルゴリズムに実装するには、DropZone クラスを使用します。 DropZone コントロールは、他のコントロールと同様に操作できます。

ユーザーが互換性のあるファイルまたはフォルダをボックスにドロップすると、Dropped イベントが生成されます。 ユーザーがフォルダまたは複数のフォルダをボックスにドロップすると、FilterExtensions で指定された拡張子を持つ互換性のあるファイルのみが処理およびコピーされます。

注意

ドロップされたファイルは通常、次の場所にコピーおよび保存されます: ..\Documents\cAlgo\Data\{AlgoType}\{AlgoName}\Selected Files\

cBotインスタンスの場所は上記とは異なります: ..\Documents\cAlgo\Data\cBots\{cBotName}\{unique-instance-number}\Selected files\

このプラグインコードは、DropZone コントロールを Trade Watch に追加する方法を示しています:

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

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class TradeWatchTabSample : Plugin
    {
        protected override void OnStart()
        {
            var tab = TradeWatch.AddTab("DropZone");

            var _border = new Border
            {
                BorderThickness = 3,
                BorderColor = Color.DarkGray,
                Opacity = 0.7,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                Height = 200,
                Width = 350,
                BackgroundColor = Color.LightGray
            };

            var _textBlock = new TextBlock
            {
                Text = "Drag your files here",
                Opacity = 1,
                ForegroundColor = Color.DarkGray,
                FontSize = 16,
                VerticalAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Center
            };

            var _dropzone = new DropZone
            {
                FilterExtensions = new string[] { "txt", "algo", "csv" },
                IsDirectoryDropAllowed = true,
                IsVisible = true,
                IsEnabled = true
            };
            _border.Child = _textBlock;
            _dropzone.Child = _border;
            //   _dropzone.Child = _textBlock;
            tab.Child = _dropzone;

            _dropzone.Dropped += Dropped_file;
        }

        private void Dropped_file(DroppedEventArgs obj)
        {
            Print("File has been added!");
        }
    }
}

Image title

ProgressBar

ProgressBar コントロールは、進行中の操作の進行状況を表示します。 プログレスバーはアルゴリズムをよりユーザーフレンドリーにし、特定の操作の待ち時間に関するトレーダーの期待を管理するのに役立ちます。

cTrader Algo APIにより、開発者は2種類の ProgressBar コントロールを追加できます:無限コントロールと確定コントロールです。

無限コントロール

以下のような状況で無限コントロールを使用することがあります:

  • 操作の待機時間を決定できない場合。
  • 操作の進行状況を検出できない場合。
  • 操作にかかる時間を示したくない場合。

Image title

確定コントロール

操作の待機時間を決定でき、ユーザーにその時間に基づいたインジケーターを見せたい場合に、このコントロールを使用することがあります。

操作の進捗を表示するには、Valueプロパティを使用して数値を設定します。 プログレスバーのパーセンテージを設定するには、MinimumMaximumプロパティを使用します。

Image title

以下のプラグインコードは、無限コントロールと確定コントロール(緑色)の両方を使用してプログレスバーを作成する方法を示しています:

 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
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 ProgressBarTest : Plugin
    {
        private ProgressBar _infiniteProgressBar;
        private ProgressBar _determinateProgressBar;

        protected override void OnStart()
        {
            var aspBlock = Asp.SymbolTab.AddBlock("Progress bar");

            var panel = new StackPanel() {Height = 200, Width = 200, Orientation = Orientation.Vertical};

            _infiniteProgressBar = new ProgressBar {IsIndeterminate = true, Height = 20};

            panel.AddChild(_infiniteProgressBar);

            _determinateProgressBar = new ProgressBar {IsIndeterminate = false, Height = 20};

            panel.AddChild(_determinateProgressBar);

            var autoProgressButton = new Button {Text = "Start"};

            autoProgressButton.Click += AutoProgressButton_Click;

            panel.AddChild(autoProgressButton);

            aspBlock.Child = panel;

        }

        private void AutoProgressButton_Click(ButtonClickEventArgs obj)
        {
            Timer.Start(1);
        }

        protected override void OnTimer()
        {
            _determinateProgressBar.Value++;

            Print($"Value: {_determinateProgressBar.Value}");
        }

        protected override void OnStop()
        {
            // Handle Plugin stop here
        }
    }        
}

ダイアログ

OpenFileDialogとOpenFolderDialog

cTrader Algo APIは、アルゴリズムで使用するファイルを選択するためにOpenFileDialogインターフェースを提供します。 ユーザーが結果ウィンドウでファイルを選択すると、そのファイルはアルゴリズムのSelected filesフォルダにコピーされます。 アルゴリズムは、Selected filesフォルダ内のファイルを制限なく操作できます。

ヒント

重要なデータファイル、バックアップや設定ファイル、カスタムインジケーターやスクリプトをロードする必要がある場合にOpenFileDialog機能を使用します。

以下のコードは、インジケーターでOpenFileDialogダイアログを使用する方法を示しています:

 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
using System;
using cAlgo.API;
using System.Text;

namespace cAlgo
{
    [Indicator(AccessRights = AccessRights.None, IsOverlay = true)]
    public class OpenFileDialogExample : Indicator
    {
        private OpenFileDialog _openFileDialog;

        protected override void Initialize()
        {
            _openFileDialog = new OpenFileDialog()
            {
                InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                Multiselect = true,
                Title = "My Open File Dialog Title"
            };

            var showOpenFileDialog = new Button { Text = "Show Open File Dialog" };
            showOpenFileDialog.Click += showOpenFileDialog_Click;

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

            panel.AddChild(showOpenFileDialog);
            Chart.AddControl(panel);
        }

        private void showOpenFileDialog_Click(ButtonClickEventArgs obj)
        {
            var result = _openFileDialog.ShowDialog();
            Print($"Result: {result} | FileName: {_openFileDialog.FileName} | FileNames: {string.Join(',', _openFileDialog.FileNames)}");
        }

        public override void Calculate(int index)
        {
        }
    }
}

Image title

cTrader Algo APIは、アルゴリズムで使用するフォルダを指定するためにOpenFolderDialogインターフェースを提供します。 ユーザーが結果ウィンドウでフォルダを選択すると、選択されたフォルダ内のすべてのファイルとフォルダがアルゴリズムのSelected filesフォルダにコピーされます。

ヒント

重要なデータファイル、バックアップや設定ファイル、カスタムインジケーターやスクリプトを含むフォルダをロードする必要がある場合にOpenFolderDialog機能を使用します。

選択されたファイルとフォルダは、通常、Selected filesフォルダにコピーされます。これは、アルゴリズムがAccessRightsNoneに設定している場合でも、そのフォルダ内のアイテムを操作できるためです。

注意

アルゴリズムのSelected filesフォルダは通常、次のパスにあります:..\Documents\cAlgo\Data\{AlgoType}\{AlgoName}\Selected files\

cBotインスタンスのSelected filesフォルダは上記とは異なります:..\Documents\cAlgo\Data\cBots\{cBotName}\{Instance-Id}\Selected files\

以下のコードは、インジケーターでOpenFolderDialogダイアログを使用する方法を示しています:

 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 cAlgo.API;

namespace cAlgo
{
    [Indicator(AccessRights = AccessRights.None, IsOverlay = true)]
    public class OpenFolderDialogExample : Indicator
    {
        private OpenFolderDialog _openFolderDialog;

        protected override void Initialize()
        {
            _openFolderDialog = new OpenFolderDialog()
            {
                InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                Title = "My Open Folder Dialog Title"
            };

            var showOpenFolderDialog = new Button { Text = "Show Open Folder Dialog" };
            showOpenFolderDialog.Click += showOpenFolderDialog_Click;

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

            panel.AddChild(showOpenFolderDialog);
            Chart.AddControl(panel);
        }

        private void showOpenFolderDialog_Click(ButtonClickEventArgs obj)
        {
            var result = _openFolderDialog.ShowDialog();
            Print($"Result: {result} | FolderName: {_openFolderDialog.FolderName}");
        }

        public override void Calculate(int index)
        {
        }
    }
}

Image title

SaveFileDialog

cTrader Algo APIは、ユーザーがファイルを(ローカルに)コンピューターに保存するためにSaveFileDialogインターフェースを提供します。 関連するウィンドウが表示されると、ユーザーはファイルを保存するフォルダを選択し、ファイル名を入力します。 ファイルは指定された場所に保存されます。

ヒント

以下のいずれかの操作が必要な場合にSaveFileDialog機能を使用します:

  • パフォーマンスレポート、バックテスト結果、設定ファイル、または最適化データを保存する。
  • 取引ログ、操作ジャーナル、または一般的なユーザーアクティビティデータをエクスポートする。
  • カスタムインジケーター、チャートや視覚化のためのデータ、または戦略のパラメーターを保存する。

以下のコードは、インジケーターでSaveFileDialogダイアログを使用する方法を示しています:

 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 System.Text;

namespace cAlgo
{
    [Indicator(AccessRights = AccessRights.None, IsOverlay = true)]
    public class SaveFileDialogExample : Indicator
    {
        private SaveFileDialog _saveFileDialog;

        protected override void Initialize()
        {
            _saveFileDialog = new SaveFileDialog()
            {
                InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                Title = "My Save File Dialog Title"
            };

            var showSaveFileDialogText = new Button { Text = "Show Save File Dialog (Set Content as text)" };
            var showSaveFileDialogBytes = new Button { Text = "Show Save File Dialog (Set Content as bytes)" };

            showSaveFileDialogText.Click += showSaveFileDialogText_Click;
            showSaveFileDialogBytes.Click += showSaveFileDialogBytes_Click;

            var panel = new StackPanel
            {
                Orientation = Orientation.Vertical,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };
            panel.AddChild(showSaveFileDialogText);
            panel.AddChild(showSaveFileDialogBytes);
            Chart.AddControl(panel);
        }

        private void showSaveFileDialogText_Click(ButtonClickEventArgs obj)
        {
            var result = _saveFileDialog.ShowDialog();
            Print($"Result: {result}");
            if (result != FileDialogResult.Cancel)
            {
                _saveFileDialog.WriteToFile("Test in text");
            }
        }

        private void showSaveFileDialogBytes_Click(ButtonClickEventArgs obj)
        {
            var result = _saveFileDialog.ShowDialog();
            Print($"Result: {result}");
            if (result != FileDialogResult.Cancel)
            {
                _saveFileDialog.WriteToFile(Encoding.UTF8.GetBytes("Test in bytes"));
            }
        }

        public override void Calculate(int index)
        {
        }
    }
}

ドラッグ可能なコントロール

チャートエリアのドラッグ可能なコントロール

ChartDraggableChartDraggablesインターフェースは、チャートに他のコントロールやさまざまな要素をホストできるドラッグ可能なコントロールを追加するためのタイプを提供します。 これらのドラッグ可能なコントロールにより、ユーザーはさまざまなチャート要素と簡単にやり取りできます。

注意

ドラッグ可能なコントロールは、追加されたチャート内でのみ移動または再配置できます。

このコードは、チャート内で移動可能な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
82
83
84
85
using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo
{
    [Indicator(AccessRights = AccessRights.None)]
    public class DragControl : Indicator
    {
        protected override void Initialize()
        {
            var draggable = Chart.Draggables.Add();
            var draggable2 = IndicatorArea.Draggables.Add();

            draggable.Child = GetDraggableChildWebView();
            draggable2.Child = GetDraggableChildText();

            draggable.LocationChanged += draggable_LocationChanged;
            draggable2.LocationChanged += draggable2_LocationChanged;
        }

        public override void Calculate(int index)
        {
            // Calculate value at specified index
            // Result[index] = 
        }

        private StackPanel GetDraggableChildWebView()
        {
            var stackPanel = new StackPanel
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                BackgroundColor = Color.Gold
            };

            var webView = new WebView() {Height = 500, Width = 300};

            webView.Loaded += webView_Loaded;

            stackPanel.AddChild(webView);

            return stackPanel;
        }

        private StackPanel GetDraggableChildText()
        {
            var stackPanel = new StackPanel
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                BackgroundColor = Color.Gold
            };
            var text_block = new TextBlock
                 {
                     Text = "Testing draggable controls",
                     Margin = 5,
                     ForegroundColor = Color.Black,
                     FontWeight = FontWeight.ExtraBold
                 };

            stackPanel.AddChild(text_block);

            return stackPanel;
        }


        private void webView_Loaded(WebViewLoadedEventArgs obj)
        {
            obj.WebView.NavigateAsync("https://www.youtube.com/");
        }

        private void draggable_LocationChanged(ChartDraggableLocationChangedEventArgs obj)
        {
            Print($"Draggable '{obj.Draggable.Id}' location changed to: ({obj.Draggable.X}, {obj.Draggable.Y})");
        }

        private void draggable2_LocationChanged(ChartDraggableLocationChangedEventArgs obj)
        {
            Print($"Draggable '{obj.Draggable.Id}' location changed to: ({obj.Draggable.X}, {obj.Draggable.Y})");
        }
    }
}

アプリケーションウィンドウのドラッグ可能なコントロール

ApplicationDraggableApplicationDraggablesインターフェースは、cTraderアプリケーションウィンドウ全体で個別に移動可能なフローティングコントロールを追加するために使用されるタイプを提供します。 このようなコントロールにより、インタラクティブでダイナミックなユーザーインターフェースを作成できます。

注意

3つのアルゴリズムタイプのうち、プラグインのみがアプリケーション全体のドラッグ可能なコントロールを実装できます。

このコードは、WebViewコンポーネントとテキストブロックを2つの別々のウィンドウに追加し、cTrader UI全体で移動可能なプラグインを作成する方法を示しています:

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

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.None)]
    public class ApplicationLevelDraggables : Plugin
    {
        private ApplicationDraggable _webDraggable;
        private ApplicationDraggable _textDraggable;

        protected override void OnStart()
        {
            _webDraggable = Application.Draggables.Add();
            _webDraggable.Child = GetDraggableChildWebView();
            _webDraggable.LocationChanged += OnDraggableLocationChanged;

            _textDraggable = Application.Draggables.Add();
            _textDraggable.Child = GetDraggableChildText();
            _textDraggable.LocationChanged += OnDraggableLocationChanged;
        }

        private void OnDraggableLocationChanged(ApplicationDraggableLocationChangedEventArgs args)
        {
            Print($"Draggable '{args.Draggable.Id}' location changed to: ({args.Draggable.X}, {args.Draggable.Y})");
        }

        private StackPanel GetDraggableChildWebView()
        {
            var stackPanel = new StackPanel
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                BackgroundColor = Color.Gold
            };

            var webView = new WebView { Width = 300, Height = 200 };
            webView.Loaded += (args) => args.WebView.NavigateAsync("https://www.youtube.com/");

            stackPanel.AddChild(webView);

            return stackPanel;
        }

        private StackPanel GetDraggableChildText()
        {
            var stackPanel = new StackPanel
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                BackgroundColor = Color.Gold
            };

            var textBlock = new TextBlock
            {
                Text = "Testing Application-level draggable",
                Margin = 5,
                ForegroundColor = Color.Black,
                FontWeight = FontWeight.ExtraBold
            };

            stackPanel.AddChild(textBlock);

            return stackPanel;
        }
    }
}

タブコントロール

TabControlクラスは、アルゴリズムに複数のタブを作成するためのタイプを提供します。 これらのタブは、関連する要素をまとめたり、機能のための別々のビューを表示するために使用できます。

このコードは、アクティブ通貨ペアパネルに追加されたプラグインでタブを使用する方法を示しています:

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

namespace cAlgo.Plugins
{
    [Plugin(AccessRights = AccessRights.FullAccess)]
    public class TabControlSimple : Plugin
    {
        private TabControl _tabControl;

        protected override void OnStart()
        {
            _tabControl = new TabControl
            {
                Height = 200,
                TabStripPlacement = Dock.Left 
            };

            var firstTab = new TabItem
            {
                Header = new TextBlock { Text = "First Tab" },
                Content = new TextBlock { Text = "First Tab Content", BackgroundColor = Color.Red }
            };

            var secondTab = new TabItem
            {
                Header = new TextBlock { Text = "Second Tab" },
                Content = new TextBlock { Text = "Second Tab Content" }
            };

            _tabControl.AddTab(firstTab);
            _tabControl.AddTab(secondTab);

            _tabControl.SelectedTabChanged += TabControl_SelectedTabChanged;

            _tabControl.SelectedTab = secondTab;

            var panel = new StackPanel { Orientation = Orientation.Vertical };
            panel.AddChild(_tabControl);

            var asp = Asp.SymbolTab.AddBlock("Simple Tab Control");
            asp.Child = panel;
            asp.Height = 300;
        }

        private void TabControl_SelectedTabChanged(TabControlSelectedTabChangedEventArgs obj)
        {
            Print($"Selected tab changed to: {obj.SelectedTab?.UniqueId}");
        }

        protected override void OnStop()
        {
        }
    }
}

カスタムコントロール

カスタムコントロールは、本質的にいくつかの事前定義されたコントロールで構成されるコントロールです。 言い換えると、他のコントロールがその内容を構成するコントロールです。

カスタムコントロールは、組み込みコントロールと同様に再利用可能なクラスとして機能します。

 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
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter("# Of Text Areas", DefaultValue = 4)]
        public int NumberOfTextAreas { get; set; }

        protected override void Initialize()
        {
            var panel = new WrapPanel
            {
                Orientation = Orientation.Horizontal,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };

            for (int i = 0; i < NumberOfTextAreas; i++)
            {
                var textArea = new TextArea
                {
                    HorizontalAlignment = HorizontalAlignment.Right,
                    VerticalAlignment = VerticalAlignment.Stretch,
                    Margin = 5,
                };

                panel.AddChild(textArea);
            }

            Chart.AddControl(panel);
        }

        public override void Calculate(int index)
        {
        }
    }

    public class TextArea : CustomControl
    {
        private readonly TextBox _textBox;

        public TextArea()
        {
            _textBox = new TextBox
            {
                TextAlignment = TextAlignment.Left,
                TextWrapping = TextWrapping.Wrap,
                AcceptsReturn = true,
                AcceptsTab = true,
                Width = 300,
                Height = 200,
            };

            AddChild(_textBox);
        }
    }
}

このインジケーターのインスタンスは、メインチャートの中央に4つのテキストボックスを直接表示する必要があります。

パネルでコントロールを整理する

コントロールをより便利に操作するために、いくつかのコントロールを独自の位置を持つ別個のグループに配置することがあります。 これを行うには、Panelsクラスとその派生クラスを使用できます。

パネルは、他のコントロールをその内容として持つコントロールと考えることができます。 cTraderは、基本のPanelsクラス(Controlクラスから継承)から継承する5つの異なるクラスをサポートしています:

  • Canvas
  • DockPanel
  • Grid
  • StackPanel
  • WrapPanel

各クラスは、以下で説明するように、異なるパネルレイアウトと配置戦略を使用します。

キャンバス

キャンバスは、特定のXおよびY座標に基づいてコントロールを配置できるパネルです。

特に、XおよびY軸は、チャートオブジェクトや描画で使用されるものとは異なります。 Canvasクラスで使用されるXおよびY座標は、チャートの左上隅から(0, 0)で始まる数値を表します。

次の例を考えてみてください。

 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
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter(DefaultValue = "Click Me")]
        public string Text { get; set; }

        [Parameter(DefaultValue = 0)]
        public double Left { get; set; }

        [Parameter(DefaultValue = 0)]
        public double Top { get; set; }

        [Parameter(DefaultValue = 0)]
        public double Margin { get; set; }

        [Parameter(DefaultValue = 10)]
        public double Padding { get; set; }

        protected override void Initialize()
        {
            var button = new Button
            {
                Text = Text,
                Left = Left,
                Top = Top,
                Margin = Margin,
                Padding = Padding
            };

            button.Click += Button_Click;

            var canvas = new Canvas();

            /* We add our button control to the canvas
            panel. */
            canvas.AddChild(button);

            // We add our canvas panel to the chart.
            Chart.AddControl(canvas);
        }

        private void Button_Click(ButtonClickEventArgs obj)
        {
            obj.Button.Text = "You clicked me, thanks";
        }

        public override void Calculate(int index)
        {
        }
    }
}

上記のインジケーターのインスタンスを作成すると、チャートの左上隅にClick meボタンが表示されます。

コントロールのTopプロパティは、Y軸上の位置を決定します。 同様に、Leftプロパティは、X軸上の位置を定義します。

上記のコードは、PaddingMarginプロパティも使用しています。 Paddingは、コントロールの内容とその外枠の間の距離を指します。 Marginは、コントロールとその親の枠の間の距離です。 PaddingMarginプロパティは、キャンバスクラスだけでなく、すべてのパネルに適用されます。 これらは、コントロール間のスペースを管理するのに役立ちます。

ほとんどの場合、Canvasクラスは、少数のコントロールをグループ化するために使用されます。

ドックパネル

DockPanelクラスは、チャート上の静的な位置にコントロールをドック(配置)するために使用されます。 ドック位置には以下の4つの選択肢があります:

各コントロールにはDockプロパティがあります。 DockPanelクラスを使用する際、このプロパティを使用してコントロールをDockPanel内に配置できます。 これは以下の例で示されています:

 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
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter(DefaultValue = Dock.Top)]
        public Dock TextBoxDock { get; set; }

        [Parameter(DefaultValue = Dock.Bottom)]
        public Dock ButtonDock { get; set; }

        private TextBox _textBox;

        protected override void Initialize()
        {
            _textBox = new TextBox
            {
                Margin = 5,
                Text = "Write here...",
                ForegroundColor = Color.Yellow,
                Dock = TextBoxDock,
                Width = 200
            };

            var button = new Button
            {
                Text = "Tell what I wrote?",
                Dock = ButtonDock,
                Width = 200
            };

            button.Click += Button_Click;

            var dockPanel = new DockPanel
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
            };

            dockPanel.AddChild(_textBox);
            dockPanel.AddChild(button);

            Chart.AddControl(dockPanel);
        }

        private void Button_Click(ButtonClickEventArgs obj)
        {
            obj.Button.Text = $"You wrote: {_textBox.Text}";
        }

        public override void Calculate(int index)
        {
        }
    }
}

このインジケーターのインスタンスを作成する際、チャートの中央にテキストフィールドとクリック可能なボタンを含むドックパネルが表示されるはずです。

ドックパネルは水平または垂直に配置できることに注意してください。 これらの配置を同時に使用することはできません。 ドックパネルの向きは、DockPanel内の最初のコントロールを設定する際に自動的に設定されます。 最初のコントロールのDockプロパティがTopまたはBottomに設定されている場合、DockPanel全体が垂直方向に配置され、逆も同様です。

スタックパネル

スタックパネルは、そのシンプルさと使いやすさから最も頻繁に使用されるコントロールの1つです。 スタックパネルは、子コントロールを水平または垂直に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
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter(DefaultValue = Orientation.Vertical)]
        public Orientation Orientation { get; set; }

        protected override void Initialize()
        {
            var firstNameTextBox = new TextBox
            {
                Margin = 5,
                Text = "First Name...",
                Width = 200
            };

            var lastNameTextBox = new TextBox
            {
                Margin = 5,
                Text = "Last Name...",
                Width = 200
            };

            var isMarriedCheckBox = new CheckBox
            {
                Text = "Is Married?",
                Margin = 5,
            };

            var submitButton = new Button
            {
                Text = "Submit",
                Margin = 5
            };

            var stackPanel = new StackPanel
            {
                Orientation = Orientation,
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Bottom,
                BackgroundColor = Color.FromArgb(80, Color.Gold),
                Margin = 20
            };

            stackPanel.AddChild(firstNameTextBox);
            stackPanel.AddChild(lastNameTextBox);
            stackPanel.AddChild(isMarriedCheckBox);
            stackPanel.AddChild(submitButton);

            Chart.AddControl(stackPanel);
        }

        public override void Calculate(int index)
        {
        }
    }
}

インジケーターのインスタンスを作成した後、メインチャートの右下隅に2つのテキストフィールドと「Submit」ボタンを含む水平スタックパネルが表示されるはずです。

ラップパネル

ラップパネルは、スタックパネルとほとんど同じです。 ただし、ラップパネルのすべての要素を収めるための十分なスペースがない場合、残りのコントロールをY軸上の次の行に自動的にラップします。

グリッド

グリッドは、指定された列数と行数を持つスプレッドシートと考えることができます。 グリッドを使用する際、各セルにコントロールを追加できます。

以下に示すように、Gridクラスのインスタンスを作成する際、その行数と列数をinteger引数として渡します。 新しい子コントロールを追加する際も、同様に子行数と子列数を指定する必要があります。

 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 ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter("Grid Rows #", DefaultValue = 10)]
        public int GridRowsNumber { get; set; }

        [Parameter("Grid Columns #", DefaultValue = 2)]
        public int GridColumnsNumber { get; set; }

        protected override void Initialize()
        {
            var grid = new Grid(GridRowsNumber, GridColumnsNumber)
            {
                BackgroundColor = Color.Gold,
                Opacity = 0.6,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                ShowGridLines = true
            };

            for (int iRow = 0; iRow < GridRowsNumber; iRow++)
            {
                for (int iColumn = 0; iColumn < GridColumnsNumber; iColumn++)
                {
                    grid.AddChild(new TextBlock
                    {
                        Text = string.Format("Row {0} and Column {1}", iRow, iColumn),
                        Margin = 5,
                        ForegroundColor = Color.Black,
                        FontWeight = FontWeight.ExtraBold
                    }, iRow, iColumn);
                }
            }

            Chart.AddControl(grid);
        }

        public override void Calculate(int index)
        {
        }
    }
}

上記のインジケーターのインスタンスを作成する際、チャートの中央に10x2のグリッドが表示されるはずです。

価格と時間座標内でのコントロールの配置

パネルコントロールに加えて、cTraderではチャートエリア内のコントロールに直接価格と時間座標を指定できます。 AddControl()MoveControl()メソッドは、アルゴリズム開発者にこの機能を提供します。

以下のメソッドオーバーロードを使用して、チャートコントロールの座標を管理できます。

絶対バーインデックスと価格(x, y)座標でチャートまたはインジケーターエリアにチャートコントロールを追加します。

1
void AddControl(ControlBase control, int barIndex, double y)

絶対バーインデックスと価格(x, y)座標でチャートまたはインジケーターエリアにチャートコントロールを移動します。

1
void MoveControl(ControlBase control, int barIndex, double y)

絶対時間と価格(x, y)座標でチャートまたはインジケーターエリアにチャートコントロールを追加します。

1
void AddControl(ControlBase control, DateTime time, double y)

絶対時間と価格(x, y)座標でチャートまたはインジケーターエリアにチャートコントロールを移動します。

1
void MoveControl(ControlBase control, DateTime time, double y)

絶対時間(x)座標でチャートまたはインジケーターエリアにチャートコントロールを追加します。

1
void AddControl(ControlBase control, DateTime time)

絶対時間(x)座標でチャートまたはインジケーターエリアにチャートコントロールを移動します。

1
void MoveControl(ControlBase control, DateTime time)

絶対バーインデックス(x)座標でチャートまたはインジケーターエリアにチャートコントロールを追加します。

1
void AddControl(ControlBase control, int barIndex)

絶対バーインデックス(x)座標でチャートまたはインジケーターエリアにチャートコントロールを移動します。

1
void MoveControl(ControlBase control, int barIndex)

絶対価格(y)座標でチャートまたはインジケーターエリアにチャートコントロールを追加します。

1
void AddControl(ControlBase control, double y)

絶対価格(y)座標でチャートまたはインジケーターエリアにチャートコントロールを移動します。

1
void MoveControl(ControlBase control, double y)

ControlBaseパラメータクラスには、上記のシグネチャに従って呼び出されるメソッドのための他の下位クラス(ControlButtonなど) を含めることができます。

以下のcBotの例では、チャート上の最後のバーの上にClick me!ボタンを追加します。 ボタンは、新しいバーが追加されるたびに一緒に移動します。 ボタンをクリックすると、画面にメッセージボックスが表示されます。

 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
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.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class ButtonTest : Robot
    {
        [Parameter(DefaultValue = "Hello world!")]
        public string Message { get; set; }

        Button button;

        protected override void OnStart() 
        {
            button = new Button
            {
                Text = "Click me!"
            };

            button.Click += Button_Click;

            Chart.AddControl(button, Bars.Count - 1);
        }

        protected override void OnBar() 
        {
            Chart.MoveControl(button, Bars.Count - 1);
        }

        private void Button_Click(ButtonClickEventArgs obj)
        {
            MessageBox.Show(Message, "Title/Caption");
        }
    }
}

警告

パフォーマンスの問題のため、チャートに追加されるルートコントロールの数は100に制限されています。 この制限は、1つのアルゴリズムインスタンスと価格およびバーにアタッチされたコントロールにのみ適用されます。

パディングとマージンのプロパティ

Marginプロパティは、Controlオブジェクトの境界線とその親(チャート、パネル、ボーダーなど)との間のスペースを定義します。

一方、Paddingプロパティは、コントロールの内容とその境界線との間のスペースを決定します。 プロパティの値を変更して、異なる側に対して異なる値にすることができます。

 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
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        [Parameter(DefaultValue = "Click Me")]
        public string Text { get; set; }

        [Parameter(DefaultValue = 0)]
        public double Left { get; set; }

        [Parameter(DefaultValue = 0)]
        public double Top { get; set; }

        [Parameter(DefaultValue = 0, Group = "Margin")]
        public double LeftMargin { get; set; }

        [Parameter(DefaultValue = 0, Group = "Margin")]
        public double TopMargin { get; set; }

        [Parameter(DefaultValue = 0, Group = "Margin")]
        public double RightMargin { get; set; }

        [Parameter(DefaultValue = 0, Group = "Margin")]
        public double BottomMargin { get; set; }

        [Parameter(DefaultValue = 5, Group = "Padding")]
        public double LeftPadding { get; set; }

        [Parameter(DefaultValue = 5, Group = "Padding")]
        public double TopPadding { get; set; }

        [Parameter(DefaultValue = 5, Group = "Padding")]
        public double RightPadding { get; set; }

        [Parameter(DefaultValue = 5, Group = "Padding")]
        public double BottomPadding { get; set; }

        protected override void Initialize()
        {
            var button = new Button
            {
                Text = Text,
                Left = Left,
                Top = Top,
                Margin = new Thickness(LeftMargin, TopMargin, RightMargin, BottomMargin),
                Padding = new Thickness(LeftPadding, TopPadding, RightPadding, BottomPadding)
            };

            button.Click += Button_Click;

            var canvas = new Canvas();

            canvas.AddChild(button);

            Chart.AddControl(canvas);
        }

        private void Button_Click(ButtonClickEventArgs obj)
        {
            obj.Button.Text = "You clicked me, thanks";
        }

        public override void Calculate(int index)
        {
        }
    }
}

このインジケーターのインスタンスは、チャートの左上隅に灰色のClick meボタンを作成します。 Add instanceまたはModify parametersウィンドウでパラメーターを変更して、異なるマージンとパディングの値がコントロールの表示方法をどのように変えるかを確認します。

スタイル

スタイルを使用する際、いくつかの異なるタイプのコントロールに同じ外観を与えることができます。 これは、多数(5つ以上)のコントロールを扱う際に特に便利です。

Styleクラスを使用すると、MarginBackgroundColorなどのコントロールのさまざまなプロパティの値を設定できます。 その後、これらの値を複数の他のコントロールのテンプレートとして再利用できます。

また、Styleクラスを使用せずに、複数のコントロールに一貫した外観を作成することもできます。

 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
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        protected override void Initialize()
        {
            var firstTextBox = new TextBox
            {
                ForegroundColor = Color.Red,
                Margin = 5,
                FontFamily = "Cambria",
                FontSize = 12,
                Text = "Type...",
                Width = 150
            };

            var secondTextBox = new TextBox
            {
                ForegroundColor = Color.Red,
                Margin = 5,
                FontFamily = "Cambria",
                FontSize = 12,
                Text = "Type...",
                Width = 150
            };

            var thirdTextBox = new TextBox
            {
                ForegroundColor = Color.Red,
                Margin = 5,
                FontFamily = "Cambria",
                FontSize = 12,
                Text = "Type...",
                Width = 150
            };

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

            panel.AddChild(firstTextBox);
            panel.AddChild(secondTextBox);
            panel.AddChild(thirdTextBox);

            Chart.AddControl(panel);
        }

        public override void Calculate(int index)
        {
        }
    }
}

以下は、Styleクラスを使用して複数のコントロールを扱う作業を簡素化する方法です。

 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
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        protected override void Initialize()
        {
            var textBoxStyle = new Style();

            textBoxStyle.Set(ControlProperty.ForegroundColor, Color.Red);
            textBoxStyle.Set(ControlProperty.Margin, 5);
            textBoxStyle.Set(ControlProperty.FontFamily, "Cambria");
            textBoxStyle.Set(ControlProperty.FontSize, 12);
            textBoxStyle.Set(ControlProperty.Width, 150);

            var firstTextBox = new TextBox
            {
                Text = "Type...",
                Style = textBoxStyle
            };

            var secondTextBox = new TextBox
            {
                Text = "Type...",
                Style = textBoxStyle
            };

            var thirdTextBox = new TextBox
            {
                Text = "Type...",
                Style = textBoxStyle
            };

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

            panel.AddChild(firstTextBox);
            panel.AddChild(secondTextBox);
            panel.AddChild(thirdTextBox);

            Chart.AddControl(panel);
        }

        public override void Calculate(int index)
        {
        }
    }
}

上記の両方のコードスニペットは、それぞれのインジケーターインスタンスを起動すると同じコントロールを表示するはずです。

また、Styleクラスを使用して、コントロールの状態に基づいてその外観を変更することもできます。

 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
using cAlgo.API;

namespace ChartControlsTest
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class ChartControls : Indicator
    {
        protected override void Initialize()
        {
            var textBoxStyle = new Style();

            textBoxStyle.Set(ControlProperty.ForegroundColor, Color.Red);
            textBoxStyle.Set(ControlProperty.Margin, 5);
            textBoxStyle.Set(ControlProperty.FontFamily, "Cambria");
            textBoxStyle.Set(ControlProperty.FontSize, 12);
            textBoxStyle.Set(ControlProperty.Width, 150);
            // Here we change the foreground color to Yellow if mouse hover over the textbox
            textBoxStyle.Set(ControlProperty.ForegroundColor, Color.Yellow, ControlState.Hover);

            var firstTextBox = new TextBox
            {
                Text = "Type...",
                Style = textBoxStyle
            };

            var secondTextBox = new TextBox
            {
                Text = "Type...",
                Style = textBoxStyle
            };

            var thirdTextBox = new TextBox
            {
                Text = "Type...",
                Style = textBoxStyle
            };

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

            panel.AddChild(firstTextBox);
            panel.AddChild(secondTextBox);
            panel.AddChild(thirdTextBox);

            Chart.AddControl(panel);
        }

        public override void Calculate(int index)
        {
        }
    }
}

画像

Imageコントロールは、ローカルに保存された画像を表示するために使用できます。 Imageコントロールは.NETのBitmapクラスを使用するため、以下のような主要な画像フォーマットのほとんどをサポートしています:

  • .PNG
  • .JPG
  • .BMP
  • .GIF
  • .TIFF

.NET Bitmapクラスのドキュメントを参照して詳細を確認してください。

Imageコントロールを使用するには、Sourceプロパティをバイト配列(byte[])の画像ファイルデータに設定します。

 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
using cAlgo.API;
using System.IO;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class ImageSample : Indicator
    {
        [Parameter("Image File Path")]
        public string ImageFilePath { get; set; }

        protected override void Initialize()
        {
            if (File.Exists(ImageFilePath) is false)
            {
                Print($"Image not found: {ImageFilePath}");

                return;
            }

            var imageBytes = File.ReadAllBytes(ImageFilePath);

            var image = new Image
            {
                Source = imageBytes,
                Width = 200,
                Height = 200,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };

            Chart.AddControl(image);
        }

        public override void Calculate(int index)
        {
        }
    }
}

上記のインジケーターのインスタンスを起動した後、メインチャートには新しいものは表示されません。 ただし、(画像ファイルパス)パラメーターの値として有効なファイルパスを入力すると、選択した画像が画面の中央に表示されるはずです。

また、プロジェクトリソースを使用して画像を保存し、Imageコントロールを通じて表示することもできます。 これを行うには、Visual Studioでプロジェクトリソースを開き、リソースタブに切り替えます。 その中で新しいリソースを作成し、既存の画像を追加します。 その後、Project_Name_Space.Properties.Resources._Image_Nameプロパティを通じて、任意のImageコントロールのソースとしてこの画像を使用できるようになります。

例として、以下の画像をコピーしてシステム上に「image.png」として保存してください:

Image title

cTraderで新しいインジケーターを作成し、その名前を「Image Sample」に設定し、Visual Studioで開きます。 その後、ロゴインジケータープロジェクトをリソースとして追加します。 これを行うには、プロジェクトを右クリックし、プロパティを選択し、リソースをクリックしてから、アセンブリリソースの作成と管理をクリックします。 logo.pngファイルを新しく開いたタブにコピーします。

以下のコードをインジケーターのメインソースコードファイルにコピーします:

 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
using cAlgo.API;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class ImageSample : Indicator
    {
        protected override void Initialize()
        {
            var image = new Image
            {
                Source = Image_Sample.Properties.Resources.logo,
                Width = 200,
                Height = 200,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };

            Chart.AddControl(image);
        }

        public override void Calculate(int index)
        {
        }
    }
}

このインジケーターのインスタンスを作成した後、以下の出力が表示されるはずです。

Image title

注意

画像の最大サイズは10 MBです。