반응형

안녕하세요. 얼마전에 롤드컵 결승전까지 끝났습니다. 이번 롤드컵이 역대급으로 재미있다는 이야기를 많이 들어서, 보기 편하도록 다시보기 링크들을 포스팅합니다.


결승전

T1-DRX 월드 챔피언십 결승전 5세트

T1-DRX 월드 챔피언십 결승전 4세트

T1-DRX 월드 챔피언십 결승전 3세트

T1-DRX 월드 챔피언십 결승전 2세트

T1-DRX 월드 챔피언십 결승전 1세트


4강

GEN-DRX 월드 챔피언십 4강 4세트

GEN-DRX 월드 챔피언십 4강 3세트

GEN-DRX 월드 챔피언십 4강 2세트

GEN-DRX 월드 챔피언십 4강 1세트

JDG-T1 월드 챔피언십 4강 4세트

JDG-T1 월드 챔피언십 4강 3세트

JDG-T1 월드 챔피언십 4강 2세트

JDG-T1 월드 챔피언십 4강 1세트


8강

DRX-EDG 월드 챔피언십 8강 5세트

DRX-EDG 월드 챔피언십 8강 4세트

DRX-EDG 월드 챔피언십 8강 3세트

DRX-EDG 월드 챔피언십 8강 2세트

DRX-EDG 월드 챔피언십 8강 1세트

GEN-DK 월드 챔피언십 8강 5세트

GEN-DK 월드 챔피언십 8강 4세트

GEN-DK 월드 챔피언십 8강 3세트

GEN-DK 월드 챔피언십 8강 2세트

GEN-DK 월드 챔피언십 8강 1세트

T1-RNG 월드 챔피언십 8강 3세트

T1-RNG 월드 챔피언십 8강 2세트

T1-RNG 월드 챔피언십 8강 1세트

JDG-RGE 월드 챔피언십 8강 3세트

JDG-RGE 월드 챔피언십 8강 2세트

JDG-RGE 월드 챔피언십 8강 1세트

2022 LoL 월드 챔피언십 8강 조추첨식


그룹스테이지

GEN-RNG 그룹스테이지 Day8 타이브레이커

RNG-GEN 그룹스테이지 Day8 6경기

CFO-RNG 그룹스테이지 Day8 5경기

GEN-100 그룹스테이지 Day8 4경기

RNG-100 그룹스테이지 Day8 3경기

CFO-GEN 그룹스테이지 Day8 2경기

100-CFO 그룹스테이지 Day8 1경기

DRX-RGE 그룹스테이지 Day7 7경기

TES-DRX 그룹스테이지 Day7 6경기

TES-RGE 그룹스테이지 Day7 5경기

DRX-GAM 그룹스테이지 Day7 4경기

DRX-RGE 그룹스테이지 Day7 3경기

GAM-TES 그룹스테이지 Day7 2경기

RGE-GAM 그룹스테이지 Day7 1경기

DK-JDG 그룹스테이지 Day6 7경기

JDG-DK 그룹스테이지 Day6 6경기

EG-DK 그룹스테이지 Day6 5경기

G2-JDG 그룹스테이지 Day6 4경기

DK-G2 그룹스테이지 Day6 3경기

EG-JDG 그룹스테이지 Day6 2경기

G2-EG 그룹스테이지 Day6 1경기

EDG-T1 그룹스테이지 Day5 6경기

T1-C9 그룹스테이지 Day5 5경기

C9-EDG 그룹스테이지 Day5 3경기

FNC-EDG 그룹스테이지 Day5 4경기

T1-FNC 그룹스테이지 Day5 2경기

FNC-C9 그룹스테이지 Day5 1경기

GAM-DRX 그룹스테이지 Day4 6경기

GEN-CFO 그룹스테이지 Day4 5경기

100-RNG 그룹스테이지 Day4 4경기

DK-EG 그룹스테이지 Day4 3경기

JDG-G2 그룹스테이지 Day4 1경기

RGE-TES 그룹스테이지 Day4 2경기

DRX-TES 그룹스테이지 Day3 6경기

RNG-CFO 그룹스테이지 Day3 5경기

C9-T1 그룹스테이지 Day3 4경기

EDG-FNC 그룹스테이지 Day3 3경기

100-GEN 그룹스테이지 Day3 2경기

GAM-RGE 그룹스테이지 Day3 1경기

DK-JDG 그룹스테이지 Day2 6경기

TES-GAM 그룹스테이지 Day2 5경기

EDG-C9 그룹스테이지 Day2 4경기

FNC-T1 그룹스테이지 Day2 3경기

EG-G2 그룹스테이지 Day2 2경기

RGE-DRX 그룹스테이지 Day2 1경기

GEN-RNG 그룹스테이지 Day1 6경기

T1-EDG 그룹스테이지 Day1 5경기

JDG-EG 그룹스테이지 Day1 4경기

CFO-100 그룹스테이지 Day1 3경기

G2-DK 그룹스테이지 Day1 2경기

C9-FNC 그룹스테이지 Day1 1경기


플레이-인 녹아웃 스테이지

RNG-DFM 플레이-인 녹아웃 스테이지 Day2 2경기 4세트

RNG-DFM 플레이-인 녹아웃 스테이지 Day2 2경기 3세트

RNG-DFM 플레이-인 녹아웃 스테이지 Day2 2경기 2세트

RNG-DFM 플레이-인 녹아웃 스테이지 Day2 2경기 1세트

EG-MAD 플레이-인 녹아웃 스테이지 Day2 1경기 3세트

EG-MAD 플레이-인 녹아웃 스테이지 Day2 1경기 2세트

EG-MAD 플레이-인 녹아웃 스테이지 Day2 1경기 1세트

LLL-DFM 플레이-인 녹아웃 스테이지 Day1 2경기 4세트

LLL-DFM 플레이-인 녹아웃 스테이지 Day1 2경기 3세트

LLL-DFM 플레이-인 녹아웃 스테이지 Day1 2경기 2세트

LLL-DFM 플레이-인 녹아웃 스테이지 Day1 2경기 1세트

SGB-MAD 플레이인 녹아웃 스테이지 Day1 1경기 4세트

SGB-MAD 플레이-인 녹아웃 스테이지 Day1 1경기 3세트

SGB-MAD 플레이-인 녹아웃 스테이지 Day1 1경기 2세트

SGB-MAD 플레이-인 녹아웃 스테이지 Day1 1경기 1세트


플레이-인 스테이지

LLL-EG 플레이-인 스테이지 Day4 Tiebreaker 2경기

EG-DFM 플레이-인 스테이지 Day4 Tiebreaker 1경기

RNG-SGB 플레이-인 스테이지 Day4 6경기

