Skip to content

블로그

파이썬 리플렉션 (동적 클래스 인스턴스 생성 및 함수 호출)

리플렉션(Reflection)이란 런타임에서 프로그램의 구조를 파악하고 동적 객체 생성 및 함수 호출 등의 행위를 수행할 수 있게 해주는 장치 입니다.

이 포스트에서는 파이썬에서의 간단한 리플렉션 예제를 소개합니다.

class MyClass:
my_var = 1
def __init__(self):
pass
def my_fnc(self, arg):
print('my_fnc({}) called.'.format(arg))
# 클래스 및 클래스변수 접근
my_class = globals()['MyClass']
print(my_class)
print(my_class.my_var)
# 객체 생성
my_inst = my_class()
print(my_inst)
# 함수 접근 및 호출
func = getattr(my_inst, 'my_fnc')
print(func)
func(2)

대신증권 크레온(Creon) API를 사용하여 파이썬에서 주식 차트 데이터 받아오기

최근 개인 투자자들의 프로그램 매매에 대한 관심이 높아지고 있습니다. 이에 따라 여러 증권사들이 API를 선보이고 있습니다. 대표적인 증권사 API로 키움증권 OpenAPI+, 이베스트투자증권 Xing API, 그리고 이번 포스트에서 다룰 대신증권 크레온 Plus API를 들 수 있습니다.

세 가지 API를 모두 사용해 봤지만, 크레온 Plus API를 가장 직관적으로 쉽게 사용할 수 있었습니다. 여기서는 크레온 Plus API로 분봉 차트 데이터를 받아오는 파이썬 소스코드를 다룹니다.

크레온 Plus API를 설치하고 파이썬 스크립트를 관리자 권한으로 실행해야 합니다.

크레온 Plus API는 다음 페이지에서 다운 받을 수 있습니다.

https://www.creontrade.com/

이 페이지 하단에 있는 다운로드센터 링크를 클릭합니다.

여기서 CREON Plus 영역의 다운로드 버튼을 클릭합니다. 그러면 팝업 메시지가 하나 뜨고 다운로드를 시작합니다. 실제로는 CREON HTS를 다운받습니다.

CREON HTS를 설치하고 실행하면 다음과 같은 창이 뜹니다.

creon

이 창의 상단에 보면 creon plus 버튼이 있습니다. 크레온 API 사용을 위해서는 이 버튼을 누른 후 로그인을 해야 합니다.

로그인이 제대로 완료되면 작업표시줄에 다음과 같이 두 아이콘이 뜹니다. creon

이제 파이선에서 크레온 Plus API를 사용하기 위해 다음 두 라이브러리를 설치합니다.

  • conda install -c anaconda pywin32
  • pip install pywinauto

이렇게 크레온 Plus API를 사용할 준비를 마친 후 파이썬 코드를 작성합니다.

import time
import logging
from logging.handlers import TimedRotatingFileHandler
import win32com.client
import pandas as pd
# 로그 파일 핸들러
fh_log = TimedRotatingFileHandler("logs/log", when="midnight", encoding="utf-8", backupCount=120)
fh_log.setLevel(logging.DEBUG)
# 콘솔 핸들러
sh = logging.StreamHandler()
sh.setLevel(logging.DEBUG)
# 로깅 포멧 설정
formatter = logging.Formatter("[%(asctime)s][%(levelname)s] %(message)s")
fh_log.setFormatter(formatter)
sh.setFormatter(formatter)
# 로거 생성
logger = logging.getLogger("creon")
logger.setLevel(logging.DEBUG)
logger.addHandler(fh_log)
logger.addHandler(sh)
class Creon:
def __init__(self):
self.obj_CpCodeMgr = win32com.client.Dispatch('CpUtil.CpCodeMgr')
self.obj_CpCybos = win32com.client.Dispatch('CpUtil.CpCybos')
self.obj_StockChart = win32com.client.Dispatch("CpSysDib.StockChart")
def creon_7400_주식차트조회(self, code, date_from, date_to):
"""
http://money2.creontrade.com/e5/mboard/ptype_basic/HTS_Plus_Helper/DW_Basic_Read_Page.aspx?boardseq=284&seq=102&page=1&searchString=StockChart&p=8841&v=8643&m=9505
:return:
"""
b_connected = self.obj_CpCybos.IsConnect
if b_connected == 0:
logger.debug("연결 실패")
return None
list_field_key = [0, 1, 2, 3, 4, 5, 8]
list_field_name = ['date', 'time', 'open', 'high', 'low', 'close', 'volume']
dict_chart = {name: [] for name in list_field_name}
while True:
self.obj_StockChart.SetInputValue(0, 'A'+code)
self.obj_StockChart.SetInputValue(1, ord('1')) # 0: 개수, 1: 기간
self.obj_StockChart.SetInputValue(2, date_to) # 종료일
self.obj_StockChart.SetInputValue(3, date_from) # 시작일
self.obj_StockChart.SetInputValue(4, 100) # 요청 개수
self.obj_StockChart.SetInputValue(5, list_field_key) # 필드
self.obj_StockChart.SetInputValue(6, ord('m')) # 'D', 'W', 'M', 'm', 'T'
self.obj_StockChart.BlockRequest()
status = self.obj_StockChart.GetDibStatus()
msg = self.obj_StockChart.GetDibMsg1()
logger.debug("통신상태: {} {}".format(status, msg))
if status != 0:
return None
cnt = self.obj_StockChart.GetHeaderValue(3) # 수신개수
for i in range(cnt):
dict_item = {name: self.obj_StockChart.GetDataValue(pos, i) for pos, name in zip(range(len(list_field_name)), list_field_name)}
for k, v in dict_item.items():
dict_chart[k].append(v)
if not self.obj_StockChart.Continue:
break
self._wait()
logger.debug("차트: {} {}".format(cnt, dict_chart))
return pd.DataFrame(dict_chart, columns=list_field_name)
def _wait(self):
time_remained = self.obj_CpCybos.LimitRequestRemainTime
cnt_remained = self.obj_CpCybos.GetLimitRemainCount(1) # 0: 주문 관련, 1: 시세 요청 관련, 2: 실시간 요청 관련
if cnt_remained <= 0:
timeStart = time.time()
while cnt_remained <= 0:
time.sleep(time_remained / 1000)
time_remained = self.obj_CpCybos.LimitRequestRemainTime
cnt_remained = self.obj_CpCybos.GetLimitRemainCount(1)
if __name__ == '__main__':
creon = Creon()
print(creon.creon_7400_주식차트조회('035420', 20180101, 20180109))

