업비트API 트레이딩 (1) -준비 및 테스트-

2019년 6월 3일 월요일

업비트API 트레이딩

업비트API를 이용하여 가상화폐 트레이딩 프로그램을 만들어본다. 모든 예제는 node.js를 이용하였다.

API키 발급받기

업비트 **[마이페이지->Open API 관리]**에서 API키를 발급받는다.

혹시모르니 출금기능을 해제하고 IP설정을 꼭 하도록하자.

**[발급받기]**를 클릭하면 나오는 secret keyaccess key를 따로 적어둔다.

API 모듈

업비트API문서 REST API 를 참고하여 만들었다.

upbit_lib.js

//https://docs.upbit.com/v1.0.3/

const rp = require('request-promise')
const sign = require('jsonwebtoken').sign
const queryEncode = require('querystring').encode

async function request(url, qs, token, method) {
  if (!method) {
    method = 'GET'
  }
  let options = {
    method: method,
    url: url,
    json: true,
    transform: function (body, response) {
      let remain_min = 0
      let remain_sec = 0
      if (response.headers && response.headers['remaining-req']) {
        let items = response.headers['remaining-req'].split(';')
        for (let item of items) {
          let [key, val] = item.split('=')
          if (key.trim() == 'min') {
            remain_min = parseInt(val.trim())
          } else if (key.trim() == 'sec') {
            remain_sec = parseInt(val.trim())
          }
        }
      }
      return {
        success: true,
        remain_min: remain_min,
        remain_sec: remain_sec,
        data: body,
      }
    },
  }
  if (method == 'POST') {
    options.json = qs
  } else {
    options.qs = qs
  }
  if (token) {
    options.headers = { Authorization: `Bearer ${token}` }
  }
  let result = { success: false, message: null, name: null }
  try {
    result = await rp(options)
  } catch (e) {
    result.data = null
    if (e.error.error) {
      result.message = e.error.error.message
      result.name = e.error.error.name
    } else {
      result.message = e.message
    }
  }

  return result
}

//전체 계좌 조회
async function accounts() {
  const url = 'https://api.upbit.com/v1/accounts'

  const payload = {
    access_key: this.accessKey,
    nonce: new Date().getTime(),
  }
  const token = sign(payload, this.secretKey)

  let result = await request(url, {}, token)
  return result
}

// 주문 리스트
async function order_list(market, state, uuids, page) {
  //market: null KRW-BTC
  //state: wait done
  const url = 'https://api.upbit.com/v1/orders'
  let qs = { state: state, page: page }
  if (market) qs['market'] = market
  if (uuids) qs['uuids'] = uuids

  const query = queryEncode(qs)
  const payload = {
    access_key: this.accessKey,
    nonce: new Date().getTime(),
    query: query,
  }
  const token = sign(payload, this.secretKey)

  let result = await request(url, qs, token)
  return result
}

// 주문(매수)
async function order_bid(market, volume, price) {
  //market: KRW-BTC
  const url = 'https://api.upbit.com/v1/orders'
  let qs = { market: market, side: 'bid', volume: volume, price: price, ord_type: 'limit' }

  const query = queryEncode(qs)
  const payload = {
    access_key: this.accessKey,
    nonce: new Date().getTime(),
    query: query,
  }
  const token = sign(payload, this.secretKey)

  let result = await request(url, qs, token, 'POST')
  return result
}

// 주문(매도)
async function order_ask(market, volume, price) {
  //market: KRW-BTC
  const url = 'https://api.upbit.com/v1/orders'
  let qs = { market: market, side: 'ask', volume: volume, price: price, ord_type: 'limit' }

  const query = queryEncode(qs)
  const payload = {
    access_key: this.accessKey,
    nonce: new Date().getTime(),
    query: query,
  }
  const token = sign(payload, this.secretKey)

  let result = await request(url, qs, token, 'POST')
  return result
}

// 주문 상세
async function order_detail(uuid) {
  const url = 'https://api.upbit.com/v1/order'
  let qs = { uuid: uuid }

  const query = queryEncode(qs)
  const payload = {
    access_key: this.accessKey,
    nonce: new Date().getTime(),
    query: query,
  }
  const token = sign(payload, this.secretKey)

  let result = await request(url, qs, token)
  return result
}

// 주문 취소
async function order_delete(uuid) {
  const url = 'https://api.upbit.com/v1/order'
  let qs = { uuid: uuid }

  const query = queryEncode(qs)
  const payload = {
    access_key: this.accessKey,
    nonce: new Date().getTime(),
    query: query,
  }
  const token = sign(payload, this.secretKey)

  let result = await request(url, qs, token, 'DELETE')
  return result
}

// 주문 가능 정보
async function order_chance(market) {
  const url = 'https://api.upbit.com/v1/orders/chance'
  let qs = { market: market }

  const query = queryEncode(qs)
  const payload = {
    access_key: this.accessKey,
    nonce: new Date().getTime(),
    query: query,
  }
  const token = sign(payload, this.secretKey)

  let result = await request(url, qs, token)
  return result
}

// 시세종목정보
async function market_all() {
  const url = 'https://api.upbit.com/v1/market/all'
  let result = await request(url)
  return result
}

