반응형

부동산 지인은 국내 부동산의 각종 지표를 제공해줍니다.

그 지표 중 하나 매매 / 전세 4분면을 살펴보도록 하겠습니다.

 

X축은 매매, Y축은 전세입니다.

3개월 대비 세종이 매매와 전세가 강세입니다. 

 

경기를 보면 매매가는 상승했으나 전세는 매매에 비해서 상승률이 적습니다.

전세가의 비해서 매매가가  높은 걸 볼 수 있습니다. (매매가가 전세가에 비해서 상승을 많이 했습니다.)

 

대구는 매매가 상승률을 올랐으나 전세가 상승률은 하락했습니다.

전세 가격은 투자의 가치가 아닌 이 정도 가격이면 전세 가격을 내고 실제로 살겠다는 마음가짐이 있습니다.

이번 코로나 바이스로 인해서 전세 가격이 떨어진 것이 아닌가 조심스럽게 추측해봅니다.

 

대구 4분면 시장 강도 현황입니다.

매매 가격은 서구가 가장 높고 남구는 (3개월 이전 보다) 매매 가격이 떨어지는 흐름을 볼 수 있습니다.

달서구와 수성구는 매매 가격은 오르고 있으나 전세 가격이 빠지고 있네요.

 

이렇게 부동산 지인의 4분면을 활용하면 지역의 흐름을 파악할 수 있습니다.

최근의 흐름이 좋은지 나쁜지 말이죠.

 

부동산 지인 사이트에서 직접 지역을 보시며 흐름을 파악하시면 좋겠습니다.

감사합니다.

반응형
반응형

일반적으로 유동성이라 함은 기업의 상태를 확인하기 위해서 확인하는 지표로 많이 사용됩니다.

저는 기업의 유동성이 궁금한 것이 아닌 시장에 돌고 있는 지표가 궁금합니다.

그럼 유동성 정의를 다시 하겠습니다.

유동성이라 함은 시장에 돌고 있는 화폐의 총량을 말합니다.

유동성 비율을 확인하기 위해서는 M1과 M2 지표를 확인해야 됩니다.

 

M1과 M2 란?

M1(협의통화): 현금 및 예금 금액 (당장 사용 가능한 돈)

M2(광의통화): 2년 미만 정기예금 (이자를 포기하고 써야 되는 돈)

 

말잔과 평잔이란?

말잔: 해당 기간의 말일자 잔액

평잔: 해당 기간 중 매일매일의 잔액을 평균한 금액

 

유동성 비율(M1/M2)을 확인한다면 유동성 비율이 많다는 건 시장에서 사용할 수 있는 돈이 많다는 것이고

즉, M1의 비율이 높을수록 현재 사용할 수 있는 금액이 많다고 생각할 수 있겠습니다.

 

 

M1과 M2 값은 한국은행경제 통계시스템에서 각각의 값을 확인 할 수 있습니다.

https://ecos.bok.or.kr/

 

 

또는 Open API를 통해서도 값을 직접 받아 올 수도 있습니다.

아래는 파이썬으로 API를 호출하는 가장 기본적인 샘플입니다.

한국은행경제 통계시스템에서 key를 발급받고 아래 key에 입력을 해주시면 되겠습니다.

from urllib.request import urlopen
import json

key = ''
url="http://ecos.bok.or.kr/api/StatisticSearch/"+key+"/json/kr/1/24/010Y002/MM/201401/201912/?/?/?/"

result = urlopen(url)
html = result.read()
data = json.loads(html)

print(data)

이제는 값을 받아오고 데이터 가공을 필요로 합니다 :)

필요한 값을 호출하고 필요에 따라 값을 재가공해서 사용을 해주시면 되겠습니다.

아래는 우리 로컬에서 테스트하기 전에 한국은행경제 통계시스템에서 직접 테스트를 해보실 수 있습니다. 우리 로컬에서 조회를 하기 전에 테스트를 해보세요!!

테스트 페이지

 

감사합니다.

반응형

'재테크 > 부동산' 카테고리의 다른 글

부동산 지인을 활용한 지역분석 (4분면 활용)  (0) 2020.03.13
반응형