DRX-MAD 플레이-인 스테이지 Day4 5경기

IW-ISG 플레이-인 스테이지 Day4 4경기

DFM-EG 플레이-인 스테이지 Day4 3경기

LLL-CHF 플레이-인 스테이지 Day4 2경기

BYG-FNC 플레이-인 스테이지 Day4 1경기

ISG-DRX 플레이-인 스테이지 Day3 8경기

RNG-IW 플레이-인 스테이지 Day3 7경기

CHF-BYG 플레이-인 스테이지 Day3 6경기

RNG-ISG 플레이-인 스테이지 Day3 5경기

EG-CHF 플레이-인 스테이지 Day3 4경기

BYG-DFM 플레이-인 스테이지 Day3 3경기

MAD-SGB 플레이-인 스테이지 Day3 2경기

LLL-FNC 플레이-인 스테이지 Day3 1경기

IW-DRX 플레이-인 스테이지 Day2 8경기

MAD-RNG 플레이-인 스테이지 Day2 7경기

DRX-SGB 플레이-인 스테이지 Day2 6경기

EG-BYG 플레이-인 스테이지 Day2 5경기

DFM-CHF 플레이-인 스테이지 Day2 4경기

SGB-ISG 플레이-인 스테이지 Day2 3경기

EG-LLL 플레이-인 스테이지 Day2 2경기

FNC-DFM 플레이-인 스테이지 Day2 1경기

DRX-RNG 플레이-인 스테이지 Day1 8경기

SGB-IW 플레이-인 스테이지 Day1 7경기

DFM-LLL 플레이-인 스테이지 Day1 6경기

CHF-FNC 플레이-인 스테이지 Day1 5경기

MAD-IW 플레이-인 스테이지 Day1 4경기

LLL-BYG 플레이-인 스테이지 Day1 3경기

FNC-EG 플레이-인 스테이지 Day1 2경기

ISG-MAD 플레이-인 스테이지 Day1 1경기

반응형

'기타' 카테고리의 다른 글

FTX/알라메다 뱅크런 사태  (0) 2022.11.09
반응형

 FTX/알라메다 뱅크런 사태 요약본입니다.

 

ICYMI 아이씨미

더블록 리서치의 FTX/알라메다 뱅크런 사태 한장 요약을 번역해 보았습니다. 지금은 전반적인 시장 상황이 안좋아져 비트코인이 이전 저점을 깨고 17k에 머무르고 있습니다.

t.me

 

 

 간밤에 큰 이슈가 있었습니다. FTX의 거래소 토큰인 FTT 가격은 25.8달러 → 2.73달러까지 떨어져서 대략 -90% 하락했었습니다. 현재는 6달러 부근에 거래중이네요. 뿐만 아니라 비트코인과 다른 알트코인들 역시 큰 하락이 있었습니다. 지난 24시간동안 9억 달러 이상 청산되었습니다.

 

FTTUSD Chart

 다들 큰 손실 없으셨으면 좋겠습니다. 감사합니다.

반응형

'기타' 카테고리의 다른 글

롤드컵 전 경기 다시보기  (0) 2022.11.10
반응형

안녕하세요. 이번 포스팅에서는 달러 환율을 가져와서, 이전 포스팅에서 받아온 거래소별 보유자산에 환율을 적용해 계산 및 정리하는 코드를 작성해 보겠습니다. 이번 포스팅의 브라우저는 크롬을 사용했습니다.

 

1. 환율 사이트 분석

 네이버나 구글 등 포털사이트에 환율을 검색해도 나오지만, 업데이트 속도가 느린 것 같아서 아래의 사이트에서 환율을 조회하고자 합니다.

https://kr.investing.com/currencies/usd-krw

 

USD KRW | 미달러 원 환율 - Investing.com

USD/KRW 미달러 원 환율 실시간 스트리밍 차트, 변환기와 기술 분석

kr.investing.com

 

Investing.com

 사이트에 접속한 모습입니다. 빨간색으로 동그라미 친 부분을 크롤링해 보겠습니다. 

 

사이트 분석

 먼저 f12를 눌러 개발자 모드에 진입해줍니다. 그 후 사진의 1번(검사할 페이지 요소 선택)을 클릭한 뒤 크롤링하고자 하는 부분인 2번(현재의 환율)을 클릭합니다. 그럼 html에서 환율에 해당하는 부분이 선택되게 됩니다. 해당 부분은 아래와 같습니다. 파이썬에서 이 부분을 이용해 환율을 가져와 보도록 하겠습니다.

<span class="text-2xl" data-test="instrument-price-last">1,403.91</span>

 

2. 환율 크롤링

 Beautifulsoup을 이용해 환율 크롤링을 해보겠습니다.

from urllib.request import Request, urlopen
from bs4 import BeautifulSoup

req = Request('https://kr.investing.com/currencies/usd-krw', headers={'User-Agent': 'Mozilla/5.0'})
html = urlopen(req)
soup = BeautifulSoup(html, 'html.parser')

dollar = soup.find("span", attrs={"class":"text-2xl"}).get_text()
dollar = float(dollar.replace(",", ""))

print(dollar)

 크롤링하고자 하는 사이트의 URL을 입력하고, 사이트의 차단을 방지하고자 headers값을 넣어줍니다. beautifulsoup을 통해 html을 가져와주고, 앞서 사이트에서 분석한 html부분을 이용해 환율을 얻어줍니다. 해당 부분의 태그인 span과 속성인 class="text-2xl"을 soup.find를 통해 찾아주고, get_text()를 이용해 텍스트 부분(1,403.91)만 얻어줍니다. 후에 계산을 위해 ','를 제거해주고, str에서 float로 바꿔주었습니다. 결과는 아래와 같습니다. 

1403.91

 

3. 환율 적용(계산)

 이전 포스팅에서 가져온 업비트와 바이낸스의 보유자산에 환율을 곱해서 원화와 달러로 얼마인지 계산해 보겠습니다. 

import dotenv
import os
import ccxt
import pandas as pd
from urllib.request import Request, urlopen
from bs4 import BeautifulSoup

dotenv_file = dotenv.find_dotenv()
dotenv.load_dotenv(dotenv_file)

apikeyUp = os.environ['up_apikey']
apisecretUp = os.environ['up_secret']
apikeyBn = os.environ['bn_apikey']
apisecretBn = os.environ['bn_secret']

binance = ccxt.binance(config={'apiKey': apikeyBn, 'secret': apisecretBn})
upbit = ccxt.upbit(config={'apiKey': apikeyUp, 'secret': apisecretUp})

