[Python] Road to Finance #00 Read Text File

in #sct5 years ago (edited)

들어가며

[빙구처럼 트레이딩] 시리즈를 연재하고 계시는 루스터(@roostermine)님이 트레이딩 뷰의 스크립트를 이용하여 최적의 전략을 세우고 계십니다. 그런데 트레이딩 뷰의 스크립트가 프로그래밍 언어라고 하기에는 약간 모자른 면이 있어서 가끔은 수작업을 하고 계시는데요, 루스터님에게 파이쏜을 알려드려 더욱 최적화된 거래 신호를 얻기 위해 이 시리즈를 시작합니다. 전략 완성 되면 매수/매도 신호 뜰 때마다 알려주기로 약속했...

사전준비

첫번째로 필요한 것은 물론 파이쏜 그 자체겠죠. 다행히도 파이쏜의 설치는 매우 쉽습니다.
A.N.A.C.O.N.D.A
이 이름만 알면 됩니다.

https://www.anaconda.com/distribution/
여기에서 각자 OS에 맞추어 다운받아 설치하면 됩니다.

Python은 현재 버전2와 버전3가 많이 쓰이는데, 이왕 시작하는 거 당연히 3으로 가야죠.


두번째로 필요한게 실습할 데이타입니다. 크립토를 기반으로 한 자료 분석이므로 당연히 비트코인같은 여러 코인의 거래 기록이 있으면 좋습니다. 문제는 고품질의 오랜 기간 자료를 공짜로 구하기가 쉽지 않습니다. 특히 주식 쪽에서는 최근 야후가 무료로 뿌리던 API를 닫아버린 게 큰 타격이라고 하더군요. (야후 자매회사인 플리커 경우를 봐도, 야후를 최근에 먹은 모회사가 공짜 서비스를 계속 없애버리고 있네요.)

일단 오늘은 처음이고 하니 코인마켓캡에서 제공하는 데일리 데이타를 이용해보도록 하겠습니다.
비트코인 자료입니다.
https://coinmarketcap.com/currencies/bitcoin/historical-data/

오른쪽 상단의 달력 모양을 클릭해서 "All Time"으로 설정하고 헤더인 "Date Open High ..." 줄을 포함하여 마우스로 긁어서 복사한 후 메모장에 붙여넣었습니다. 파일 이름은 "BTC_daily_20130428-20190715.txt"라고 했네요.

Python을 시작하며

기본적으로 파이쏜의 시작은 Command Line에서

>> python3 some_program.py

이렇게 시작합니다.
물론 당연히 "some_program.py"를 미리 준비해야겠죠.

파이쏜은 띄어쓰기에 매우 민감합니다.
프로그램 내부의 어떤 구조가 띄어쓰기를 몇 칸 했냐로 결정됩니다. 처음 시작은 무조건 띄어쓰기가 없어야 하며, 다음 하부 구조에선 일정한 띄어쓰기가 이뤄져야 합니다. (3칸이든 10칸이든 그건 상관 없습니다. 그런데 3칸으로 시작했으면 그 하부 구조에 해당하는 부분은 모두 정확히 3칸 띄어써야 합니다.) 그래서 파이쏜 프로그래밍에 있어 리눅스의 vi같은 너무 기본적인 에디터를 비추합니다. 리눅스에서는 emacs / gedit, 윈도우즈에서는 notepad++, 맥에서는 atom을 위시한 다양한 에디터를 사용하시는 게 좋습니다.

파이쏜은 마치 한자와 같습니다. 한글은 기본이되는 자음과 모음으로 하나하나 만들어가면 되는데, 한자는 이미 정확한 뜻을 지닌 글자가 몇 천 몇 만 개가 준비가 되어있죠. 파이쏜도 마찬가지로 다양한 module이 이미 준비되어 있어서 필요할 때 적당한 것을 불러와 사용하면 됩니다. 문제는 초보자의 경우 어떤 모듈이 있는 지 전혀 모른다는 것인데요, 결국 필요한 부분은 웹 검색을 통해 찾을 수 밖에 없습니다. G신에게 물어보면 99.99% 이미 누군가가 내가 필요한 것을 물어보았고, 답도 이미 거기 있습니다.

오늘의 예제: 텍스트 파일 읽기

오늘은 가볍게 텍스트 파일 읽어들이는 것으로 시작하겠습니다. 읽어들이는 파일은 당연히 위에서 언급한 "BTC_daily_20130428-20190715.txt"입니다.

