반응형

[Bitget Futures API 사용 주의사항]

  • ccxt 연결시 options defaultType 에 future 대신 swap 사용
    • exchange = ccxt.bitget({

                                                       'apiKey': 'xxx',

                                                       'secret': 'yyy,

                                                       'password': 'zzz',

                                                       'options': {'defaultType': 'swap'},

                                                     })

  • 주문시 리턴값으로 가격 등등.. 빈값이고 id 만 리턴 됨.
    • fetch_order(id) 로 다시 가져와야 함

 


[프로그램 소스]

import ccxt, time, sys

SYMBOL = "ETH/USDT:USDT"
POSITION_SIZE = 0.02

# gridbot settings
NUM_BUY_GRID_LINES = 3
NUM_SELL_GRID_LINES = 3
GRID_SIZE = 4

# 너무 짧으면 간혹 가져오기 실패..
CHECK_ORDERS_FREQUENCY = 0.2

CANCELED_ORDERS_STATUS = "canceled"
CLOSED_ORDER_STATUS = "filled"

exchange = ccxt.bybit({
    "apiKey": "xxx",
    "secret": "yyy",
    "password": "zzz",
    "options": {"defaultType": "swap"}
})

buy_orders = []
sell_orders = []

def new_buy_orders():
    ticker = exchange.fetch_ticker(SYMBOL)
    for i in range(NUM_BUY_GRID_LINES):
        price = ticker['close'] - (GRID_SIZE * (i+1))
        print("신규 Buy : {}".format(price))
        order = exchange.create_order(symbol=SYMBOL, type='limit', side='buy', \
                                        amount=POSITION_SIZE, price=price, \
                                        params={'reduce_only': False})
        time.sleep(CHECK_ORDERS_FREQUENCY)
        order = exchange.fetch_order(symbol= SYMBOL, id= order['info']['orderId'])
        buy_orders.append(order['info'])

def new_sell_orders():
    ticker = exchange.fetch_ticker(SYMBOL)
    for i in range(NUM_SELL_GRID_LINES):
        price = ticker['close'] + (GRID_SIZE * (i+1))
        print("신규 Sell : {}".format(price))
        order = exchange.create_order(symbol=SYMBOL, type='limit', side='sell', \
                                        amount=POSITION_SIZE, price=price, \
                                        params={'reduce_only': False})
        time.sleep(CHECK_ORDERS_FREQUENCY)
        order = exchange.fetch_order(symbol= SYMBOL, id= order['info']['orderId'])
        sell_orders.append(order['info'])

new_buy_orders()
new_sell_orders()

while True:
    closed_order_ids = []

    for buy_order in buy_orders:
          
        try:
            order = exchange.fetch_order(symbol=SYMBOL, id=buy_order['orderId'])
        except Exception as e:
            print("주문 체크 오류 : ", e)
            continue
            
        order_info = order['info']

        if order_info['state'] == CANCELED_ORDER_STATUS:
            closed_order_ids.append(order_info['orderId'])

        if order_info['state'] == CLOSED_ORDER_STATUS:
            closed_order_ids.append(order_info['orderId'])
            print("{} 체결 : {}".format(order_info['side'], order_info['price']))

            if order_info['side'] == 'open_long': 
                new_side = 'close_long'
            else:
                new_side = 'open_short'
            new_sell_price = float(order_info['price']) + GRID_SIZE
            print("{} 추가 : {}".format(new_side, new_sell_price))
            # 기존 주문이 신규이면 새로운 청산 주문, 기존 주문이 청산이면 신규 주문
            new_reduce_only = not order_info['reduce_only']
            new_sell_order = exchange.create_order(symbol=SYMBOL, type='limit', side='sell', \
                                    amount=POSITION_SIZE, price=new_sell_price, \
                                    params={'reduce_only': new_reduce_only})
            sell_orders.append(new_sell_order['info'])

        time.sleep(CHECK_ORDERS_FREQUENCY)

    for sell_order in sell_orders:
        
        try:
            order = exchange.fetch_order(symbol=SYMBOL, id=sell_order['order_id'])
        except Exception as e:
            print("request failed, retrying : ", e)
            continue
            
        order_info = order['info']

        if order_info['order_status'] == CLOSED_ORDER_STATUS:
            closed_order_ids.append(order_info['order_id'])
            print("Sell 체결 : {}".format(order_info['price']))

            if order_info['side'] == 'open_short': 
                new_side = 'close_short'
            else:
                new_side = 'open_long'

            new_buy_price = float(order_info['price']) - GRID_SIZE
            print("{} 추가 : {}".format(new_side, new_buy_price))
            # 기존 주문이 신규이면 새로운 청산 주문, 기존 주문이 청산이면 신규 주문
            new_reduce_only = not order_info['reduce_only']
            new_buy_order = exchange.create_order(symbol=SYMBOL, type='limit', side='buy', \
                        amount=POSITION_SIZE, price=new_buy_price, \
                        params={'reduce_only': new_reduce_only})
            buy_orders.append(new_buy_order['info'])

        time.sleep(CHECK_ORDERS_FREQUENCY)

    for order_id in closed_order_ids:
        buy_orders = [buy_order for buy_order in buy_orders if buy_order['orderId'] != order_id]
        sell_orders = [sell_order for sell_order in sell_orders if sell_order['orderId'] != order_id]

    if len(sell_orders) == 0:
        print("새로운 Sells")
        new_sell_orders()

    if len(buy_orders) == 0:
        print("새로운 Buys")
        new_buy_orders()

 

 

반응형

+ Recent posts