소스 출처는 위키독스의 파이썬으로 배우는 알고리즘 트레이딩을 보며 학습했습니다.

pyqt를 활용하여 GUI를 만드는 작업까지는 저번 시간에 진행했습니다. 파이썬으로 키움 API 연습을 활용하는 연습을 진행하도록 하겠습니다. 풀 소스는 위키독스에서 제공이 됩니다. 어떻게 학습을 하고 어떻게 소스코드를 이해하는지 잘 살펴 봐주세요.

 

1. Open API+ 로그인

def __init__(self):
    super().__init__()
    self.setWindowTitle("PyStock")
    self.setGeometry(300, 300, 300, 150)

    self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")

    btn1 = QPushButton("Login", self)
    btn1.move(20, 20)
    btn1.clicked.connect(self.btn1_clicked)

    btn2 = QPushButton("Check state", self)
    btn2.move(20, 70)
    btn2.clicked.connect(self.btn2_clicked)

def btn1_clicked(self):
    ret = self.kiwoom.dynamicCall("CommConnect()")

def btn2_clicked(self):
    if self.kiwoom.dynamicCall("GetConnectState()") == 0:
        self.statusBar().showMessage("Not connected")
    else:
        self.statusBar().showMessage("Connected")

GUI를 만드는 작업은 진행을 했으니 API 사용을 집중적으로 보겠습니다.

키움 증권에서 제공하는 키움 클래스를 활용하기 위해서 키움 API를 설치할 때 우리의 컴퓨터에 미리 등록되어 있는 ID를 갖고 옵니다. ID는 레지스트리에 등록이 되어 있으며 다음과 같습니다. -> KHOPENAPI.KHOpenAPICtrl.1

이로써 우리는 키움 클래스를 사용할 수 있습니다. 아래는 2개 버튼을 만들었는데 1)하나는 로그인 그리고 다른 하나는 2)접속 상태를 확인 하는 버튼입니다. 버튼이 눌릴 때 이벤트 clicked라는 이벤트가 발생합니다. 이때 등록해놓은 btn1_clicked / btn2_clicked 함수가 호출이 되는 것입니다. 

키움 API에서 제공되는 함수는 1)Commconnect() 와 2)GetConnectState() 함수입니다. 일반적으로 API를 호출한다고 하면 함수를 그냥 호출하면 되지만 OCX 방식이기 때문에 API 호출 시 dynamiccall을 wrapper로 사용해주셔야 됩니다.

QAxWidget -> self.kiwoom -> dynamiccall

API 호출 할 때 이점을 유의해주세요.

또 하나 눈여 볼 것은 kiwoom은 self라는 키워드가 붙어 있고 btn1, btn2는 그냥 쓰여 있습니다. kiwoom은 다른 메서드에서도 사용이 되기 때문에 self 키워드를 붙여 줍니다.

 

 

2. 로그인 이벤트

def __init__(self):
    super().__init__()
    self.setWindowTitle("PyStock")
    self.setGeometry(300, 300, 300, 150)

    self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
    self.kiwoom.dynamicCall("CommConnect()")

    self.text_edit = QTextEdit(self)
    self.text_edit.setGeometry(10, 60, 280, 80)
    self.text_edit.setEnabled(False)

    self.kiwoom.OnEventConnect.connect(self.event_connect)

def event_connect(self, err_code):
    if err_code == 0:
        self.text_edit.append("로그인 성공")

1번 코드에서는 CommentConnect() 호출을 통해서 로그인을 진행했습니다. CommentConnect() 호출 이후로그인을 하면 OnEventConnect 이벤트가 발생(연결 상태가 변경될 때마다 발생)이 됩니다. 서버로부터 받는 응답입니다. 이벤트가 발생이 되면 등록되어 있는 event_connect() 함수가 호출이 됩니다.

 

3. 주식 기본정보 갖고 오기

단어 정리를 하나하고 가자면 TR은 서버로부터 데이터를 주고받는 작업입니다. 서버와 데이터를 주고받아 보도록 하겠습니다.

    # OpenAPI+ Event
    self.kiwoom.OnEventConnect.connect(self.event_connect)
    self.kiwoom.OnReceiveTrData.connect(self.receive_trdata)

    self.code_edit = QLineEdit(self)
    self.code_edit.setText("039490")

    btn1 = QPushButton("조회", self)
    btn1.clicked.connect(self.btn1_clicked)

    self.text_edit = QTextEdit(self)