def receiveUp():
    global upbit_krw
    print('업비트에서 받아오는 중...')
    # 보유자산 조회
    balance = upbit.fetch_balance()['total']

    # 원화 마켓만 저장
    markets = upbit.fetch_tickers()
    coins = []
    amount = []
    price = []
    for key in balance.keys():
        try:
            price.append(markets[key+'/KRW']['last'])
            coins.append(key)
            amount.append(balance[key])
        except:
            pass

    # 소액 자산 제거
    acc_krw = balance['KRW']
    nameUp = ['KRW']
    amountUp = [acc_krw]
    priceUp = [1]
    krwUp = [acc_krw]

    for i in range(len(coins)):
        krw = amount[i] * price[i]
        if krw > 10000:
            nameUp.append(coins[i])
            amountUp.append(amount[i])
            priceUp.append(price[i])
            krwUp.append(krw)

    # 업비트 종합
    dfUp = []
    dfUp.append(nameUp)
    dfUp.append(amountUp)
    dfUp.append(priceUp)
    dfUp.append(krwUp)
    dfUp = pd.DataFrame(dfUp)
    dfUp = dfUp.transpose()
    dfUp.columns = ['Name', 'Amount', 'Price', 'KRW']
    upbit_krw = dfUp.sum(axis=0)['KRW']

    print(dfUp)
    print("Upbit KRW: {:,.0f} KRW".format(upbit_krw))

def receiveBn():
    global binance_usd
    print('바이낸스에서 받아오는 중...')
    # spot 
    balanceSpot = binance.fetch_balance()['total']
    spot = pd.DataFrame(list(balanceSpot.items()), columns=['name', 'balance'])

    # coin-m
    balanceCoinm = binance.fetch_balance(params={"type": 'delivery'})['total']
    Coinm = pd.DataFrame(list(balanceCoinm.items()), columns=['name', 'balance'])

    # spot and coin-m
    total = pd.concat([spot, Coinm])
    total = total[total['balance'] > 0]

    ############################################################
    # 중복데이터 정리
    dfBn = total.drop_duplicates("name", keep=False)

    df1 = total[total.duplicated('name', keep = 'first')]
    df2 = total[total.duplicated('name', keep = 'last')]

    # 분리된 데이터 더하기
    nameBn = []
    amountBn = []
    for coin in df1['name']:
        nameBn.append(coin)
        am = df1[df1['name'] == coin]['balance'].values[0] + df2[df2['name'] == coin]['balance'].values[0]
        amountBn.append(am)

    dfz = []
    dfz.append(nameBn)
    dfz.append(amountBn)
    dfz = pd.DataFrame(dfz)
    dfz =dfz.transpose()
    dfz.columns = ['name', 'balance']
    # dfBn: 중복 제거, dfz: 중복된 것들
    dfBn = pd.concat([dfz, dfBn])

    ############################################################
    # 비상장/소액 제거하기
    nameBn = []
    usdBn = []
    amountBn = []
    priceBn = []

    # 페어 및 가격 가져오기
    markets = binance.fetch_tickers()
    keys = markets.keys()

    for coin in dfBn['name']:
        amount = dfBn[dfBn['name'] == coin]['balance'].values[0]
        coin2 = coin + "/USDT"
        for pair in keys:
            if pair == coin2: # usdt 페어 있는 경우만
                price = markets[pair]['last']
                usd = price * amount
                if usd > 10: # 10$ 이상만
                    nameBn.append(coin)
                    usdBn.append(usd)
                    amountBn.append(amount)
                    priceBn.append(price)

    dfBn = [nameBn, amountBn, priceBn, usdBn]
    dfBn = pd.DataFrame(dfBn)
    dfBn = dfBn.transpose()
    dfBn.columns = ['Name', 'Amount', 'Price', 'USD']

    ############################################################
    # spot usdt + futures usds
    spot_usdt = balanceSpot['USDT']

    balanceUsds = binance.fetch_balance(params={"type": "future"})
    future_usd = balanceUsds['total']['USDT'] + balanceUsds['total']['BUSD']

    total_usd = spot_usdt + future_usd
    dfBn.loc[len(dfBn)+1] = ['USD', total_usd, 1, total_usd]

    binance_usd = dfBn.sum(axis=0)['USD']

    print(dfBn)
    print("Binance USD: {0:,.2f} USD".format(binance_usd))

def exchange():
    req = Request('https://kr.investing.com/currencies/usd-krw', headers={'User-Agent': 'Mozilla/5.0'})
    html = urlopen(req)

    soup = BeautifulSoup(html, 'html.parser')
    dollar = soup.find("span", attrs={"class":"text-2xl"}).get_text()
    dollar = float(dollar.replace(",", ""))

    return dollar

receiveUp()
receiveBn()

dollar = exchange()
totalKrw = upbit_krw + binance_usd*dollar
totalUsd = upbit_krw/dollar + binance_usd

print('현재 환율: {}'.format(dollar))
print('Total KRW: {:,.0f} KRW'.format(totalKrw))
print('Total USD: {:,.2f} USD'.format(totalUsd))

 이전에 작성한 코드의 보유자산에 환율을 대입해 모든 거래소의 총가치를 계산하고 출력했습니다. 결과는 아래와 같습니다. 

 

Total Finance

 

 추가적으로 수정한 사항을 적자면, 각각의 포스팅(업비트/바이낸스/환율)에서 작성한 코드들을 def 해주었고, 환율 계산을 위해 필요한 값들을 global을 통해 전역 변수로 지정해주었습니다. 각 거래소별로 보유자산을 받아오기 전에 문구를 출력해, 과정을 알 수 있게 했습니다.

 


 다음 포스팅에서는 계산한 결과들 중 필요한 정보들만 엑셀에 저장해, 지난 자산흐름을 알아보기 쉽게 해 보겠습니다. 읽어주셔서 감사합니다.

반응형
반응형

 안녕하세요. 이번 포스팅에서는 바이낸스의 보유자산을 조회하는 코드를 포스팅해보겠습니다. ccxt를 이용해 바이낸스의 계좌를 조회해 볼 텐데, 바이낸스의 계좌는 Fiat and Spot, Margin, Futures, Earn 등이 있습니다. 그중 제가 사용하는 Fiat and Spot과 Futures 지갑을 조회해보겠습니다.

 

1. Spot(현물) 및 coin-m(선물) 조회

 먼저 Spot과 Futures의 coin-m 계좌부터 불러와보도록 하겠습니다.

import dotenv
import os
import ccxt
import pandas as pd

dotenv_file = dotenv.find_dotenv()
dotenv.load_dotenv(dotenv_file)

apikeyBn = os.environ['bn_apikey']
apisecretBn = os.environ['bn_secret']

binance = ccxt.binance(config={'apiKey': apikeyBn, 'secret': apisecretBn})

# spot 
balanceSpot = binance.fetch_balance()['total']
spot = pd.DataFrame(list(balanceSpot.items()), columns=['name', 'balance'])

