Amostras de código de indicadores
Esta página fornece vários exemplos de código Python e C# para criar indicadores técnicos utilizados para negociação manual ou algorítmica.
Repositórios de amostras de indicadores
Amostras de código de indicadores abrangentes, incluindo modelos prontos a executar para vários tipos de indicadores e ferramentas de análise técnica, estão disponíveis em repositórios separados Python e C# no GitHub.
Indicadores simples
O indicador high minus low calcula a diferença entre os preços máximo e mínimo da barra atual e apresenta-a numa série de saída. A série é desenhada no gráfico como uma linha que liga os valores resultantes em cada barra.
1 2 3 4 5 6 7 8 9 10 11 | |
Nota
Os indicadores Python utilizam parâmetros personalizáveis declarados nos seus ficheiros .cs.
1 2 3 4 5 6 7 | |
A declaração [Indicator...] inclui vários parâmetros que são definidos da seguinte forma:
IsOverlay- um booleano que define se a linha será sobreposta no gráfico ou exibida num painel de UI separado.TimeZone- um campo da classeTimeZonesque especifica o fuso horário dos dados do indicador e o tempo do servidor.AccessRights- um campo da classeAccessRightsque determina os direitos de acesso atribuídos ao seu indicador.ScalePrecision- um int que define a precisão da escala da saída do indicador.
Como aprendeu anteriormente ao editar o código do indicador, o atributo Output é declarado para marcar uma propriedade como saída do indicador. Esta propriedade deve ser public para que possa ser referenciada por outras classes.
A saída do indicador deve ser sempre do tipo de dados IndicatorDataSeries, que é uma lista de doubles que pode ser indexada como um array. Portanto, o valor em cada [index] na lista Result pode ser atribuído no método Calculate da seguinte forma.
1 2 3 4 | |
1 2 | |
Indicadores com parâmetros
Na maioria dos casos, a saída dos indicadores pode variar dependendo da entrada do utilizador. A forma como os parâmetros personalizáveis são configurados para indicadores é semelhante a como isto é feito para cBots.
O indicador de média móvel simples abaixo foi concebido para aceitar uma fonte de preço e um período como parâmetros personalizáveis. Tais parâmetros (Source e Periods neste exemplo em particular) devem ser precedidos pelo atributo Parameter.
Semelhante aos atributos [Indicator()] e [Output()] discutidos anteriormente, o atributo [Parameter()] pode definir certas características aplicadas à entrada do utilizador.
1 | |
Nota
Os indicadores Python utilizam parâmetros personalizáveis declarados nos seus ficheiros .cs.
Acima, especificamos as seguintes características:
- O nome exibido para denotar este parâmetro na UI do cTrader (
"MA Periods"). - O valor predefinido do parâmetro; pode ser alterado pelo utilizador ao personalizar uma instância (
DefaultValue = 14) - Os valores mínimo e máximo do parâmetro (
MinValue = 1, MaxValue = 20)
No seguinte snippet, mostramos como os parâmetros personalizáveis podem ser integrados no código do indicador.
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 | |
Nota
Os indicadores Python utilizam parâmetros personalizáveis declarados nos seus ficheiros .cs.
1 2 3 4 5 6 7 8 | |
Indicadores aninhados
Indicadores aninhados são definidos como indicadores cujo valor depende dos resultados de cálculos realizados por outros indicadores. São úteis ao escrever certos tipos de extensões, como o indicador DeMark 9. Considere o seguinte código de exemplo:
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 | |
Nota
Os indicadores Python utilizam parâmetros personalizáveis declarados nos seus ficheiros .cs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
No exemplo acima, deMinMA e deMaxMA são duas variáveis utilizadas para calcular o valor do nosso indicador DeMarker.
Os indicadores aninhados precisam de ser definidos no método Initialize(). Por exemplo, deMinMA é definido como a média móvel simples da série deMin.
1 | |
1 | |
deMin, por sua vez, é definido no método Calculate() como o máximo dos dois últimos valores de preço baixo.
1 | |
1 | |
Para simplificar o trabalho com indicadores aninhados, o IntelliSense preenche automaticamente a lista de todos os indicadores integrados quando digita Indicators seguido de um ponto no editor de código. Também exibirá todos os parâmetros de entrada relacionados assim que selecionar um determinado indicador desta lista.