def btn1_clicked(self):
    code = self.code_edit.text()
    self.text_edit.append("종목코드: " + code)

    # SetInputValue
    self.kiwoom.dynamicCall("SetInputValue(QString, QString)", "종목코드", code)

    # CommRqData
    self.kiwoom.dynamicCall("CommRqData(QString, QString, int, QString)", "opt10001_req", "opt10001", 0, "0101")

def receive_trdata(self, screen_no, rqname, trcode, recordname, prev_next, data_len, err_code, msg1, msg2):
    if rqname == "opt10001_req":
        name = self.kiwoom.dynamicCall("CommGetData(QString, QString, QString, int, QString)", trcode, "", rqname, 0, "종목명")
        volume = self.kiwoom.dynamicCall("CommGetData(QString, QString, QString, int, QString)", trcode, "", rqname, 0, "거래량")

        self.text_edit.append("종목명: " + name.strip())
        self.text_edit.append("거래량: " + volume.strip())

데이터 요청을 하는 API 호출 시 패턴이 있습니다. 패턴은 아래와 같습니다.

 

SetInputValue(값 세팅) -> CommRqData(요청) -> 서버 -> 이벤트 대기 중(OnReceiveTrData) -> CommGetData(수신데이터 갖고 오기)

 

버튼이 눌릴 때 아래 함수가 호출이 됩니다.

-> dynamicCall("SetInputValue(QString, QString)""종목코드", code)

종목코드라는 필드 값과 코드 값이 세팅이 됩니다.

 

-> dynamicCall("CommRqData(QString, QString, int, QString)""opt10001_req""opt10001"0"0101")

TR을 구분하기 위한 문자열을 첫번 째 인자로 입력해줍니다 -> opt10001_req

TR 구분을 위한 값 동일하게 입력해줍니다. -> opt10001

단순 조회 TR 일 때는 -> 0

화면번호 동일하게 입력해줍니다. -> 0101

 

* TR 구분(2번째 인자 - KOA Studio 문서 확인)

 

요청 이후에는 OnReceiveTrData 이벤트가 발생됩니다. 이벤트에 등록된 함수 receive_trdata 함수가 호출이 되고 등록된 함수 인자 값도 키움 문서와 동일해야 됩니다.

이전에 요청했던 opt10001 TR이면 이라면 분기를 한번 해주고 CommGetData() 함수를 통해서 종목명, 거래량을 갖고 옵니다.

종목명, 거래량 이외에도 자본금, 매출액, 영업이익 등 필드가 정말 많습니다.

필요하신 필드  KOA Studio를 열어서 TR목록 탭 -> OUTPUT을 보시면 되겠습니다.

 

4) 계좌 정보 갖고 오기

    btn1.clicked.connect(self.btn1_clicked)

def btn1_clicked(self):
    account_num = self.kiwoom.dynamicCall("GetLoginInfo(QString)", ["ACCNO"])
    self.text_edit.append("계좌번호: " + account_num.rstrip(';'))

GetLoginInfo() 함수를 호출하면 계좌 정보를 갖고 옵니다. 이벤트 호출이 아닌 경우에는 값이 바로 반환이 됩니다. 값을 바로 받아와서 텍스트 창에 보여 줄 수 있습니다. 간단합니다 :)

 

 

 

5) 종목코드, 종목명 갖고 오기

    btn1.clicked.connect(self.btn1_clicked)

def btn1_clicked(self):
    ret = self.kiwoom.dynamicCall("GetCodeListByMarket(QString)", ["0"])
    kospi_code_list = ret.split(';')
    kospi_code_name_list = []

    for x in kospi_code_list:
        name = self.kiwoom.dynamicCall("GetMasterCodeName(QString)", [x])
        kospi_code_name_list.append(x + " : " + name)

    self.listWidget.addItems(kospi_code_name_list)

 

종목코드를오기 위해서 GetCodeListByMarket() 함수를 호출 했습니다.

