Os controlos permitem certas interações envolvendo cBots, indicadores e plugins. Usando o guia abaixo, pode criar facilmente controlos de UI básicos e avançados diretamente num gráfico.
Existem várias classes incorporadas que representam controlos populares, como botões, blocos de texto, caixas de texto e formas. No entanto, também pode criar controlos personalizados.
Se criar o indicador acima e criar uma instância, deverá ver um botão cinzento Click me no centro do gráfico.
Diferença entre controlos e objetos do gráfico
Numa secção anterior, já abordámos os objetos do gráfico. Os controlos permitem que os utilizadores interajam com cBots e indicadores. Por outro lado, os objetos do gráfico dão a oportunidade de desenhar algo no gráfico de negociação ou numa janela de saída de indicador separada.
Os controlos do gráfico derivam da classe ControlBase, enquanto os objetos do gráfico são derivados da classe ChartObject.
Os controlos do gráfico são posicionados estaticamente usando diferentes opções de alinhamento. Embora os objetos do gráfico possam ser posicionados exatamente da mesma forma, a sua posição também pode mudar dinamicamente dependendo de certas coordenadas X e Y.
De forma semelhante aos objetos do gráfico, os controlos do gráfico podem ser adicionados tanto ao gráfico principal como a quaisquer janelas de saída de indicadores (se existirem). Um exemplo desse posicionamento é dado abaixo:
Após criar uma instância do indicador, deverá ver um botão Click me na janela de saída do indicador.
ColorPicker
O controlo ColorPicker permite aos traders selecionar a sua cor preferida para elementos ou objetos-chave no cTrader. Por exemplo, um desenvolvedor pode integrar o controlo ColorPicker num cBot que desenha linhas de tendência para que os utilizadores possam selecionar a sua cor preferida para cada linha de tendência. Esta configuração facilita aos traders a distinção entre vários tipos de linhas de tendência.
Um plugin que adiciona indicadores aos gráficos também pode implementar o controlo ColorPicker, pois esta funcionalidade permite aos utilizadores escolher uma cor para diferentes linhas de indicadores.
Quando os utilizadores clicam no quadrado de cor, o seletor de cores aparece. Os utilizadores podem então escolher entre cores padrão e personalizadas.
O controlo DropZone permite aos traders realizar ações de arrastar e largar envolvendo cBots, indicadores ou plugins. Para implementar este controlo no seu algoritmo, utilize a classe DropZone. O controlo DropZone pode ser manipulado como qualquer outro controlo.
Quando um utilizador larga um ficheiro ou pasta compatível na caixa, o evento Dropped é gerado. Quando um utilizador larga uma pasta ou várias pastas na caixa, apenas os ficheiros compatíveis com as extensões especificadas em FilterExtensions são processados e copiados.
Nota
Os ficheiros largados são geralmente copiados e guardados nesta localização: ..\Documents\cAlgo\Data\{AlgoType}\{AlgoName}\Selected Files\
A localização para instâncias de cBot difere da acima: ..\Documents\cAlgo\Data\cBots\{cBotName}\{unique-instance-number}\Selected files\
Este código de plugin mostra-lhe como adicionar um controlo DropZone à Observação da Negociação:
usingSystem;usingSystem.Drawing;usingcAlgo.API;usingcAlgo.API.Collections;usingcAlgo.API.Indicators;usingcAlgo.API.Internals;namespacecAlgo.Plugins{[Plugin(AccessRights = AccessRights.None)]publicclassTradeWatchTabSample:Plugin{protectedoverridevoidOnStart(){vartab=TradeWatch.AddTab("DropZone");var_border=newBorder{BorderThickness=3,BorderColor=Color.DarkGray,Opacity=0.7,HorizontalAlignment=HorizontalAlignment.Center,VerticalAlignment=VerticalAlignment.Center,Height=200,Width=350,BackgroundColor=Color.LightGray};var_textBlock=newTextBlock{Text="Drag your files here",Opacity=1,ForegroundColor=Color.DarkGray,FontSize=16,VerticalAlignment=VerticalAlignment.Center,HorizontalAlignment=HorizontalAlignment.Center};var_dropzone=newDropZone{FilterExtensions=newstring[]{"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;}privatevoidDropped_file(DroppedEventArgsobj){Print("File has been added!");}}}
ProgressBar
O controlo ProgressBar apresenta a progressão de uma operação em curso. As barras de progresso tornam os algoritmos mais fáceis de utilizar e ajudam a gerir as expectativas dos traders em relação ao tempo de espera de certas operações.
A API cTrader Algo permite aos programadores adicionar dois tipos de controlos ProgressBar: controlo infinito e controlo determinado.
Controlo infinito
Pode querer utilizar o controlo infinito nas seguintes situações:
Não consegue determinar o tempo de espera de uma operação.
Não consegue detetar a progressão de uma operação.
Não quer indicar quanto tempo uma operação irá demorar.
Controlo determinado
Pode querer utilizar este controlo quando consegue determinar o tempo de espera de uma operação e quer que os utilizadores vejam um indicador baseado nesse tempo.
Para apresentar o progresso da operação, utilize a propriedade Value para definir um número. Para definir a percentagem da barra de progresso, utilize as propriedades Minimum e Maximum.
O código de plugin abaixo mostra-lhe como criar uma barra de progresso utilizando controlos infinitos e determinados (verde):
A API cTrader Algo fornece a interface OpenFileDialog para permitir que os utilizadores selecionem um ficheiro para um algoritmo. Quando um utilizador seleciona um ficheiro na janela resultante, o ficheiro é copiado para a pasta Selected files do algoritmo. Um algoritmo pode trabalhar com ficheiros dentro da sua pasta Selected files sem restrições.
Dica
Utilize a funcionalidade OpenFileDialog quando precisar de carregar ficheiros de dados importantes, ficheiros de backup ou configuração, indicadores personalizados ou scripts.
O código abaixo mostra-lhe como utilizar o diálogo OpenFileDialog num indicador:
A API cTrader Algo fornece a interface OpenFolderDialog para permitir que os utilizadores especifiquem uma pasta para um algoritmo. Quando um utilizador seleciona uma pasta na janela resultante, todos os ficheiros e pastas com ficheiros dentro da pasta selecionada são copiados para a pasta Selected files do algoritmo.
Dica
Utilize a funcionalidade OpenFolderDialog quando precisar de carregar uma pasta contendo ficheiros de dados críticos, ficheiros de backup ou configuração, indicadores personalizados ou scripts.
Os ficheiros e pastas selecionados são geralmente copiados para a pasta Selected files porque um algoritmo pode trabalhar com itens dentro dessa pasta mesmo quando o seu AccessRights está definido como None.
Nota
A pasta Selected files de um algoritmo está geralmente neste caminho: ..\Documents\cAlgo\Data\{AlgoType}\{AlgoName}\Selected files\
A pasta Selected files para uma instância de cBot difere da acima: ..\Documents\cAlgo\Data\cBots\{cBotName}\{Instance-Id}\Selected files\
O código abaixo mostra-lhe como utilizar o diálogo OpenFolderDialog num indicador:
usingSystem;usingcAlgo.API;namespacecAlgo{[Indicator(AccessRights = AccessRights.None, IsOverlay = true)]publicclassOpenFolderDialogExample:Indicator{privateOpenFolderDialog_openFolderDialog;protectedoverridevoidInitialize(){_openFolderDialog=newOpenFolderDialog(){InitialDirectory=Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),Title="My Open Folder Dialog Title"};varshowOpenFolderDialog=newButton{Text="Show Open Folder Dialog"};showOpenFolderDialog.Click+=showOpenFolderDialog_Click;varpanel=newStackPanel{Orientation=Orientation.Vertical,HorizontalAlignment=HorizontalAlignment.Center,VerticalAlignment=VerticalAlignment.Center};panel.AddChild(showOpenFolderDialog);Chart.AddControl(panel);}privatevoidshowOpenFolderDialog_Click(ButtonClickEventArgsobj){varresult=_openFolderDialog.ShowDialog();Print($"Result: {result} | FolderName: {_openFolderDialog.FolderName}");}publicoverridevoidCalculate(intindex){}}}
SaveFileDialog
A API cTrader Algo fornece a interface SaveFileDialog para permitir que os utilizadores guardem ficheiros (localmente) nos seus computadores. Quando a janela relevante aparece, um utilizador seleciona a pasta onde quer guardar o ficheiro e introduz um nome para o ficheiro. O ficheiro é então guardado na localização especificada.
Dica
Utilize a funcionalidade SaveFileDialog quando precisar de fazer qualquer uma das seguintes ações:
Guardar relatórios de desempenho, resultados de testes de verificação, ficheiros de configuração ou dados de otimização.
Exportar registos de negociação, diários de operações ou dados gerais de atividade do utilizador.
Armazenar indicadores personalizados, dados para gráficos e visualizações ou parâmetros para uma estratégia.
O código abaixo mostra-lhe como utilizar o diálogo SaveFileDialog num indicador:
usingSystem;usingcAlgo.API;usingSystem.Text;namespacecAlgo{[Indicator(AccessRights = AccessRights.None, IsOverlay = true)]publicclassSaveFileDialogExample:Indicator{privateSaveFileDialog_saveFileDialog;protectedoverridevoidInitialize(){_saveFileDialog=newSaveFileDialog(){InitialDirectory=Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),Title="My Save File Dialog Title"};varshowSaveFileDialogText=newButton{Text="Show Save File Dialog (Set Content as text)"};varshowSaveFileDialogBytes=newButton{Text="Show Save File Dialog (Set Content as bytes)"};showSaveFileDialogText.Click+=showSaveFileDialogText_Click;showSaveFileDialogBytes.Click+=showSaveFileDialogBytes_Click;varpanel=newStackPanel{Orientation=Orientation.Vertical,HorizontalAlignment=HorizontalAlignment.Center,VerticalAlignment=VerticalAlignment.Center};panel.AddChild(showSaveFileDialogText);panel.AddChild(showSaveFileDialogBytes);Chart.AddControl(panel);}privatevoidshowSaveFileDialogText_Click(ButtonClickEventArgsobj){varresult=_saveFileDialog.ShowDialog();Print($"Result: {result}");if(result!=FileDialogResult.Cancel){_saveFileDialog.WriteToFile("Test in text");}}privatevoidshowSaveFileDialogBytes_Click(ButtonClickEventArgsobj){varresult=_saveFileDialog.ShowDialog();Print($"Result: {result}");if(result!=FileDialogResult.Cancel){_saveFileDialog.WriteToFile(Encoding.UTF8.GetBytes("Test in bytes"));}}publicoverridevoidCalculate(intindex){}}}
Controlos arrastáveis
Controlo arrastável da área do gráfico
As interfaces ChartDraggable e ChartDraggables fornecem tipos que permitem adicionar um controlo arrastável capaz de alojar outros controlos e diferentes elementos a um gráfico. Estes controlos arrastáveis facilitam a interação dos utilizadores com vários elementos do gráfico.
Nota
Um controlo arrastável só pode ser movido ou reposicionado dentro do gráfico onde foi adicionado.
Este código mostra-lhe como criar um indicador que adiciona dois controlos que podem ser movidos dentro de um gráfico:
usingSystem;usingcAlgo.API;usingcAlgo.API.Collections;usingcAlgo.API.Indicators;usingcAlgo.API.Internals;namespacecAlgo{[Indicator(AccessRights = AccessRights.None)]publicclassDragControl:Indicator{protectedoverridevoidInitialize(){vardraggable=Chart.Draggables.Add();vardraggable2=IndicatorArea.Draggables.Add();draggable.Child=GetDraggableChildWebView();draggable2.Child=GetDraggableChildText();draggable.LocationChanged+=draggable_LocationChanged;draggable2.LocationChanged+=draggable2_LocationChanged;}publicoverridevoidCalculate(intindex){// Calculate value at specified index// Result[index] = }privateStackPanelGetDraggableChildWebView(){varstackPanel=newStackPanel{HorizontalAlignment=HorizontalAlignment.Center,VerticalAlignment=VerticalAlignment.Center,BackgroundColor=Color.Gold};varwebView=newWebView(){Height=500,Width=300};webView.Loaded+=webView_Loaded;stackPanel.AddChild(webView);returnstackPanel;}privateStackPanelGetDraggableChildText(){varstackPanel=newStackPanel{HorizontalAlignment=HorizontalAlignment.Center,VerticalAlignment=VerticalAlignment.Center,BackgroundColor=Color.Gold};vartext_block=newTextBlock{Text="Testing draggable controls",Margin=5,ForegroundColor=Color.Black,FontWeight=FontWeight.ExtraBold};stackPanel.AddChild(text_block);returnstackPanel;}privatevoidwebView_Loaded(WebViewLoadedEventArgsobj){obj.WebView.NavigateAsync("https://www.youtube.com/");}privatevoiddraggable_LocationChanged(ChartDraggableLocationChangedEventArgsobj){Print($"Draggable '{obj.Draggable.Id}' location changed to: ({obj.Draggable.X}, {obj.Draggable.Y})");}privatevoiddraggable2_LocationChanged(ChartDraggableLocationChangedEventArgsobj){Print($"Draggable '{obj.Draggable.Id}' location changed to: ({obj.Draggable.X}, {obj.Draggable.Y})");}}}
Controlo arrastável da janela da aplicação
As interfaces ApplicationDraggable e ApplicationDraggables fornecem os tipos utilizados para adicionar controlos flutuantes que podem ser movidos individualmente por toda a janela da aplicação cTrader. Tais controlos permitem-lhe criar interfaces de utilizador interativas e dinâmicas.
Nota
Dos três tipos de algoritmos, apenas os plugins têm permissão para implementar controlos arrastáveis em toda a aplicação.
Este código mostra-lhe como criar um plugin que adiciona um componente WebView e um bloco de texto em duas janelas separadas, que podem ser movidas por toda a interface do cTrader:
A classe TabControl fornece tipos que permitem criar vários separadores para um algoritmo. Estes separadores podem ser utilizados para manter elementos relacionados juntos ou apresentar vistas separadas para funcionalidades.
Este código mostra-lhe como utilizar separadores num plugin adicionado ao Painel de símbolo ativo:
Um controlo personalizado é um controlo que é, essencialmente, construído a partir de vários controlos pré-definidos. Por outras palavras, é um controlo para o qual outros controlos constituem o seu conteúdo.
Os controlos personalizados atuam como classes reutilizáveis, de forma semelhante aos controlos integrados.
usingcAlgo.API;namespaceChartControlsTest{[Indicator(IsOverlay = true, AccessRights = AccessRights.None)]publicclassChartControls:Indicator{[Parameter("# Of Text Areas", DefaultValue = 4)]publicintNumberOfTextAreas{get;set;}protectedoverridevoidInitialize(){varpanel=newWrapPanel{Orientation=Orientation.Horizontal,HorizontalAlignment=HorizontalAlignment.Center,VerticalAlignment=VerticalAlignment.Center};for(inti=0;i<NumberOfTextAreas;i++){vartextArea=newTextArea{HorizontalAlignment=HorizontalAlignment.Right,VerticalAlignment=VerticalAlignment.Stretch,Margin=5,};panel.AddChild(textArea);}Chart.AddControl(panel);}publicoverridevoidCalculate(intindex){}}publicclassTextArea:CustomControl{privatereadonlyTextBox_textBox;publicTextArea(){_textBox=newTextBox{TextAlignment=TextAlignment.Left,TextWrapping=TextWrapping.Wrap,AcceptsReturn=true,AcceptsTab=true,Width=300,Height=200,};AddChild(_textBox);}}}
Uma instância deste indicador deve apresentar quatro caixas de texto diretamente no centro do gráfico principal.
Organizar controlos com painéis
Para tornar o trabalho com controlos mais conveniente, poderá querer colocar vários controlos num grupo distinto com a sua própria posição na interface do utilizador. Para fazer isto, pode utilizar a classe Panels e os seus derivados.
Pense num painel como um controlo com outros controlos como o seu conteúdo. O cTrader suporta cinco classes diferentes que herdam da classe base Panels (que por sua vez herda da classe Control):
Canvas
DockPanel
Grid
StackPanel
WrapPanel
Cada uma das classes acima utiliza diferentes layouts de painel e estratégias de posicionamento, como discutido abaixo.
Canvas
O canvas é um painel que permite o posicionamento de controlos com base em determinadas coordenadas X e Y.
Notavelmente, os eixos X e Y são diferentes dos utilizados por objetos de gráfico ou desenhos. As coordenadas X e Y utilizadas pela classe Canvas representam valores numéricos começando em (0, 0) a partir do canto superior esquerdo do gráfico.
usingcAlgo.API;namespaceChartControlsTest{[Indicator(IsOverlay = true, AccessRights = AccessRights.None)]publicclassChartControls:Indicator{[Parameter(DefaultValue = "Click Me")]publicstringText{get;set;}[Parameter(DefaultValue = 0)]publicdoubleLeft{get;set;}[Parameter(DefaultValue = 0)]publicdoubleTop{get;set;}[Parameter(DefaultValue = 0)]publicdoubleMargin{get;set;}[Parameter(DefaultValue = 10)]publicdoublePadding{get;set;}protectedoverridevoidInitialize(){varbutton=newButton{Text=Text,Left=Left,Top=Top,Margin=Margin,Padding=Padding};button.Click+=Button_Click;varcanvas=newCanvas();/* We add our button control to the canvas panel. */canvas.AddChild(button);// We add our canvas panel to the chart.Chart.AddControl(canvas);}privatevoidButton_Click(ButtonClickEventArgsobj){obj.Button.Text="You clicked me, thanks";}publicoverridevoidCalculate(intindex){}}}
Ao criar uma instância do indicador acima, deverá ver o botão Click me no canto superior esquerdo do gráfico.
A propriedade Top de um controlo determina o seu posicionamento no eixo Y. Por sua vez, a propriedade Left define o seu posicionamento no eixo X.
O código acima também utiliza as propriedades Padding e Margin. Padding refere-se à distância entre o conteúdo do controlo e as suas bordas exteriores. Margin é a distância entre o controlo e as bordas do seu pai. As propriedades Padding e Margin são aplicáveis a todos os painéis, não apenas à classe canvas. São úteis para gerir o espaçamento entre os seus controlos.
Na maioria dos casos, a classe Canvas é utilizada para agrupar apenas um pequeno número de controlos.
Painel de ancoragem
A classe DockPanel é utilizada para ancorar (colocar) um controlo numa localização estática no gráfico. Existem quatro posições de ancoragem possíveis:
Topo
Fundo
Esquerda
Direita
Cada controlo tem uma propriedade Dock. Ao utilizar a classe DockPanel, pode usar esta propriedade para posicionar um controlo dentro de um DockPanel. Isto é ilustrado no seguinte exemplo:
usingcAlgo.API;namespaceChartControlsTest{[Indicator(IsOverlay = true, AccessRights = AccessRights.None)]publicclassChartControls:Indicator{[Parameter(DefaultValue = Dock.Top)]publicDockTextBoxDock{get;set;}[Parameter(DefaultValue = Dock.Bottom)]publicDockButtonDock{get;set;}privateTextBox_textBox;protectedoverridevoidInitialize(){_textBox=newTextBox{Margin=5,Text="Write here...",ForegroundColor=Color.Yellow,Dock=TextBoxDock,Width=200};varbutton=newButton{Text="Tell what I wrote?",Dock=ButtonDock,Width=200};button.Click+=Button_Click;vardockPanel=newDockPanel{HorizontalAlignment=HorizontalAlignment.Center,VerticalAlignment=VerticalAlignment.Center,};dockPanel.AddChild(_textBox);dockPanel.AddChild(button);Chart.AddControl(dockPanel);}privatevoidButton_Click(ButtonClickEventArgsobj){obj.Button.Text=$"You wrote: {_textBox.Text}";}publicoverridevoidCalculate(intindex){}}}
Ao criar uma instância deste indicador, deverá ver um painel de ancoragem no centro do gráfico contendo um campo de texto e um botão clicável.
Note que os painéis de ancoragem podem ser preenchidos horizontal ou verticalmente. Não pode utilizar ambos estes alinhamentos ao mesmo tempo. A orientação do painel de ancoragem é definida automaticamente ao configurar o primeiro controlo num DockPanel. Se a propriedade Dock do primeiro controlo for definida como Top ou Bottom, todo o DockPanel será orientado verticalmente, e vice-versa.
Painel de pilha
Os painéis de pilha são um dos controlos mais frequentemente utilizados devido à sua simplicidade e usabilidade. Os painéis de pilha alinham os controlos filhos horizontal ou verticalmente, um a um. Como mostrado abaixo, só tem de definir a sua orientação e a classe irá gerir o resto:
Após criar uma instância do indicador, deverá ver um painel de pilha horizontal com dois campos de texto e um botão 'Submit' no canto inferior direito do gráfico principal.
Painel de envolvimento
Os painéis de envolvimento são maioritariamente idênticos aos painéis de pilha. No entanto, quando não há espaço suficiente para acomodar todos os elementos de um painel de envolvimento, este irá automaticamente envolver os controlos restantes para a linha seguinte no eixo Y.
Grelha
Pense nas grelhas como folhas de cálculo com um número definido de colunas e linhas. Ao utilizar grelhas, pode adicionar controlos a cada célula separada.
Como demonstrado abaixo, quando cria uma instância da classe Grid, passa o número das suas linhas e colunas como argumentos integer. Ao adicionar novos filhos ou controlos, tem de especificar de forma semelhante o número de linhas e colunas filhas.
Ao criar uma instância do indicador acima, deverá ver uma grelha 10x2 mesmo no centro do gráfico.
Controlos de posição dentro das coordenadas de preço e tempo
Além dos controlos do painel, o cTrader permite especificar coordenadas de preço e tempo para controlos diretamente na área do gráfico. Os métodos AddControl() e MoveControl() fornecem aos desenvolvedores de algoritmos esta funcionalidade.
Utilize as seguintes sobrecargas de método para gerir as coordenadas dos seus controlos de gráfico de acordo com as suas preferências.
Para adicionar um controlo de gráfico à área do gráfico ou do indicador em coordenadas absolutas de índice de barra e preço (x, y).
Para adicionar um controlo de gráfico à área do gráfico ou do indicador na coordenada absoluta de tempo (x).
1
voidAddControl(ControlBasecontrol,DateTimetime)
Para mover um controlo de gráfico para a área do gráfico ou do indicador na coordenada absoluta de tempo (x).
1
voidMoveControl(ControlBasecontrol,DateTimetime)
Para adicionar um controlo de gráfico à área do gráfico ou do indicador na coordenada absoluta de índice de barra (x).
1
voidAddControl(ControlBasecontrol,intbarIndex)
Para mover um controlo de gráfico para a área do gráfico ou do indicador na coordenada absoluta de índice de barra (x).
1
voidMoveControl(ControlBasecontrol,intbarIndex)
Para adicionar um controlo de gráfico à área do gráfico ou do indicador na coordenada absoluta de preço (y).
1
voidAddControl(ControlBasecontrol,doubley)
Para mover um controlo de gráfico para a área do gráfico ou do indicador na coordenada absoluta de preço (y).
1
voidMoveControl(ControlBasecontrol,doubley)
O parâmetro da classe ControlBase pode incluir qualquer outra classe subordinada (Control, Button, etc.) para que o método seja chamado de acordo com as assinaturas acima.
O seguinte exemplo de cBot adiciona o botão Clique-me! acima da última barra no gráfico. O botão é movido para a frente juntamente com cada nova barra adicionada. Após clicar no botão, aparece uma caixa de mensagem no ecrã.
O número de controlos raiz a serem adicionados num gráfico é limitado a 100 devido a possíveis problemas de desempenho. Esta limitação aplica-se apenas a uma instância de algoritmo e controlos anexados ao preço e barras.
Propriedades de preenchimento e margem
A propriedade Margin define o espaço entre as bordas de um objeto Control e o seu pai (um gráfico, um painel, uma borda, etc.).
Por sua vez, a propriedade Padding determina o espaço entre o conteúdo do controlo e as suas bordas. Pode variar os valores da propriedade para que sejam todos diferentes para lados diferentes.
usingcAlgo.API;namespaceChartControlsTest{[Indicator(IsOverlay = true, AccessRights = AccessRights.None)]publicclassChartControls:Indicator{[Parameter(DefaultValue = "Click Me")]publicstringText{get;set;}[Parameter(DefaultValue = 0)]publicdoubleLeft{get;set;}[Parameter(DefaultValue = 0)]publicdoubleTop{get;set;}[Parameter(DefaultValue = 0, Group = "Margin")]publicdoubleLeftMargin{get;set;}[Parameter(DefaultValue = 0, Group = "Margin")]publicdoubleTopMargin{get;set;}[Parameter(DefaultValue = 0, Group = "Margin")]publicdoubleRightMargin{get;set;}[Parameter(DefaultValue = 0, Group = "Margin")]publicdoubleBottomMargin{get;set;}[Parameter(DefaultValue = 5, Group = "Padding")]publicdoubleLeftPadding{get;set;}[Parameter(DefaultValue = 5, Group = "Padding")]publicdoubleTopPadding{get;set;}[Parameter(DefaultValue = 5, Group = "Padding")]publicdoubleRightPadding{get;set;}[Parameter(DefaultValue = 5, Group = "Padding")]publicdoubleBottomPadding{get;set;}protectedoverridevoidInitialize(){varbutton=newButton{Text=Text,Left=Left,Top=Top,Margin=newThickness(LeftMargin,TopMargin,RightMargin,BottomMargin),Padding=newThickness(LeftPadding,TopPadding,RightPadding,BottomPadding)};button.Click+=Button_Click;varcanvas=newCanvas();canvas.AddChild(button);Chart.AddControl(canvas);}privatevoidButton_Click(ButtonClickEventArgsobj){obj.Button.Text="You clicked me, thanks";}publicoverridevoidCalculate(intindex){}}}
Uma instância deste indicador irá criar um botão cinzento Clique-me no canto superior esquerdo do gráfico. Modifique os parâmetros nas janelas Adicionar instância ou Modificar parâmetros para ver exatamente como diferentes valores de margem e preenchimento alteram a forma como o controlo é exibido.
Estilos
Ao usar estilos, pode dar uma aparência semelhante a vários tipos diferentes de controlos. Isto é particularmente útil quando se lida com um grande número (cinco ou mais) de controlos.
A classe Style permite definir valores para diferentes propriedades de controlos, como Margin ou BackgroundColor. Posteriormente, pode reutilizar estes valores como um modelo para vários outros controlos.
Também podemos criar uma aparência consistente para vários controlos sem usar a classe Style de todo.
usingcAlgo.API;namespaceChartControlsTest{[Indicator(IsOverlay = true, AccessRights = AccessRights.None)]publicclassChartControls:Indicator{protectedoverridevoidInitialize(){vartextBoxStyle=newStyle();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 textboxtextBoxStyle.Set(ControlProperty.ForegroundColor,Color.Yellow,ControlState.Hover);varfirstTextBox=newTextBox{Text="Type...",Style=textBoxStyle};varsecondTextBox=newTextBox{Text="Type...",Style=textBoxStyle};varthirdTextBox=newTextBox{Text="Type...",Style=textBoxStyle};varpanel=newStackPanel{Orientation=Orientation.Vertical,HorizontalAlignment=HorizontalAlignment.Center,VerticalAlignment=VerticalAlignment.Center};panel.AddChild(firstTextBox);panel.AddChild(secondTextBox);panel.AddChild(thirdTextBox);Chart.AddControl(panel);}publicoverridevoidCalculate(intindex){}}}
Imagem
O controlo Image pode ser usado para exibir uma imagem armazenada localmente. O controlo Image usa a classe Bitmap .NET, o que significa que suporta a maioria dos formatos de imagem populares, tais como os seguintes:
.PNG
.JPG
.BMP
.GIF
.TIFF
Consulte a documentação da classe Bitmap .NET para saber mais sobre ela.
Para usar um controlo Image, defina a sua propriedade Source para os dados do ficheiro de imagem num array de bytes (byte[]).
Após lançar uma instância do indicador acima, não deverá ver nada de novo no gráfico principal. No entanto, insira um caminho de ficheiro válido como valor do parâmetro (Caminho do Ficheiro de Imagem), e deverá ver a imagem escolhida exibida no centro do ecrã.
Também pode usar os recursos do seu projeto para armazenar imagens e exibi-las através do controlo Image. Para fazer isso, abra os recursos do projeto no Visual Studio e mude para a aba Resources. Nela, crie um novo recurso e adicione uma imagem existente. Depois, poderá usar esta imagem como fonte em qualquer controlo Image através da propriedade Project_Name_Space.Properties.Resources._Image_Name.
Como exemplo, copie a imagem abaixo e guarde-a como "image.png" no seu sistema:
Crie um novo indicador no cTrader, defina o seu nome como "Image Sample", e abra-o através do Visual Studio. Depois, adicione o indicador de logótipo ao projeto como um recurso. Para fazer isso, clique com o botão direito no seu projeto, selecione Properties e clique em Resources, depois clique em Create and manage assembly resources. Copie o ficheiro logo.png para a aba recém-aberta.
Copie o código abaixo para o ficheiro de código-fonte principal do seu indicador: