언어 개요¶
QuantiqDSL은 한국 주식시장 자동매매를 위한 Python 유사 스크립팅 언어입니다. 일반 Python과 다른 점은 세 가지입니다.
- 이벤트 기반 실행 — 가격 변동이나 봉 마감마다 스크립트 전체가 처음부터 다시 실행됩니다.
- 샌드박스 환경 —
import,def,class등을 사용할 수 없습니다. 보안과 예측 가능성을 위한 제약입니다. - 내장 트레이딩 API —
chart(),ta.*,buy(),sell()등 트레이딩 전용 함수가 기본 제공됩니다.
스크립트 구조¶
모든 전략 스크립트는 아래 구조를 따릅니다.
# 1. 메타데이터 (필수)
version("1.0")
description("전략 이름")
# 2. 파라미터 선언 (선택)
param("period", "RSI 계산 기간", 14)
# 3. 청산 규칙 선언 (선택, rule.* 사용 시)
rule.order_on("5T")
rule.stop_loss(pct=3.0)
# 4. 데이터 로딩
c = chart("1D")
# 5. 지표 계산
rsi = ta.rsi(c.close, script_params["period"])
# 6. 매매 결정 (반드시 하나만)
if rsi[0] < 30:
buy(tag="RSI 과매도")
elif rsi[0] > 70:
sell(tag="RSI 과매수")
else:
hold()
타입 시스템¶
TSeries — 시계열 데이터¶
chart() 함수와 ta.* 지표 함수는 모두 TSeries를 반환합니다. 인덱스 [0]이 가장 최신 값, [1]이 한 단계 이전 값입니다.
c = chart("1D")
c.close[0] # 현재 봉 종가
c.close[1] # 이전 봉 종가
c.close[2] # 2봉 전 종가
# 교차 감지
sma5 = ta.sma(c.close, 5)
sma20 = ta.sma(c.close, 20)
sma5.cross_up(sma20) # bool: 이번 봉에서 상향 교차 발생 여부
sma5.cross_down(sma20) # bool: 이번 봉에서 하향 교차 발생 여부
유효성 확인이 필요한 경우:
ScaleChart — 차트 객체¶
chart(timeframe) 함수가 반환하는 객체입니다. OHLCV 데이터와 오버레이 그리기 메서드를 제공합니다.
c = chart("5T") # 5분봉
# OHLCV 데이터
c.open[0] # 시가
c.high[0] # 고가
c.low[0] # 저가
c.close[0] # 종가
c.volume[0] # 거래량
# 차트 오버레이
c.line("이름", series, color="orange")
c.hline("기준선", 50, color="gray")
c.marker("신호", color="green", position="below", shape="triangle_up")
지원 타임프레임: "1T", "3T", "5T", "10T", "15T", "30T", "60T" (분봉), "1D" (일봉)
네임스페이스¶
| 네임스페이스 | 용도 | 예시 |
|---|---|---|
ta.* |
기술 지표 | ta.sma(), ta.rsi(), ta.macd() |
math.* |
수학 함수 | math.mean(), math.abs(), math.max() |
var.* |
실행 간 상태 유지 | var.init(), var.counter |
rule.* |
선언형 청산 규칙 | rule.stop_loss(), rule.take_profit() |
매매 결정 함수¶
스크립트 실행이 끝날 때 마지막으로 호출된 결정 함수가 최종 결정입니다.
| 함수 | 의미 |
|---|---|
buy(tag, qty, price) |
매수 |
sell(tag, qty, price) |
매도 |
hold(tag) |
현재 포지션 유지 |
exit(tag) |
포지션 청산 |
release(tag) |
종목 감시 해제 |
# tag는 사유 문자열, 나중에 로그에서 확인
buy(tag="RSI 반등 진입")
# qty로 수량 지정 (생략 시 전략 설정값 사용)
sell(qty=5, tag="절반 매도")
# price로 지정가 주문 (생략 시 시장가)
buy(qty=10, price=price * 0.995, tag="현재가 -0.5% 지정가")
상태 유지 (var)¶
일반 변수는 이벤트마다 초기화됩니다. 실행 간 값을 유지하려면 var를 사용하세요.
# 잘못된 방법 (매 이벤트마다 0으로 초기화)
count = 0
count += 1 # 항상 1
# 올바른 방법
var.init(count=0, last_price=0.0)
var.count += 1 # 누적됨
var.last_price = price # 이전 가격 저장
저장 제약: JSON 직렬화 가능한 타입만 허용 (int, float, str, bool, list, dict). 총 64KB 한도.
샌드박스 제약¶
보안을 위해 다음 구문은 사용할 수 없습니다.
import numpy as np # ❌ import 금지
def calc(): # ❌ def (함수 정의) 금지
class Model: # ❌ class 금지
lambda x: x * 2 # ❌ lambda 금지
eval("2+2") # ❌ eval 금지
exec("code") # ❌ exec 금지
open("file.txt") # ❌ 파일 접근 금지
대신 내장 함수와 허용된 네임스페이스를 활용합니다.
# 수학 계산
result = math.mean([c.close[i] for i in range(5)])
# 리스트 컴프리헨션 (허용)
prices = [c.close[i] for i in range(10)]
자세한 목록은 샌드박스 제약 문서를 참고하세요.
파라미터 (param)¶
param()으로 스크립트에 파라미터를 선언합니다. 거래 탭에서 실행 전에 값을 조정할 수 있습니다.
param("period", "RSI 계산 기간", 14) # 기본값 14
param("threshold", "과매도 기준", 30.0) # 기본값 30.0
param("name", "전략 이름", "RSI 전략") # 문자열 파라미터
# 값 읽기
rsi = ta.rsi(c.close, script_params["period"])
if rsi[0] < script_params["threshold"]:
buy(tag="과매도 진입")