# coin-m
balanceCoinm = binance.fetch_balance(params={"type": 'delivery'})['total']
Coinm = pd.DataFrame(list(balanceCoinm.items()), columns=['name', 'balance'])

# spot and coin-m
total = pd.concat([spot, Coinm])
total = total[total['balance'] > 0]
print(total)

 dotenv를 이용해 환경변수 저장하는 방법은 아래 포스팅을 참고해주세요.

2022.10.05 - [Python] - 파이썬 dotenv를 이용한 환경변수 저장 및 호출

 

파이썬 dotenv를 이용한 환경변수 저장 및 호출

블로그 만든 뒤에 처음 작성하는 글이네요. 블로그에 공유하기 위해 중요한 정보(암호) 등을 환경변수로 지정해 다른 파일에 저장하고, 공유시에 다른 사람들에게 노출되는 것을 막고자 합니다.

bitcoding.tistory.com

 

 ccxt의 'fetch_balance'를 통해 각 계좌의 보유 수량을 불러왔습니다. 두 가지 데이터를 합한 뒤 수량이 0 이상인 값들만 남겨주었습니다. 

 결과는 아래와 같습니다. (수정된 예시입니다.) 앞서 작성한 업비트와 마찬가지로 상장되어있지 않은 코인도 존재하고, 소량만 있어 가치가 낮은 코인들도 존재합니다. 또한 현물 계좌와 선물계좌의 데이터를 합쳐서, 중복된 데이터들도 존재합니다. 이러한 항목들을 정리하는 코드를 작성해 보겠습니다. (텍스트 가시성에 문제가 있어 사진으로 첨부합니다.)

 

spot and coin-m

 

2. 중복 데이터 취합

 먼저 현물과 선물의 계좌에 같은 종류의 코인이 있는 경우 이를 더하는 코드를 작성해 보겠습니다.

import dotenv
import os
import ccxt
import pandas as pd

dotenv_file = dotenv.find_dotenv()
dotenv.load_dotenv(dotenv_file)

apikeyBn = os.environ['bn_apikey']
apisecretBn = os.environ['bn_secret']

binance = ccxt.binance(config={'apiKey': apikeyBn, 'secret': apisecretBn})

# spot 
balanceSpot = binance.fetch_balance()['total']
spot = pd.DataFrame(list(balanceSpot.items()), columns=['name', 'balance'])

# coin-m
balanceCoinm = binance.fetch_balance(params={"type": 'delivery'})['total']
Coinm = pd.DataFrame(list(balanceCoinm.items()), columns=['name', 'balance'])

# spot and coin-m
total = pd.concat([spot, Coinm])
total = total[total['balance'] > 0]

############################################################
# 중복데이터 정리
df = total.drop_duplicates("name", keep=False)
df1 = total[total.duplicated('name', keep = 'first')]
df2 = total[total.duplicated('name', keep = 'last')]

# 분리된 데이터 더하기
nameBn = []
amountBn = []
for coin in df1['name']:
    nameBn.append(coin)
    am = df1[df1['name'] == coin]['balance'].values[0] + df2[df2['name'] == coin]['balance'].values[0]
    amountBn.append(am)

dfz = []
dfz.append(nameBn)
dfz.append(amountBn)
dfz = pd.DataFrame(dfz)
dfz =dfz.transpose()
dfz.columns = ['name', 'balance']
# df: 중복제거, dfz: 중복된 것들
df = pd.concat([dfz, df])

print(df)

 

 중복되지 않은 항목은 df에, 중복된 항목들 중 spot은 df1, coin-m은 df2에 할당해주었습니다. 반복문을 통해 df1과 df2의 name이 같은 항목들끼리 balance 값을 더해 새로운 리스트에 지정해주었습니다. 그 뒤 중복되지 않은 항목들과 합해서, 중복된 항들을 모두 없앴습니다.

 

중복 데이터 삭제

 중복돼있던 BTC와 SOL이 하나로 합해진 모습입니다. 

 

 

3. 비상장/소액 코인 제거

 이번에는 바이낸스의 USDT페어가 없는 항목들과 10$ 보다 적은 값을 제거해주겠습니다.

import dotenv
import os
import ccxt
import pandas as pd

dotenv_file = dotenv.find_dotenv()
dotenv.load_dotenv(dotenv_file)

apikeyBn = os.environ['bn_apikey']
apisecretBn = os.environ['bn_secret']

binance = ccxt.binance(config={'apiKey': apikeyBn, 'secret': apisecretBn})

# spot 
balanceSpot = binance.fetch_balance()['total']
spot = pd.DataFrame(list(balanceSpot.items()), columns=['name', 'balance'])

# coin-m
balanceCoinm = binance.fetch_balance(params={"type": 'delivery'})['total']
Coinm = pd.DataFrame(list(balanceCoinm.items()), columns=['name', 'balance'])

# spot and coin-m
total = pd.concat([spot, Coinm])
total = total[total['balance'] > 0]

############################################################
# 중복데이터 정리
dfBn = total.drop_duplicates("name", keep=False)

df1 = total[total.duplicated('name', keep = 'first')]
df2 = total[total.duplicated('name', keep = 'last')]

# 분리된 데이터 더하기
nameBn = []
amountBn = []
for coin in df1['name']:
    nameBn.append(coin)
    am = df1[df1['name'] == coin]['balance'].values[0] + df2[df2['name'] == coin]['balance'].values[0]
    amountBn.append(am)

dfz = []
dfz.append(nameBn)
dfz.append(amountBn)
dfz = pd.DataFrame(dfz)
dfz =dfz.transpose()
dfz.columns = ['name', 'balance']
# dfBn: 중복 제거, dfz: 중복된 것들
dfBn = pd.concat([dfz, dfBn])

############################################################
# 비상장/소액 제거하기
nameBn = []
usdBn = []
amountBn = []
priceBn = []

# 페어 및 가격 가져오기
markets = binance.fetch_tickers()
keys = markets.keys()

for coin in dfBn['name']:
    amount = dfBn[dfBn['name'] == coin]['balance'].values[0]
    coin2 = coin + "/USDT"
    for pair in keys:
        if pair == coin2: # usdt 페어 있는 경우만
            price = markets[pair]['last']
            usd = price * amount
            if usd > 10: # 10$ 이상만
                nameBn.append(coin)
                usdBn.append(usd)
                amountBn.append(amount)
                priceBn.append(price)

dfBn = [nameBn, amountBn, priceBn, usdBn]
dfBn = pd.DataFrame(dfBn)
dfBn = dfBn.transpose()
dfBn.columns = ['Name', 'Amount', 'Price', 'USD']

