참고사항 시스템 트레이딩 관련 블로그들은 개인 경험을 바탕으로 작성되었습니다. 각자 자신만의 투자방식과 매매전략을 만들어 가시기 바랍니다.
개요
시스템 트레이딩에서는 벡테스트를 통해서 매매 로직이 검증되면 실전 거래를 통해서 매매를 직접 수행해볼수 있습니다. 실전 거래시시 고려해야 할 사항과 그에 대한 처리 방법에 대해 알아보겠습니다.
실전거래시 고려사항
실전 거래의 기본은 기본적인 매수와 매도 기능입니다. 시장가와 지정가에 맞게 매매를 어떻게 수행할수 있는지 거래소의 API를 통해서 먼저 기능 검증이 완료되어야합니다. 실전거래에서는 내가 입금한 금액을 가지고 거래하기 때문에 소액(약 1만이내)의 금액으로 매수와 매도기능을 검증하시기 바랍니다.
실전 거래는 항상 이전의 매수정보를 기반으로 앞으로 매수/매도로직이 동작하기 때문에, 현재 거래내역에 대해서 정보를 확인하는 기능이 필요합니다. 이는 벡테스트의 자금관리자객체에서 했던 기능으로 거래소객체가 대신하여 담당하게 됩니다. 거래소 객체는 거래소 API와 호출하여 직접 거래 및 데이터를 조회하는 역할을 가지는 객체입니다.
- 거래소의 기본적인 기능 목록
- 전체 종목 정보(전체 종목목록 가져옴)
- 유의종목(유의종목은 제외하기 위해서)
- 자금정보(총보유자산, 주문가능자산)
- 거래내역확인(매수평단가, 매수체결량)
- 티커확인 (종목의 현재가)
- 캔들 데이터 조회 기능 (벡테스트를 위해서 데이터수집할때 이미 구현한 기능임)
- 매수/매도(시장가 or 지정가)
기본적인 기능 구현이 되면, 벡테스트에서 사용했던 공통 컴포넌트와 같이 실전 거래 코드를 작성합니다.
실전거래 위한 컴포넌트
설전거래를 위해서는 몇 가지 컴포넌트가 필요합니다. 벡테스트에서 사용한 동일한 매매 로직으로 실전 거래를 수행합니다.
- 실전거래를 위한 컴포넌트
- 공통 컴포넌트 (백테스트와 실전 거래에 공통으로 사용됨)
- 개별 종목 데이터 관리 객체 (종목 객체) - 캔들 데이터가 입력되면 매매 변수를 생성하고 매매 로직을 이용하여 매매 결과를 반환합니다.
- 여러 종목을 관리하는 객체 (종목 그룹 객체) - 종목들의 매매 수행 결과를 통합하여 필요한 데이터를 제공합니다.
- 거래소와 연동한 컴포넌트(거래소객체)(실전거래에서만 사용)
- 거래소를 직접 통신하면 필요한 거래에 필요한 데이터를 조회하고 매매(매수/매도)를 실행합니다.
- 공통 컴포넌트 (백테스트와 실전 거래에 공통으로 사용됨)
실전거래 방안
아래는 앞서 언급한 컴포넌트를 기반으로 실전 거래를 Pseudo 코드입니다. 백테스트에서 4시간 캔들 데이터를 기준으로 매매를 수행했었기 때문애 아래 작성된 프로그램은 OS의 JOB에 등록하여 4시간에 한번씩 실행하도록 등록합니다.
** 실전거래를 위한 입력 변수들입니다.
var 총투자금액 = 100만원(임의 값)
var 건별투자금액 = 1만원(임의 값)
var 캔들데이터개수 = 20개(임의 값)
거래소 ={
자금정보() - 거래소API를 호출해서 투자가능자산를 조회합니다.
종목리스트() - 거래소API를 호출해서 거래하려는 마켓(예시: KRW)에서 종목리스트를 가져옵니다.
현재가정보(종목코드) - 거래소API를 호출해서 종목코드별 현재가를 가져옵니다. 현재가를 가져와야 평단가와 비교하여 손익을 계산할수 있습니다.
보유중인종목() - 거래소API를 호출하여 보유중인 종목을 가져옵니다.(평단가와 보유수량을 가져옵니다.)
실전매매(매매계획) - 종목별 매매결과를 받아서, 거래소 API와 호출하여 매수/매도를 수행합니다.
전체매매결과출력() - 총보유자산, 투자가능자산, 평가금액, 손익률을 계산합니다.
캔들데이터(종목코드, 캔들데이터개수) - 종목코드별 최근 지정된 개수의 캔들데이터를 조회합니다.
}
종목 = {
종목명, 종목코드, 유의종목여부
종목변수
지표관리
데이터처리(캔들데이터) - 캔들데이터를 저장하고 자동으로 매매변수들을 생성함.
매매관리자 = { -- 종목내 캔들데이터가 들어오면 매매로직을 참고하여 매매를 수행함.
매매이력목록,
매매로직목록 - 매수/매도로직 목록을 관리
매매수행() - 매수/매도로직을 이용하여 매매를 수행후 결과를 저장
매매계획(조회날짜,조회시간) - 해당일/시간의 매매결과를 리턴함.
}
}
var 종목리스트 = 거래소에서 종목리스트가져오기()
종목리스트에서 유의종목제외
종목그룹 = {
종목리스트,
데이터처리(종목코드, 캔들데이터) - 종목별로 캔들데이터 저장함
매매수행() - 종목별 매매수행()를 호출함
매매계획(조회날짜,조회시간) - 해당일/시간의 종목별 매매결과()를 리턴함.
매매계획() - 현재매매결과()를 리턴함(실전거래에서만 사용)
}
** 매우 중요한 부분입니다. 이전 매수정보를 등록하므로, 이후에 매매계획을 작성할때, 추가 매수, 매도의 계획이 수립됩니다. 만약 매수정보가 없으면 신규매수를 위한 계획이 수립될것입니다.
** 보유중인 종목을 참고하여 종목그룹객체의 매매관리자를 통해서 매매이력정보를 추가함.
for 거래내용 in 거래소.보유중인종목() loop
종목그룹.종목(거래내용.종목코드).매매관리자.매매이력목록.추가(거래내용의 보유수량 및 평단가를 이용하여 매매이력에 추가)
end loop
** 종목별로 캔들데이터를 추가하여 매매계획을 수립합니다.
for 종목 in 종목그룹.종목리스트 loop
var 캔들데이터 = 거래소에서 캔들데이터가져오기(종목.종목코드)
종목그룹.데이터처리(종목.종콕코드, 캔들데이터)
end loop
종목그룹.매매수행()
var 매매계획 = 종목그룹.매매계획()
거래소.실전매매(매매계획)
거래소.전체매매결과출력()
Pseudo 코드이기 때문에 개략적으로 작성되었습니다. 거래소 API를 호출하여 보유중인종목에 대한 정보를 가져와서 종목객체에 매매이력정보를 추가합니다. 이전에 백테스트에서 했던 그대로 종목 객체로 거래소API로부터 조회한 캔들 데이터를 넣고 매매 로직을 수행한 후 결과를 추출합니다. 추출한 결과를 이용하여 거래소 API로 호출하여 실전 매매로 수행되는 구조로 작성되어 있습니다.
마무리
실전거래 처리 방법을 전반적으로 살펴보았습니다. 벡테스트작성 코드와 비교하면 거래소 객체를 작성을 제외하고는 크게 차이가 없습니다. 오히려 절차적으로 기존 코드들을 재사용하므로 심플합니다.
실전거래과 백테스트 결과와 동일한지 지속적으로 확인하는 작업이 필요합니다. 실전거래는 실전거래대로 자동으로 스케줄러와 같은 도구에 등록되어 기계적으로 실행하고, 이의 결과가 벡테스트 결과와 차이가 없는지 확인해야합니다. 결과차이는 필연적으로 발생할수 밖에 없지만 그 차이가 크다면 무엇인가 오류가 있다는 뜻입니다.
시스템 트레이드의 가장 큰 장점은 내가 작성한대로 실행하는 코드의 신뢰성입니다. 백테스트 결과와 비교하여 의미적인 신뢰성을 갖을수 있다면 일단은 성공적인 트레이딩이라고 말할수 있을것 같습니다. 시스템관점으로 성공적인 트레이딩이 되면 이후에는 로직 개선이 곧바로 투자의 결과에 직접적으로 영향을 줄수 있으므로 조금씨 좀더 좋은 결과로 이어질수 있습니다.
댓글남기기