Python/파이썬과 주식, 코인

[코인원 이용내역] 2. 정리

컴닥 2025. 4. 13. 19:02
반응형

구조는 간단하다.

코인원 이용내역에서 코인별로 데이터를 분리한 뒤 

쓴 돈 = 코인 매수 금액 + 매수 수수료
수익률 = 모은 코인의 현재 가격 / 쓴 돈

모은 코인 판매 시 수수료는 어떡하냐고?

미래의 수수료가 어떻게 될지 알 수 없으니 미리 반영하는 것은 포기.. 

중간에 코인을 팔았으면 어쩌지?

쓴 돈 = 코인 매수 금액 + 매수 수수료
번 돈 = 코인 매도 금액 - 매도 수수료
코인의 현재 가치 = 코인 개수 * 현재가

(코인의 현재 가치) / (쓴 돈 - 번 돈) 

여러 방법이 있을 것 같은데, 이렇게 보는 게 맞을 것 같아서...

ROI(Return on Investment) = 투자 수익률. 
투자한 비용 대비 얻는 수익을 백분율로 표시.

이런 방식도 생각해 보았으나  
(코인의 현재 가치 + 번 돈) / (쓴 돈)
이미 회수한 돈을 투자 영역에 남겨두는 것은 어색한 것 같다.

from configparser import ConfigParser

import pandas as pd
import requests

config = ConfigParser()
config.read("saving.ini")

DB_FILE = config["file"]["db"]

db = pd.read_csv(DB_FILE, parse_dates=["시간"], index_col=0)


def _get_response(action, payload=None):
    url = "{}{}".format("https://api.coinone.co.kr", action)
    headers = {"accept": "application/json"}
    response = requests.get(url, data=payload, headers=headers)
    if response.status_code != 200:
        print(f"status_code, {response.status_code}")
        return None
    resp_json = response.json()
    if resp_json["result"] != "success":
        print(f"error_code, {resp_json['error_code']}")
        return None
    return resp_json


def fetch_ticker(target_currency="BTC", quote_currency="KRW"):
    action = f"/public/v2/ticker_new/{quote_currency}/{target_currency}"
    resp_json = _get_response(action)
    tickers = resp_json["tickers"]
    return float(tickers[0]["last"])


def calc(df):
    체결횟수 = len(df.index)
    체결금액 = df["체결금액"].sum()
    수수료 = df["수수료"].sum()
    체결코인수 = df["체결수량"].sum()

    return (
        체결횟수,
        체결금액,
        수수료,
        체결코인수,
    )


def print_result(
    거래종류,
    횟수,
    금액_수수료미반영,
    수수료,
    코인수,
    코인금액,
    coin,
    투자수익률=None,
):
    print(f"\n[{거래종류}]\n")
    print(f"거래횟수 : {횟수:,}회")
    print(f"금액 : {금액_수수료미반영:,.0f} KRW")
    print(f"수수료 : {수수료:,.2f} KRW")
    print()
    print(f"코인 수 : {코인수:,} {coin.upper()}")
    print(f"코인 현재가 : {코인금액:,.0f} KRW")
    if 투자수익률 is not None:
        print()
        print(f"투자수익률(ROI, 수수료 반영) : {투자수익률:,.2f} %")


def make_statement(coin):
    coin_df = db[db.가상자산 == coin]
    coin_df = coin_df.sort_index()

    # float 값으로 변환
    for each in ("체결수량", "체결가격", "체결금액", "수수료"):
        coin_df[each] = coin_df[each].str[:-4].str.replace(",", "").astype(float)

    print(f"\n[{coin} 결산]\n")

    코인가격 = fetch_ticker(coin)
    print(f"현재 가격 : {코인가격:,.0f} KRW")

    first_data = coin_df.index[0].date()
    last_date = coin_df.index[-1].date()
    print(f"기간 : {first_data} ~ {last_date}")

    buy_df = coin_df[coin_df.구분 == "매수"]
    매수횟수, 매수금액, 매수수수료, 매수코인수 = calc(buy_df)
    매수코인가치 = 매수코인수 * 코인가격
    print_result(
        "매수",
        매수횟수,
        매수금액,
        매수수수료,
        매수코인수,
        매수코인가치,
        coin,
    )

    sell_df = coin_df[coin_df.구분 == "매도"]
    매도횟수, 매도금액, 매도수수료, 매도코인수 = calc(sell_df)
    매도코인가치 = 매도코인수 * 코인가격
    print_result(
        "매도",
        매도횟수,
        매도금액,
        매도수수료,
        매도코인수,
        매도코인가치,
        coin,
    )

    if 매도코인수 > 매수코인수:
        print(f"\n* 결산이 불가능합니다. 매수 {coin} < 매도 {coin}")
        return

    총거래횟수 = 매수횟수 + 매도횟수
    누적투입액 = 매수금액 - 매도금액
    누적수수료 = 매수수수료 + 매도수수료
    누적투입액_수수료반영 = 누적투입액 + 누적수수료
    누적코인수 = 매수코인수 - 매도코인수
    누적코인가치 = 누적코인수 * 코인가격
    누적수익률_수익률반영 = 누적코인가치 / 누적투입액_수수료반영 * 100

    print_result(
        "누적",
        총거래횟수,
        누적투입액,
        누적수수료,
        누적코인수,
        누적코인가치,
        coin,
        투자수익률=누적수익률_수익률반영,
    )


coin_set = sorted(set(db["가상자산"]))
for coin in coin_set:
    make_statement(coin)

각 코인 별로 넣은 돈, 찾은 돈, 남은 코인, 이익률을 누적해서 볼 수 있다. 

다만 이벤트 입금이 있거나, 포트폴리오를 이용하거나, 스마트 트레이딩을 이용하는 경우
계산이 정확하지 않으므로 수동 입력이 필요하다. 

코인원에서 포트폴리오는 일종의 가상계좌를 의미한다.

이런 입출력 데이터를
"2025-03-14 18:53:13","입금 완료 ","BTC","0.00013765 BTC","0 BTC","0.00013765 BTC"
"2025-03-10 18:48:21","입금 완료 ","USDT","1.3201 USDT","0 USDT","1.3201 USDT"

이렇게 DB에 기록했다. 
2025-03-10 18:48:21,USDT,대표 포트폴리오,이벤트,매수,1.3201 USDT,"1,488 KRW","1,964 KRW",0 KRW
2025-03-14 18:53:13,BTC,대표 포트폴리오,이벤트,매수,0.00013765 BTC,"122,430,000 KRW","16,852 KRW",0 KRW

원 단위 반올림 오차가 보이지만 그 외엔 일치한다. 
물론 이것도 자동화할 수 있겠으나... 2건이 다라...

반응형