Search

IQTimer

목차

개요

IQTimer는 iQ 스튜디오 전략 코드에서 전역으로 접근 가능한 싱글톤 타이머 객체입니다.
매월 지정된 날짜에 원하는 함수를 자동으로 호출하는 스케줄 기능을 제공합니다. 주기적인 리밸런싱 로직을 onDayClose() 안에서 직접 날짜를 비교하지 않고도 깔끔하게 분리하여 등록할 수 있습니다.
현재 제약: 분(minute) 단위까지 파라미터로 입력받지만, iQ 스튜디오 시뮬레이션 환경은 일(day) 단위로 동작하므로 실질적으로는 월 중 특정 일에 함수가 호출됩니다.
function initialize() { IQTimer.setSchedule(onRebalance, 15, 16, 0); // 매월 15일에 onRebalance 호출 } function onRebalance() { logger.info('리밸런싱 실행'); // 리밸런싱 로직 }
JavaScript
복사

메서드 목록

메서드
반환 타입
설명
setSchedule(func, day, hour, min)
없음
매월 특정 날짜에 호출할 함수를 등록

setSchedule(func, day, hour, min)

매월 day일에 func를 호출하는 스케줄을 등록합니다.
스케줄 등록은 initialize() 함수 안에서 한 번만 수행합니다. 등록된 함수는 시뮬레이션 중 매월 해당 날짜(거래일 기준)가 되면 자동으로 호출됩니다. 해당 날짜가 거래일이 아닌 경우(주말, 공휴일) 그 이후 첫 번째 거래일에 호출됩니다.

파라미터

파라미터
타입
설명
func
function
매월 호출될 콜백 함수 (파라미터 없음)
day
number
매월 호출할 날짜 (1~31). 해당 날짜가 거래일이 아니면 다음 거래일에 호출됩니다.
hour
number
호출 시각 — 시(0~23). 현재 시뮬레이션 환경에서는 실질적으로 적용되지 않습니다.
min
number
호출 시각 — 분(0~59). 현재 시뮬레이션 환경에서는 실질적으로 적용되지 않습니다.

반환값

없음.

Sample

function initialize() { IQTimer.setSchedule(onTimer, 15, 16, 0); // 매월 15일 오후 4시 } function onTimer() { logger.debug('타이머 실행'); }
JavaScript
복사

활용 패턴

패턴 1: 월별 리밸런싱 기본 구조

가장 일반적인 IQTimer 활용 패턴입니다. 리밸런싱 로직을 별도 함수로 분리하여 setSchedule()에 등록합니다.
var acc; var universe; function initialize() { acc = IQAccount.getDefaultAccount(); IQTimer.setSchedule(onRebalance, 1, 9, 0); // 매월 1일에 리밸런싱 } function onRebalance() { // 유니버스 재구성 universe = IQStock.filter(function(stock) { return stock.market === 1 // KOSPI && !stock.isETF // ETF 제외 && stock.isListed() // 상장 중 && stock.manage === 0 // 관리종목 아님 && stock.getMarketCapital() > 50000; // 시가총액 500억 이상 }); // 기존 보유 종목 전량 매도 var eggs = acc.getEggs(); for (var i = 0; i < eggs.length; i++) { acc.sell(eggs[i].code, eggs[i].quantity); } // 새 유니버스 상위 종목 매수 var budget = acc.cash * 0.95; // 현금의 95%만 사용 (수수료 여유분 확보) var topN = Math.min(10, universe.length); var perStockBudget = budget / topN; for (var j = 0; j < topN; j++) { var stock = universe[j]; var qty = Math.floor(perStockBudget / stock.getClose()); if (qty > 0) { acc.buy(stock.code, qty); logger.info('[매수] ' + stock.name + ' ' + qty + '주'); } } logger.info('리밸런싱 완료 | 잔여현금: ' + IQUtil.getNumberWithCommas(acc.cash.toFixed(0))); } function onDayClose(now) { // 일별 평가액 로깅 (선택 사항) logger.debug(now + ' 총 평가액: ' + IQUtil.getNumberWithCommas(acc.getTotalEquity().toFixed(0))); }
JavaScript
복사

패턴 2: 복수 타이머 — 분기 리밸런싱

한국 재무데이터가 업데이트되는 4월·6월·9월·12월 1일에 리밸런싱합니다.
IQTimer.setSchedule()은 매월 동일 날짜에 호출되므로, 분기 리밸런싱이 필요하면 콜백 함수 내부에서 월을 직접 필터링합니다.
function initialize() { IQTimer.setSchedule(onQuarterlyRebalance, 1, 9, 0); // 매월 1일 등록 } function onQuarterlyRebalance() { // 4월, 6월, 9월, 12월에만 실제 리밸런싱 실행 var month = new Date().getMonth() + 1; // 주의: 시뮬레이션 날짜가 아닌 JS Date() 사용 시 주의 필요 if (month !== 4 && month !== 6 && month !== 9 && month !== 12) return; logger.info('분기 리밸런싱 실행 (' + month + '월)'); // 리밸런싱 로직 ... }
JavaScript
복사
권장: 분기 리밸런싱의 경우 IQDate.addRebalSchedule()을 함께 검토하세요. 날짜 비교는 onDayClose(now)now 파라미터를 활용하는 것이 더 정확합니다.

패턴 3: 매월 말일 리밸런싱

말일은 월마다 날짜가 달라지므로 day를 31로 설정하면 해당 월의 마지막 거래일 이후 첫 거래일에 호출됩니다. 이 경우 onDayClose() 안에서 IQDate로 말일을 직접 판별하는 것이 더 안정적입니다.
// IQTimer로 매월 28일 등록 (대부분 월말에 근접) function initialize() { IQTimer.setSchedule(onMonthEndRebalance, 28, 16, 0); } function onMonthEndRebalance() { logger.info('월말 리밸런싱 실행'); // 리밸런싱 로직 ... }
JavaScript
복사

IQTimer vs IQDate 비교

구분
IQTimer.setSchedule()
IQDate.addRebalSchedule()
방식
콜백 함수를 등록, 자동 호출
onDayClose() 안에서 isRebalancingDay() 조건 판별
코드 구조
리밸런싱 로직을 별도 함수로 분리
onDayClose() 안에 인라인으로 작성
유연성
단일 월별 주기
월별·분기별 등 다양한 스케줄 지원
권장 사용처
간단한 월별 리밸런싱
복잡한 다중 리밸런싱 스케줄

주의사항

setSchedule()initialize() 함수 안에서 한 번만 호출합니다.
지정한 날짜가 주말이나 공휴일인 경우, 그 이후 첫 거래일에 콜백 함수가 호출됩니다.
hour, min 파라미터는 시뮬레이션 환경에서 실질적인 영향이 없으므로 관례적으로 16, 0 (장 마감 시각)을 사용합니다.
콜백 함수에서 acc.sell() 후 즉시 acc.buy()를 호출하면, IQEnvironment.simulationMethod 설정에 따라 매도 대금이 당일 확보되지 않을 수 있습니다. 매도·매수 체결 시점을 전략 설계 시 반드시 고려하세요.

관련 API

IQDate 객체 — 리밸런싱 스케줄 관리, 날짜 판별
Account 객체 — 매수/매도 주문 및 잔고 조회
IQAccount 객체 — 계좌 컨테이너
logger 객체 — 콘솔 출력 및 디버깅