본문 바로가기
주식/주식자동매매

주식 자동매매 변동성 돌파 전략 - 매수량 조절하기

by 날아라키위새 2021. 7. 22.
반응형

변동성 돌파 전략에서 매수량 자동으로 조절하기

변동성 돌파 전략 단점 업그레이드에서는 기본 변동성 돌파 전략에서 사용하는 고정된 돌파계수 K값을 시장의 변화에 따라 변동시켜주는 방법을 다루었다면 이번 포스팅에서는 매수량을 자동으로 조절하는 방법을 알아보자. 

 

매수량을 바꿔주면 좋은 이유?

일반적인 자동매매에서 종목을 매수하는 경우에는 그날그날 시장 혹은 종목에 따라 매수량을 바꿔주지는 않는다. 즉 종목당 1000만원으로 자동매매를 하는경우 대충 1000만원을 주가로 나누어 매수량을 정하게 된다.

 

이때 주의할 점은 매수량은 반올림보다는 버림으로 계산하는걸 추천한다. 아래와 같이 그냥 나누기인 "/" 오퍼레이터를 사용하는 게 아니라 더블 슬래쉬 "//" 오퍼레이터를 사용하면 된다. 

buy_qty = buy_amount // ask_price

하지만 위와 같이 매수량을 정하게 되면 매번 최대에 가까운 수량을 매수하게 된다. (풀매수 가즈아)

 

각설하고 아무리 변동성 돌파 전략의 기본이 정해진 종목들 중에서 특정 주가를 돌파하는 경우에만 매수를 한다고 하지만 일반적인 시장 상황에 맞지 않는 (작전주라든지 작전주 같은 거라던지) 종목이 갑자기 급등하는 경우 우리의 정직한 변동성 전략으로는 손실이 날 수 있다고 판단을 한 사람들이 있었다. 누군지는 모르겠다.

 

그래서 종목에 따라 매수량을 조절하는 방법이 나왔는데 듣기에 그럴싸해서 매매스크립트에 적용해볼까 하고 공부해보았다. 

리스크 관리

최근 X일 까지의 주가를 확인하여 계속 주가가 어느 정도 상승하는 종목이었다면 매수를 많이.

반대로 갑자기 급등한 경우에는 매수를 적게.

뭐 그런 아이디어를 가지고 나온 방법이다.

 

자세히 설명하자면 최근 X일동안 5일 이동평균가보다 현재 사려는 시점의 주가보다 몇 번이나 높았는지를 확인해서 점수를 준다. 그리고 그 점수만큼 매수량을 조절한다.

 

예를 들어 최근 10일을 확인하는 경우

10일 전부 5일 이동평균가가 현재 주가보다 높다면 1

9일만 높았다면 0.9

8일만 높았다면 0.8

... 뭐 이런 식으로

그리고 한 번도 높은 적이 없다면 (우하향하던 주가가 갑자기 오른 경우) 0.1의 점수를 주는 방법이다. 

코드 공유

import win32com.client
import pandas as pd

cpohlc = win32com.client.Dispatch('CpSysDib.StockChart')
cpStock = win32com.client.Dispatch('DsCbo1.StockMst')


def get_ohlc(code, qty): #code의 OHLC 가격 정보를 qty 개수만큼 반환한다
    try:
        cpohlc.SetInputValue(0, code)  # 종목코드
        cpohlc.SetInputValue(1, ord('2'))  # 1:기간, 2:개수
        cpohlc.SetInputValue(4, qty)  # 요청개수
        cpohlc.SetInputValue(5, [0, 2, 3, 4, 5])  # 0:날짜, 2~5:OHLC
        cpohlc.SetInputValue(6, ord('D'))  # D:일단위
        cpohlc.SetInputValue(9, ord('1'))  # 0:무수정주가, 1:수정주가
        cpohlc.BlockRequest()
        count = cpohlc.GetHeaderValue(3)  # 3:수신개수
        columns = ['open', 'high', 'low', 'close']
        index = []
        rows = []
        for i in range(count):
            index.append(cpohlc.GetDataValue(0, i))
            rows.append([cpohlc.GetDataValue(1, i), cpohlc.GetDataValue(2, i),
                         cpohlc.GetDataValue(3, i), cpohlc.GetDataValue(4, i)])
        df = pd.DataFrame(rows, columns=columns, index=index)
        return df
    except Exception as ex:
        print('get_ohlc() -> 에러: ' + str(ex))
        return None


