코인 - 라이프 - 밸런스

당신의 코인과 인생의 밸런스를 위하여 코라밸을 만들었습니다.

코라밸 UI 바로가기

함께만드는 자동매매

업비트 자동매매 프로그램 만들기 - 실습

코라밸 2022. 1. 17. 18:07
320x100

안녕하세요.

코라밸 입니다.

 

지난글에 이어서 업비트 자동매매 프로그램 코드 실습을 해보도록 하겠습니다.

 

로직 및 코드 설명에 앞서 '인증가능한 요청' 을 만드는 방법을 알아보겠습니다. (문서 바로가기)

 

자동매매를 구현하기 위해 기본적으로 아래 두가지 기능을 만들어야 합니다.

  1. (일괄)주문 하기
    반복문을 이용해 선택한 코인의 매수 주문 또는 매도 주문을 전송한다.
    예) 리플(XRP) 코인을 시작가 1000원 부터 1200원 까지 10원 단위로 10개씩 매수 주문을 전송한다.
    > 시작
    > 리플 10개 1000원에 매수 주문
    > 리플 10개 1010원에 매수 주문
    > 리플 10개 1020원에 매수 주문
    > 리플 10개 1030원에 매수 주문
    > ...
    > 리플 10개 1180원에 매수 주문
    > 리플 10개 1190원에 매수 주문
    > 리플 10개 1200원에 매수 주문
    > 종료
  2. 조건식 만들기
    특정 조건이 충족되는 경우 해당 주문을 전송한다.
    예) 리플(XRP) 코인 10개 매도(매수) 주문이 체결되면 체결 금액 -10(+10)원에 10개 매수(매도) 주문을 전송한다.
    > 리플 10개 1100원에 매수 체결 -> 리플 10개 1110원에 매도 주문 전송
    > 리플 10개 1090원에 매수 체결 -> 리플 10개 1100원에 매도 주문 전송
    > 리플 10개 1100원에 매도 체결 -> 리플 10개 1090원에 매수 주문 전송

위 기능 중 첫번째 주문하기를 만들어 보겠습니다.

리플(XRP) 10개를 1100원에 지정가 매수 주문을 넣는 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
const axios = require('axios');
const crypto = require('crypto');
const querystring = require('querystring');
const { v4: uuidv4 } = require('uuid');
const jsonwebtoken = require('jsonwebtoken');
 
const sign = jsonwebtoken.sign;
const queryEncode = querystring.encode;
 
const ACCESS_KEY = '업비트 Access Key';
const SECRET_KEY = '업비트 Secret Key';
const market = 'KRW-XRP';
const side = 'bid';
const price = 1100;
const ord_type = 'limit';
const volume = 10;
 
const body = {
    market,
    side,
    price,
    volume,
    ord_type,
};
const query = queryEncode(body);
const hash = crypto.createHash('sha512');
const queryHash = hash.update(query, 'utf-8').digest('hex');
const payload = {
    access_key: ACCESS_KEY,
    nonce: uuidv4(),
    query_hash: queryHash,
    query_hash_alg: 'SHA512',
};
const token = sign(payload, SECRET_KEY);
 
await axios({
    method: 'POST',
    url: 'https://api.upbit.com/v1/orders',
    headers: { Authorization: `Bearer ${token}` },
    data: body,
})
    .then((response) => {
        console.log(`주문전송 성공.`);
    })
    .catch(async (error) => {
        console.log(error);
    });
cs

위 코드를 응용해서 반복문에 넣어 주시면 일괄 주문 기능을 구현하실 수 있습니다.

 

 

이어서 두번째 '조건식 만들기' 를 구현하기 위해서는 주문이 체결되었는지를 알아야 합니다.

바이낸스의 경우 주문이 체결될 때마다 웹소켓을 통해 즉시 알려주지만

업비트는....그런게 없습니다. (업비트 개발자 보고있나?)

 

그래서 노가다를 통해 어떤 주문이 체결되었는지를 체크해서 조건식을 작동시켜줘야 합니다.