종목명을 갖고 오기 위해서 GetMasterCodeName() 함수를 호출했습니다.

 

 

호출하는 함수들에 대해서 KOA Studio 내용을 직접 확인하면서 학습을 해주세요.

기본을 다지고 이후에 활용하는 부분은 우리의 몫이니까요.

재료들은 주어져있습니다. 잘 만들고 잘 소화시킬 수 있도록 이해하고 연습하고 코드들을 또 읽고 읽어야겠습니다.

감사합니다.

 

 

* 참고 소스 및 참고

https://wikidocs.net/4239

반응형
반응형

파이썬으로 무얼 할 수 있을까? 하다가 자료도 많고 정리도 잘 되어 있는 주식 트레이딩을 활용해볼까 합니다.

주식 데이터는 실제 데이터들이고 파이썬을 활용할 수 있는 곳이 명확합니다. 데이터 핸들, API 활용 및 자동화와 같이 말이죠. 돈을 벌려는 것이 아닌 파이썬을 잘 활용하고자 하는 마음에 학습을 시작합니다 :)

 

파이썬의 기본 개념은 앞 글에서 숙지를 했습니다. 파이썬 설치도 했고 환경 구축도 완료가 이미 되었습니다.

그래서 시작할 것은 주식계좌를 만들어 주세요.

계좌를 만들고 주식 데이터를 받아 올 수 있도록 키움주식회사에서 제공하는 모듈을 설치했습니다. 키움 번개 / 키움 OPEN API / KOA Studio 3가지를 설치하고 접속까지 되는 모습을 확인했습니다.

주식 트레이딩 전용 파이썬 가상 환경을 만들고 PYQT도 설치했습니다. 일반적으로 많은 사람들은 아나콘다라는 파이썬 패키지 묶음을 한 번에 설치를 하는데 우리는 파이썬만 설치를 했기에 다음과 같은 명령어로 pyqt를 설치해주세요.

가상환경을 구동하고 설치를 해주세요 :)

pip install pyqt5

설치가 어렵지 않습니다.

 

오늘은 pyqt 사용법을 간략하게 익혔습니다.

 

1. 기본 pyqt 사용

PYQT5.QtWidgets 패키지를 임포트하고 QApplication을 만들어서 레이블을 만들고 실행을 시켜주시면 됩니다.

 

2. QMainWindow 상송 후 창 크기 조절

QMainWindow를 상속받는 MyWindow 클래스를 만들었습니다. MyWindow는 QMainWindow의 기능들을 사용할 수 있고 타이틀과 창 크기는 원하는 값으로 변경했습니다.

super().__init__() 라인이 있습니다. 이 라인의 뜻은 QMainWindow 생성자를 호출하는 모습입니다. 이 라인이 없다면 상속받은 기능들을 사용할 수는 있지만 별도로 생성자를 호출하지는 않습니다. 그렇다면 기본 세팅은 안 되겠죠? 그렇기 때문에 부모 생성자를 호출해주는 모습니다.

 

3. 이벤트 등록

2번 항목의 향상된 기능입니다. 바로 사용자가 버튼을 누를 때 발생하는 이벤트를 등록했습니다. 이로써 우리는 프로그램을 만들고 무언가 액션을 취할수 있게 되었습니다.

 

주식 트레이딩을 하기 위한 기본 환경설정과 pyqt 사용법을 익혀 봤습니다.

무리하지 않고 조금씩 나아가 보겠습니다 :)

감사합니다.

 

 

* 참고자료

https://wikidocs.net/4235

반응형
반응형

안녕하세요.

장고의 폼 사용법에 대해서 학습을 하도록 하겠습니다.

 

장고를 활용하여 웹사이트를 만들 때 사용자에게 보여주는 기능만 제공하는 웹사이트를 만드시는 것이 아니라면, 사용자가 데이터도 입력을 할 수 있어야 됩니다.

장고는 입력에 대한 처리를 할 수 있도록 폼 기능을 제공해줍니다.

 

HTML에서 form이란  <form> ... </form> 태그 내에서 우리의 웹사이트를 사용하는 사용자가 데이터를 입력할 수 있도록 하고 서버로 데이터를 보내주는 역할을 제공합니다.