def get_current_price(code): # code의 현재가, 매수호가, 매도호가를 리턴
    try:
        cpStock.SetInputValue(0, code)  # 종목코드에 대한 가격 정보
        cpStock.BlockRequest()
        item = {}
        item['cur_price'] = cpStock.GetHeaderValue(11)  # 현재가
        item['ask'] = cpStock.GetHeaderValue(17)  # 매수호가 /주찬 크레온에는 매도호가 -> 16, 매수호가 -> 17 수정함
        item['bid'] = cpStock.GetHeaderValue(16)  # 매도호가
        item['dlow'] = cpStock.GetHeaderValue(15)  # 저가
        item['start'] = cpStock.GetHeaderValue(13)  # 시가
        return item['cur_price'], item['ask'], item['bid'], item['dlow'], item['start']
    except Exception as ex:
        print('get_current_price() -> 에러: ' + str(ex))
        return None

 def get_movingaveragescore(code):  # code의 5일 이동평균가보다 현재가가 며칠이나 더 높은지를 점수로 리턴
    try:
        ohlc = get_ohlc(code, 10)   # 최근 10일 확인
        closes = ohlc['close'].sort_index()
        ma = closes.rolling(window=5).mean()
        madf = ma.to_frame()
        current_price, ask_price, bid_price, dlow_price, start_price = get_current_price(code)
        madf['cprice'] = current_price
        return round((madf['cprice'] > madf['close']).sum() / madf['close'].count(), 2)
    except Exception as ex:
        print('get_movingaveragescore(code) -> 에러 ' + str(ex))
        return None

함수 get_movingaveragescore()에 종목의 점수를 0에서 1의 값을 리턴하고 

나중에 이 리턴값을 매수하는 함수에 적용하여 매수량을 자동으로 조절할 수 있다.

gmas = get_movingaveragescore(code)  # moving average 5일 점수값

if ask_price > 0:  # 매수호가가 존재하면
    if gmas == 0:  # moving average score 가 0인 경우 10%만 매수
        buy_qty = buy_cash * 0.1 // ask_price
    else: 
        buy_qty = buy_cash // ask_price

buy_cash라는 종목당 정해높은 금액이 있다면 

점수만큼 비율을 조절하여 최종 구매하는 buy_qty를 정할 수 있다.

위 코드의 경우 점수가 0을 받는다면 매수하지 않는 게 아니라 10%만 매수하는 방법이다.

 

그리고 리스크를 줄인다고 했지만 또 거기에서 잃을 수 있는 수익을 포기하기 싫다면

아래처럼 최소 점수(0.4)를 설정해놓으면 40%만 매수할 수 있다.

gmas = get_movingaveragescore(code)  # moving average 5일 점수값

if ask_price > 0:  # 매수호가가 존재하면
    if gmas < 0.4:  # moving average score 가 0.4보다 작은 경우 40% 매수
        buy_qty = buy_cash * 0.4 // ask_price
    else:
        buy_qty = buy_cash // ask_price

 

위에 설명한 방법을 적용한 지 시간이 꽤 지났으니

과연 효과는 있었는지

수익은 늘었는지

다음 포스트에서 만나보아요.

 

관련 글:

주식 자동매매 변동성 돌파 전략 업그레이드 - 거래량 상위 종목 매수하기

주식 자동매매 변동성 돌파 전략 단점 업그레이드 하기 - 매도 타이밍

주식 자동매매 프로그램 변동성 돌파 전략 단점 업그레이드 하기 (대신증권 크레온 플러스 파이썬 API)

반응형

댓글