Carregamento preguiçoso
O cTrader Algo utiliza carregamento preguiçoso quando usa indicadores referenciados. Os valores fornecidos pelo indicador referenciado não são calculados até que o seu código comece a utilizá-los ativamente.
Se aceder aos dados Outputs de um indicador referenciado, o cTrader começará a carregar os dados do indicador chamando o seu método Calculate() em barras passadas e futuras. Em qualquer outro caso, o indicador referenciado permanecerá inativo e, portanto, não consumirá quaisquer recursos do sistema.
Isto também significa que se o seu indicador não tiver nenhum Output ou se tentar aceder a qualquer uma das suas propriedades públicas, obterá o valor predefinido da propriedade em questão. Para resolver este problema, chame o método Calculate() do seu indicador personalizado a partir do método Calculate() do indicador atual.
Osciladores e o atributo de níveis
O termo "osciladores" engloba todos os indicadores que oscilam em torno de uma determinada variável constante.
Ao criar osciladores, é útil primeiro desenhar uma linha horizontal ou "de nível" nesse valor constante; o indicador irá então oscilar em torno desta linha. Em muitos casos, o valor constante é igual a zero.
No exemplo abaixo, definimos um oscilador de momentum. Normalmente, oscila em torno do valor 100. Adicionamos uma linha de nível neste valor usando o atributo Levels que é declarado antes dos atributos do indicador.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
Nota
Os indicadores Python utilizam parâmetros personalizáveis declarados nos seus ficheiros .cs.
1 2 3 4 | |
Note que o atributo Levels só pode ser utilizado se o indicador não estiver sobreposto no gráfico, o que significa que a propriedade IsOverlay não está definida como true. Por predefinição, o valor de IsOverlay é false. Se este atributo for omitido do seu código, Levels deverá funcionar corretamente.
Se precisar de estabelecer várias linhas de "nível", adicione uma lista de valores separados por vírgulas entre parênteses, como mostrado abaixo.
1 | |
1 | |
1 | |
Níveis em Indicadores Python
Em Python, declara os Níveis no seu ficheiro de indicador C# da mesma forma que os indicadores C#.
A propriedade IsLastBar
Em alguns casos, pode querer criar um indicador que tenha de ser calculado apenas para a última barra no gráfico de negociação. Simplificando, a propriedade IsLastBar pode ser utilizada para verificar se o parâmetro de índice do método Calculate() é o da última barra.
O indicador abaixo baseia-se na hora UTC; no entanto, pode mostrar a última hora de abertura em Nova Iorque e Tóquio.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Combinar indicadores
O cTrader permite combinar vários indicadores no mesmo painel ou dentro do mesmo gráfico.
O seguinte indicador combina os indicadores Aroon, RSI e sistema de movimento direcional num só.
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 | |
Nota
Os indicadores Python utilizam parâmetros personalizáveis declarados nos seus ficheiros .cs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Múltiplos intervalos de tempo
-
Utilizar múltiplos intervalos de tempo
O seguinte exemplo mostra um indicador de Moving Average em diferentes intervalos de tempo.
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
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC)] public class MultiTF_MA : Indicator { [Parameter(DefaultValue = 50)] public int Period { get; set; } [Output("MA", LineColor = "Yellow")] public IndicatorDataSeries MA { get; set; } [Output("MA5", LineColor = "Orange")] public IndicatorDataSeries MA5 { get; set; } [Output("MA10", LineColor = "Red")] public IndicatorDataSeries MA10 { get; set; } private Bars bars5; private Bars bars10; private MovingAverage ma; private MovingAverage ma5; private MovingAverage ma10; protected override void Initialize() { bars5 = MarketData.GetBars(TimeFrame.Minute5); bars10 = MarketData.GetBars(TimeFrame.Minute10); ma = Indicators.MovingAverage(Bars.ClosePrices, Period, MovingAverageType.Triangular); ma5 = Indicators.MovingAverage(bars5.ClosePrices, Period, MovingAverageType.Triangular); ma10 = Indicators.MovingAverage(bars10.ClosePrices, Period, MovingAverageType.Triangular); } public override void Calculate(int index) { MA[index] = ma.Result[index]; var index5 = bars5.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]); if (index5 != -1) MA5[index] = ma5.Result[index5]; var index10 = bars10.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]); if (index10 != -1) MA10[index] = ma10.Result[index10]; } }Nota
Os indicadores Python utilizam parâmetros personalizáveis declarados nos seus ficheiros
.cs.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
class MultiTF_MA(): def initialize(self): self.bars5 = api.MarketData.GetBars(TimeFrame.Minute5) self.bars10 = api.MarketData.GetBars(TimeFrame.Minute10) # Period is declared as a parameter in the C# file # We use indicator time frame bars for this moving average self.ma = Indicators.MovingAverage(api.Bars.ClosePrices, api.Period, MovingAverageType.Triangular) # We use other two time frame bars that we created previously # for these two moving averages self.ma5 = Indicators.MovingAverage(self.bars5.ClosePrices, api.Period, MovingAverageType.Triangular) self.ma10 = Indicators.MovingAverage(self.bars10.ClosePrices, api.Period, MovingAverageType.Triangular) def calculate(self, index): # MA, MA5, and MA10 are outputs we declared in the C# file api.MA[index] = self.ma.Result[index] index5 = self.bars5.OpenTimes.GetIndexByTime(api.Bars.OpenTimes[index]) if index5 > -1: api.MA5[index] = self.ma5.Result[index5] index10 = self.bars10.OpenTimes.GetIndexByTime(api.Bars.OpenTimes[index]) if index10 > -1: api.MA10[index] = self.ma10.Result[index10] -
Utilizar múltiplos intervalos de tempo e símbolos
O seguinte exemplo mostra o indicador de Moving Average em múltiplos intervalos de tempo e símbolos.
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
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC)] public class MultiSymbolMA : Indicator { private MovingAverage ma1, ma2, ma3; private Bars bars2, bars3; private Symbol symbol2, symbol3; [Parameter(DefaultValue = "EURCHF")] public string Symbol2 { get; set; } [Parameter(DefaultValue = "EURCAD")] public string Symbol3 { get; set; } [Parameter(DefaultValue = 14)] public int Period { get; set; } [Parameter(DefaultValue = MovingAverageType.Simple)] public MovingAverageType MaType { get; set; } [Output("MA Symbol 1", LineColor = "Magenta")] public IndicatorDataSeries Result1 { get; set; } [Output("MA Symbol 2", LineColor = "Magenta")] public IndicatorDataSeries Result2 { get; set; } [Output("MA Symbol 3", LineColor = "Magenta")] public IndicatorDataSeries Result3 { get; set; } protected override void Initialize() { symbol2 = Symbols.GetSymbol(Symbol2); symbol3 = Symbols.GetSymbol(Symbol3); bars2 = MarketData.GetBars(TimeFrame, symbol2.Name); bars3 = MarketData.GetBars(TimeFrame, symbol3.Name); ma1 = Indicators.MovingAverage(Bars.ClosePrices, Period, MaType); ma2 = Indicators.MovingAverage(bars2.ClosePrices, Period, MaType); ma3 = Indicators.MovingAverage(bars3.ClosePrices, Period, MaType); } public override void Calculate(int index) { ShowOutput(Symbol, Result1, ma1, Bars, index); ShowOutput(symbol2, Result2, ma2, bars2, index); ShowOutput(symbol3, Result3, ma3, bars3, index); } private void ShowOutput(Symbol symbol, IndicatorDataSeries result, MovingAverage movingAverage, Bars bars, int index) { var index2 = bars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]); result[index] = movingAverage.Result[index2]; string text = string.Format("{0} {1}", symbol.Name, Math.Round(result[index], symbol.Digits)); Chart.DrawStaticText(symbol.Name, text, VerticalAlignment.Top, HorizontalAlignment.Right, Color.Yellow); } }Nota
Os indicadores Python utilizam parâmetros personalizáveis declarados nos seus ficheiros
.cs.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
class MultiSymbolMA(): def initialize(self): # Symbol2 and Symbol3 are declared as parameters in the C# file self.symbol2 = api.Symbols.GetSymbol(api.Symbol2) self.symbol3 = api.Symbols.GetSymbol(api.Symbol3) self.bars2 = api.MarketData.GetBars(api.TimeFrame, self.symbol2.Name) self.bars3 = api.MarketData.GetBars(api.TimeFrame, self.symbol3.Name) self.ma1 = api.Indicators.MovingAverage(api.Bars.ClosePrices, api.Period, api.MaType) self.ma2 = api.Indicators.MovingAverage(self.bars2.ClosePrices, api.Period, api.MaType) self.ma3 = api.Indicators.MovingAverage(self.bars3.ClosePrices, api.Period, api.MaType) def calculate(self, index): # Result1, Result2, and Result3 are declared as outputs in the C# file self.show_output(api.Symbol, api.Result1, self.ma1, api.Bars, index) self.show_output(self.symbol2, api.Result2, self.ma2, self.bars2, index) self.show_output(self.symbol3, api.Result3, self.ma3, self.bars3, index) def show_output(self, symbol, result, movingAverage, bars, index): index2 = bars.OpenTimes.GetIndexByTime(api.Bars.OpenTimes[index]) result[index] = movingAverage.Result[index2] text = f"{symbol.Name} {round(result[index], symbol.Digits)}" api.Chart.DrawStaticText(symbol.Name, text, VerticalAlignment.Top, HorizontalAlignment.Right, Color.Yellow)
