index.js 8.17 KB
const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));

const options = { method: 'GET', headers: { Accept: 'application/json' } };
const express = require('express');
const app = express();
const { Coin } = require("./models/Coin");
const {User}=require('./models/User');

require("dotenv").config();

const crypto=require('crypto');
const queryEncode=require('querystring').encode;


console.log("test");
console.log("test2");

const request = require('request')
const {v4} = require("uuid")
const sign = require('jsonwebtoken').sign


var sort_info = new Array();
const mongoose = require('mongoose');
const config = require('./config/key');
const { json } = require('express');

const connect = mongoose.connect(config.mongoURI, {
    useNewUrlParser: true, useUnifiedTopology: true
})
    .then(() => console.log('디비연결 성공'))
    .catch((err) => console.log(err));



var korean_name = new Object();
const access_key = process.env.access_key;
const secret_key = process.env.secret_key;
const server_url = "https://api.upbit.com"

function get_asset(){
    const payload = {
        access_key: access_key,
        nonce: v4(),
    }
    const token = sign(payload, secret_key)
    const options = {
        method: "GET",
        url: server_url + "/v1/accounts",
        headers: {Authorization: `Bearer ${token}`},
    }
    return new Promise(resolve=>{
        request(options,function(err,res,body){
            if (err) throw new Error(err)
            // test=res.json();
            data=JSON.parse(body);
            // console.log(data[0].currency)
            data.filter(function(item){
                if(item.currency=="PLA"){
                    resolve(item);
                }
            })
        })
    })
}

async function get_marketName() {
    var data = new Array();
    //전체 암호화폐 리스트 불러오기
    let response = await fetch(`${server_url}/v1/market/all`, options)
        .then(res => res.json())
        .then(json => {
            for (i in json) {
                data.push(json[i].market);
                korean_name[json[i].market] = json[i].korean_name;
            }
        })
    return data;
}
async function transaction_coin(coin_name,side,volume,price,ord_type){
    const body = {
        market: coin_name,
        side: side,
        volume: volume,
        price: price,
        ord_type: ord_type,
    }
    //시장가 매수인 경우 price를 얼마치 살건지 입력
    //시장가 매도인경우 volume에 몇개를 팔건지 입력
    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: v4(),
        query_hash: queryHash,
        query_hash_alg: 'SHA512',
    }
    
    const token = sign(payload, secret_key)
    
    const options = {
        method: "POST",
        url: server_url + "/v1/orders",
        headers: {Authorization: `Bearer ${token}`},
        json: body
    }
    request(options, (error, response, body) => {
        if (error) throw new Error(error)
        console.log(body)
    })
}
async function get_marketInfo() {
    //각 암호화폐 정보 조회
    var name_list = await get_marketName();
    const url2 = `${server_url}/v1/ticker/?markets=${name_list}`;
    var arr = new Array();
    let response2 = await fetch(url2, options)
        .then(res => res.json())
        .then(json => {
            for (i in json) {
                if (json[i].acc_trade_price_24h > 100000000000) {
                    arr.push([json[i].market, json[i].acc_trade_price_24h, json[i].trade_price]);
                }
            }
        })
    return arr
}
async function sort_data() {
    arr = await get_marketInfo();
    arr.sort((a, b) => {
        return b[1] - a[1];
    })
    return arr;
}
async function save_coin(arr) {
    for (var i = 0; i < 10; i++) {
        if (arr[i]) {
            const coin = new Coin({
                tid: i + 1,
                name: arr[i][0],
                korean_name: korean_name[arr[i][0]],
                acc_trade_price_24h: arr[i][1],
                current_price: arr[i][2]
            });
            await coin.save((err) => {
                if (err) {
                    console.log(err)
                }
            })
        }
    }
    return true;
}
async function refresh_db() {
    Coin.find()
        .then(result => {
            if (result.length !== 0) {
                Coin.deleteMany({ tid: { $gt: 0 } }, (err, result) => {
                    if (err) {
                        console.log(err);
                    } else {
                        console.log(result);
                    }
                })
            }
            save_coin(sort_info);
        })
}
async function get_candle(minute, market) {
    const url = `https://api.upbit.com/v1/candles/minutes/${minute}?market=${market}&count=1`;
    var candle = new Array();
    let response = await fetch(url, options)
        .then(res => res.json())
        .then(json => candle = json)
    return candle;
}
async function check_coin(t1) {
    for (var i = 0; i < t1.length; i++) {
        var candle = await get_candle(5, t1[i]);
        await Coin.findOne({ name: candle[0].market }).then((result) => {
            //가격이 떨어졌을때
            if (result.current_price > candle[0].trade_price) {
                Coin.findOneAndUpdate({ name: candle[0].market }, { current_price: candle[0].trade_price, $inc: { count: 1 } }, { new: true }, (err, result) => {
                    if (err) {
                        console.log(err);
                    } else {
                        console.log("***" + result.korean_name + "은(는)" + result.count * 5 + "분 동안 하락중");
                        if(count>=3){
                            transaction_coin(result.name,"bid",null,"얼마치 살건지","price");
                        }
                    }
                })
            }//그대로 이거나 올랐을때
            else {
                Coin.findOneAndUpdate({ name: candle[0].market }, { current_price: candle[0].trade_price, count: 0 }, { new: true }, (err, result) => {
                    if (err) {
                        console.log(err);
                    } else {
                        //특정 조건...
                        transaction_coin(result.name,"ask","몇개를 팔건지",null,"market");
                        console.log(result.korean_name + "은(는)" + result.count * 5 + "분 동안 상승 혹은 정체중");
                    }
                })

            }
        })
    }
}
async function latest_repeat(t1) {
    await Coin.find().sort({ tid: 1 }).then(result => {
        for (var key in result) {
            t1.push(result[key].name)
        }
    })
    let check_time = setInterval(async () => {
        let today = new Date();
        let minutes = today.getMinutes();
        let seconds = today.getSeconds();
        // if (seconds == 0) {
        if (minutes == 0 && seconds == 0) {
            clearInterval(check_time);
            sort_info = (await sort_data());
            (await refresh_db());
            console.log("현재 시간은 " + today.toLocaleTimeString());
            var count=0;
            let coin=setInterval(async () => {
                let today = new Date();
                let minutes=today.getMinutes();
                let seconds=today.getSeconds();
                console.log("현재 시간은 " + today.toLocaleTimeString());
                await (check_coin(t1).then(count++));
                //1시간마다 db 최신화...
                if(count==12){
                    count=0;
                    sort_info=(await sort_data());
                    (await refresh_db());
                    console.log("db최신화");
                }
            }, 60000*5);
        }
    }, 1000);
}
app.listen(5000, async () => {
    console.log('server start')
    //coin 이름,가격,거래대금 저장 , DB 최신화 1시간마다 반복
    //5분마다 현재 가격 가져와서 db랑 비교후 매수 매도 기준잡기
    var t1 = new Array();
    test_data=await (latest_repeat(t1));
    //계좌 정보 db 최신화
    console.log(await get_asset());
})