print(df)

 

 ccxt의 fetch_tickers를 통해 마켓정보(페어 및 가격 등)를 불러왔습니다. 이후 if문을 통해 각 코인 별 USDT 페어가 존재하는 경우에만 다음 코드를 실행하도록 했습니다. 테더 페어가 존재하는 경우, 가격정보를 받아와서 보유 중인 수량과 곱해 usd가치가 10$ 이상인 경우만 리스트에 저장해주었습니다.

 

비상장/소액 코인 정리

 usdt 페어가 있는 경우만 남기다 보니, 보유 중인 usdt가 사라진 모습입니다. 다음 항목에서 현물 테더와 선물 usds의 스테이블 코인들을 더해서 정리하겠습니다.

 

 

4. 현물 테더 및 선물 usds 종합하기

 현물 계좌의 usdt와 선물 usds 계좌의 usdt와 busd를 추가해 보겠습니다.

import dotenv
import os
import ccxt
import pandas as pd

dotenv_file = dotenv.find_dotenv()
dotenv.load_dotenv(dotenv_file)

apikeyBn = os.environ['bn_apikey']
apisecretBn = os.environ['bn_secret']

binance = ccxt.binance(config={'apiKey': apikeyBn, 'secret': apisecretBn})

# spot 
balanceSpot = binance.fetch_balance()['total']
spot = pd.DataFrame(list(balanceSpot.items()), columns=['name', 'balance'])

# coin-m
balanceCoinm = binance.fetch_balance(params={"type": 'delivery'})['total']
Coinm = pd.DataFrame(list(balanceCoinm.items()), columns=['name', 'balance'])

# spot and coin-m
total = pd.concat([spot, Coinm])
total = total[total['balance'] > 0]

############################################################
# 중복데이터 정리
dfBn = total.drop_duplicates("name", keep=False)

df1 = total[total.duplicated('name', keep = 'first')]
df2 = total[total.duplicated('name', keep = 'last')]

# 분리된 데이터 더하기
nameBn = []
amountBn = []
for coin in df1['name']:
    nameBn.append(coin)
    am = df1[df1['name'] == coin]['balance'].values[0] + df2[df2['name'] == coin]['balance'].values[0]
    amountBn.append(am)

dfz = []
dfz.append(nameBn)
dfz.append(amountBn)
dfz = pd.DataFrame(dfz)
dfz =dfz.transpose()
dfz.columns = ['name', 'balance']
# dfBn: 중복 제거, dfz: 중복된 것들
dfBn = pd.concat([dfz, dfBn])

############################################################
# 비상장/소액 제거하기
nameBn = []
usdBn = []
amountBn = []
priceBn = []

# 페어 및 가격 가져오기
markets = binance.fetch_tickers()
keys = markets.keys()

for coin in dfBn['name']:
    amount = dfBn[dfBn['name'] == coin]['balance'].values[0]
    coin2 = coin + "/USDT"
    for pair in keys:
        if pair == coin2: # usdt 페어 있는 경우만
            price = markets[pair]['last']
            usd = price * amount
            if usd > 10: # 10$ 이상만
                nameBn.append(coin)
                usdBn.append(usd)
                amountBn.append(amount)
                priceBn.append(price)

dfBn = [nameBn, usdBn, amountBn, priceBn]
dfBn = pd.DataFrame(dfBn)
dfBn = dfBn.transpose()
dfBn.columns = ['Name', 'Amount', 'Price', 'USD']

############################################################
# spot usdt + futures usds
spot_usdt = balanceSpot['USDT']

balanceUsds = binance.fetch_balance(params={"type": "future"})
future_usd = balanceUsds['total']['USDT'] + balanceUsds['total']['BUSD']

total_usd = spot_usdt + future_usd
dfBn.loc[len(dfBn)+1] = ['USD', total_usd, 1, total_usd]

binance_usd = dfBn.sum(axis=0)['USD']

print(dfBn)
print("Total USD: {0:,.2f} USD".format(binance_usd))

 

 spot의 usdt를 따로 불러서 더해주고, fetch_balace의 타입을 'future'로 지정해서 호출하면 futures의 usds 지갑의 정보를 불러옵니다. 불러온 usdt와 busd를 더해서 df의 마지막 줄에 추가해 주었습니다. 마지막으로 각 항목별 usd값을 더해서 출력해 주었습니다.

 

바이낸스 보유 자산 출력

 

 이번 포스팅에서는 바이낸스의 현물 및 선물 계좌의 보유 자산을 조회하고 정리해서 출력해보았습니다. 다음 포스팅에서는 환율을 가져와서 업비트와 바이낸스의 보유자산을 계산 및 정리해 보겠습니다. 읽어주셔서 감사합니다.

반응형
반응형

안녕하세요. 이번 카테고리에서는 아래과 같은 작업을 하는 코드를 작성해 보겠습니다.

  1. 업비트와 바이낸스의 보유자산 조회
  2. 조회 당시의 환율에 따라 krw 및 usd 가치 계산
  3. 일정 시간마다 보유 자산을 자동적으로 저장

이번 포스팅에서는 먼저 ccxt 패키지를 이용해 업비트에서의 잔고를 조회해보겠습니다.

1. 업비트 잔고 조회

먼저 ccxt 패키지를 이용해 업비트의 보유자산을 조회해 보도록 하겠습니다.

import dotenv
import os
import ccxt

dotenv_file = dotenv.find_dotenv()
dotenv.load_dotenv(dotenv_file)

apikeyUp = os.environ['up_apikey']
apisecretUp = os.environ['up_secret']

upbit = ccxt.upbit(config={'apiKey': apikeyUp, 'secret': apisecretUp})

# 보유자산 조회
balance = upbit.fetch_balance()['total']

print(balance)

dotenv를 이용해 환경변수 저장하는 방법은 아래 포스팅을 참고해주세요.
2022.10.05 - [Python] - 파이썬 dotenv를 이용한 환경변수 저장 및 호출

 

파이썬 dotenv를 이용한 환경변수 저장 및 호출

블로그 만든 뒤에 처음 작성하는 글이네요. 블로그에 공유하기 위해 중요한 정보(암호) 등을 환경변수로 지정해 다른 파일에 저장하고, 공유시에 다른 사람들에게 노출되는 것을 막고자 합니다.

bitcoding.tistory.com


아래 결과는 실제 자산은 아니고, 조회한 보유자산을 수정한 모습입니다.

{'KRW': 90000, 'ETH': 4.64, 'XRP': 320, 'EOS': 3.07e-06, 'TRX': 4.4e-07, 'VTHO': 500, 'APENFT': 20}


