본문 바로가기

주식/[Upbit] 자동매매

[Upbit] 자동매매 프로그램 (Python) #3

728x90
반응형

이전에 자동매도 프로그램을 따로 작성을 하였습니다.

bab-dev-study.tistory.com/10

 

[Upbit] 자동매매 프로그램 (Python) #2

이전에 자동매매프로그램을 만들어보았습니다. https://bab-dev-study.tistory.com/8 [Upbit] 자동매매 프로그램 (Python) #1 ○ 준비작업 Upbit Open API 를 활용하여 자동매매 프로그램을 만들어 보겠습니다. 먼..

bab-dev-study.tistory.com

이번엔 자동매수 프로그램을 만들어보겠습니다.

매수 / 매도 프로그램을 따로 만드는 이유는 많은 ticker를 순차적으로 조회하다보니

타이밍을 놓치는거같아서 따로 사용하고 있습니다.

 

 


○ class Myupbit 생성
    이전에 만들었던 Myupbit class에 매수를 위한 함수를 추가하겠습니다.

 

class MyUpbit(pyupbit.Upbit):
    def getPurchaseCoins(self, ticker="KRW"):
        try:
            balances, req = self.get_balances(contain_req=True)
            return balances
        except Exception as x:
            print(x.__class__.__name__)
            return None
         
         
def get_df(ticker="BTC", window=20, interval="minute1"):
    try:
        df = pyupbit.get_ohlcv(ticker, interval=interval, count=window+5)
        return df
    except:
        return None


def order_buy(session, ticker, price, unit):
    result = session.buy_limit_order(ticker, price, unit)
    return result

    - get_df() : 해당 ticker의 거래기록을 가져옵니다.

    - order_buy() : 해당 ticker 매수 요청을 합니다.

 


○ Util 함수 생성

 

def time_sleep(startTime=1, sleep=60):
    if startTime != 0:
        while True:
            if datetime.datetime.now().second == startTime:
                break
            else:
                time.sleep(1)
        else:
            time.sleep(sleep)


def checkHoldingTicker(purchaseCoinsInfo, ticker):
    for purchaseCoin in purchaseCoinsInfo:
        if not purchaseCoin['currency'] == 'KRW' and purchaseCoin['currency'] in ticker:
            return True
    return False


def buyCheck(df, ticker, price, close_ma_5, close_ma_15, volume_ma_5, volume_ma_15):
    if 매수 조건 1:  
        return True    

    if 매수 조건 2:  
        return True
        
    return False

def buy(session, ticker, price, amount):
    unit = round(amount / price, 4)
    result = myupbit.order_buy(session, ticker, price, unit)

    if result is not None:
        print(myupbit.getTime(), '[BUY]', ticker, 'price:', price, 'unit:', unit)
        return result['uuid']
    else:
        print(myupbit.getTime(), '[BUY_Fail]', ticker, 'price:', price, 'unit:', unit)
    return None
    
    
def trade_wait_append(array, result_uuid):
    if result_uuid is not None:
        array.append(result_uuid)

    - time_sleep() : startTime 은 ticker 를 조회할 시간을 나타냅니다.

                        특정시간(초) 에 데이터를 조회하기 위해서 만들었습니다.

    - checkHoldingTicker() : 현재 보유하고있는 코인은 추가로 매수하지 않을것이므로

                                   데이터 조회를 막기위해 사용합니다. ( 다른 코인을 빠르게 조회하기 위함..)

    - buyCheck() : 매수 조건을 체크하는 함수입니다. 이전의 거래금액과 거래량으로 조건을 만들어 봅시다.

    - buy() : 매수 요청을 합니다.

    - trade_wait_append() : 매수가 오랫동안 대기중일때 취소시키기 위해 사용합니다.

 

 


○ Main 함수 생성

 

def main():
    session = myupbit.getSession()
    properties = configparser.ConfigParser()
    trade_wait = []

    print(myupbit.getTime(), 'start')
    while True:
        properties.read('./config/buyconfig.ini')

        initConfig = properties["INIT"]
        buy_amount = int(initConfig["buy_amount"])
        startTime = int(initConfig["starting"])
        sleep = int(initConfig["sleep"])

        # 현재 보유코인
        purchaseCoinsInfo = session.getPurchaseCoins()

        # 매수 체크할 Ticker 목록
        tickerList = properties["TICKER"]

        for ticker_temp in tickerList:
            try:
                ticker = ticker_temp.upper()
                if tickerList[ticker] == '0' or checkHoldingTicker(purchaseCoinsInfo, ticker):
                    continue

                # 과거 거래 기록 조회
                df = myupbit.get_df(ticker=ticker, interval='minute1', window=30)
                
                # Ticker 현재 가격 조회
                price = myupbit.inquiry_price(ticker)

                # 조회 실패시 에러 처리
                if df is None or price is None:
                    print(myupbit.getTime(), '[df_error] ', ticker)
                    continue

                close_ma_5 = df['close'].rolling(window=5).mean()
                close_ma_15 = df['close'].rolling(window=15).mean()
                close_ma_30 = df['close'].rolling(window=30).mean()
                volume_ma_5 = df['volume'].rolling(window=5).mean()
                volume_ma_15 = df['volume'].rolling(window=15).mean()

                if buyCheck(df, ticker, price, close_ma_5, close_ma_15, volume_ma_5, volume_ma_15):
                    result_uuid = buy(session, ticker, price, buy_amount)
                    trade_wait_append(trade_wait, result_uuid)

            except Exception as e:
                print(myupbit.getTime(), '[exception]', ticker, ' : ', e)
                print(traceback.format_exc())
                
            ## for-end
            
        time_sleep(startTime, sleep)

        for cancel_uuid in trade_wait:
            session.cancel_order(cancel_uuid)

        trade_wait.clear()
        ## while-end

if __name__ == '__main__':
    main()

    이전에 매도 프로그램과 유사합니다.

    차이점은 거래정보를 1분에 한번씩 조회를 하도록 하였습니다.

    그리고 조회하는 시간을 일정하게 시작하도록 했습니다. ( 15초에 조회 시작 -> 조회가 끝나면 대기 )

    설정값에서 구매 금액과 ticker 목록을 관리하도록 했습니다

 


○ config.ini 설정파일

 

[INIT]
buy_amount = 100000
starting = 15
sleep=30


[TICKER]
krw-eth = 1
krw-eos = 1
krw-gas = 1
krw-xrp = 1
krw-neo = 1
krw-ltc = 1
krw-etc = 1
krw-omg = 1
krw-waves = 1

    - buy_amount : 매수금액

    - starting : 거래정보 조회 시간

    - sleep : 대기시간 ( starting 값을 사용하면 sleep값은 사용안함)

    - [TICKER] : ticker 목록 ( 1 : 매수 , 0 : 무시 )

 


○ 마무리

   소스를 개선한지 얼마 안되서 문제가 발생할 수 있습니다.

   오류가 나면 바로 수정해서 업데이트 하겠습니다.

728x90
반응형