폼은 2가지의 정보를 담고 있어야 되는데요. 서버로 보낼 때 어디로 보낼지 그리고 HTTP 방법을 명시해줘야 됩니다. 데이터를 보낼 때, HTTP 방법은 POST 방식으로 보내기 되어 POST를 입력을 해줄 겁니다.

아래의 submit type이 트리거가 되어 사용자가 Log in 버튼을 누르면 데이터가 전송이 되는 것이죠.

<input type="submit" value="Log in">

 

장고에서 폼이란?

폼을 핸들링하는 것은 생각보다 복잡합니다. 사용자를 위해서 수많은 타입의 데이터 항목들이 필요로 하고 화면에 보여줘야 되며 이런 값들은 다시 서버로 보내집니다. 이후에도 값들에 대한 유효성 검증이 필요로 하죠. 검증 이후에는 데이터를 처리하는 로직까지도 필요로 합니다. 

장고에서는 이런 작업들에 대해서 단순화시켜주고 자동화 기능을 제공해줍니다. 또한 개발자가 HTML 작성을 하여 폼 관련 핸들링하는 코드를 작성하는 것보다 장고에서 제공하는 폼 기능이 더욱 보안적 요소가 훌륭합니다.

 

포괄적으로 장고 폼 기능은 다음 3가지로 요약할 수 있습니다.

  • 렌더링을 위해서 데이터를 준비하고 재구성을 해줍니다.
  • HTML 폼을 만들어줍니다.
  • 클라이언트로부터 제출이 된 데이터를 받고 처리해줍니다.

HTML의 form 태그는 폼 역할의 단지 한 부분의 불과합니다. 하지만 장고에서의 폼 개념은 위에서 설명드린 기능들을 제공합니다. 이런 기능들을 사용하기 위해서 Form Class를 사용해주시면 되는데요.

모델 클래스의 필드는 모델 클래스의 필드가 데이터베이스 필드에 매칭 되는 것처럼, 폼도 폼 필드의 클래스는 html 요소 즉 태그에 매핑이 됩니다. 폼이 제출되면 유효성 검사까지 수행이 됩니다.

 

장고에서 폼을 사용하기

이제는 장고에서 폼을 어떻게 사용하는지 코드를 작성하며 살펴보도록 하겠습니다.

사용자 이름을 받는 웹사이트가 있다고 생각을 해보겠습니다.

<form action="{% url 'myform:index' %}" method="post">
    <label for="your_name">Your name: </label>
    <input id="your_name" type="text" name="your_name" value="{{ current_name }}">
    <input type="submit" value="OK">
</form>

이름을 입력받을 때 text input과 submit input이 있습니다. 유저로부터 받은 데이터는 myform:index 위치로 전송되고 HTTP 방식은 POST입니다. 우리가 많이 봐 오던 폼 형태입니다.

예제에서는 예시 코드로 코드 내용이 그리 많지 않으나 실제로는 폼 관련 코드가 복잡하고 양이 많을 겁니다.

그중 많은 필드는 미리 데이터가 작성이 되어 있어야 되고 유효성 검사도 필요로 합니다.

이쯤 되면 장고에서의 폼 기능을 필요로 합니다.

 

forms.py

from django import forms

class NameForm(forms.Form):
    your_name = forms.CharField(label='Your name name', max_length=7)

우리는 위에서 작성한 HTML 모습의 폼 모양이 필요로 하는 것을 필요로 하는데, 그 점이 폼을 작성하기 위한 시작점입니다.

forms 코드를 보시게 되면 charField를 갖는 your_name 폼을 하나 갖고 있습니다. you_name의 최대 길이는 7로 제한(값 유효성 확인 가능)을 뒀으며 label 명도 직접 설정을 할 수 있습니다. 이상 폼 코드를 작성한 내용입니다.

위의 작성한 코드를 사용해서 화면에 rendering 하기도 하고 값을 받아와서 처리를 하는 것입니다. form html 코드를 작성하지 않고 말이죠.

 