보시면 KRW, ETH, XRP처럼 거래 가능하고, 일정 금액 이상의 가치를 가진 것들이 있습니다. 반면에 EOS, TRX처럼 극 소량만 있어서 별 가치가 없는 항목들도 있습니다. 또한 VTHO, APENFT와 같이 거래소에 상장되어 있지 않은 코인들도 존재합니다. 이런 가치가 낮은 항목들을 제거하는 코드를 추가로 작성하겠습니다.

2. 비상장 항목 제외 및 가격 조회

앞서 말한 것처럼 업비트 거래소에 상장되어있지 않은 코인을 제거하고, 남은 코인들의 현재 가격을 가져와보겠습니다.

import dotenv
import os
import ccxt

dotenv_file = dotenv.find_dotenv()
dotenv.load_dotenv(dotenv_file)

apikeyUp = os.environ['up_apikey']
apisecretUp = os.environ['up_secret']

upbit = ccxt.upbit(config={'apiKey': apikeyUp, 'secret': apisecretUp})

# 보유자산 조회
balance = upbit.fetch_balance()['total']

# 원화 마켓만 저장
markets = upbit.fetch_tickers()
coins = []
amount = []
price = []
for key in balance.keys():
    try:
        price.append(markets[key+'/KRW']['last'])
        coins.append(key)
        amount.append(balance[key])
    except:
        pass

print(coins)
print(amount)
print(price)

업비트에는 원화/BTC/usdt 페어가 존재하는데 주로 원화 마켓을 이용하기 때문에 KRW페어만 남기고 제거하는 코드를 작성했습니다. 원화 마켓의 코인만 남기기 위해 try문을 사용해, 조회가 되면 append, 에러가 발생하면 pass 하도록 했습니다. 앞선 코드에서 얻은 보유한 항목들에 '/KRW'를 붙이고 현재 가격을 조회해서, 조회가 되는 항목들만 리스트에 저장했습니다.

['ETH', 'XRP', 'EOS', 'TRX']
[4.64, 320, 3.07e-06, 4.4e-07]
[2202000.0, 645.0, 1630.0, 88.4]

결과는 위와 같습니다. 여전히 소액의 자산이 남아있으며, 보유 중인 원화가 사라진 모습입니다. 다음 항목은 이에 대한 내용을 작성해보겠습니다.

3. 원화 추가 및 소액자산 제외

앞서 말했듯이 사라진 KRW를 추가해주고 소액의 자산을 제거해보겠습니다.

import dotenv
import os
import ccxt

dotenv_file = dotenv.find_dotenv()
dotenv.load_dotenv(dotenv_file)

apikeyUp = os.environ['up_apikey']
apisecretUp = os.environ['up_secret']

upbit = ccxt.upbit(config={'apiKey': apikeyUp, 'secret': apisecretUp})

# 보유자산 조회
balance = upbit.fetch_balance()['total']

# 원화 마켓만 저장
markets = upbit.fetch_tickers()
coins = []
amount = []
price = []
for key in balance.keys():
    try:
        price.append(markets[key+'/KRW']['last'])
        coins.append(key)
        amount.append(balance[key])
    except:
        pass

# 소액 자산 제거
acc_krw = balance['KRW']
nameUp = ['KRW']
amountUp = [acc_krw]
priceUp = [1]
krwUp = [acc_krw]

for i in range(len(coins)):
    krw = amount[i] * price[i]
    if krw > 10000:
        nameUp.append(coins[i])
        amountUp.append(amount[i])
        priceUp.append(price[i])
        krwUp.append(krw)

print(nameUp)
print(amountUp)
print(priceUp)
print(krwUp)


먼저 새로운 리스트를 만들어 KRW 정보를 넣어주었습니다. 이후 보유 수량과 현재 가격을 곱하여 평가금을 계산해, 10000원이 넘는 항목만 리스트에 저장해주었습니다.

['KRW', 'ETH', 'XRP']
[984318, 4.64, 320]
[1, 2201000.0, 646.0]
[90000.0, 10212640.0, 206720.0]

 

4. pandas를 이용한 정리 및 출력

이번 항목에서는 앞서 조회한 업비트의 보유자산을 pandas 패키지를 이용해 정리하고 출력해 보겠습니다.

import dotenv
import os
import ccxt
import pandas as pd

dotenv_file = dotenv.find_dotenv()
dotenv.load_dotenv(dotenv_file)

apikeyUp = os.environ['up_apikey']
apisecretUp = os.environ['up_secret']

upbit = ccxt.upbit(config={'apiKey': apikeyUp, 'secret': apisecretUp})

# 보유자산 조회
balance = upbit.fetch_balance()['total']

# 원화 마켓만 저장
markets = upbit.fetch_tickers()
coins = []
amount = []
price = []
for key in balance.keys():
    try:
        price.append(markets[key+'/KRW']['last'])
        coins.append(key)
        amount.append(balance[key])
    except:
        pass

# 소액 자산 제거
acc_krw = balance['KRW']
nameUp = ['KRW']
amountUp = [acc_krw]
priceUp = [1]
krwUp = [acc_krw]

for i in range(len(coins)):
    krw = amount[i] * price[i]
    if krw > 10000:
        nameUp.append(coins[i])
        amountUp.append(amount[i])
        priceUp.append(price[i])
        krwUp.append(krw)
        
# 업비트 종합
dfUp = []
dfUp.append(nameUp)
dfUp.append(amountUp)
dfUp.append(priceUp)
dfUp.append(krwUp)

dfUp = pd.DataFrame(dfUp)
dfUp = dfUp.transpose()
dfUp.columns = ['Name', 'Amount', 'Price', 'KRW']
upbit_krw = dfUp.sum(axis=0)['KRW']

print(dfUp)
print("Total KRW: {:,.0f} KRW".format(upbit_krw))


새로운 리스트를 만들어 앞선 리스트들을 집어넣어 데이터프레임으로 변경해주었습니다. 이후 행과 열을 바꾸고 각 행에 이름을 붙여주었으며, 모든 자산의 krw를 더해 출력했습니다. (텍스트 가시성에 문제가 있어 사진으로 첨부합니다.)

 

업비트 보유자산 출력


이번 포스팅에서는 업비트의 보유자산을 조회해봤습니다. 다음 포스팅에서는 바이낸스의 보유자산을 조회해보도록 하겠습니다. 읽어주셔서 감사합니다.

반응형
반응형

 안녕하세요. 이번 포스팅에서는 tkinter의 위젯을 배치하는 함수에 대해 포스팅하겠습니다.

 

1. 함수 소개

위젯을 배치하는 함수는 pack, place, grid 이렇게 세 가지 종류가 있습니다. 간략한 설명은 아래와 같습니다.

place - 절대 위치

grid - 격자 배치

