fxsaber #: 아닙니다. 모든 변수에 대해 항상 최신 상태를 유지하는 것이 목표입니다. 제 예시에서 OnTimer에서는 항상 최신 상태 조건이 충족됩니다. 포지션 개설은 단지 예시를 보여주기 위한 것일 뿐입니다.
알겠습니다.
아직 OnTickMulti 이벤트에서 구현된 부분이 어디에서 틱을 ‘놓치고’ 있는지, 다시 말해, SymbolInfoTick이 예상했던 가격과 다른 값을 반환하는 이유가 무엇인지(저는 앞서 지표의 커스텀 이벤트 디스패칭으로 인해 지연이 발생할 가능성이 있다고 추측했습니다) - 실험의 순수성을 위해 스파이 지표 없이 테스트해 보고 싶습니다. 일반적인 OnTick에서 모든 심볼에 대해 SymbolInfoTick/CopyTicks를 호출하는 것, 적어도 동일한 타임스탬프에 대해서는 말이죠.
OnTimer에 관해서는 몇 가지 의문이 듭니다(제가 잘못 이해한 부분이 있다면 지적해 주세요):
핸들러가 1밀리초 이내에 실행될 것이라는 보장이 없기 때문에, 단순히 카운터를 증가시키는 것만으로는 초기 동기화가 유지된다고 보장할 수 없습니다. 즉, 서버 시간과의 동기화는 매번(포지션 개설 후 또는 인크리먼트보다 더 복잡한 계산이 있을 경우) 실시간으로 제대로 수행해야 합니다. 다시 말해, 제시된 정교한 접근 방식은 포지션을 많이 개설해야 할 때는 통하지 않을 것입니다.
같은 시간의 틱은 동시에 도착하지 않습니다. 모두 순차적으로 도착합니다. 만약 EURUSD의 더 늦은 시간 틱이 먼저 도착했다면, 그 시점에서는 두 번째로 도착할 GBPUSD의 같은 시간 틱에 대해서는 아무것도 알 수 없습니다. 따라서 첫 번째 EURUSD 틱이 도착하는 시점에는 두 번째 GBPUSD 틱은 단순히 존재하지 않으며, 대신 이전 GBPUSD 틱의 데이터만 존재합니다.
이러한 메커니즘을 통해 일반 모드(OnTickMulti가 없는 단일 통화 모드)에서도 최신 데이터만으로 작업할 수 있습니다. 예를 들어, EURUSD에는 시간이 동일한 틱이 여러 개 있을 수 있습니다. 업데이트를 통해 해당 시퀀스에서 가장 최근의 틱, 즉 최신 틱으로 작업할 수 있습니다.
추신: 이것이 사용자 정의 심볼을 생성해야 하는 또 다른 이유입니다. 즉, 시간이 동일한 시퀀스 중 마지막 틱만 기록에 남기기 위해서입니다. 이 경우 단일 통화 모드에서도 항상 최신 데이터가 반영됩니다.
시작 가격을 기준으로 한 테스터 모드를 다시 떠올려 보았습니다. 핵심은 이름과는 달리, 테스터가 이 모드에서 1틱이 아닌 4틱의 OHLC 데이터를 생성한다는 점입니다. 이 4개의 제어 지점 중에서 전문가 자문 시스템의 경우 첫 번째 O만 선택되어 OnTick이 호출되며, 지표의 경우 HLC 또는 LHC(봉의 방향에 따라 다름)에 대해 해당 가격의 틱 데이터를 포함한 OnCalculate가 추가로 3회 호출됩니다. 이 세 개의 추가 지점에 대한 시간은 인위적으로 막대의 마지막 3초와 동일하게 설정됩니다. 결과적으로 스파이 지표는 심볼당 하나의 이벤트 대신 여러 개의 이벤트를 전송하게 됩니다. 시가 모드를 사용하는 사용자들은 이 점을 고려해야 할 것입니다.
또한 (책에 나온 유사한 스파이 지표에 디버깅 코드를 추가해 본 결과) 지난 바의 추가 종목 틱에 대한 이벤트가 왠지 모르게 새 바에서 반복되는 현상을 관찰했는데, 그 후에야 스파이 지표의 OnCalculate가 호출되고, 가격이 갱신된 추가 종목의 새로운 틱 이벤트가 도착합니다. 결과적으로, 추가 종목에 대한 최신 가격을 얻으려면 이벤트 자체에 타임스탬프를 포함시키고 이미 처리된 이벤트를 다시 처리하지 않아야 합니다. 저는 전송 시 다음과 같이 처리하고 있습니다:
완벽한 테스트 케이스를 만들기 위해서는 실제 상황을 파악해야 할 것 같습니다. 밀리초 단위의 정확도로 시간이 일치하는 틱에 대해서만 거래를 하는 것입니까?
아닙니다. 모든 변수에 대해 항상 최신 상태를 유지하는 것이 목표입니다. 제 예시에서 OnTimer에서는 항상 최신 상태 조건이 충족됩니다. 포지션 개설은 단지 예시를 보여주기 위한 것일 뿐입니다.
알겠습니다.
아직 OnTickMulti 이벤트에서 구현된 부분이 어디에서 틱을 ‘놓치고’ 있는지, 다시 말해, SymbolInfoTick이 예상했던 가격과 다른 값을 반환하는 이유가 무엇인지(저는 앞서 지표의 커스텀 이벤트 디스패칭으로 인해 지연이 발생할 가능성이 있다고 추측했습니다) - 실험의 순수성을 위해 스파이 지표 없이 테스트해 보고 싶습니다. 일반적인 OnTick에서 모든 심볼에 대해 SymbolInfoTick/CopyTicks를 호출하는 것, 적어도 동일한 타임스탬프에 대해서는 말이죠.
OnTimer에 관해서는 몇 가지 의문이 듭니다(제가 잘못 이해한 부분이 있다면 지적해 주세요):
핸들러가 1밀리초 이내에 실행될 것이라는 보장이 없기 때문에, 단순히 카운터를 증가시키는 것만으로는 초기 동기화가 유지된다고 보장할 수 없습니다. 즉, 서버 시간과의 동기화는 매번(포지션 개설 후 또는 인크리먼트보다 더 복잡한 계산이 있을 경우) 실시간으로 제대로 수행해야 합니다. 다시 말해, 제시된 정교한 접근 방식은 포지션을 많이 개설해야 할 때는 통하지 않을 것입니다.
게다가 초기 동기화(카운터 초기화)도 제 생각에는 100% 완벽하지 않습니다.
테스터에서 서버 시간이 실제로 밀리초 없이 시작된다고 가정하더라도, 이런 코드가 온라인 환경에서는 어떻게 작동할까요? 그리고 왜 1밀리초를 더하는 것일까요? 저는 여전히 틱에서 서버 시간을 가져올 것입니다.
이건 트집 잡기가 아니라, 단순히 "항상 최신 상태를 유지한다는 조건"에 대한 의문일 뿐입니다.
카운터를 단순히 증가시키는 것만으로는 초기 동기화가 유지된다는 보장이 없습니다
테스터에서는 보장됩니다.
하지만 이런 코드가 온라인에서는 어떻게 작동할까요?
온라인에서는 이런 문제가 없습니다. 터미널로 들어오는 모든 데이터는 참고용이기 때문인데, 지연으로 인해 최신 정보가 아니기 때문입니다.
그리고 왜 1밀리초를 더하는 것일까요?
가장 첫 번째 OnTimer가 즉시 호출되는 것이 아니라, 지정된 간격 후에 호출되기 때문입니다.
OnTickMulti 이벤트에서 실행되는 코드가 어디에서 틱을 '놓치고' 있는지, 다시 말해 SymbolInfoTick이 예상했던 가격과 다른 가격을 반환하게 되는 이유가 아직 불분명합니다.
OnTickMulti는 분명히 문제가 아닙니다. 왜냐하면 특정 심볼의 기본 SymbolInfoTick은 올바른 틱을 반환하지만, 다른 심볼의 경우 그렇지 않기 때문입니다.
원인은 오로지 틱이 전달되는 순서에 있습니다.
트레이딩, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼
라이브러리: OnTickMulti
fxsaber, 2025.09.30 09:24
같은 시간의 틱은 동시에 도착하지 않습니다. 모두 순차적으로 도착합니다. 만약 EURUSD의 더 늦은 시간 틱이 먼저 도착했다면, 그 시점에서는 두 번째로 도착할 GBPUSD의 같은 시간 틱에 대해서는 아무것도 알 수 없습니다. 따라서 첫 번째 EURUSD 틱이 도착하는 시점에는 두 번째 GBPUSD 틱은 단순히 존재하지 않으며, 대신 이전 GBPUSD 틱의 데이터만 존재합니다.가장 처음 설정된 OnTimer는 즉시 호출되는 것이 아니라 지정된 간격 후에 호출되기 때문입니다.
모든 데이터를 빠르게 갱신하는 방법을 고안했습니다.
이러한 메커니즘을 통해 일반 모드(OnTickMulti가 없는 단일 통화 모드)에서도 최신 데이터만으로 작업할 수 있습니다. 예를 들어, EURUSD에는 시간이 동일한 틱이 여러 개 있을 수 있습니다. 업데이트를 통해 해당 시퀀스에서 가장 최근의 틱, 즉 최신 틱으로 작업할 수 있습니다.
추신: 이것이 사용자 정의 심볼을 생성해야 하는 또 다른 이유입니다. 즉, 시간이 동일한 시퀀스 중 마지막 틱만 기록에 남기기 위해서입니다. 이 경우 단일 통화 모드에서도 항상 최신 데이터가 반영됩니다.
하지만 개장 가격은 똑같은데, 모든 종목의 개장 시간은 동일하잖아요.
그리고 이러한 동작 때문에 일부 시스템은 정상적으로 테스트할 수 없습니다.
시작 가격을 기준으로 한 테스터 모드를 다시 떠올려 보았습니다. 핵심은 이름과는 달리, 테스터가 이 모드에서 1틱이 아닌 4틱의 OHLC 데이터를 생성한다는 점입니다. 이 4개의 제어 지점 중에서 전문가 자문 시스템의 경우 첫 번째 O만 선택되어 OnTick이 호출되며, 지표의 경우 HLC 또는 LHC(봉의 방향에 따라 다름)에 대해 해당 가격의 틱 데이터를 포함한 OnCalculate가 추가로 3회 호출됩니다. 이 세 개의 추가 지점에 대한 시간은 인위적으로 막대의 마지막 3초와 동일하게 설정됩니다. 결과적으로 스파이 지표는 심볼당 하나의 이벤트 대신 여러 개의 이벤트를 전송하게 됩니다. 시가 모드를 사용하는 사용자들은 이 점을 고려해야 할 것입니다.
또한 (책에 나온 유사한 스파이 지표에 디버깅 코드를 추가해 본 결과) 지난 바의 추가 종목 틱에 대한 이벤트가 왠지 모르게 새 바에서 반복되는 현상을 관찰했는데, 그 후에야 스파이 지표의 OnCalculate가 호출되고, 가격이 갱신된 추가 종목의 새로운 틱 이벤트가 도착합니다. 결과적으로, 추가 종목에 대한 최신 가격을 얻으려면 이벤트 자체에 타임스탬프를 포함시키고 이미 처리된 이벤트를 다시 처리하지 않아야 합니다. 저는 전송 시 다음과 같이 처리하고 있습니다:
그리고 수신 시에는 (여기서는 하나의 추가 종목 사례만 보여드리지만, 여러 종목의 경우 timestamp[] 배열이 필요합니다!):
밀리초 값이 동일한 틱이 있을 경우, 마지막 틱이 아닌 첫 번째 틱이 거래 처리된다는 점에 유의해야 합니다.
가장 간단한 동기화 방법