이 파이썬 스크립트를 실행하면 다음과 같이 NAVER 종목의 20180101부터 20180109까지의 분봉 차트 데이터를 받아올 수 있습니다.

분봉차트데이터

크레온 Plus API를 설치하고 파이썬 스크립트를 관리자 권한으로 실행할 것을 권장합니다.

파이썬에서 크레온 API 사용을 위한 준비사항

최근 개인 투자자들의 프로그램 매매에 대한 관심이 높아지고 있습니다. 이에 따라 여러 증권사들이 API를 선보이고 있습니다. 대표적인 증권사 API로 키움증권 OpenAPI+, 이베스트투자증권 Xing API, 그리고 이번 포스트에서 다룰 대신증권 크레온 Plus API를 들 수 있습니다.

세 가지 API를 모두 사용해 봤지만, 크레온 Plus API를 가장 직관적으로 쉽게 사용할 수 있었습니다. 이번 포스트에서 크레온 Plus API를 사용하기 위한 준비사항을 정리합니다.

우선 크레온 Plus API를 설치해야 합니다. 대부분의 HTS API는 윈도우 환경에서만 사용 가능합니다. 크레온 Plus API 또한 그렇습니다.

크레온 Plus API는 다음 페이지에서 다운로드할 수 있습니다. https://www.creontrade.com/

여기서 CREON Plus 영역의 다운로드 버튼을 클릭합니다. 그러면 팝업 메시지가 하나 뜨고 다운로드를 시작합니다. 실제로는 CREON HTS를 다운로드합니다.

CREON HTS를 설치하고 실행하면 다음과 같은 창이 뜹니다. 1

이 창의 상단에 보면 creon plus 버튼이 있습니다. 크레온 API 사용을 위해서는 이 버튼을 누른 후 로그인을 해야 합니다.

로그인이 제대로 완료되면 작업표시줄에 다음과 같이 두 아이콘이 뜹니다.

2

대부분의 HTS API는 사용을 위해서 윈도우 운영체제와 32비트 파이썬이 필요합니다. 여기서는 32비트 아나콘다 설치를 권장합니다. 아나콘다는 파이썬과 주요 라이브러리를 동시에 설치하는 오픈소스입니다.

다음 경로에서 아나콘다를 다운받을 수 있습니다.

https://www.anaconda.com/products/individual

상단에 있는 Download 버튼을 누르면 64비트 아나콘다를 다운받습니다. 그러므로 이 버튼을 누르지 말고 페이지의 하단부분에 있는 다음 영역에서 32비트 아나콘다 설치파일을 다운로드 받아야 합니다.

3

기존에 아나콘다 64비트를 설치한 상태에서도 별도로 아나콘다 32비트를 설치하시면 됩니다. 이 때 설치 경로를 다음과 같이 다르게 주는 것이 좋습니다.

  • 아나콘다 64비트 경로 예: C:\Users\USER\anaconda3
  • 아나콘다 32비트 경로 예: C:\Users\USER\anaconda3x86

이제 파이선에서 크레온 Plus API를 사용하기 위해 다음 두 라이브러리를 설치합니다.

conda install -c anaconda pywin32
pip install pywinauto

위에서 설치한 32비트 아나콘다에서 라이브러리를 설치해야 함을 주의해야 합니다.