Form 인스턴스는 is_valid() 함수를 갖고 있습니다. is_valid() 함수는 입력받은 폼의 대한 유효성 검사를 실행합니다. is_valid() 함수가 호출되면 값이 유효하다면 참이 리턴되고 cleaned_data에 값이 저장이 됩니다. 이 내용은 뷰 로직에서 다뤄지니 뷰 코드에서 다시 보도록 하겠습니다. 지금은 값이 유효하다면 참이 리턴되고 cleaned_data에 저장이 되는 것을 명심해주시면 됩니다.

 

뷰에서 작성한 폼을 사용하도록 하겠습니다.

views.py

from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import NameForm

def index(request):
    # if this is a POST request we need to process the form data
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        form = NameForm(request.POST)

        # check whether it's valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required
            # ...
            # redirect to a new URL:
            return HttpResponseRedirect('/myform/thanks/')

    # if a GET (or any other method) we'll create a blank form
    else:
        form = NameForm()

    return render(request, 'myform/name.html', {'form': form})

def thanks(request):
    return render(request, 'myform/thanks.html')

GET 요청이 들어왔다면 NameForm()을 통해서 비어 있는 폼을 사용자 화면에 보여 줄 것입니다.

POST 요청이 들어온다면 NameForm(request.POST)을 통해서 요청으로부터 받은 데이터와 폼을 묶어(바인딩) 줍니다. form.is_valid()를 통해서 유효성 검사를 하는 겁니다. 앞서 설명드린 바와 같이 유효하다면 참이 리턴되어 thanks 페이지로 이동하고 그렇지 않다면 다시 이름 입력 페이지가 보이게 됩니다.

참이 될 때는 cleaned_data에 유효한 데이터는 모두 저장이 됩니다. cleaned_data는 어떻게 사용이 되는지 잠시 후에 보도록 하겠습니다.

 

뷰 로직까지 작성을 했으니 템플릿에서 어떻게 장고 폼 관련에 처리를 하는지 보겠습니다.

name.html

<form action="{% url 'myform:index' %}" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="OK">
</form>

GET 요청이 들어왔을 때 form을 context에 담아서 템플릿에 보냈습니다. 그럼 템플릿에서는 {{ form }}을 작성을 해주시면 장고 forms.py에서 작성한 form관련 모습을 보실 수 있습니다.

위에서 html을 직접 작성한 모습과 동일한 모습입니다. 레이블 모습은 구분을 위해서 name을 하나 더 추가하였습니다. 눈여겨볼 것은 문자의 최대길이를 7자리로 제한을 뒀기 때문에 7자리 이상은 입력이 되지 않습니다.

 

여기까지가 form 사용에 기본적인 방법입니다. 지금은 input이 하나이기 때문에 조금 더 복잡해 보일 수 있으나 입력받는 값이 많거나 데이터베이스에 값을 저장한다거나 할 때는 장고 폼의 위력이 대단합니다.

 

cleaned_data 사용하는 예제를 보기 위해서 조금 더 복잡한 예제를 보겠습니다.

forms.py

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField(widget=forms.Textarea)
    sender = forms.EmailField()
    cc_myself = forms.BooleanField(required=False)

NameForm과 달리 데이터 타입이 늘어났습니다.

폼이 늘어 나도 사용방법은 동일합니다 :)

 

views.py

if form.is_valid():
    subject = form.cleaned_data['subject']
    message = form.cleaned_data['message']
    sender = form.cleaned_data['sender']
    cc_myself = form.cleaned_data['cc_myself']

    recipients = ['info@example.com']
    if cc_myself:
        recipients.append(sender)

    send_mail(subject, message, sender, recipients)
    return HttpResponseRedirect('/thanks/')

is_valid()를 통해서 유효성 검사 이후에 필요에 따라서 cleaned_data에 저장된 데이터를 갖고 오는 겁니다. 그리고 메일 발송 로직을 추가해준 코드입니다.

 

이상으로 폼의 대한 개념과 사용방법에 대해서 학습을 했습니다.

위의 내용은 기본 기능들에 대한 설명이고 장고 폼은 더욱 많은 기능을 담고 있습니다. 내용이 조금 더 필요하시다면 아래의 문서를 읽어 보시고 폼을 조금 더 잘 활용하시면 좋겠습니다.

https://docs.djangoproject.com/en/3.0/topics/forms/

 

감사합니다 :)

반응형

+ Recent posts