지표 코드 샘플
이 페이지에서는 수동 또는 알고리즘 트레이딩에 사용되는 기술적 지표를 생성하기 위한 여러 Python 및 C# 코드 예제를 제공합니다.
지표 샘플 저장소
다양한 지표 유형 및 기술적 분석 도구를 위한 실행 가능한 템플릿을 포함한 포괄적인 지표 코드 샘플은 GitHub의 별도 Python 및 C# 저장소에서 확인할 수 있습니다.
간단한 지표
High Minus Low 지표는 현재 바의 고가와 저가 사이의 차이를 계산하고 이를 출력 시리즈로 표시합니다. 이 시리즈는 각 바에서 결과값을 연결하는 선으로 차트에 그려집니다.
1 2 3 4 5 6 7 8 9 10 11 | |
참고
Python 지표는 .cs 파일에 선언된 맞춤형 매개변수를 사용합니다.
1 2 3 4 5 6 7 | |
[Indicator...] 선언에는 다음과 같이 정의된 여러 매개변수가 포함됩니다:
IsOverlay- 선이 차트 위에 오버레이될지 아니면 별도의 UI 패널에 표시될지를 정의하는 불리언 값입니다.TimeZone- 지표 데이터와 서버 시간의 시간대를 지정하는TimeZones클래스 필드입니다.AccessRights- 지표에 할당된 접근 권한을 결정하는AccessRights클래스 필드입니다.ScalePrecision- 지표 출력의 스케일 정밀도를 설정하는 정수입니다.
이전에 지표 코드를 편집할 때 배운 것처럼, Output 속성은 지표 출력으로 표시할 속성을 표시하기 위해 선언됩니다. 이 속성은 다른 클래스에서 참조할 수 있도록 public으로 선언되어야 합니다.
지표 출력은 항상 IndicatorDataSeries 데이터 타입이어야 하며, 이는 배열처럼 인덱싱할 수 있는 더블 값의 리스트입니다. 따라서 Calculate 메서드에서 Result 리스트의 각 [index]에 값을 할당할 수 있습니다.
1 2 3 4 | |
1 2 | |
매개변수가 있는 지표
대부분의 경우, 지표의 출력은 사용자 입력에 따라 달라질 수 있습니다. 지표에 대한 맞춤형 매개변수를 설정하는 방법은 cBot에 대해 이렇게 설정하는 방법과 유사합니다.
아래의 Simple Moving Average 지표는 가격 소스와 기간을 맞춤형 매개변수로 받도록 설계되었습니다. 이러한 매개변수(이 예제에서는 Source 및 Periods)는 Parameter 속성 앞에 와야 합니다.
이전에 논의한 [Indicator()] 및 [Output()] 속성과 유사하게, [Parameter()] 속성은 사용자 입력에 적용될 특정 특성을 정의할 수 있습니다.
1 | |
참고
Python 지표는 .cs 파일에 선언된 맞춤형 매개변수를 사용합니다.
위에서 우리는 다음 특성을 지정합니다:
- cTrader UI에서 이 매개변수를 나타내는 이름(
"MA Periods"). - 매개변수의 기본값; 사용자가 인스턴스를 맞춤 설정할 때 변경할 수 있습니다(
DefaultValue = 14). - 매개변수의 최소 및 최대 값(
MinValue = 1, MaxValue = 20).
다음 스니펫에서는 맞춤형 매개변수가 지표 코드에 통합될 수 있는 방법을 보여줍니다.
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 | |
참고
Python 지표는 .cs 파일에 선언된 맞춤형 매개변수를 사용합니다.
1 2 3 4 5 6 7 8 | |
중첩 지표
중첩 지표는 다른 지표의 계산 결과에 따라 값이 결정되는 지표로 정의됩니다. 이러한 지표는 DeMark 9 지표와 같은 특정 유형의 확장을 작성할 때 유용합니다. 다음 샘플 코드를 고려해 보십시오:
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 | |
참고
Python 지표는 .cs 파일에 선언된 맞춤형 매개변수를 사용합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
위의 예에서 deMinMA와 deMaxMA는 DeMarker 지표의 값을 계산하는 데 사용되는 두 변수입니다.
중첩 지표는 Initialize() 메서드에서 정의되어야 합니다. 예를 들어, deMinMA는 deMin 시리즈의 Simple Moving Average로 정의됩니다.
1 | |
1 | |
deMin은 차례로 Calculate() 메서드에서 마지막 두 저가 값의 최대값으로 정의됩니다.
1 | |
1 | |
중첩 지표 작업을 단순화하기 위해, IntelliSense는 코드 편집기에 Indicators 뒤에 점을 입력할 때 모든 내장 지표의 목록을 자동으로 채웁니다. 또한 이 목록에서 특정 지표를 선택하면 관련된 모든 입력 매개변수를 표시합니다.