방법은...(순서도를 그리기 귀찮았습니다....죄송합니다 ㅜㅡ)

  1. 현재 오픈 주문 목록 가져오기
    1. 주문 배열이 비어있는 경우 -> 주문 배열에 저장
    2. 주문 배열에 값이 있는 경우 -> 주문 배열과 오픈 주문 목록 비교
  2. 주문 목록과 비교해서 달라진 부분 찾기
    1. 달라진 부분이 있는 경우 -> 달라진 주문이 부분 체결되었는지, 완전 체결되었는지, 취소되었는지 확인
  3. 달라진 주문이 완전 체결된 경우
    1. 해당 주문이 조건식에 해당하는 경우 조건식 발동

아래 코드를 참조하셔서 위 로직을 구현하시면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
const axios = require('axios');
const crypto = require('crypto');
const querystring = require('querystring');
const { v4: uuidv4 } = require('uuid');
const jsonwebtoken = require('jsonwebtoken');
const { compare, compareUnsorted } = require('js-deep-equals');
 
const sign = jsonwebtoken.sign;
const queryEncode = querystring.encode;
 
const ACCESS_KEY = '업비트 Access Key';
const SECRET_KEY = '업비트 Secret Key';
 
const getOrdersValues = ({ accessKey, secretKey, page, uuids }) => {
    const body = {
        state: 'wait',
        page,
        order_by: 'asc',
        limit: 100,
    };
    let query = queryEncode(body);
 
    if (uuids.length) {
        body.states = ['done''cancel'];
        body.uuids = uuids;
        query =
            `page=${page}&order_by=asc&limit=100&states[]=done&states[]=cancel&+
            uuids.map((uuid) => `uuids[]=${uuid}`).join('&');
    }
 
    const hash = crypto.createHash('sha512');
    const queryHash = hash.update(query, 'utf-8').digest('hex');
    const payload = {
        access_key: accessKey,
        nonce: uuidv4(),
        query_hash: queryHash,
        query_hash_alg: 'SHA512',
    };
    const token = sign(payload, secretKey);
    const options = {
        method: 'GET',
        url: 'https://api.upbit.com/v1/orders?' + query,
        headers: { Authorization: `Bearer ${token}` },
        json: body,
    };
 
    return options;
};
 
const options = getOrdersValues({
    accessKey: ACCESS_KEY,
    secretKey: SECRET_KEY,
    page: 1,
    uuids: [],
});
let upbitOrders = [];
 
axios(options)
    .then(async (response) => {
        const currentOrders = response.data;
        if (upbitOrders.length || currentOrders.length) {
            if (!compareUnsorted(upbitOrders, currentOrders)) {
                const uuids = [];
                for (const upbitOrder of upbitOrders) {
                    if (!currentOrders.find((x) => x.uuid === upbitOrder.uuid))
                        uuids.push(upbitOrder.uuid);
                }
                if (uuids.length) {
                    const diffOptions = getOrdersValues({
                        accessKey: ACCESS_KEY,
                        secretKey: SECRET_KEY,
                        page: 1,
                        uuids,
                    });
                    await axios(diffOptions)
                        .then((response) => {
                            if (response.data.length) {
                                for (const diffOrder of response.data) {
                                    if (diffOrder.state === 'done') {
                                        // 조건식에 따른 주문 전송
                                    }
                                }
                            }
                            upbitOrders = currentOrders || [];
                        })
                        .catch((error) => {
                            console.log(error);
                        });
                } else upbitOrders = currentOrders || [];
            }
        }
    })
    .catch((error) => {
        console.log(error);
    });
cs

다음 글에서는 바이낸스 자동매매 만드는 것을 한번 다뤄보도록 하겠습니다~

 

 

자동매매 개발자 오픈톡: https://open.kakao.com/o/gbD73Bud

 

함께만드는 자동매매

#코인 #암호화폐 #자동매매 #반자동매매

open.kakao.com

 

320x100