Muestras de código de indicadores
Esta página proporciona varios ejemplos de código en Python y C# para crear indicadores técnicos utilizados para operaciones manuales o algorítmicas.
Repositorios de muestras de indicadores
Muestras de código de indicadores completas, incluyendo plantillas listas para ejecutar para varios tipos de indicadores y herramientas de análisis técnico, están disponibles en repositorios separados de Python y C# en GitHub.
Indicadores simples
El indicador de máximo menos mínimo calcula la diferencia entre los precios máximo y mínimo de la barra actual y la muestra en una serie de salida. La serie se dibuja en el gráfico como una línea que conecta los valores resultantes en cada barra.
1 2 3 4 5 6 7 8 9 10 11 | |
Nota
Los indicadores de Python utilizan parámetros personalizables declarados en sus archivos .cs.
1 2 3 4 5 6 7 | |
La declaración [Indicator...] incluye varios parámetros que se definen de la siguiente manera:
IsOverlay- un booleano que define si la línea se superpondrá en el gráfico o se mostrará en un panel de interfaz de usuario separado.TimeZone- un campo de la claseTimeZonesque especifica la zona horaria de los datos del indicador y la hora del servidor.AccessRights- un campo de la claseAccessRightsque determina los derechos de acceso asignados a su indicador.ScalePrecision- un entero que configura la precisión de escala de la salida del indicador.
Como aprendió anteriormente al editar el código del indicador, el atributo Output se declara para marcar una propiedad como salida del indicador. Esta propiedad debe ser public para que pueda ser referenciada por otras clases.
La salida del indicador siempre debe ser del tipo de datos IndicatorDataSeries, que es una lista de doubles que se puede indexar como un array. Por lo tanto, el valor en cada [index] en la lista Result se puede asignar en el método Calculate de la siguiente manera.
1 2 3 4 | |
1 2 | |
Indicadores con parámetros
En la mayoría de los casos, la salida de los indicadores puede variar dependiendo de la entrada del usuario. La forma en que se configuran los parámetros personalizables para los indicadores es similar a cómo se hace para los cBots.
El siguiente indicador de media móvil simple está diseñado para aceptar una fuente de precio y un período como parámetros personalizables. Dichos parámetros (Source y Periods en este ejemplo particular) deben ir precedidos por el atributo Parameter.
De manera similar a los atributos [Indicator()] y [Output()] discutidos anteriormente, el atributo [Parameter()] puede definir ciertas características aplicadas a la entrada del usuario.
1 | |
Nota
Los indicadores de Python utilizan parámetros personalizables declarados en sus archivos .cs.
Arriba, especificamos las siguientes características:
- El nombre que se muestra para denotar este parámetro en la interfaz de usuario de cTrader (
"MA Periods"). - El valor predeterminado del parámetro; puede ser cambiado por el usuario al personalizar una instancia (
DefaultValue = 14) - Los valores mínimo y máximo del parámetro (
MinValue = 1, MaxValue = 20)
En el siguiente fragmento, mostramos cómo se pueden integrar los parámetros personalizables en el código del 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
Los indicadores de Python utilizan parámetros personalizables declarados en sus archivos .cs.
1 2 3 4 5 6 7 8 | |
Indicadores anidados
Los indicadores anidados se definen como indicadores cuyo valor depende de los resultados de los cálculos realizados por otros indicadores. Son útiles al escribir ciertos tipos de extensiones como el indicador DeMark 9. Considere el siguiente código de ejemplo:
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
Los indicadores de Python utilizan parámetros personalizables declarados en sus archivos .cs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
En el ejemplo anterior, deMinMA y deMaxMA son dos variables utilizadas para calcular el valor de nuestro indicador DeMarker.
Los indicadores anidados deben definirse en el método Initialize(). Por ejemplo, deMinMA se define como la media móvil simple de la serie deMin.
1 | |
1 | |
deMin, a su vez, se define en el método Calculate() como el máximo de los dos últimos valores de precio mínimo.
1 | |
1 | |
Para simplificar el trabajo con indicadores anidados, IntelliSense completa automáticamente la lista de todos los indicadores incorporados cuando escribe Indicators seguido de un punto en el editor de código. También mostrará todos los parámetros de entrada relacionados una vez que seleccione un indicador determinado de esta lista.

Carga perezosa
cTrader Algo utiliza carga perezosa cuando usa indicadores referenciados. Los valores proporcionados por el indicador referenciado no se calculan hasta que su código comienza a usarlos activamente.
Si accede a los datos Outputs de un indicador referenciado, cTrader comenzará a cargar los datos del indicador llamando a su método Calculate() en barras pasadas y futuras. En cualquier otro caso, el indicador referenciado permanecerá inactivo y, por lo tanto, no consumirá ningún recurso del sistema.
Esto también significa que si su indicador no tiene ningún Output o si intenta acceder a cualquiera de sus propiedades públicas, obtendrá el valor predeterminado de la propiedad en cuestión. Para resolver este problema, llame al método Calculate() de su indicador personalizado desde el método Calculate() del indicador actual.
Osciladores y el atributo de niveles
El término "osciladores" abarca todos los indicadores que oscilan alrededor de una cierta variable constante.
Al crear osciladores, es útil dibujar primero una línea horizontal o de "nivel" en ese valor constante; el indicador luego oscilará alrededor de esta línea. En muchos casos, el valor constante es igual a cero.
En el ejemplo siguiente, definimos un oscilador de momento. Típicamente oscila alrededor del valor de 100. Agregamos una línea de nivel en este valor usando el atributo Levels que se declara antes de los atributos del indicador.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
Nota
Los indicadores de Python utilizan parámetros personalizables declarados en sus archivos .cs.
1 2 3 4 | |
Tenga en cuenta que el atributo Levels solo se puede usar si el indicador no está superpuesto en el gráfico, lo que significa que la propiedad IsOverlay no está configurada como true. Por defecto, el valor de IsOverlay es false. Si este atributo se omite en su código, Levels debería funcionar correctamente.
Si necesita establecer múltiples líneas de "nivel", agregue una lista de valores separados por comas dentro del paréntesis como se muestra a continuación.
1 | |
1 | |
1 | |
Niveles en indicadores Python
En Python, declara los Niveles en su archivo C# del indicador de la misma manera que los indicadores C#.
La propiedad IsLastBar
En algunos casos, es posible que desee crear un indicador que deba calcularse solo para la última barra en el gráfico de operaciones. Simplificando esto, la propiedad IsLastBar se puede usar para verificar si el parámetro de índice del método Calculate() es el de la última barra.
El siguiente indicador se basa en la hora UTC; sin embargo, puede mostrar la última hora de apertura en Nueva York y Tokio.
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 | |
Combinando indicadores
cTrader permite combinar múltiples indicadores en el mismo panel o dentro del mismo gráfico.
El siguiente indicador combina los indicadores Aroon, RSI y sistema de movimiento direccional en uno.
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
Los indicadores de Python utilizan parámetros personalizables declarados en sus archivos .cs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Múltiples marcos de tiempo
-
Usando múltiples marcos de tiempo
El siguiente ejemplo muestra un indicador de media móvil en diferentes períodos de tiempo.
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
Los indicadores de Python utilizan parámetros personalizables declarados en sus archivos
.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] -
Usando múltiples marcos de tiempo y símbolos
El siguiente ejemplo muestra el indicador de media móvil en múltiples períodos de tiempo y 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
Los indicadores de Python utilizan parámetros personalizables declarados en sus archivos
.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)