크레온 Plus API를 설치하고 파이썬 스크립트를 관리자 권한으로 실행해야 합니다. 아나콘다 프롬프트의 경우 다음과 같이 아이콘을 우클릭하고 관리자 권한으로 실행을 누르면 됩니다.

4

VSCode를 사용하는 경우도 같은 방식으로 관리자 권한으로 실행할 수 있습니다. 만약 VSCode를 앞으로도 계속 관리자 권한으로 실행하고 싶으면 먼저 다음과 같이 속성 메뉴로 들어갑니다.

5

다음으로 호환성 탭에서 관리자 권한으로 이 프로그램 실행을 체크하고 적용합니다.

6

이제 크레온 API를 사용할 준비가 됐습니다. 이어지는 시스템 트레이딩 관련 콘텐츠를 확인해 주세요. 시스템 트레이딩 카테고리에서 크레온 API를 이용한 차트 수집, 투자자별 매매내역 수집, 주문내기 등의 콘텐츠를 다룹니다.

Django 서버 시작할 때 실행할 코드 설정하기

Django는 파이썬 계열에서 대표적인 웹 프레임워크 입니다. 많지는 않지만 서버를 실행함과 동시에 특정 코드를 실행할 일이 생깁니다. 예를 들어서, 서버를 시작하면서 파일을 읽거나, 객체를 생성해 놓거나, 다른 서버에 메시지를 전송하는 등이 될 수 있습니다.

이 때, AppConfig를 사용하면 됩니다. 먼저 AppConfig를 상속하는 클래스를 정의합니다.

app/broker.py
from django.apps import AppConfig
class MyAppConfig(AppConfig):
name = 'my_app'
verbose_name = "My App"
def ready(self):
# TODO: Write your codes to run on startup
pass

이렇게 정의한 클래스를 __init__.py에 명시해 주면 끝입니다.

app/__init__.py
default_app_config = 'app.broker.MyAppConfig'

그런데 한가지 주의할 점이 있습니다. 이 부분을 간과하면 곤란한 상황이 생길 수 있습니다. Django가 기본적으로 코드 검증 과정에서 한번, 코드 실행 과정에서 한번, 총 2번 MyAppConfig를 실행합니다.

두번 실행되는 일을 피하기 위해서 Django 서버를 실행할 때 다음과 같이 --noreload 옵션을 넣어줍니다.

Terminal window
python manage.py runserver 0.0.0.0:8000 --noreload

자바스크립트 (JavaScript)에서 객체지향 프로그래밍 (OOP) 하기

자바스크립트에서는 명시적으로 지원되는 객체지향 프로그래밍 방법이 부족합니다. 객체지향 프로그래밍의 철학을 철저하게 따르는 자바 (Java)와는 이름은 비슷하지만 차이가 많습니다.

이번 포스트에서는 자바스크립트에서 OOP를 흉내낼 수 있는 팁을 소개합니다.

OOP 꽃은 클래스 입니다. 클래스는 상태 (State)과 행동 (Behavior)을 캡슐화 (Encapsulation)하는 단위입니다. 상태는 속성 (Attribute)로, 행동은 메소드 (Method)로 구현됩니다. 물론 자바스크립트에서는 메소드를 함수 (Function)라고 명명하는 것이 더 자연스러울 것입니다.

그럼 자바스크립트에서 클래스를 만들어 보겠습니다.

function MyClass() {
}

사실 자바스크립트는 class 키워드를 완전히 지원하고 있지 않습니다. 클래스 역할을 function 키워드가 대신합니다. function 키워드로 클래스도, 함수도 선언하는 것입니다.

여기서 MyClass의 객체를 생성하려면 var myClassInstance = new MyClass();와 같이 하면 됩니다.

그럼 MyClass에 상태와 행동을 넣어 보겠습니다.

function MyClass() {
var myPrivateAttr1 = 1;
var myPrivateAttr2 = 2;
function myPrivateFnc1 () {
return myPrivateAttr1;
}
function myPrivateFnc2 () {
return myPrivateAttr2;
}
}

변수 2개와 함수 2개를 넣었는데, 모두 MyClass 외부에서는 사용할 수 없습니다. 즉 이들은 Private 속성과 함수 입니다. 그럼 Public 속성과 함수를 추가하는 방법을 보겠습니다.

function MyClass() {
var myPrivateAttr1 = 1;
var myPrivateAttr2 = 2;
function myPrivateFnc1 () {
return myPrivateAttr1;
}
function myPrivateFnc2 () {
return myPrivateAttr2;
}
var self = {
myPublicAttr1: 1,
myPublicAttr2: 2,
myPublicFnc1: function () {
return myPrivateFnc1();
},
myPublicFnc2: function () {
return myPrivateFnc2();
}
};
return self;
}

이렇게 하면 외부에서 self 변수 안에 들어 있는 속성과 함수들을 접근할 수 있게 됩니다. 즉 이들은 Public 속성과 함수들 입니다.

var myClassInstance = new MyClass();
console.log(myClassInstance.myPublicFnc1());

이렇게 하면 브라우저 콘솔에 1이 출력될 것입니다.