2019102152 김다빈

Modify README and Add LICENSE & Add images

Copyright (c) [2021] 김다빈,이가원
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
\ No newline at end of file
#Trading Service
<div align="center">
<a href="https://github.com/othneildrew/Best-README-Template">
<img src="images/logo.png" alt="Logo" width="80" height="80">
</a>
./config/dev.js 생성 필요
module.exports = {
mongoURI:{mongoURI}
}
.env 파일 생성 후 access_key와 secret_key 할당 필요
<h3 align="center">업비트 암호화폐 자동 매매 서비스</h3>
</p>
</div>
## About The Project
<img src="images/about01.jpg" alt="about" width="80" height="80">
<h4>24시간 시세가 변하는 암호화폐를 위한 자동 매매 서비스<br/></h4>
해당 서비스를 만든 이유 <br/>
● 24시간 가격변동이 있지만 사람이 하루종일 보고 있을 수는 없다.<br/>
● 매매 기준을 정해두어도 이성적인 판단을 못하고 감정적으로 매매를 할 수 있다.<br/>
● 일상샐활을 하면서 고정적인 수익을 얻을 수 있다.<br/>
#### DB Schema
* User
- uid : 유저의 고유 아이디
- krw_balance : 보유 원화
- market : 보유 암호화폐 이름
- count : 매수 횟수
- avg_buy_price : 매수 평균가
- volume : 보유 암호화폐 갯수
* Coin
- tid : 거래량별 암호화폐 순위
- name : 암호화폐 이름
- korean_name : 암호화폐 한글 이름
- acc_trade_price_24h : 24시간 거래대금
- current_price : 현재 암호화폐 가격
- up_count : 5분 간격 연속 상승 횟수
- down_count : 5분 간격 연속 하락 횟수
### Built With
* [Node.js](https://nodejs.org/)
### Installation
1. repository를 clone한다.
```sh
git clone http://khuhub.khu.ac.kr/Crypto/Crypto_trade_bot.git
```
2. NPM package들을 설치한다.
```sh
npm install
```
3. 해당 프로젝트는 aws ec2와 ssl인증서를 사용한다. 개인 PC에서 작동하려면 domain과 sslport를 지우고 express.app을 사용해서 서버를 작동시키면 된다.(이 경우 4번은 생략)
4. 최상위 폴더의 index.js의 domain과 sslport를 본인 domain과 sslport로 변경한다.
```js
const domain = "{your domain}";
const sslport = {your port};
```
5. https://cloud.mongodb.com/ 가입 후 db connect url을 복사한다.
6. /config 폴더에 dev.js 파일 추가
```js
module.exports = {
mongoURI:"복사한 connect url"
}
```
7. https://upbit.com/service_center/open_api_guide 에서 access_key와 secret_key를 발급받는다.
8. https://developers.line.biz/en/services/messaging-api/ 에서 line message-api를 생성하고 channel access token을 복사한다.
9. 3번에서 입력한 도메인을 webhook url로 설정해준다.(4번을 생략했다면 webhook url에 본인 네트워크망IP를 입력)
10. 프로젝트 최상위 폴더에 .env 파일 추가
```env
access_key={upbit에서 발급 받은 access_key}
secret_key={upbit에서 발급 받은 secret_key}
token={line message-api 의 channel access token}
userid={테스트 알림을 받을 line userid}
```
## Usage
프로젝트 최상위 폴더에서 명령어 실행
```sh
nodemon
```
<img src="images/first.jpg" alt="first" width="80" height="80">
<img src="images/second.jpg" alt="second" width="80" height="80">
## Roadmap
- [x] Add get_marketname
- [x] Add get_marketInfo
- [x] Add price_comparison
- [x] Add transaction_coin
- [x] Add latest_repeat
- [x] Add send the order breakdown to the user
- [x] Add send the asset to the user
- [x] Add Whenever a sale is signed, the details of the signing are sent.
## Contributing
1. 프로젝트를 fork 하세요.
2. 여러분의 feature 브랜치를 만들어 주세요.(`git checkout -b feature/{function}`)
3. 변경사항을 commit 해주세요.(`git commit -m 'Add some function`)
4. 원격 브랜치로 push 해주세요.(`git push origin feature/{function}`)
5. pull request를 보내주세요.
## License
[MIT License](http://khuhub.khu.ac.kr/Crypto/Crypto_trade_bot/blob/master/LICENSE)
<!-- CONTACT -->
## Contact
이름 - [@김다빈,이가원](https://github.com/dogsoft0937) - dogsoft0937@khu.ac.kr,juneee0864@gmail.com <br/>
프로젝트 주소: [http://khuhub.khu.ac.kr/Crypto/Crypto_trade_bot](http://khuhub.khu.ac.kr/Crypto/Crypto_trade_bot)
## Acknowledgments
* [upbit-reference](https://docs.upbit.com/reference)
* [line-reference](https://developers.line.biz/en/reference/messaging-api/)
......
......@@ -12,8 +12,7 @@ const HTTPS = require('https');
const domain = "2019102152.osschatbot.ga"
const sslport = 23023;
const TARGET_URL = 'https://api.line.me/v2/bot/message/reply'
const TOKEN = process.env.token;
var userid = process.env.userid;
const bodyParser = require('body-parser');
const crypto = require('crypto');
......@@ -24,6 +23,8 @@ const sign = require('jsonwebtoken').sign
const access_key = process.env.access_key;
const secret_key = process.env.secret_key;
const server_url = "https://api.upbit.com"
const TOKEN = process.env.token;
const userid = process.env.userid;
var delay_count=1;
......@@ -76,7 +77,7 @@ function get_asset(market) {
// hold_coin[data[i].currency]={avg_buy_price:data[i].avg_buy_price,volume:data[i].balance,current_price:candle[0].trade_price};
}
}
resolve({ pre_asset: pre_asset.toFixed(0), current_asset: current_asset.toFixed(0), profit_data: (current_asset - pre_asset).toFixed(0), yield_data: ((current_asset - pre_asset) / pre_asset * 100).toFixed(2) });
resolve({ pre_asset: pre_asset.toFixed(0).replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ","), current_asset: current_asset.toFixed(0).replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ","), profit_data: (current_asset - pre_asset).toFixed(0).replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",") , yield_data: Number((current_asset - pre_asset) / pre_asset * 100).toFixed(2).replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",") });
} else if (market == "coin") {
var hold_coin = new Object();
......@@ -132,9 +133,14 @@ async function get_marketName() {
}
async function transaction_coin(coin_name, side, volume, price, ord_type, first = true) {
var volume = volume;
if (side == "ask" && volume == "") {
var avg_buy_price=0,market="";
if (side == "ask") {
await User.findOne({ market: coin_name }).then((result) => {
volume = String(result.volume);
if(volume == ""){
volume = String(result.volume);
}
avg_buy_price=result.avg_buy_price;
market=result.market.split('-')[1];
}).catch(err => { console.log(err.error) });
}
const body = {
......@@ -144,7 +150,6 @@ async function transaction_coin(coin_name, side, volume, price, ord_type, first
price: price,
ord_type: ord_type,
}
console.log(body);
//시장가 매수인 경우 price를 얼마치 살건지 입력
//시장가 매도인경우 volume에 몇개를 팔건지 입력
const query = queryEncode(body)
......@@ -170,8 +175,10 @@ async function transaction_coin(coin_name, side, volume, price, ord_type, first
}, delay)
})
var my_asset = await asset(1000);
if(my_asset.market&&my_asset.market.avg_buy_price){
lookup_order(result.uuid,my_asset.market.avg_buy_price);
if(avg_buy_price!=0){
console.log(avg_buy_price);
lookup_order(result.uuid,avg_buy_price,market);
}else{
lookup_order(result.uuid);
}
......@@ -332,7 +339,6 @@ async function price_comparison(candle, user_data = null, isbuying = false) {
}).catch(err => { console.log(err); })
}
}else{
console.log(촛불);
console.log(result);
}
})
......@@ -371,7 +377,7 @@ async function latest_repeat(t1) {
let today = new Date();
let minutes = today.getMinutes();
let seconds = today.getSeconds();
if (seconds == 0) {
if (seconds ==0) {
// if (minutes == 0 && seconds == 0) {
clearInterval(check_time);
sort_info = (await sort_data());
......@@ -401,7 +407,7 @@ async function latest_repeat(t1) {
}
}, 1000);
}
function lookup_order(uuid,avg_buy_price=0) {
function lookup_order(uuid,avg_buy_price=0,market="") {
const body = {
uuid: uuid
}
......@@ -441,21 +447,21 @@ function lookup_order(uuid,avg_buy_price=0) {
volume = volume.toFixed(8).toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
funds = funds.toFixed(0).toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
if(avg_buy_price!=0){
trading_notice(body.side, price, funds, volume,yield_data);
trading_notice(body.side, price, funds, volume,yield_data,market);
}else{
trading_notice(body.side, price, funds, volume);
}
})
return;
}
function trading_notice(side, price, funds, volume,yield_data=0) {
function trading_notice(side, price, funds, volume,yield_data=0,market="") {
var messages = new Array();
if (side == "bid") {
messages.push({ "type": "text", "text": "매수 주문이 체결되었습니다." });
messages.push({ "type": "text", "text": `체결 금액 : ${funds}원\n체결 수량 : ${volume}개\n체결 평균가 : ${price}원\n` });
messages.push({ "type": "text", "text": `${market}\n체결 금액 : ${funds}원\n체결 수량 : ${volume}개\n체결 평균가 : ${price}원\n` });
} else {
messages.push({ "type": "text", "text": "매도 주문이 체결되었습니다." });
messages.push({ "type": "text", "text": `체결 금액 : ${funds}원\n체결 수량 : ${volume}개\n체결 평균가 : ${price}원\n수익률 : ${yield_data}%` });
messages.push({ "type": "text", "text": `${market}\n체결 금액 : ${funds}원\n체결 수량 : ${volume}개\n체결 평균가 : ${price}원\n수익률 : ${yield_data}%` });
}
var TARGET_URL = 'https://api.line.me/v2/bot/message/push';
......
const mongoose=require('mongoose');
const coinSchema=mongoose.Schema({
tid:{
type:Number,
......@@ -20,11 +19,14 @@ const coinSchema=mongoose.Schema({
type:Number,
required:true
},
count:{
up_count:{
type:Number,
default:0
},
down_count:{
type:Number,
default:0
}
})
const Coin=mongoose.model("Coin",coinSchema);
module.exports={Coin};
\ No newline at end of file
......
const mongoose=require('mongoose');
const userSchema=mongoose.Schema({
uid:{
type:Number
......@@ -11,7 +10,7 @@ const userSchema=mongoose.Schema({
type:String,
},
count:{
type:Number,
type:Number
},
avg_buy_price:{
type:Number
......@@ -20,6 +19,5 @@ const userSchema=mongoose.Schema({
type:Number
}
})
const User=mongoose.model("User",userSchema);
module.exports={User};
module.exports={User};
\ No newline at end of file
......