처음 시작하는 프로그램은 "txt_file_check.py3.py"입니다. 뭘 체크하는 걸까요? ^^

###--- Main ---###

## Input File
in_dir='./'
in_txt_fn=in_dir+'BTC_daily_20130428-20190715.txt'

## Read Text File
with open(in_txt_fn,'r') as f:
    for i,line in enumerate(f):
        if i==0:
            print(line)
        else:
            words=line.strip().split()
            if i==1:
                num=len(words)
                print(num,words)
            else:
                if num!=len(words):
                    print(num,len(words),words)

print("All Done!")

몇 가지 설명

  1. 변수는 '='을 통해 어떤 값을 할당함으로써 정의됩니다.
  2. 문자열의 경우 "+"는 이어붙인다는 의미입니다.
  3. with로 시작해서 파일을 열면 나중에 알아서 닫아줍니다. with를 안쓰면 나중에 "f.close()"가 필요하죠. 없다고 에러나진 않지만요.
  4. "for" 문은 "in" 뒤에 있는 어떤 집단에서 원소 하나씩 방문합니다.
  5. 텍스트 파일의 경우 각 원소는 파일 안의 1줄입니다. (여기선 line으로 정의)
  6. enumerate()은 각 원소를 하나씩 꺼낼 때 그게 몇번째인지 숫자도 같이 붙여줍니다.
  7. 각 line의 끝을 정리하고 (strip()) 잘라줍니다 (split()). split 괄호 안이 비어있으면 기본적으로 빈칸 (space)를 기준으로 잘라줍니다. 만약 split(',')라고 하면 콤마를 기준으로 잘라냅니다.
  8. 이제 line은 여러 조각으로 잘렸으며, 그래도 그 여러 조각이 한 묶음으로 묶여있습니다. 이 묶음을 파이쏜에서 LIST라고 부릅니다. 파이쏜의 기본 데이타 형태 중 하나입니다.
  9. len() 은 짐작하듯이 안에 원소가 몇 개 인가를 세는 내장함수 입니다.

이제 위 프로그램을 실행해봅시다.

$ python3 tx*py
Date    Open*   High    Low     Close**     Volume  Market Cap

9 ['Jul', '15,', '2019', '10,257.84', '11,052.77', '9,992.01', '10,895.09', '25,384,047,207', '194,147,627,475']
All Done!

프로그램을 실행시키면 일단 헤더를 출력하고, 그 바로 밑의 첫 줄도 보여줍니다. "[ ]" 이 직각 괄호는 LIST를 나타내는 심볼입니다. 그리고 바로 "All Done!"이 나오는 걸로 보아, 텍스트 파일의 모든 줄은 언제나 9개의 항목을 지니고 있음을 알 수 있습니다.

여기까지 텍스트 파일을 읽는 데 성공했습니다.

오늘의 예제2: 텍스트 파일 읽고 데이타 형식 변환하기

위의 예제에서 LIST로 출력된 자료를 보면 몇 가지 문제가 있습니다. 첫째는 숫자가 숫자로 취급되지 않고 문자로 취급되고 있습니다. 따옴표에 묶여있는 모습으로 알 수 있죠. 둘째는 여기 저기 콤마가 많습니다. 콤마는 숫자를 읽는 데 하등 도움이 되지 않죠. 그래서 이번에는 이런 것들을 처리해보도록 하겠습니다.

이번 프로그램 이름은 "read_txt_data.py3.py"입니다.

import sys
import numpy as np
from datetime import datetime

def conv2date(mon_str,day_str,year_str):
    """
    mon_str: Month Name Abbre. (3-letters)
    day_str: Need to remove the last comma
    year_str: 4-digit number
    """

    return datetime.strptime(mon_str+day_str.strip(',')+year_str,'%b%d%Y')

###--- Main ---###

## Input File
in_dir='./'
in_txt_fn=in_dir+'BTC_daily_20130428-20190715.txt'

## Read Text File
dates=[]; prices=[]
with open(in_txt_fn,'r') as f:
    for i,line in enumerate(f):
        if i==0:
            print(line)
        else:
            words=line.strip().split()
            if i==1:
                num=len(words)
                print(num,words)
            elif num!=len(words):
                print(num,len(words),words)
                sys.exit()
            dates.append(conv2date(*words[:3]))
            price_tmp=[]
            for ww in words[3:7]:
                if "," in ww:
                    ww=ww.replace(",","")
                price_tmp.append(float(ww))
            prices.append(price_tmp)

            print(dates[-1],prices[-1])

