저는 프로는 아니지만 이 코드가 잘못되었다고 생각합니다. Recount 변수는 항상 참입니다. 따라서 각 틱은 새로운 막대로 취급됩니다. 이 변수가 왜 거기에 있을까요? CopyClose를 호출하는 이유는 무엇인가요? 게시된 코드가 올바르게 작동하는지 확인했나요? 제가 틀렸다면 정정하고 설명해 주세요.
lordlev:
저는 프로는 아니지만 이 코드가 잘못되었다고 생각합니다. Recount 변수는 항상 참입니다. 따라서 각 틱은 새로운 막대로 취급됩니다. 이 변수가 왜 거기에 있을까요? CopyClose를 호출하는 이유는 무엇인가요? 게시된 코드가 올바르게 작동하는지 확인했나요? 제가 틀렸다면 정정하고 설명해 주세요.
모든 것을 다시 확인했는데 실수를 발견했습니다. 첨부 파일 자체에는 Recount가 false로 할당되어 있지 않지만 예제 코드에서는 모든 것이 올바릅니다.
저는 프로는 아니지만 이 코드가 잘못되었다고 생각합니다. Recount 변수는 항상 참입니다. 따라서 각 틱은 새로운 막대로 취급됩니다. 이 변수가 왜 거기에 있을까요? CopyClose를 호출하는 이유는 무엇인가요? 게시된 코드가 올바르게 작동하는지 확인했나요? 제가 틀렸다면 정정하고 설명해 주세요.
lordlev:
모든 것을 다시 확인한 결과 오류를 발견했습니다. 첨부 파일 자체에는 Recount가 false로 할당되어 있지 않지만 예제 코드에서는 모든 것이 올바릅니다.
고칠 수 있습니다!
모든 것을 다시 확인한 결과 오류를 발견했습니다. 첨부 파일 자체에는 Recount가 false로 할당되어 있지 않지만 예제 코드에서는 모든 것이 올바릅니다.
제가 틀렸을 수도 있지만 이것이 올바른 방법이라고 생각합니다.
if(TNew>m_TOld)그렇지 않으면 페이징(기록 편집) 중에 부정확해질 수 있습니다.
이것이 무엇이며 왜 이 수표가 삽입되는지 설명해 주시겠어요?
if(... && TNew)이해가 되지 않습니다. 이 조건은 언제 참이고 언제 거짓인가요? 감사합니다
Prival:
이것이 무엇이며 왜 이 수표가 삽입되는지 설명해 주시겠어요?
이해가 되지 않습니다. 이 조건은 언제 참이고 언제 거짓인가요? 감사합니다
Imho, TNew가 m_TOld와 같지 않고 동시에 0이 아닌지 확인합니다 ( 즉, D'1970.01.01.01 00:00:00:00')....
두 번째 조건 역시 imho는 함수가 0이 아닌 다른 값을 반환했는지 확인합니다.
datetime TNew=datetime(SeriesInfoInteger(symbol,timeframe,SERIES_LASTBAR_DATE));
가 0과 다른 것을 반환했는지 확인합니다.
이제 이 함수로 스크립트를 실행했는데 정확히 0을 반환했습니다. 주말 때문일 수도 있습니다.
Prival:
제가 틀렸을 수도 있지만, 저는 이것이 올바른 방법이라고 생각합니다.
그렇지 않으면 페이징(기록 편집) 중에 작업이 부정확해질 수 있습니다.
이 수표가 무엇이며 왜 삽입되는지 설명해 주시겠어요?
이해가 되지 않습니다. 이 조건은 언제 참이고 언제 거짓인가요? 감사합니다.
예방 조치로 이렇게하는 것이 더 논리적이라고 생각합니다.
if(TNew>m_TOld && TNew) 히스토리가 바뀌면 TNew는 여전히 0이 되겠지만요. 0은 언제든지 TNew 변수에 들어갈 수 있으므로 항상 0을 확인해야 합니다.
정적 변수가 없는 대체 버전의 CIsNewBar를 만들었습니다. 방금 Tick.time_msc를 사용하여 무능력한 함수를 수행했습니다 :
class CIsNewBar{
private:
long checkedMs;
datetime lastBarOpenedAt;
bool lastValue;
CTickUtils tickUtils;
public:
CIsNewBar(){}
~CIsNewBar(){}
bool isNewBar(){
MqlTick tick;
SymbolInfoTick(_Symbol, tick);
long tickMs = tick.time_msc;
if(checkedMs >= tickMs){ //이 틱에서 이 함수를 이미 처리했나요?
return lastValue; //그래서 버퍼링된 값을 반환합니다.
}
datetime time[1];
CopyTime(_Symbol, _Period, 0, 1, time);
if(lastBarOpenedAt != time[0]){
lastBarOpenedAt = time[0];
lastValue = true;
} else {
lastValue = false;
}
checkedMs = tickMs;
return lastValue;
}
class CIsNewBar{
private:
long checkedMs;
datetime lastBarOpenedAt;
bool lastValue;
CTickUtils tickUtils;
public:
CIsNewBar(){}
~CIsNewBar(){}
bool isNewBar(){
MqlTick tick;
SymbolInfoTick(_Symbol, tick);
long tickMs = tick.time_msc;
if(checkedMs >= tickMs){ //이 틱에서 이 함수를 이미 처리했나요?
return lastValue; //그래서 버퍼링된 값을 반환합니다.
}
datetime time[1];
CopyTime(_Symbol, _Period, 0, 1, time);
if(lastBarOpenedAt != time[0]){
lastBarOpenedAt = time[0];
lastValue = true;
} else {
lastValue = false;
}
checkedMs = tickMs;
return lastValue;
}
위에서 언급한 문제를 해결한 빠른 경량 클래스라고 생각합니다.
이 버전:
- 은 .isNewBar() 함수가 처음 호출될 때 잘못된 경고를 표시하지 않습니다.
- 정적 변수를 사용하지 않고 함수가 호출될 때마다 새 변수를 지속적으로 다시 인스턴스화하지 않으므로 실행 속도가 빨라집니다.
- 바당 한 번만 참을 반환합니다.
- 메모리 사용량이 가볍습니다.
class CIsNewBar{ private: datetime lastBarOpenedAt; datetime time[1]; public: CIsNewBar(){CopyTime(_Symbol, _Period, 0, 1, time);lastBarOpenedAt = time[0];} ~CIsNewBar(){} bool isNewBar(){ CopyTime(_Symbol, _Period, 0, 1, time); if(lastBarOpenedAt < time[0]){ lastBarOpenedAt = time[0]; return(true); } else { return(false);} } };
클래스를 구현하려면
CIsNewBar someName; void OnTick(){ if(someName.isNewBar()){ /// 새 바 이벤트 핸들러를 호출하거나 /// 새 바에서 작업을 수행합니다. } }
Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
- www.mql5.com
Predefined Macro Substitutions - Named Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
IsNewBar:
막대 변경이 발생하는 시점을 결정하는 CIsNewBar 클래스입니다.
Author: Nikolay Kositsin