pack - 상대 위치

 place는 위젯을 놓을 위치의 절대좌표(x, y 좌표)를 입력해서 사용할 수 있습니다. 직접 좌표를 입력해서 배치하기 때문에 정확한 위치에 배치할 수 있습니다.

 grid는 위젯을 놓을 위치를 행(column)과 열(row)을 입력하여 배치합니다. 바둑판이나 엑셀과 같다고 생각하면 좋을 것 같습니다.

 pack은 상대 위치로 윈도우의 상하좌우 등에 배치할 수 있으며, 윈도우의 크기를 변경하면, 변하는 크기에 따라 움직입니다.

 

2. place

 윈도우 창의 좌상단을 원점으로(0,0) 좌우를 x축, 상하를 y축으로 구성되어 있습니다. 각각 우측과 아래 방향이 양(+)의 방향입니다. x와 y에 숫자를 입력해, 원하는 위치에 위젯을 배치할 수 있습니다.

import tkinter

window = tkinter.Tk()
window.geometry('300x300')

lb_1 = tkinter.Label(text='1번 라벨', background='green')
lb_2 = tkinter.Label(text='2번 라벨', background='green')
lb_3 = tkinter.Label(text='3번 라벨', background='green')

lb_1.place(x=220, y=50)
lb_2.place(x=20, y=100)
lb_3.place(x=150, y=210)

window.mainloop()

 

tkinter place

 

3. grid

 grid는 격자구조로 행과 열에 맞추어 배치할 수 있습니다. 행은 column에, 열은 row에 원하는 숫자를 대입해 위젯을 배치할 수 있습니다. 좌우가 row이고, 상하가 column입니다.

import tkinter

window = tkinter.Tk()
window.geometry('300x300')

lb_1 = tkinter.Label(text='1번 라벨', background='green')
lb_2 = tkinter.Label(text='2번 라벨', background='green')
lb_3 = tkinter.Label(text='3번 라벨', background='green')
lb_4 = tkinter.Label(text='4번 라벨', background='green')
lb_5 = tkinter.Label(text='5번 라벨', background='green')
lb_6 = tkinter.Label(text='6번 라벨', background='green')
lb_7 = tkinter.Label(text='7번 라벨', background='green')
lb_8 = tkinter.Label(text='8번 라벨', background='green')
lb_9 = tkinter.Label(text='9번 라벨', background='green')

lb_1.grid(row=1,column=1)
lb_2.grid(row=1,column=2)
lb_3.grid(row=1,column=3)
lb_4.grid(row=2,column=1)
lb_5.grid(row=2,column=2)
lb_6.grid(row=2,column=3)
lb_7.grid(row=3,column=1)
lb_8.grid(row=3,column=2)
lb_9.grid(row=3,column=3)

window.mainloop()

 

tkinter grid

 

4. pack

 pack은 윈도우 상대적인 위치에 배치할 수 있습니다. 추가 요소를 주지 않고 pack()만 사용하게 되면 아래와 같이 중앙 상단부터 내려가게 됩니다.

import tkinter

window = tkinter.Tk()
window.geometry('300x300')

lb_1 = tkinter.Label(text='1번 라벨', background='green')
lb_2 = tkinter.Label(text='2번 라벨', background='green')
lb_3 = tkinter.Label(text='3번 라벨', background='green')
lb_4 = tkinter.Label(text='4번 라벨', background='green')
lb_5 = tkinter.Label(text='5번 라벨', background='green')

lb_1.pack()
lb_2.pack()
lb_3.pack()
lb_4.pack()
lb_5.pack()

window.mainloop()

 

tkinter pack

 

side 값을 주게 된다면 그에 해당하는 위치에 배치할 수 있습니다. pack은 앞서 말했듯이 상대적인 위치에 배치하기 때문에 윈도우의 크기를 변경해도, 변하는 윈도우에 맞춰 각각의 위치에 있게 됩니다.

import tkinter

window = tkinter.Tk()
window.geometry('300x300')

lb_1 = tkinter.Label(text='1번 라벨', background='green')
lb_2 = tkinter.Label(text='2번 라벨', background='green')
lb_3 = tkinter.Label(text='3번 라벨', background='green')
lb_4 = tkinter.Label(text='4번 라벨', background='green')

lb_1.pack(side='right')
lb_2.pack(side='left')
lb_3.pack(side='top')
lb_4.pack(side='bottom')

window.mainloop()

 

 

 이번 포스팅은 tkinter의 위젯들을 배치하는 방법에 대한 포스팅을 작성해봤습니다. 읽어주셔서 감사합니다.

반응형
반응형

 안녕하세요. 이번 포스팅에서는 'tkinter' 패키지를 이용해 GUI를 만들어보겠습니다.

 GUI란? 그래픽 사용자 인터페이스(graphical user interface)의 약자로, 컴퓨터를 사용하면서 화면 위의 틀이나 색상과 같은 그래픽 요소들을 기능과 용도를 나타내기 위해 고안된 컴퓨터 인터페이스라고 합니다. 

 tkinter을 이용해 새로운 윈도우 창을 만들고 몇 가지 기능들을 넣어보겠습니다. 이번 포스팅에서는 간단한 기능들만 다루고 추가적인 기능은 차후에 포스팅하도록 하겠습니다.

 

1. 윈도우 생성 및 출력

import tkinter

window = tkinter.Tk()
window.title("Bitcoding's window")
window.geometry('400x400')

window.mainloop()

 윈도우의 제목과 크기에 대해 설정하였습니다. 다른 것들은 넣은게 없기 때문에 텅 비어있는 모습입니다.

 

tkinter window

 

2. 레이블을 이용한 텍스트 출력

 레이블은 tkinter에서 텍스트를 배치하기 위해 사용합니다. 간단한 레이블을 배치해보겠습니다.

import tkinter

window = tkinter.Tk()
window.title("Bitcoding's window")
window.geometry('400x400')

lb_1 = tkinter.Label(text='안녕하세요. Bitcoding 입니다.')
lb_1.pack()

window.mainloop()

 

 '안녕하세요. Bitcoding 입니다' 라는 텍스트가 정상적으로 출력된 모습입니다. 

tkinter Label

 

3. 클릭시 작동하는 버튼 생성

 클릭시 window를 닫는 버튼을 생성해 보겠습니다.

import tkinter

def close():
    window.destroy()

window = tkinter.Tk()
window.title("Bitcoding's window")
window.geometry('400x400')

lb_1 = tkinter.Label(text='안녕하세요. Bitcoding 입니다.')
lb_1.pack()

bt_1 = tkinter.Button(text='창닫기', command = close)
bt_1.pack()

window.mainloop()

 

 close를 정의하고 command에 연결해, 버튼을 클릭하면 창이 닫히도록 했습니다. 

close window