지연 로딩
cTrader Algo는 참조된 지표를 사용할 때 지연 로딩을 사용합니다. 참조된 지표가 제공하는 값은 코드가 이를 적극적으로 사용하기 시작할 때까지 계산되지 않습니다.
참조된 지표의 Outputs 데이터에 접근하면, cTrader는 과거 및 미래 바에서 Calculate() 메서드를 호출하여 지표 데이터를 로드하기 시작합니다. 다른 경우에는 참조된 지표가 유휴 상태로 유지되며, 따라서 시스템 리소스를 소비하지 않습니다.
이는 또한 지표에 Output이 없거나 공개 속성에 접근하려고 시도할 경우 해당 속성의 기본값을 얻게 된다는 것을 의미합니다. 이 문제를 해결하려면 현재 지표의 Calculate() 메서드에서 맞춤 지표의 Calculate() 메서드를 호출하십시오.
오실레이터와 레벨 속성
오실레이터라는 용어는 특정 상수 변수 주위를 진동하는 모든 지표를 포괄합니다.
오실레이터를 생성할 때, 먼저 그 상수 값에 수평 또는 "레벨" 선을 그리는 것이 유용합니다; 지표는 이 선 주위를 진동할 것입니다. 많은 경우, 상수 값은 0과 같습니다.
아래 예제에서는 모멘텀 오실레이터를 정의합니다. 이것은 일반적으로 100 값을 중심으로 진동합니다. 이 값을 사용하여 Levels 속성을 선언하여 레벨 선을 추가합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
참고
Python 지표는 .cs 파일에 선언된 맞춤형 매개변수를 사용합니다.
1 2 3 4 | |
Levels 속성은 지표가 차트 위에 오버레이되지 않은 경우에만 사용할 수 있습니다. 즉, IsOverlay 속성이 true로 설정되지 않은 경우입니다. 기본적으로 IsOverlay의 값은 false입니다. 이 속성이 코드에서 생략된 경우, Levels는 제대로 작동해야 합니다.
여러 "레벨" 선을 설정해야 하는 경우, 아래와 같이 괄호 안에 쉼표로 구분된 값 목록을 추가하십시오.
1 | |
1 | |
1 | |
Python 지표의 레벨
Python에서는 C# 지표와 동일하게 지표 C# 파일에서 레벨을 선언합니다.
IsLastBar 속성
경우에 따라 거래 차트의 마지막 바에 대해서만 계산되어야 하는 지표를 생성하고 싶을 수 있습니다. 이를 단순화하기 위해 IsLastBar 속성을 사용하여 Calculate() 메서드의 인덱스 매개변수가 마지막 바의 인덱스인지 확인할 수 있습니다.
아래 지표는 UTC 시간을 기반으로 하지만, 뉴욕과 도쿄의 마지막 개장 시간을 표시할 수 있습니다.
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 | |
지표 결합
cTrader는 동일한 패널 또는 동일한 차트 내에서 여러 지표를 결합할 수 있습니다.
다음 지표는 Aroon, RSI 및 Directional Movement System 지표를 하나로 결합합니다.
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 | |
참고
Python 지표는 .cs 파일에 선언된 맞춤형 매개변수를 사용합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
여러 시간 프레임
-
여러 시간 프레임 사용
다음 예제는 다른 시간 프레임에서 이동 평균 지표를 표시합니다.
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]; } }참고
파이썬 지표는
.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] -
여러 시간 프레임 및 심벌 사용
다음 예제는 여러 시간 프레임 및 심볼에서 이동 평균 지표를 표시합니다.
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); } }참고
파이썬 지표는
.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)