## Convert list to numpy array
prices=np.asarray(prices)
print(prices.shape)

몇 가지 설명

  1. 자체 함수를 하나 정의했습니다. 정의는 "def"로 시작합니다.
  2. 앞의 날짜 부분은은 "Datetime" 모듈을 이용하여 날짜 형식으로 바꿨습니다.
  3. 리스트의 경우 처음에 빈 리스트를 정의하고 필요할 때 마다 ".append(something)"의 형태로 리스트에 원소를 하나씩 집어넣었습니다.
  4. 일단은 가격 정보 4가지만 가져옵니다.
  5. 파이쏜에서 기본적으로 시작은 0부터이고, 마지막 숫자에 해당하는 원소는 포함되지 않습니다. 따라서 words[3:7]은 4번째 항목부터 7번째 항목(포함) 까지라는 뜻입니다.
  6. 마지막에 리스트를 Numpy의 행렬(Array)로 형식을 바꿨습니다. 숫자의 처리는 기본적으로 Numpy에서 이뤄집니다. (나중에 계속)

위 프로그램을 실행시키면

...
2013-05-03 00:00:00 [106.25, 108.13, 79.1, 97.75]
2013-05-02 00:00:00 [116.38, 125.6, 92.28, 105.21]
2013-05-01 00:00:00 [139.0, 139.89, 107.72, 116.99]
2013-04-30 00:00:00 [144.0, 146.93, 134.05, 139.0]
2013-04-29 00:00:00 [134.44, 147.49, 134.0, 144.54]
2013-04-28 00:00:00 [135.3, 135.98, 132.1, 134.21]
(2270, 4)

2019년 7월 15일부터 거꾸로 돌아가 2013년 4월 28일까지 모두 2270개의 자료가 모였군요. 당시의 BTC 가격은 $130 이었습니다ㅋ

오늘은 여기까지 하고, 다음에는 이 자료를 이용해서 캔들 그래프를 그려보도록 하겠습니다.

관련 글들

Matplotlib List
[Matplotlib] 00. Intro + 01. Page Setup
[Matplotlib] 02. Axes Setup: Subplots
[Matplotlib] 03. Axes Setup: Text, Label, and Annotation
[Matplotlib] 04. Axes Setup: Ticks and Tick Labels
[Matplotlib] 05. Plot Accessories: Grid and Supporting Lines
[Matplotlib] 06. Plot Accessories: Legend
[Matplotlib] 07. Plot Main: Plot
[Matplotlib] 08. Plot Main: Imshow
[Matplotlib] 09. Plot Accessary: Color Map (part1)
[Matplotlib] 10. Plot Accessary: Color Map (part2) + Color Bar

F2PY List
[F2PY] 01. Basic Example: Simple Gaussian 2D Filter
[F2PY] 02. Basic Example: Moving Average
[F2PY] 03. Advanced Example: Using OpenMP

Scipy+Numpy List
[SciPy] 1. Linear Regression (Application to Scatter Plot)
[SciPy] 2. Density Estimation (Application to Scatter Plot)
[Scipy+Numpy] 3. 2D Histogram + [Matplotlib] 11. Plot Main: Pcolormesh

Sort:  

zorba님이 dj-on-steem님을 멘션하셨습니당. 아래 링크를 누르시면 연결되용~ ^^
zorba님의 [2019/7/16] 가장 빠른 해외 소식! 해외 스티미언 소모임 회원들의 글을 소개해드립니다.

...enerva 뉴욕 dj-on-steem/td> DC 근교 hello-sunshine DC

오오 감사합니다. 글도 딱딱하지 않고 아주 정성들여 재미있게 쓰셨네요.

Isi님도 파이쏜이 필요하셨나봐요 ^^ 도움이 되면 좋겠습니다~

Posted using Partiko Android

우와아아아아ㅏ!!!!! 대박입니다!!!! ㅎㅎㅎ 열심히 따라가보도록 하겠습니다~~ :))

설명이 조금 듬성듬성한게 완전 초보용은 아닙니다. 필요하면 언제든 댓글로 질문주세요.

Posted using Partiko Android