คอนโทรล คอนโทรลช่วยให้เกิดการโต้ตอบบางอย่างที่เกี่ยวข้องกับ 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 )
{
}
}
}
หากคุณสร้างอินดิเคเตอร์ข้างต้นและสร้างอินสแตนซ์ คุณควรเห็นปุ่มสีเทา คลิกฉัน ตรงกลางกราฟ
ความแตกต่างระหว่างคอนโทรลและออบเจ็กต์กราฟ ในส่วนก่อนหน้านี้ เราได้กล่าวถึงออบเจ็กต์กราฟไปแล้ว คอนโทรลช่วยให้ผู้ใช้สามารถโต้ตอบกับ 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 )
{
}
}
}
หลังจากสร้างอินสแตนซ์ของอินดิเคเตอร์ คุณควรเห็นปุ่ม คลิกฉัน ในหน้าต่างแสดงผลอินดิเคเตอร์
ColorPicker คอนโทรล ColorPicker ช่วยให้นักเทรดสามารถเลือกสีที่ต้องการสำหรับองค์ประกอบหรือออบเจ็กต์หลักใน cTrader ตัวอย่างเช่น นักพัฒนาอาจรวมคอนโทรล ColorPicker เข้ากับ cBot ที่วาดเส้นแนวโน้มเพื่อให้ผู้ใช้สามารถเลือกสีที่ต้องการสำหรับเส้นแนวโน้มแต่ละเส้น การตั้งค่านี้ช่วยให้นักเทรดแยกแยะระหว่างประเภทเส้นแนวโน้มต่างๆ ได้ง่ายขึ้น
ปลั๊กอินที่เพิ่มอินดิเคเตอร์ลงในกราฟก็สามารถใช้คอนโทรล 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
}
}
}
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!" );
}
}
}
ProgressBar คอนโทรล ProgressBar แสดงความคืบหน้าของการดำเนินการที่กำลังดำเนินอยู่ แถบความคืบหน้าทำให้อัลกอริทึมใช้งานง่ายขึ้นและช่วยจัดการความคาดหวังของนักเทรดเกี่ยวกับเวลารอสำหรับการดำเนินการบางอย่าง
cTrader Algo API อนุญาตให้นักพัฒนาเพิ่มคอนโทรล ProgressBar สองประเภท: คอนโทรลไม่มีที่สิ้นสุดและคอนโทรลที่กำหนดได้
ขอบเขตการควบคุมไม่จำกัด คุณอาจต้องการใช้การควบคุมแบบไม่จำกัดในสถานการณ์ต่อไปนี้:
คุณไม่สามารถกำหนดเวลารอสำหรับการดำเนินการได้ คุณไม่สามารถตรวจจับความคืบหน้าของการดำเนินการได้ คุณไม่ต้องการระบุว่าการดำเนินการจะใช้เวลานานเท่าใด
การควบคุมแบบกำหนดได้ คุณอาจต้องการใช้การควบคุมนี้เมื่อคุณสามารถกำหนดเวลารอสำหรับการดำเนินการได้และต้องการให้ผู้ใช้เห็นตัวบ่งชี้ตามเวลานั้น
ในการแสดงความคืบหน้าของการดำเนินการ ให้ใช้คุณสมบัติ Value เพื่อกำหนดตัวเลข ในการกำหนดเปอร์เซ็นต์ของแถบความคืบหน้า ให้ใช้คุณสมบัติ Minimum และ Maximum
โค้ดปลั๊กอินด้านล่างแสดงวิธีการสร้างแถบความคืบหน้าโดยใช้การควบคุมทั้งแบบไม่จำกัดและแบบกำหนดได้ (สีเขียว):
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 มี interface 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 )
{
}
}
}
cTrader Algo API มี interface OpenFolderDialog เพื่อให้ผู้ใช้สามารถระบุโฟลเดอร์สำหรับอัลกอริทึม เมื่อผู้ใช้เลือกโฟลเดอร์ในหน้าต่างที่ปรากฏขึ้น ไฟล์และโฟลเดอร์ทั้งหมดที่มีไฟล์อยู่ภายในโฟลเดอร์ที่เลือกจะถูกคัดลอกไปยังโฟลเดอร์ Selected files ของอัลกอริทึม
เคล็ดลับ
ใช้ฟังก์ชัน OpenFolderDialog เมื่อคุณต้องการโหลดโฟลเดอร์ที่มีไฟล์ข้อมูลสำคัญ ไฟล์สำรองข้อมูลหรือไฟล์การกำหนดค่า ตัวบ่งชี้ที่กำหนดเองหรือสคริปต์
ไฟล์และโฟลเดอร์ที่เลือกมักจะถูกคัดลอกไปยังโฟลเดอร์ Selected files เนื่องจากอัลกอริทึมสามารถทำงานกับรายการภายในโฟลเดอร์นั้นได้แม้ว่า AccessRights จะถูกตั้งค่าเป็น None
หมายเหตุ
โฟลเดอร์ Selected files ของอัลกอริทึมมักจะอยู่ตามเส้นทางนี้: ..\Documents\cAlgo\Data\{AlgoType}\{AlgoName}\Selected files\
โฟลเดอร์ Selected files สำหรับอินสแตนซ์ของ cBot จะแตกต่างจากข้างต้น: ..\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 )
{
}
}
}
SaveFileDialog cTrader Algo API มี interface SaveFileDialog เพื่อให้ผู้ใช้สามารถบันทึกไฟล์ (ในเครื่อง) ลงในคอมพิวเตอร์ของตนเองได้ เมื่อหน้าต่างที่เกี่ยวข้องปรากฏขึ้น ผู้ใช้จะเลือกโฟลเดอร์ที่ต้องการบันทึกไฟล์และป้อนชื่อสำหรับไฟล์ จากนั้นไฟล์จะถูกบันทึกในตำแหน่งที่ระบุ
เคล็ดลับ
ใช้ฟังก์ชัน SaveFileDialog เมื่อคุณต้องการทำสิ่งใดสิ่งหนึ่งต่อไปนี้:
บันทึกรายงานประสิทธิภาพ ผลลัพธ์การ backtesting ไฟล์การกำหนดค่า หรือข้อมูลการปรับให้เหมาะสม ส่งออกบันทึกการเทรด บันทึกการดำเนินการ หรือข้อมูลกิจกรรมทั่วไปของผู้ใช้ จัดเก็บตัวบ่งชี้ที่กำหนดเอง ข้อมูลสำหรับแผนภูมิและการแสดงผล หรือพารามิเตอร์สำหรับกลยุทธ์ โค้ดด้านล่างแสดงวิธีการใช้กล่องโต้ตอบ 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 )
{
}
}
}
การควบคุมแบบลาก การควบคุมแบบลากในพื้นที่แผนภูมิ Interface ChartDraggable และ ChartDraggables มีประเภทที่ช่วยให้คุณสามารถเพิ่มการควบคุมแบบลากที่สามารถรองรับการควบคุมอื่น ๆ และองค์ประกอบต่าง ๆ ลงในแผนภูมิได้ การควบคุมแบบลากเหล่านี้ช่วยให้ผู้ใช้สามารถโต้ตอบกับองค์ประกอบต่าง ๆ ของแผนภูมิได้ง่ายขึ้น
หมายเหตุ
การควบคุมแบบลากสามารถเคลื่อนย้ายหรือจัดตำแหน่งใหม่ได้เฉพาะภายในแผนภูมิที่ถูกเพิ่มเข้าไปเท่านั้น
โค้ดนี้แสดงวิธีการสร้างตัวบ่งชี้ที่เพิ่มการควบคุมสองอย่างที่สามารถเคลื่อนย้ายได้ภายในแผนภูมิ:
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})" );
}
}
}
การควบคุมแบบลากในหน้าต่างแอปพลิเคชัน Interface ApplicationDraggable และ ApplicationDraggables มีประเภทที่ใช้เพิ่มการควบคุมแบบลอยที่สามารถเคลื่อนย้ายแต่ละอันได้ทั่วทั้งหน้าต่างแอปพลิเคชัน cTrader การควบคุมดังกล่าวช่วยให้คุณสามารถสร้างส่วนติดต่อผู้ใช้แบบโต้ตอบและแบบไดนามิกได้
หมายเหตุ
ในบรรดาประเภทอัลกอริทึมทั้งสามประเภท มีเพียงปลั๊กอินเท่านั้นที่ได้รับอนุญาตให้ใช้การควบคุมแบบลากทั่วทั้งแอปพลิเคชัน
โค้ดนี้แสดงวิธีการสร้างปลั๊กอินที่เพิ่มคอมโพเนนต์ WebView และบล็อกข้อความในหน้าต่างแยกกันสองหน้าต่าง ซึ่งสามารถเคลื่อนย้ายได้ทั่วทั้ง UI ของ 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
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 );
}
}
}
อินสแตนซ์ของตัวบ่งชี้นี้ควรแสดงกล่องข้อความสี่กล่องโดยตรงที่ตรงกลางของแผนภูมิหลัก
จัดระเบียบการควบคุมด้วยแผง เพื่อให้การทำงานกับการควบคุมสะดวกยิ่งขึ้น คุณอาจต้องการวางการควบคุมหลายอย่างไว้ในกลุ่มที่แยกต่างหากซึ่งมีตำแหน่งของตัวเองใน UI ในการทำเช่นนี้ คุณสามารถใช้คลาส Panels และอนุพันธ์ของมัน
คิดว่าแผงเป็นการควบคุมที่มีการควบคุมอื่น ๆ เป็นเนื้อหาของมัน cTrader รองรับห้าคลาสที่แตกต่างกันซึ่งสืบทอดมาจากคลาส Panels พื้นฐาน (ซึ่งสืบทอดมาจากคลาส Control ):
Canvas DockPanel Grid StackPanel WrapPanel แต่ละคลาสข้างต้นใช้เค้าโครงแผงและกลยุทธ์การจัดตำแหน่ง
แคนวาส แคนวาสเป็นแผงที่อนุญาตให้จัดตำแหน่งของตัวควบคุมตามพิกัด X และ Y ที่กำหนด
โดยเฉพาะอย่างยิ่ง แกน X และ Y นั้นแตกต่างจากที่ใช้กับวัตถุหรือการวาดบนกราฟ พิกัด X และ Y ที่ใช้โดยคลาส Canvas แสดงค่าตัวเลขเริ่มต้นจาก (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
โค้ดข้างต้นยังใช้คุณสมบัติ Padding และ Margin ด้วย Padding หมายถึงระยะห่างระหว่างเนื้อหาของตัวควบคุมและขอบนอกของมัน Margin คือระยะห่างระหว่างตัวควบคุมและขอบของตัวควบคุมหลักของมัน คุณสมบัติ Padding และ Margin สามารถใช้ได้กับทุกแผง ไม่เฉพาะแค่คลาสแคนวาส พวกมันมีประโยชน์สำหรับการจัดการระยะห่างระหว่างตัวควบคุมของคุณ
ในกรณีส่วนใหญ่ คลาส Canvas ถูกใช้เพื่อจัดกลุ่มตัวควบคุมจำนวนน้อยเท่านั้น
สร้างแผงใหม่ คลาส DockPanel ใช้เพื่อยึด (วาง) ตัวควบคุมในตำแหน่งคงที่บนกราฟ มีตำแหน่งยึดที่เป็นไปได้สี่ตำแหน่ง:
แต่ละตัวควบคุมมีคุณสมบัติ 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
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 )
{
}
}
}
หลังจากสร้างอินสแตนซ์ของอินดิเคเตอร์ คุณควรเห็นแผงซ้อนแนวนอนที่มีช่องข้อความสองช่องและปุ่ม '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)
void AddControl ( ControlBase control , int barIndex , double y )
เพื่อย้ายการควบคุมแผนภูมิไปยังพื้นที่แผนภูมิหรืออินดิเคเตอร์บนดัชนีแท่งเทียนสัมบูรณ์และพิกัดราคา (x, y)
void MoveControl ( ControlBase control , int barIndex , double y )
เพื่อเพิ่มการควบคุมแผนภูมิลงในพื้นที่แผนภูมิหรืออินดิเคเตอร์บนพิกัดเวลาและราคาสัมบูรณ์ (x, y)
void AddControl ( ControlBase control , DateTime time , double y )
เพื่อย้ายการควบคุมแผนภูมิไปยังพื้นที่แผนภูมิหรืออินดิเคเตอร์บนพิกัดเวลาและราคาสัมบูรณ์ (x, y)
void MoveControl ( ControlBase control , DateTime time , double y )
เพื่อเพิ่มการควบคุมแผนภูมิลงในพื้นที่แผนภูมิหรืออินดิเคเตอร์บนพิกัดเวลาสัมบูรณ์ (x)
void AddControl ( ControlBase control , DateTime time )
เพื่อย้ายการควบคุมแผนภูมิไปยังพื้นที่แผนภูมิหรืออินดิเคเตอร์บนพิกัดเวลาสัมบูรณ์ (x)
void MoveControl ( ControlBase control , DateTime time )
เพื่อเพิ่มการควบคุมแผนภูมิลงในพื้นที่แผนภูมิหรืออินดิเคเตอร์บนพิกัดดัชนีแท่งเทียนสัมบูรณ์ (x)
void AddControl ( ControlBase control , int barIndex )
เพื่อย้ายการควบคุมแผนภูมิไปยังพื้นที่แผนภูมิหรืออินดิเคเตอร์บนพิกัดดัชนีแท่งเทียนสัมบูรณ์ (x)
void MoveControl ( ControlBase control , int barIndex )
เพื่อเพิ่มการควบคุมแผนภูมิลงในพื้นที่แผนภูมิหรืออินดิเคเตอร์บนพิกัดราคาสัมบูรณ์ (y)
void AddControl ( ControlBase control , double y )
เพื่อย้ายการควบคุมแผนภูมิไปยังพื้นที่แผนภูมิหรืออินดิเคเตอร์บนพิกัดราคาสัมบูรณ์ (y)
void MoveControl ( ControlBase control , double y )
พารามิเตอร์คลาส ControlBase สามารถรวมคลาสย่อยอื่น ๆ (Control, Button ฯลฯ) เพื่อให้เมธอดถูกเรียกตามลายเซ็นข้างต้น
ตัวอย่าง 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 เนื่องจากปัญหาประสิทธิภาพที่อาจเกิดขึ้น ข้อจำกัดนี้ใช้กับอินสแตนซ์อัลกอริทึมเดียวและการควบคุมที่แนบกับราคาและแท่งเทียนเท่านั้น
คุณสมบัติ padding และ margin คุณสมบัติ 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 เพื่อดูว่าค่า margin และ padding ที่แตกต่างกันเปลี่ยนแปลงการแสดงผลการควบคุมอย่างไร
สไตล์ เมื่อใช้สไตล์ คุณสามารถให้ลักษณะที่คล้ายกันกับการควบคุมหลายประเภทที่แตกต่างกันได้ สิ่งนี้มีประโยชน์อย่างยิ่งเมื่อต้องจัดการกับการควบคุมจำนวนมาก (ห้าหรือมากกว่า)
คลาส Style อนุญาตให้กำหนดค่าสำหรับคุณสมบัติต่าง ๆ ของการควบคุม เช่น Margin หรือ BackgroundColor หลังจากนั้น คุณสามารถนำค่าเหล่านี้มาใช้ซ้ำเป็นเทมเพลตสำหรับการควบคุมอื่น ๆ หลายรายการ
เราสามารถสร้างลักษณะที่สอดคล้องกันสำหรับการควบคุมหลายรายการโดยไม่ต้องใช้คลาส 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 ใช้คลาส Bitmap ของ .NET ซึ่งหมายความว่ารองรับรูปแบบรูปภาพยอดนิยมส่วนใหญ่ เช่นต่อไปนี้:
.PNG .JPG .BMP .GIF .TIFF ปรึกษาเอกสาร คลาส Bitmap ของ .NET เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับมัน
เพื่อใช้การควบคุม 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 File Path) และคุณควรเห็นรูปภาพที่เลือกแสดงที่กึ่งกลางของหน้าจอ
คุณยังสามารถใช้ทรัพยากรโครงการของคุณเพื่อจัดเก็บรูปภาพและแสดงผ่านการควบคุม Image ได้ เพื่อทำเช่นนั้น ให้เปิดทรัพยากรโครงการใน Visual Studio และสลับไปที่แท็บ Resources ในนั้น ให้สร้างทรัพยากรใหม่และเพิ่มรูปภาพที่มีอยู่ หลังจากนั้น คุณจะสามารถใช้รูปภาพนี้เป็นแหล่งที่มาในการควบคุม Image ใด ๆ ผ่านคุณสมบัติ Project_Name_Space . Properties . Resources . _Image_Name
ตัวอย่างเช่น คัดลอกรูปภาพด้านล่างและบันทึกเป็น "image.png" บนระบบของคุณ:
สร้างอินดิเคเตอร์ใหม่ใน cTrader ตั้งชื่อเป็น "Image Sample" และเปิดผ่าน Visual Studio หลังจากนั้น ให้เพิ่มโครงการอินดิเคเตอร์โลโก้เป็นทรัพยากร เพื่อทำเช่นนั้น ให้คลิกขวาที่โครงการของคุณ เลือก Properties และคลิก Resources จากนั้นคลิก Create and manage assembly resources คัดลอกไฟล์ 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 )
{
}
}
}
หลังจากสร้างอินสแตนซ์ของอินดิเคเตอร์นี้ คุณควรเห็นผลลัพธ์ต่อไปนี้
หมายเหตุ
ขนาดสูงสุดสำหรับรูปภาพคือ 10 MB