cTrader API에 메서드를 추가하는 방법
cTrader API에 새로운 기능을 추가하려는 경우 확장 메서드는 중요한 도구입니다. 상대적으로 간단한 구문을 사용하여 Symbol 또는 Position과 같은 미리 정의된 API 클래스에 새로운 동작을 추가할 수 있습니다. 확장 메서드를 정의한 후에는 확장한 클래스의 모든 객체에서 이를 호출할 수 있습니다.
확장 메서드의 사용 사례
먼저, 확장 메서드를 사용하고 싶은 이유에 대해 간단히 설명하겠습니다.
cBot을 사용하여 주어진 포지션의 크기를 로트 단위로 접근할 수 있기를 원합니다. 이 정보는 우리가 선호하는 거래 전략에 직접적인 영향을 미치기 때문입니다. 이를 위해 Position 클래스의 변수를 초기화하고 Lots() 메서드에 접근하려고 시도할 수 있습니다.
1 2 | |
코드를 그대로 입력하면 API에 Lots() 접근자가 존재하지 않는다는 오류가 발생할 것입니다. 하지만 기존 API 멤버에 새로운 메서드를 추가하면서 다른 기능에 영향을 미치지 않는 방법이 있다면 어떨까요?
이 메서드가 존재한다고 가정하면, 매 바마다 현재 모든 포지션 목록을 반복하고 로트 단위로 그 크기를 로그에 출력하는 간단한 cBot을 만들 수 있습니다. OnBar() 메서드를 다음과 같이 정의할 것입니다.
1 2 3 4 5 6 | |
확장 메서드를 사용하면 Lots() 기능을 몇 줄의 코드로 추가하고, Position 클래스의 어떤 객체에서든 재사용할 수 있습니다. 아래에서는 이를 생성하는 방법과 이를 사용한 알고리즘의 몇 가지 예를 제공합니다.
확장 메서드의 작동 방식
확장 메서드를 사용할 때는 다음 규칙을 염두에 두세요.
- 확장 메서드는 항상 정적입니다.
정적 메서드를 선언하려면 static 키워드를 사용하기만 하면 됩니다. 아래에서 Lots() 메서드를 빈 본문으로 선언합니다.
1 2 3 4 | |
- 확장 메서드는 임의의 수의 인수를 가질 수 있지만 첫 번째 인수는 항상 메서드가 호출될 데이터 타입/클래스를 지정해야 하며
this키워드가 앞에 옵니다.
Position 클래스의 객체를 Lots() 메서드의 첫 번째이자 유일한 인수로 추가할 것입니다. Position 객체는 포지션이 열린 심볼에 대한 정보도 포함하고 있으므로 다른 인수가 필요하지 않습니다.
1 2 3 | |
- 확장 메서드는 제공된 인수에 적합한 어떤 로직도 포함할 수 있습니다.
확장 메서드의 본문을 정의할 때 특별한 구문을 사용할 필요가 없습니다. 다른 메서드처럼 취급할 수 있으므로 본문을 다음과 같이 정의할 수 있습니다.
1 2 3 4 5 | |
- 확장 메서드는 인스턴스 메서드 또는 정적 메서드로 호출할 수 있습니다.
cBot의 코드에서 확장 메서드를 호출하는 두 가지 방법이 있습니다.
인스턴스 메서드 구문을 사용할 때는 Position 타입의 적합한 객체에서 메서드를 호출합니다.
1 2 | |
정적 메서드 구문을 사용할 때는 해당 정적 클래스를 완전히 지정한 후 확장 메서드를 호출할 수 있습니다.
1 2 | |
어떤 방법으로 확장 메서드를 호출하는 것이 가장 편리한지는 여러분이 결정할 문제입니다.
메서드 시그니처
인스턴스 구문을 사용할 때, 확장 메서드의 시그니처가 내장 API 메서드(예: Position.Close())와 동일한 경우를 피하세요. 이러한 상황에서는 일치하는 시그니처로 확장 메서드를 호출하려고 할 때마다 내장 메서드가 호출됩니다.
IntelliSense
확장 메서드를 호출하려고 할 때, IntelliSense는 내장 API 멤버와 구별하기 위해 특별한 아이콘을 사용합니다.
새로운 메서드를 실제로 보여주기 위해 시작 시 각각 다른 볼륨으로 세 개의 주문을 하는 cBot을 만들 수 있습니다. 모든 바에서 cBot은 현재 열린 모든 포지션의 볼륨을 로트 단위로 출력합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
cBot을 빌드하고 실행한 후 로그에 올바른 값이 출력되는 것을 볼 수 있습니다.
cBot에서 확장 메서드 사용
이제 더 복잡한 cBot을 만들어 보겠습니다. 모든 바에서 우리의 알고리즘은 현재 열린 포지션 목록을 검토하고 손절매 수준을 손익분기점에 맞게 조정합니다. 이를 위해 Position 클래스에 대한 BreakEven() 확장 메서드를 생성할 필요가 있습니다.
새 cBot을 만들고 이름을 변경합니다. 그 후 필요 없는 모든 코드를 삭제하고 MyExtensions 클래스를 추가합니다.
1 2 3 | |
BreakEven() 메서드에 대한 코드는 비교적 간단합니다. 포지션에 손절매가 있는지, 총 이익이 0보다 큰지, 현재 설정된 손절매가 포지션 진입 가격과 동일하지 않은지 확인합니다. 이 모든 조건이 참이면 포지션의 손절매를 포지션 진입 가격과 동일하게 수정합니다.
1 2 3 4 5 6 7 | |
cBot 자체에서는 OnBar() 메서드 외에 다른 메서드를 사용할 필요가 없습니다. 모든 바에서 cBot에게 간단한 작업을 수행하도록 요청합니다. 즉, Positions 컬렉션을 반복하고 각 요소에 대해 새로운 BreakEven() 메서드를 호출합니다.
1 2 3 4 5 6 | |
cBot을 빌드하고 실행한 후 실제로 작동하는 것을 볼 수 있습니다. 이는 특히 많은 오픈 포지션을 관리할 때 유용한 트레이딩 도우미가 될 수 있습니다.
지표에서 확장 메서드 사용
확장 메서드에 의존하는 유용한 지표도 만들 것입니다. 이 지표는 각 바의 시가와 비교하여 심볼 가격이 얼마나 변했는지 백분율로 표시하여 변동성을 측정합니다.
이를 위해 새 지표를 만들고 이름을 변경합니다. 코드 편집기 창에서 Bar 클래스를 확장하는 MyExtensions 클래스를 생성합니다.
1 2 3 | |
또한 PercentageChange() 메서드를 추가합니다. priceChange 변수에서 바의 종가에서 시가를 뺍니다. 이 메서드는 가격 변동을 시가로 나누고 100을 곱한 값을 반환합니다.
1 2 3 4 5 6 7 8 | |
지표 코드 자체에서는 Initialize() 메서드와 불필요한 매개변수가 필요하지 않습니다. Calculate() 메서드의 본문에서는 모든 바에서 새로운 PercentageChange() 메서드를 호출합니다.
1 2 3 4 5 6 7 8 | |
그 후 지표를 저장하고 빌드합니다. 지표의 인스턴스를 생성한 후 올바른 백분율 변화가 표시되는 것을 볼 수 있습니다. 이를 사용하여 단기 및 장기 변동성을 결정할 수 있으며 모든 종류의 트레이딩 전략에 도움이 됩니다.
요약
결론적으로, 확장 메서드는 cTrader API에 새로운 기능을 추가하는 재사용 가능한 코드를 만들고자 할 때 귀중한 도구입니다. 확장 메서드를 실험해 보는 것을 적극 권장합니다. 이를 통해 알고리즘을 더 효율적이고 유지 관리하기 쉽게 만들 수 있습니다.