커뮤니티
특정 시간대의 최고/최저 및 시가/종가를 구하는 함수 도움 부탁드립니다.
2019-03-12 12:04:51
370
글번호 126970
아래 함수는, 예를 들어 전전일 09시부터 전일 08시까지의 최고/최저값과 시가/고가를 구하거나 할때 사용하고자 하는 함수입니다.
이것을 실행해본 즉, 지표에서 이 함수를 딱 한번만 부르게 특정일 특정시간으로 한정시켜 놓았는데 로그를 찍어보면 매 봉마다 함수도 실행되는 모습을 발견하였습니다.
TS에서도 함수뒤에 []를 붙이면 위와 같은 메커니즘으로 실행하는 것은 아는데, 저는 굳이 과거값이 필요없기 때문에 매 봉마다 저 함수가 자동으로 실행되는 것을 피하는 방법이나 또는 매 봉마나 내부적으로 저 함수가 실행되야만 한다면 오버헤드를 최소한 하는 방식으로 함수를 고치는 것이 필요합니다.
HighD의 코드를 보고 수정하려 하였는데, 그럼 유사한 방법으로 barnumber가 0인것부터 현재까지 순차적으로 진행하면서 O H L C 배열을 각각 만들어서 만들어야 하나 하는 생각을 하다보니 HighD의 입력값처럼 배열의 인자로 쓸 수 있는게 아니라 입력값이 몇일전, 몇시 등과 같이 여러개로 구성된 것이라서 유사하게는 적용하긴 어렵고, 과연 어떻게 구현을 접근해야 할 지 난해한 상황입니다.
아래 코드를 보시면 아시겠지만 특정 시간대의 고가와 저가를 구하고 시가와 종가도 같이 구해서 함수 하나에서 OHLC를 한번에 문자열로 반환하는 함수입니다.
이것을 시뮬레이션챠트에서, 해외선물(예:나스닥) 5분봉 2년치에 적용해서 돌려보시면 1회 실행시간이 10분이 넘어버립니다.
함수를 테스트하기 위해 만든 지표 예제도 함께 첨부합니다.
지표의 인풋값으로는 (090000, 1, 093000, 1, 143000)을 입력하셔 테스트 해 보셔도 됩니다.
적용한 상황에서의 디버깅창 출력 내용도 첨부합니다.
지금 방금 1만개 봉 챠트에서 적용하니 대략 10초 정도 걸리네요.
그럼 도움 부탁드리겠습니다~
ps :
아 그리고 CurrnetTime은 초단위까지 조회가 되던데 밀리세컨드까지 측정할 수 있는 예약어나 함수는 혹시 있을까요?
// 지표로 만든 함수 사용예제
input: st(0), d1(0), t1(0), d2(0), t2(0);
var: val(""), hval(0), lval(0);
if BarIndex == 0 then {
ClearDebug;
}
if sdate == 20190311 and stime == st then {
MessageLog("sdate %.f stime %.f st %.f", sdate, stime, st);
val = OHLCduring(d1, t1, d2, t2);
// hval = ValueOfOHLC(val, 2);
// lval = ValueOfOHLC(val, 3);
}
Plot1(1, "H");
//Plot1(hval, "high");
//Plot2(lval, "low");
-----------------------------------------------------------------------
/*
함수 코드 : OHLCduring
*/
input: 시작일수(NumericSimple), 시작(NumericSimple), 끝일수(NumericSimple), 끝(NumericSimple); //시각포맷은 HHMMSS형태로 입력한다.
var: srcidx(0), ii(0), jj(0), baridx(0), dayidx(0), 시가(0), 고가(0), 저가(0), 종가(0);
var: retval("");
var: 끝도달(0), 시작도달(0);
끝도달 = 0;
시작도달 = 0;
retval = "X333";
dayidx = 0;
종가 = 0;
for ii = 0 to CurrentBar-1 {
if dayidx == 끝일수 then {
끝도달 = 1;
baridx = ii;
ii = CurrentBar;
} else {
if date[ii] <> date[ii+1] then {
dayidx = dayidx + 1;
}
}
}
if 끝도달 <> 1 then { retval = "X000"; baridx = CurrentBar; }
for ii = baridx to CurrentBar-1 {
if time[ii] == 끝 then {
baridx = ii;
종가 = C[ii];
고가 = H[ii];
저가 = L[ii];
끝도달 = 2;
}
}
if 끝도달 == 1 then { retval = "X111"; baridx = CurrentBar; }
for ii = baridx to CurrentBar-1 {
if dayidx < 시작일수 then {
for jj = ii to CurrentBar-1 {
if H[jj] > 고가 then 고가 = H[jj];
if L[jj] < 저가 then 저가 = L[jj];
if date[jj] <> date[jj+1] then {
dayidx = dayidx + 1;
ii = jj;
jj = CurrentBar;
}
}
} else {
for jj = ii to CurrentBar-1 {
if H[jj] > 고가 then 고가 = H[jj];
if L[jj] < 저가 then 저가 = L[jj];
if time[jj] > 시작 then {
// Do nothing
} else {
시가 = O[jj];
baridx = jj; // baridx는 시작봉의 위치를 가리킨다.
ii = CurrentBar;
jj = CurrentBar;
시작도달 = 1;
}
}
}
}
if 시작도달 == 1 Then
retval = "O"+NumToStr(시가, 2)+"H"+NumToStr(고가, 2)+"L"+NumToStr(저가, 2)+"C"+NumToStr(종가, 2)+"E";
Else if 끝도달 == 2 and 시작도달 == 0 Then
retval = "X222";
MessageLog("%s", retval);
OHLCduring = retval;
- 1. OHLCduring.png (0.01 MB)
답변 2
예스스탁 예스스탁 답변
2019-03-12 16:38:00
안녕하세요
예스스탁입니다.
1
현재봉 기준으로 과거 특정 구간의 값을 가져오는 것은
highD 함수와 같이 작성하는 것이 가장 로드가 적게 걸리게 됩니다.
배열사용하지 않고 현재시점에서만 계산하게 하면
기존에 작성하신 방식대로 for문으로 작성하는 방법뿐이 없습니다.
지표식으로만 작성해 드립니다.
아래식 참고하셔서 함수화 하시면 됩니다.
2
input : starttime(90000),endtime(080000),preday(2);
var : Tcond(false),cnt(0);
Array : OO[10](0),HH[10](0),LL[10](0),CC[10](0);
if (sdate != sdate[1] and stime >= starttime) or
(sdate == sdate[1] and stime >= starttime and stime[1] < starttime) then
{
Tcond = true;
OO[0] = O;
HH[0] = H;
LL[0] = L;
for cnt = 1 to 9
{
OO[cnt] = OO[cnt-1][1];
HH[cnt] = HH[cnt-1][1];
LL[cnt] = LL[cnt-1][1];
CC[cnt] = CC[cnt-1][1];
}
}
if (sdate != sdate[1] and stime >= endtime) or
(sdate == sdate[1] and stime >= endtime and stime[1] < endtime) then
{
Tcond = false;
}
if Tcond == true then
{
if H > HH[0] Then
HH[0] = H;
if L < LL[0] Then
LL[0] = L;
CC[0] = C;
}
if OO[preday] > 0 then
{
plot1(OO[preday]);
plot2(HH[preday]);
plot3(LL[preday]);
plot4(CC[preday]);
}
3
CurrnetTime는 컴퓨터의 현재시간입니다.
현재시간이므로 초단위까지 리턴됩니다.
예약어로 제공되는 stime,time 시간은 시세의 시간입니다.
time은 봉의 마지막시간이므로 초단위 제공되고
stime은 일정시간주기의 시작값이므로 분주기 이상은 초가 없습니다.
틱봉이면 초단위가 표시됩니다.
즐거운 하루되세요
> 온고지신 님이 쓴 글입니다.
> 제목 : 특정 시간대의 최고/최저 및 시가/종가를 구하는 함수 도움 부탁드립니다.
> 아래 함수는, 예를 들어 전전일 09시부터 전일 08시까지의 최고/최저값과 시가/고가를 구하거나 할때 사용하고자 하는 함수입니다.
이것을 실행해본 즉, 지표에서 이 함수를 딱 한번만 부르게 특정일 특정시간으로 한정시켜 놓았는데 로그를 찍어보면 매 봉마다 함수도 실행되는 모습을 발견하였습니다.
TS에서도 함수뒤에 []를 붙이면 위와 같은 메커니즘으로 실행하는 것은 아는데, 저는 굳이 과거값이 필요없기 때문에 매 봉마다 저 함수가 자동으로 실행되는 것을 피하는 방법이나 또는 매 봉마나 내부적으로 저 함수가 실행되야만 한다면 오버헤드를 최소한 하는 방식으로 함수를 고치는 것이 필요합니다.
HighD의 코드를 보고 수정하려 하였는데, 그럼 유사한 방법으로 barnumber가 0인것부터 현재까지 순차적으로 진행하면서 O H L C 배열을 각각 만들어서 만들어야 하나 하는 생각을 하다보니 HighD의 입력값처럼 배열의 인자로 쓸 수 있는게 아니라 입력값이 몇일전, 몇시 등과 같이 여러개로 구성된 것이라서 유사하게는 적용하긴 어렵고, 과연 어떻게 구현을 접근해야 할 지 난해한 상황입니다.
아래 코드를 보시면 아시겠지만 특정 시간대의 고가와 저가를 구하고 시가와 종가도 같이 구해서 함수 하나에서 OHLC를 한번에 문자열로 반환하는 함수입니다.
이것을 시뮬레이션챠트에서, 해외선물(예:나스닥) 5분봉 2년치에 적용해서 돌려보시면 1회 실행시간이 10분이 넘어버립니다.
함수를 테스트하기 위해 만든 지표 예제도 함께 첨부합니다.
지표의 인풋값으로는 (090000, 1, 093000, 1, 143000)을 입력하셔 테스트 해 보셔도 됩니다.
적용한 상황에서의 디버깅창 출력 내용도 첨부합니다.
지금 방금 1만개 봉 챠트에서 적용하니 대략 10초 정도 걸리네요.
그럼 도움 부탁드리겠습니다~
ps :
아 그리고 CurrnetTime은 초단위까지 조회가 되던데 밀리세컨드까지 측정할 수 있는 예약어나 함수는 혹시 있을까요?
// 지표로 만든 함수 사용예제
input: st(0), d1(0), t1(0), d2(0), t2(0);
var: val(""), hval(0), lval(0);
if BarIndex == 0 then {
ClearDebug;
}
if sdate == 20190311 and stime == st then {
MessageLog("sdate %.f stime %.f st %.f", sdate, stime, st);
val = OHLCduring(d1, t1, d2, t2);
// hval = ValueOfOHLC(val, 2);
// lval = ValueOfOHLC(val, 3);
}
Plot1(1, "H");
//Plot1(hval, "high");
//Plot2(lval, "low");
-----------------------------------------------------------------------
/*
함수 코드 : OHLCduring
*/
input: 시작일수(NumericSimple), 시작(NumericSimple), 끝일수(NumericSimple), 끝(NumericSimple); //시각포맷은 HHMMSS형태로 입력한다.
var: srcidx(0), ii(0), jj(0), baridx(0), dayidx(0), 시가(0), 고가(0), 저가(0), 종가(0);
var: retval("");
var: 끝도달(0), 시작도달(0);
끝도달 = 0;
시작도달 = 0;
retval = "X333";
dayidx = 0;
종가 = 0;
for ii = 0 to CurrentBar-1 {
if dayidx == 끝일수 then {
끝도달 = 1;
baridx = ii;
ii = CurrentBar;
} else {
if date[ii] <> date[ii+1] then {
dayidx = dayidx + 1;
}
}
}
if 끝도달 <> 1 then { retval = "X000"; baridx = CurrentBar; }
for ii = baridx to CurrentBar-1 {
if time[ii] == 끝 then {
baridx = ii;
종가 = C[ii];
고가 = H[ii];
저가 = L[ii];
끝도달 = 2;
}
}
if 끝도달 == 1 then { retval = "X111"; baridx = CurrentBar; }
for ii = baridx to CurrentBar-1 {
if dayidx < 시작일수 then {
for jj = ii to CurrentBar-1 {
if H[jj] > 고가 then 고가 = H[jj];
if L[jj] < 저가 then 저가 = L[jj];
if date[jj] <> date[jj+1] then {
dayidx = dayidx + 1;
ii = jj;
jj = CurrentBar;
}
}
} else {
for jj = ii to CurrentBar-1 {
if H[jj] > 고가 then 고가 = H[jj];
if L[jj] < 저가 then 저가 = L[jj];
if time[jj] > 시작 then {
// Do nothing
} else {
시가 = O[jj];
baridx = jj; // baridx는 시작봉의 위치를 가리킨다.
ii = CurrentBar;
jj = CurrentBar;
시작도달 = 1;
}
}
}
}
if 시작도달 == 1 Then
retval = "O"+NumToStr(시가, 2)+"H"+NumToStr(고가, 2)+"L"+NumToStr(저가, 2)+"C"+NumToStr(종가, 2)+"E";
Else if 끝도달 == 2 and 시작도달 == 0 Then
retval = "X222";
MessageLog("%s", retval);
OHLCduring = retval;
온고지신
2019-03-12 22:29:42
감사합니다. 시도해 보고 결과 올리겠습니다.
수고 많으셨습니다~
> 예스스탁 님이 쓴 글입니다.
> 제목 : Re : 특정 시간대의 최고/최저 및 시가/종가를 구하는 함수 도움 부탁드립니다.
>
안녕하세요
예스스탁입니다.
1
현재봉 기준으로 과거 특정 구간의 값을 가져오는 것은
highD 함수와 같이 작성하는 것이 가장 로드가 적게 걸리게 됩니다.
배열사용하지 않고 현재시점에서만 계산하게 하면
기존에 작성하신 방식대로 for문으로 작성하는 방법뿐이 없습니다.
지표식으로만 작성해 드립니다.
아래식 참고하셔서 함수화 하시면 됩니다.
2
input : starttime(90000),endtime(080000),preday(2);
var : Tcond(false),cnt(0);
Array : OO[10](0),HH[10](0),LL[10](0),CC[10](0);
if (sdate != sdate[1] and stime >= starttime) or
(sdate == sdate[1] and stime >= starttime and stime[1] < starttime) then
{
Tcond = true;
OO[0] = O;
HH[0] = H;
LL[0] = L;
for cnt = 1 to 9
{
OO[cnt] = OO[cnt-1][1];
HH[cnt] = HH[cnt-1][1];
LL[cnt] = LL[cnt-1][1];
CC[cnt] = CC[cnt-1][1];
}
}
if (sdate != sdate[1] and stime >= endtime) or
(sdate == sdate[1] and stime >= endtime and stime[1] < endtime) then
{
Tcond = false;
}
if Tcond == true then
{
if H > HH[0] Then
HH[0] = H;
if L < LL[0] Then
LL[0] = L;
CC[0] = C;
}
if OO[preday] > 0 then
{
plot1(OO[preday]);
plot2(HH[preday]);
plot3(LL[preday]);
plot4(CC[preday]);
}
3
CurrnetTime는 컴퓨터의 현재시간입니다.
현재시간이므로 초단위까지 리턴됩니다.
예약어로 제공되는 stime,time 시간은 시세의 시간입니다.
time은 봉의 마지막시간이므로 초단위 제공되고
stime은 일정시간주기의 시작값이므로 분주기 이상은 초가 없습니다.
틱봉이면 초단위가 표시됩니다.
즐거운 하루되세요
> 온고지신 님이 쓴 글입니다.
> 제목 : 특정 시간대의 최고/최저 및 시가/종가를 구하는 함수 도움 부탁드립니다.
> 아래 함수는, 예를 들어 전전일 09시부터 전일 08시까지의 최고/최저값과 시가/고가를 구하거나 할때 사용하고자 하는 함수입니다.
이것을 실행해본 즉, 지표에서 이 함수를 딱 한번만 부르게 특정일 특정시간으로 한정시켜 놓았는데 로그를 찍어보면 매 봉마다 함수도 실행되는 모습을 발견하였습니다.
TS에서도 함수뒤에 []를 붙이면 위와 같은 메커니즘으로 실행하는 것은 아는데, 저는 굳이 과거값이 필요없기 때문에 매 봉마다 저 함수가 자동으로 실행되는 것을 피하는 방법이나 또는 매 봉마나 내부적으로 저 함수가 실행되야만 한다면 오버헤드를 최소한 하는 방식으로 함수를 고치는 것이 필요합니다.
HighD의 코드를 보고 수정하려 하였는데, 그럼 유사한 방법으로 barnumber가 0인것부터 현재까지 순차적으로 진행하면서 O H L C 배열을 각각 만들어서 만들어야 하나 하는 생각을 하다보니 HighD의 입력값처럼 배열의 인자로 쓸 수 있는게 아니라 입력값이 몇일전, 몇시 등과 같이 여러개로 구성된 것이라서 유사하게는 적용하긴 어렵고, 과연 어떻게 구현을 접근해야 할 지 난해한 상황입니다.
아래 코드를 보시면 아시겠지만 특정 시간대의 고가와 저가를 구하고 시가와 종가도 같이 구해서 함수 하나에서 OHLC를 한번에 문자열로 반환하는 함수입니다.
이것을 시뮬레이션챠트에서, 해외선물(예:나스닥) 5분봉 2년치에 적용해서 돌려보시면 1회 실행시간이 10분이 넘어버립니다.
함수를 테스트하기 위해 만든 지표 예제도 함께 첨부합니다.
지표의 인풋값으로는 (090000, 1, 093000, 1, 143000)을 입력하셔 테스트 해 보셔도 됩니다.
적용한 상황에서의 디버깅창 출력 내용도 첨부합니다.
지금 방금 1만개 봉 챠트에서 적용하니 대략 10초 정도 걸리네요.
그럼 도움 부탁드리겠습니다~
ps :
아 그리고 CurrnetTime은 초단위까지 조회가 되던데 밀리세컨드까지 측정할 수 있는 예약어나 함수는 혹시 있을까요?
// 지표로 만든 함수 사용예제
input: st(0), d1(0), t1(0), d2(0), t2(0);
var: val(""), hval(0), lval(0);
if BarIndex == 0 then {
ClearDebug;
}
if sdate == 20190311 and stime == st then {
MessageLog("sdate %.f stime %.f st %.f", sdate, stime, st);
val = OHLCduring(d1, t1, d2, t2);
// hval = ValueOfOHLC(val, 2);
// lval = ValueOfOHLC(val, 3);
}
Plot1(1, "H");
//Plot1(hval, "high");
//Plot2(lval, "low");
-----------------------------------------------------------------------
/*
함수 코드 : OHLCduring
*/
input: 시작일수(NumericSimple), 시작(NumericSimple), 끝일수(NumericSimple), 끝(NumericSimple); //시각포맷은 HHMMSS형태로 입력한다.
var: srcidx(0), ii(0), jj(0), baridx(0), dayidx(0), 시가(0), 고가(0), 저가(0), 종가(0);
var: retval("");
var: 끝도달(0), 시작도달(0);
끝도달 = 0;
시작도달 = 0;
retval = "X333";
dayidx = 0;
종가 = 0;
for ii = 0 to CurrentBar-1 {
if dayidx == 끝일수 then {
끝도달 = 1;
baridx = ii;
ii = CurrentBar;
} else {
if date[ii] <> date[ii+1] then {
dayidx = dayidx + 1;
}
}
}
if 끝도달 <> 1 then { retval = "X000"; baridx = CurrentBar; }
for ii = baridx to CurrentBar-1 {
if time[ii] == 끝 then {
baridx = ii;
종가 = C[ii];
고가 = H[ii];
저가 = L[ii];
끝도달 = 2;
}
}
if 끝도달 == 1 then { retval = "X111"; baridx = CurrentBar; }
for ii = baridx to CurrentBar-1 {
if dayidx < 시작일수 then {
for jj = ii to CurrentBar-1 {
if H[jj] > 고가 then 고가 = H[jj];
if L[jj] < 저가 then 저가 = L[jj];
if date[jj] <> date[jj+1] then {
dayidx = dayidx + 1;
ii = jj;
jj = CurrentBar;
}
}
} else {
for jj = ii to CurrentBar-1 {
if H[jj] > 고가 then 고가 = H[jj];
if L[jj] < 저가 then 저가 = L[jj];
if time[jj] > 시작 then {
// Do nothing
} else {
시가 = O[jj];
baridx = jj; // baridx는 시작봉의 위치를 가리킨다.
ii = CurrentBar;
jj = CurrentBar;
시작도달 = 1;
}
}
}
}
if 시작도달 == 1 Then
retval = "O"+NumToStr(시가, 2)+"H"+NumToStr(고가, 2)+"L"+NumToStr(저가, 2)+"C"+NumToStr(종가, 2)+"E";
Else if 끝도달 == 2 and 시작도달 == 0 Then
retval = "X222";
MessageLog("%s", retval);
OHLCduring = retval;
다음글
이전글