// 분 캔들
async function market_minute(market, unit, to, count) {
  //unit:  1, 3, 5, 15, 10, 30, 60, 240
  //to: yyyy-MM-dd'T'HH:mm:ssXXX
  const url = 'https://api.upbit.com/v1/candles/minutes/' + unit
  let qs = { market: market }
  if (to) qs.to = to
  if (count) qs.count = count

  let result = await request(url, qs)
  return result
}

// 일 캔들
async function market_day(market, to, count) {
  //to: yyyy-MM-dd'T'HH:mm:ssXXX
  const url = 'https://api.upbit.com/v1/candles/days'
  let qs = { market: market }
  if (to) qs.to = to
  if (count) qs.count = count

  let result = await request(url, qs)
  return result
}

// 주 캔들
async function market_week(market, to, count) {
  //to: yyyy-MM-dd'T'HH:mm:ssXXX
  const url = 'https://api.upbit.com/v1/candles/weeks'
  let qs = { market: market }
  if (to) qs.to = to
  if (count) qs.count = count

  let result = await request(url, qs)
  return result
}

// 월 캔들
async function market_month(market, to, count) {
  //to: yyyy-MM-dd'T'HH:mm:ssXXX
  const url = 'https://api.upbit.com/v1/candles/months'
  let qs = { market: market }
  if (to) qs.to = to
  if (count) qs.count = count

  let result = await request(url, qs)
  return result
}

// 채결 정보
async function market_trade_tick(market, to, count) {
  //to: yyyy-MM-dd'T'HH:mm:ssXXX
  const url = 'https://api.upbit.com/v1/trades/ticks'
  let qs = { market: market }
  if (to) qs.to = to
  if (count) qs.count = count

  let result = await request(url, qs)
  return result
}

// 시세 Ticker
async function market_ticker(markets) {
  // markets: KRW-BTC,KRW-ETH
  const url = 'https://api.upbit.com/v1/ticker'
  let qs = { markets: markets }

  let result = await request(url, qs)
  return result
}

// 호가 정보
async function trade_orderbook(markets) {
  // markets: KRW-BTC,KRW-ETH
  const url = 'https://api.upbit.com/v1/orderbook'
  let qs = { markets: markets }

  let result = await request(url, qs)
  return result
}

// class Upbit
function Upbit(s, a) {
  this.secretKey = s
  this.accessKey = a
}
Upbit.prototype.accounts = accounts
Upbit.prototype.order_list = order_list
Upbit.prototype.order_bid = order_bid
Upbit.prototype.order_ask = order_ask
Upbit.prototype.order_detail = order_detail
Upbit.prototype.order_delete = order_delete
Upbit.prototype.order_chance = order_chance
Upbit.prototype.market_all = market_all
Upbit.prototype.market_minute = market_minute
Upbit.prototype.market_day = market_day
Upbit.prototype.market_week = market_week
Upbit.prototype.market_month = market_month
Upbit.prototype.market_trade_tick = market_trade_tick
Upbit.prototype.market_ticker = market_ticker
Upbit.prototype.trade_orderbook = trade_orderbook

module.exports = Upbit

request(request-promise) 를 이용하여 rest api를 호출하였다. Upbit class를 반환한다. 모든 함수는 success, message, data, remain_min, remain_sec 를 반환한다.

success 성공여부
message 메세지
remain_min 남은호출횟수(1분당)
remain_sec 남은호출횟수(1초당)
data 결과값
const Upbit = require('./upbit_lib')
var upbit = new Upbit('secret key', 'access key')

이렇게 사용하면 된다.

테스트 프로그램

api 모듈을 이용해서 간단한 테스트 프로그램을 작성해보자.

test.js

const Upbit = require('./upbit_lib')

async function start() {
  const upbit = new Upbit('secret-key', 'access-key')

  console.log('-- market_all -------------------------------------------------')
  let json = await upbit.market_all()
  console.log(json.data)

  {
    console.log('-- market_minute -------------------------------------------------')
    let {
      success: success,
      message: message,
      data: data,
      remain_min: remain_min,
      remain_sec: remain_sec,
    } = await upbit.market_minute('KRW-BTC', 1, '', 2)
    console.log('remain_sec:', remain_sec)
    console.log('remain_min:', remain_min)
    console.log(data)
  }

  {
    console.log('-- order_chance -------------------------------------------------')
    let { data: data } = await upbit.order_chance('KRW-BTC')
    console.log(data)
  }
}

start()

코인목록, 분봉값, 주문정보등의 api를 호출하였다. secret-key access-key에 본인이 발급받은 키를 입력하면 된다.

실행결과

ubuntu@ip-x:~/app/upbit$ node test.js
-- market_all -------------------------------------------------
{ success: true,
  remain_min: 598,
  remain_sec: 9,
  data:
   [ { market: 'KRW-BTC',
       korean_name: '비트코인',
       english_name: 'Bitcoin' },
     { market: 'KRW-DASH', korean_name: '대시', english_name: 'Dash' },
     { market: 'KRW-ETH',
       korean_name: '이더리움',
       english_name: 'Ethereum' },
     { market: 'BTC-ETH',
       korean_name: '이더리움',
       english_name: 'Ethereum' },
     { market: 'BTC-LTC',
       korean_name: '라이트코인',
       english_name: 'Litecoin' },
     { market: 'BTC-STRAT',
       korean_name: '스트라티스',
...

다음에는 이를 이용한 간단한 자동 손절프로그램을 만들어 보도록 하겠다.