4. 윈도우에서 입력 받기

 지금까지는 출력하는 것이었다면, 이번에는 윈도우 창에서 간단한 수식을 입력받아 계산해보겠습니다.

import tkinter

def close():
    window.destroy()

def calculate():
    lb_2.configure(text='결과: {}'.format(str(eval(entry_1.get()))))

window = tkinter.Tk()
window.title("Bitcoding's window")
window.geometry('400x400')

lb_1 = tkinter.Label(text='안녕하세요. Bitcoding 입니다.')
lb_1.pack()

bt_1 = tkinter.Button(text='창닫기', command = close)
bt_1.pack()

entry_1 = tkinter.Entry()
entry_1.pack()

bt_2 = tkinter.Button(text='계산', command = calculate)
bt_2.pack()

lb_2 = tkinter.Label()
lb_2.pack()

window.mainloop()

 

 entry 를 이용해 수식을 입력받은 뒤, 계산 버튼을 클릭해 결과를 출력합니다.

tkinter Entry

 

 이번 포스팅에서는 tkinter 패키지를 이용해 새로운 윈도우 창을 만들어서 간단하게 출력하고 수식을 입력받아 계산하여 출력하는 코드를 작성해 봤습니다. 다른 기능이나 구체적인 설정 등 추가적인 부분은 향후 포스팅 할 계획입니다. 읽어주셔서 감사합니다.

반응형

'Python > GUI - tkinter' 카테고리의 다른 글

파이썬 tkinter을 이용해 GUI 만들기 - 위젯 배치  (0) 2022.11.02
반응형

 안녕하세요. 이번 포스팅에서는 이전에 작성했던 코드들을 취합 및 수정하고, 메모장 기능을 추가한 코드를 포스팅하도록 하겠습니다. 

 

1. 메모장 추가

 tkinter의 Text를 이용하여 메모할 수 있도록 공간을 마련했습니다. '.env' 파일에 memoBefore이라는 key로 메모 내용을 저장하고 불러와서 text에 insert 하여, 코드 실행 시 자동적으로 이전의 메모를 불러오고, 메모 내용에 변화가 있을 시 해당 내용을 '.env' 파일에 수정할 수 있게 했습니다.

 

2. 수정사항

 가독성을 위해 기본 글씨색을 노란색으로 수정해 주었고, 메모장 내의 깜빡이는 커서 색은 흰색으로 할당해주었습니다.(insertbackground)

 새로고침 할 경우 이전내용이 삭제가 안되고 남아있는 경우가 발생해 (특히 포지션 개수가 줄어드는 경우), 업데이트 이전의 레이블을 destroy 하는 방법을 생각했으나 코드가 복잡해질 것 같아, 새로고침 할 때 다른 레이블들을 덮어버릴 큰 레이블 하나를 배치하는 것으로 대신했습니다.

 

작동 모습

 

3. 코드

import ccxt
import os
import dotenv
import tkinter
import tkinter.font
from tkinter import *
import datetime as dt
import threading
import time

dotenv_file = dotenv.find_dotenv()
dotenv.load_dotenv(dotenv_file)

apikey = os.environ['bn_apikey']
apisecret = os.environ['bn_secret']
memoBefore = os.environ['memoBefore']

############################################################
# 폰트색상
def color(amount):
    if amount >=0:
        return 'green'
    else:
        return 'red'

############################################################
# 윈도우 생성
def gui():
    global font
    win = tkinter.Tk ()
    win.title("Traiding Tools")
    win.configure(background='black')
    win.geometry('155x400')
    font=tkinter.font.Font(family="Arial", size=10, slant="italic", weight='bold')
    #메모장
    text = Text(win, bg = 'black', insertbackground='white', height=10, width=17, fg='yellow',font=tkinter.font.Font(family="Arial", size=12, weight='bold'))
    text.place(x = 0, y =200)
    text.insert(END, memoBefore)

    binance = ccxt.binance(config={'apiKey': apikey, 'secret': apisecret})


    ############################################################
    # 새로고침
    def update():
        ############################################################
        # 선물 포지션 불러오기
        def from_binance():
            global symbol
            global size
            global pnl
            
            while True:
                try:
                    balance = binance.fetch_balance(params={"type": "future"})
                    break
                except:
                    time.sleep(5)

            positions = balance['info']['positions']
            # 오픈 포지션 분리
            symbol = []
            size = []
            pnl = []
            for position in positions:
                if position['initialMargin'] != '0':
                    symbol.append(position['symbol'])
                    size.append(position['notional'])
                    pnl.append(float(position['unrealizedProfit']))

        ############################################################
        # 레이블 배치
        def arrange_label():
            # 지우기
            lb_clear = tkinter.Label(width=20, height=10, background='black')
            lb_clear.place(x=0, y=0)
            # 현재시간 표시
            y = 0
            lb_time = tkinter.Label(font=font, fg='yellow', background='black')
            lb_time.place(x = 0, y = y)
            now_time = dt.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            lb_time.configure(text = now_time)
            # 현재포지션 표시
            for n in range(len(symbol)):
                # 포지션 배치
                x = 70
                y += 16.5
                globals()['lb_sym_' + symbol[n]] = tkinter.Label(font=font, fg=color(float(size[n])), background='black')
                globals()['lb_pnl_' + symbol[n]] = tkinter.Label(font=font, fg=color(pnl[n]), background='black')
                globals()['lb_sym_' + symbol[n]].place(x = 0, y = y)
                globals()['lb_pnl_' + symbol[n]].place(x = x, y = y)
                globals()['lb_sym_' + symbol[n]].configure(text = "{0}".format(symbol[n]))
                globals()['lb_pnl_' + symbol[n]].configure(text = "{0:.2f} $".format(pnl[n]))

            # total pnl
            pnl_tot = sum(pnl)
            y = y+16.5
            lb_tot = tkinter.Label(font=font, fg = color(sum(pnl)), background='black')
            lb_tot.place(x=0, y=y)
            lb_tot.configure(text = "Total pnl: {0:.2f} $".format(pnl_tot))
        
        ############################################################
        # 메모장 내용 저장
        def saveMemo():
            global memoBefore
            memoText = text.get(1.0, 'end-1c')
            if memoText != memoBefore:
                dotenv.set_key(dotenv_file, 'memoBefore', memoText)
                memoBefore = memoText

        from_binance()
        arrange_label()
        saveMemo()

        threading.Timer(5, update).start()

    update()

    win.mainloop()


gui()

 

여기까지 tkinter을 이용해 새로운 윈도우에 필요한 정보들(시간, 포지션, 메모)을 띄울 수 있는 코드를 작성해 보았습니다. 향후 추가적인 기능을 넣거나, 에러 발생 시 추가 업데이트 예정입니다. 읽어주셔서 감사합니다.

 

반응형

+ Recent posts