[파이썬] 대신증권 API를 활용한 알고리즘 개발

2023. 9. 20. 11:47DATA PROGRAMMING/PYTHON

대신증권 API를 활용한 알고리즘

 

PER, EPS 구하기

MarketEye클래스를 활용하여 주식의 PER 등의 정보를 가져올 수 있다.

 

import win32com.client

# 객체생성
instMarketEye = win32com.client.Dispatch("CpSysDib.MarketEye"

instMarketEye.SetInputValue(0, (4, 67, 70, 111))
instMarketEye.SetInputValue(1, 'A003540')

 

SetInputValue(0, ())를 통해 가져오고 싶은 정보를 선택한다. 현재가(4), PER(67), EPS(70), 최근분기년월(111) 데이터를 가져온다.

 

SetInputValue(1, 종목코드)를 통해 'A003540'코드를 가진 종목의 정보를 가져올 수 있다.

 

 

정리

import win32com.client

# 객체생성
instMarketEye = win32com.client.Dispatch("CpSysDib.MarketEye")

instMarketEye.SetInputValue(0, (4, 67, 70, 111))
instMarketEye.SetInputValue(1, 'A003540')

instMarketEye.BlockRequest()

print("현재가: ", instMarketEye.GetDataValue(0, 0))
print("PER: ", instMarketEye.GetDataValue(1, 0))
print("EPS: ", instMarketEye.GetDataValue(2, 0))
print("최근분기년월: ", instMarketEye.GetDataValue(3, 0))

 

출력

 

파이썬을 통한 매매 알고리즘 개발

파이썬을 통해 실제 존재하는 투자 전략을 알고리즘 형태로 변환해주기만 하면 된다. 실제 존재하는 투자 전략 중 하나 예를 들면, 최근 60일의 거래량 평균보다 10배 높은 거래량이 발생하면 대박 주로 판단하는 방법이 있다. 이는 거래량이 갑자기 증가한 종목을 유망하다고 판단하는 것이다.

 

먼저 위 조건에 해당하는 종목을 판단하는 메소드를 만들면,

 

import win32com.client

def CheckVolumn(instStockChart, code):
    # SetInputValue
    instStockChart.SetInputValue(0, code)
    instStockChart.SetInputValue(1, ord('2'))
    instStockChart.SetInputValue(4, 60)
    instStockChart.SetInputValue(5, 8)
    instStockChart.SetInputValue(6, ord('D'))
    instStockChart.SetInputValue(9, ord('1'))

    # BlockRequest
    instStockChart.BlockRequest()

    # GetData
    volumes = []
    numData = instStockChart.GetHeaderValue(3)
    for i in range(numData):
        volume = instStockChart.GetDataValue(0, i)
        volumes.append(volume)

    # Calculate average volume
    averageVolume = (sum(volumes) - volumes[0]) / (len(volumes) -1)

    if(volumes[0] > averageVolume * 10):
        return 1
    else:
        return 0

위 코드처럼 작성할 수 있다.

 

판정할 코드를 인자로 입력받고 해당 인자 즉, 해당 코드의 60일 치의 거래량 중, 가장 최근 거래량을 제외한 59일치의 거래량 평균을 낸다. 가장 최근 일의 거래량이 평균 거래량의 10배보다 크면 1을, 그렇지 않으면 0을 출력한다.

 

instCpCodeMgr = win32com.client.Dispatch("CpUtil.CpCodeMgr")
codeList = instCpCodeMgr.GetStockListByMarket(1)

instStockChart = win32com.client.Dispatch("CpSysDib.StockChart")
buyList = []
for code in codeList:
    if CheckVolumn(instStockChart, code) == 1:
        buyList.append(code)

 

존재하는 모든 코드를 가져온 이후 for문을 이용해 위에서 만들어 놓은 CheckVolumn 메소드에 모든 코드를 하나하나 대입해 보고 그 값이 1인(최근 거래량이 평균 거래량보다 10배 이상인) 코드들을 buyList 리스트에 대입한다.

 

전체 코드

import win32com.client

def CheckVolumn(instStockChart, code):
    # SetInputValue
    instStockChart.SetInputValue(0, code)
    instStockChart.SetInputValue(1, ord('2'))
    instStockChart.SetInputValue(4, 60)
    instStockChart.SetInputValue(5, 8)
    instStockChart.SetInputValue(6, ord('D'))
    instStockChart.SetInputValue(9, ord('1'))

    # BlockRequest
    instStockChart.BlockRequest()

    # GetData
    volumes = []
    numData = instStockChart.GetHeaderValue(3)
    for i in range(numData):
        volume = instStockChart.GetDataValue(0, i)
        volumes.append(volume)

    # Calculate average volume
    averageVolume = (sum(volumes) - volumes[0]) / (len(volumes) -1)

    if(volumes[0] > averageVolume * 10):
        return 1
    else:
        return 0

if __name__ == "__main__":
    instStockChart = win32com.client.Dispatch("CpSysDib.StockChart")
    instCpCodeMgr = win32com.client.Dispatch("CpUtil.CpCodeMgr")
    codeList = instCpCodeMgr.GetStockListByMarket(1)
    buyList = []
    for code in codeList:
        if CheckVolumn(instStockChart, code) == 1:
            buyList.append(code)
            print(code)

 

 

업종별 PER분석을 통한 유망주 찾기

 

PER의 의미는 업종별로 상이하다. 예를 들면 똑같이 PER가 10이라고 해도, 어떤 업종에서는 PER가 높은 것으로 판단할 수도 있고, 어떤 업종에서는 낮은 것으로 판단할 수도 있다. 그렇기에 업종별로 분류해서 그 업종에서도 상대적으로 낮은 PER의 종목을 선택하는 전략이 존재한다. 이 알고리즘을 파이썬을 통해서 만들 수 있다.

 

import win32com.client

instCpCodeMgr = win32com.client.Dispatch("CpUtil.CpCodeMgr")
industryCodeList = instCpCodeMgr.GetIndustryList()

for industryCode in industryCodeList:
    print(industryCode, instCpCodeMgr.GetIndustryName(industryCode))

해당 코드를 통해 업종별 코드와 업종 이름을 출력할 수 있다.

 

 

이제 특정 업종별로 퍼를 구하는 코드를 작성해 보자

import win32com.client

instCpCodeMgr = win32com.client.Dispatch("CpUtil.CpCodeMgr")
tarketCodeList = instCpCodeMgr.GetGroupCodeList(5)

for code in tarketCodeList:
    print(code, instCpCodeMgr.CodeToName(code))

instMarketEye.SetInputValue(0, 67)
instMarketEye.SetInputValue(1, tarketCodeList)

tarketCodeList에 '5'에 해당하는 음식료업 업종의 종목들을 대입한다. 여기에 포함된 종목들을 for 문을 통해 확인할 수 있다.

또한 MarketEye를 활용해 tarketCodeList에 저장된 음식료업 업종 종목들의 PER를 불러온다.

 

음식료품 업종에 포함된 종목들

 

 

instMarketEye.BlockRequest()
numStock = instMarketEye.GetHeaderValue(2)

sumPer = 0
for i in range(numStock):
    sumPer += instMarketEye.GetDataValue(0, i)

print("Average PER: ", sumPer / numStock)

MarketEye는 Request가 필요하다. 이후 GetHeaderValue()에 2 인자를 대입하면 해당 종목의 수를 구할 수 있고, numStock에 대입한다.

for 문을 활용해 모든 종목의 PER를 더하고 종목의 수로 나눠주면 해당 업종의평균 PER를 구할 수 있다. 이와 비교하여 원하는 수준의 PER값을 가진 종목을 선택해 주면 된다.

 

 

AveragePer = sumPer/numStock
BuyList = []
for i in range(numStock):
    if instMarketEye.GetDataValue(1, i) < AveragePer:
        BuyList.append(instCpCodeMgr.CodeToName(instMarketEye.GetDataValue(0, i)))

예를 들어 평균 PER보다 낮은 PER를 가진 종목들을 가져오고 싶을 땐 이런 식으로 하면 된다.