2019102152 김다빈

Add selling algorithm and Modify buying algorithm

...@@ -21,24 +21,21 @@ const secret_key = process.env.secret_key; ...@@ -21,24 +21,21 @@ const secret_key = process.env.secret_key;
21 const server_url = "https://api.upbit.com" 21 const server_url = "https://api.upbit.com"
22 22
23 23
24 -var krw_balance = 60000; 24 +var krw_balance;
25 -var divided_money = krw_balance / 10; 25 +var divided_money;
26 26
27 var sort_info = new Array(); 27 var sort_info = new Array();
28 const mongoose = require('mongoose'); 28 const mongoose = require('mongoose');
29 const config = require('./config/key'); 29 const config = require('./config/key');
30 - 30 +app.use(bodyParser.json());
31 const connect = mongoose.connect(config.mongoURI, { 31 const connect = mongoose.connect(config.mongoURI, {
32 useNewUrlParser: true, useUnifiedTopology: true 32 useNewUrlParser: true, useUnifiedTopology: true
33 }) 33 })
34 .then(() => console.log('디비연결 성공')) 34 .then(() => console.log('디비연결 성공'))
35 .catch((err) => console.log(err)); 35 .catch((err) => console.log(err));
36 36
37 -app.use(bodyParser.json());
38 -var korean_name = new Object();
39 -
40 -
41 37
38 +var korean_name = new Object();
42 39
43 function get_asset(market) { 40 function get_asset(market) {
44 const payload = { 41 const payload = {
...@@ -88,9 +85,8 @@ async function get_marketName() { ...@@ -88,9 +85,8 @@ async function get_marketName() {
88 } 85 }
89 async function transaction_coin(coin_name, side, volume, price, ord_type, first = true) { 86 async function transaction_coin(coin_name, side, volume, price, ord_type, first = true) {
90 var volume = volume; 87 var volume = volume;
91 - if (side == "ask") { 88 + if (side == "ask" && volume == "") {
92 - await User.findOne({ uid: 1 }).then((result) => { 89 + await User.findOne({ market:coin_name }).then((result) => {
93 - console.log(result.volume);
94 volume = String(result.volume); 90 volume = String(result.volume);
95 }).catch(err => { console.log(err.error) }); 91 }).catch(err => { console.log(err.error) });
96 } 92 }
...@@ -133,25 +129,36 @@ async function transaction_coin(coin_name, side, volume, price, ord_type, first ...@@ -133,25 +129,36 @@ async function transaction_coin(coin_name, side, volume, price, ord_type, first
133 await user.save().then(() => { isuser = true }) 129 await user.save().then(() => { isuser = true })
134 //2회 이상 매수일 때 130 //2회 이상 매수일 때
135 } else { 131 } else {
136 - User.findOneAndUpdate({uid:1},{krw_balance:my_asset.KRW.balance,avg_buy_price: my_asset.market.avg_buy_price, volume: my_asset.market.balance,$inc: { count: 1 }},{new :true},(err,result)=>{ 132 + User.findOneAndUpdate({ uid: 1 }, { krw_balance: my_asset.KRW.balance, avg_buy_price: my_asset.market.avg_buy_price, volume: my_asset.market.balance, $inc: { count: 1 } }, { new: true }, (err, result) => {
137 - if(err){ 133 + if (err) {
138 - console.log(err); 134 + // console.log(err);
139 - }else{ 135 + } else {
140 - console.log(result); 136 + // console.log(result);
141 } 137 }
142 }) 138 })
143 } 139 }
144 } else if (side == "ask") { 140 } else if (side == "ask") {
145 //1회 매수 후 매도일 때 141 //1회 매수 후 매도일 때
142 + console.log("매도 쪽으로 진입");
146 if (first) { 143 if (first) {
147 - User.deleteOne({ uid: 1 }, (err, res) => { 144 + console.log("1회 매수 후 매도")
145 + User.deleteOne({ market:coin_name }, (err, res) => {
148 if (err) { 146 if (err) {
149 - console.log(err); 147 + // console.log(err);
150 } 148 }
149 + krw_balance = my_asset.KRW.balance;
150 + console.log(krw_balance);
151 + divided_money = krw_balance / 10;
151 }); 152 });
152 //분할 매수 분할 매도 중일 때 153 //분할 매수 분할 매도 중일 때
153 } else { 154 } else {
154 - 155 + User.findOneAndUpdate({ uid: 1 }, { krw_balance: my_asset.KRW.balance, avg_buy_price: my_asset.market.avg_buy_price, volume: my_asset.market.balance, count: 1 }, { new: true }, (err, result) => {
156 + if (err) {
157 + // console.log(err);
158 + } else {
159 + // console.log(result);
160 + }
161 + })
155 } 162 }
156 } 163 }
157 }).catch((err) => { console.log(err.error) }) 164 }).catch((err) => { console.log(err.error) })
...@@ -191,7 +198,7 @@ async function save_coin(arr) { ...@@ -191,7 +198,7 @@ async function save_coin(arr) {
191 }); 198 });
192 await coin.save((err) => { 199 await coin.save((err) => {
193 if (err) { 200 if (err) {
194 - console.log(err) 201 + // console.log(err)
195 } 202 }
196 }) 203 })
197 } 204 }
...@@ -204,9 +211,9 @@ async function refresh_db() { ...@@ -204,9 +211,9 @@ async function refresh_db() {
204 if (result.length !== 0) { 211 if (result.length !== 0) {
205 Coin.deleteMany({ tid: { $gt: 0 } }, (err, result) => { 212 Coin.deleteMany({ tid: { $gt: 0 } }, (err, result) => {
206 if (err) { 213 if (err) {
207 - console.log(err); 214 + // console.log(err);
208 } else { 215 } else {
209 - console.log(result); 216 + // console.log(result);
210 } 217 }
211 }) 218 })
212 } 219 }
...@@ -221,79 +228,89 @@ async function get_candle(minute, market) { ...@@ -221,79 +228,89 @@ async function get_candle(minute, market) {
221 .then(json => candle = json) 228 .then(json => candle = json)
222 return candle; 229 return candle;
223 } 230 }
224 -async function price_comparison(candle, avg_buy_price = 0) { 231 +async function price_comparison(candle, user_data = null,isbuying=false) {
225 - var isbuying=true; 232 + //매수한 코인이 있을 때
226 - if (avg_buy_price == 0) { 233 + if(user_data!=null) {
234 + console.log("매수 평균가 : " + user_data.avg_buy_price + ", 현재 가격 : " + candle[0].trade_price);
235 + //매수평균가가 현재 시장 가격보다 더 비쌀 경우
236 + var yield_data = (candle[0].trade_price - user_data.avg_buy_price) / user_data.avg_buy_price * 100;
237 + if (user_data.avg_buy_price > candle[0].trade_price) {
238 + if (user_data.count < 10) {
239 + transaction_coin(user_data.market, "bid", null, divided_money, "price", false)
240 + } else {
241 + transaction_coin(user_data.market, "bid", null, user_data.krw_balance, "price", false)
242 + }
243 + //매수평균가가 현재 시장 가격보다 더 쌀 경우
244 + //수수료 포함 0.5% 이상 수익중일 때
245 + } else if (yield_data>= 0.5) {
246 + //매수 count가 1회이면서 수익률이 1.5프로 이상일때 시장가 전액 매도
247 + if (user_data.count == 1 && yield_data >= 1.5) {
248 + transaction_coin(user_data.market, "ask", user_data.volume, null, "market");
249 + //전체 계좌 제산의 10프로를 제외한 나머지 코인을 매도
250 + } else {
251 + transaction_coin(user_data.market, "ask", (user_data.volume / user_data.count) * (user_data.count - 1), null, "market", false);
252 + }
253 + }
254 + //매수한 코인이 없을 때
255 + }else{
227 await Coin.findOne({ name: candle[0].market }).then(async (result) => { 256 await Coin.findOne({ name: candle[0].market }).then(async (result) => {
228 //가격이 떨어졌을때 257 //가격이 떨어졌을때
258 + //해당 코인의 count를 +1 해준다
259 + //해당 코인의 count가 3이상이면 upbit api로 매수 주문을 보낸다.
260 + var yield_data = (candle[0].trade_price - result.current_price) / result.current_price * 100;
229 if (result.current_price > candle[0].trade_price) { 261 if (result.current_price > candle[0].trade_price) {
230 - Coin.findOneAndUpdate({ name: candle[0].market }, { current_price: candle[0].trade_price, $inc: { count: 1 } }, { new: true }, (err, result) => { 262 + console.log("***" + result.korean_name + " " + candle[0].unit + "분 동안 "+yield_data.toFixed(2)+"%");
231 - if (err) { 263 + await Coin.findOneAndUpdate({ name: candle[0].market }, { current_price: candle[0].trade_price,up_count:0,$inc: { down_count: 1 }}, { new: true }).then(async (result) => {
232 - console.log(err); 264 + if (result.down_count >= 3) {
233 - } else {
234 - console.log("***" + result.korean_name + "은(는)" + result.count * 5 + "분 동안 하락중");
235 - if (result.count >= 3) {
236 transaction_coin(result.name, "bid", null, divided_money, "price"); 265 transaction_coin(result.name, "bid", null, divided_money, "price");
237 - isbuying=false;
238 } 266 }
239 - } 267 + }).catch(err=>{console.log(err)})
240 - }) 268 + //가격이 상승하거나 변동이 없을 때
241 - } else if (result.current_price < candle[0].trade_price) { 269 + //해당 코인의 count를 초기화한다.
242 - await Coin.findOneAndUpdate({ name: candle[0].market }, { current_price: candle[0].trade_price, count: 0 }, { new: true }).then(async (err, result) => { 270 + } else{
243 - if (err) { 271 + console.log(result.korean_name + " " + candle[0].unit + "분 동안"+yield_data.toFixed(2)+"%");
244 - console.log(err); 272 + await Coin.findOneAndUpdate({ name: candle[0].market }, { current_price: candle[0].trade_price, down_count: 0,$inc:{up_count:1} }, { new: true }).then(async (result) => {
245 - } else { 273 + }).catch(err=>{console.log(err);})
246 - console.log(result.korean_name + "은(는)" + result.count * 5 + "분 동안 상승 혹은 정체중");
247 - }
248 - })
249 } 274 }
250 - 275 + })
251 - })
252 - } else {
253 - if (avg_buy_price < candle[0].trade_price) {
254 - transaction_coin(candle[0].market, "bid", null, divided_money, "price", false)
255 - } else {
256 - transaction_coin(candle[0].market, "ask", "", null, "market", false);
257 - }
258 } 276 }
259 - return isbuying;
260 } 277 }
261 async function check_coin(t1) { 278 async function check_coin(t1) {
262 User.find().then(async (user_data) => { 279 User.find().then(async (user_data) => {
263 - //아직 매수한 코인이 없을 때 280 + //매수한 코인이 있을 때
264 - if (user_data.length == 0) { 281 + if(user_data.length!=0) {
265 - var isbuying = false;
266 - for (var i = 0; i < t1.length; i++) {
267 - if (isbuying) {
268 - var candle = await get_candle(5, t1[i]);
269 - isbuying=await price_comparison(candle);
270 - console.log(isbuying);
271 - }
272 - }
273 - //매수한 코인이 있을 때
274 - } else {
275 //3회 이상 매수 했을시 15분봉으로 교체해서 가격 확인 282 //3회 이상 매수 했을시 15분봉으로 교체해서 가격 확인
276 //15분봉 처리해야함 283 //15분봉 처리해야함
277 if (user_data[0].count > 3) { 284 if (user_data[0].count > 3) {
278 - var candle = await get_candle(15, user_data[0].market); 285 + setTimeout(async () => {
279 - await price_comparison(candle, user_data[0].avg_buy_price); 286 + candle = await get_candle(15, user_data[0].market);
280 - } else { 287 + }, 60000 * 10);
288 + }else{
281 var candle = await get_candle(5, user_data[0].market); 289 var candle = await get_candle(5, user_data[0].market);
282 - await price_comparison(candle, user_data[0].avg_buy_price);
283 } 290 }
291 + await price_comparison(candle, user_data[0]);
292 +
293 + }
294 + var isbuying=user_data.length==0;
295 + //코인 count and 매수 매도 작업
296 + for(var i=0;i<t1.length;i++){
297 + if(user_data[0]&&user_data[0].market!=t1[i]){
298 + break;
299 + }
300 + var candle=await get_candle(5,t1[i]);
301 + await price_comparison(candle,null,isbuying);
284 } 302 }
285 }).catch((err) => { 303 }).catch((err) => {
286 console.log(err); 304 console.log(err);
287 }) 305 })
288 -
289 } 306 }
290 async function latest_repeat(t1) { 307 async function latest_repeat(t1) {
291 let check_time = setInterval(async () => { 308 let check_time = setInterval(async () => {
292 let today = new Date(); 309 let today = new Date();
293 let minutes = today.getMinutes(); 310 let minutes = today.getMinutes();
294 let seconds = today.getSeconds(); 311 let seconds = today.getSeconds();
295 - // if (seconds == 0) { 312 + if (seconds == 0) {
296 - if (minutes == 0 && seconds == 0) { 313 + // if (minutes == 0 && seconds == 0) {
297 clearInterval(check_time); 314 clearInterval(check_time);
298 sort_info = (await sort_data()); 315 sort_info = (await sort_data());
299 (await refresh_db()); 316 (await refresh_db());
...@@ -309,13 +326,14 @@ async function latest_repeat(t1) { ...@@ -309,13 +326,14 @@ async function latest_repeat(t1) {
309 let minutes = today.getMinutes(); 326 let minutes = today.getMinutes();
310 let seconds = today.getSeconds(); 327 let seconds = today.getSeconds();
311 console.log("현재 시간은 " + today.toLocaleTimeString()); 328 console.log("현재 시간은 " + today.toLocaleTimeString());
312 - await (check_coin(t1).then(count++));
313 //1시간마다 db 최신화... 329 //1시간마다 db 최신화...
314 if (count == 12) { 330 if (count == 12) {
315 count = 0; 331 count = 0;
316 sort_info = (await sort_data()); 332 sort_info = (await sort_data());
317 (await refresh_db()); 333 (await refresh_db());
318 console.log("db최신화"); 334 console.log("db최신화");
335 + } else {
336 + await (check_coin(t1).then(count++));
319 } 337 }
320 }, 60000 * 5); 338 }, 60000 * 5);
321 } 339 }
...@@ -327,12 +345,15 @@ try { ...@@ -327,12 +345,15 @@ try {
327 key: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain + '/privkey.pem'), 'utf8').toString(), 345 key: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain + '/privkey.pem'), 'utf8').toString(),
328 cert: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain + '/cert.pem'), 'utf8').toString(), 346 cert: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain + '/cert.pem'), 'utf8').toString(),
329 }; 347 };
330 -
331 HTTPS.createServer(option, app).listen(sslport, async () => { 348 HTTPS.createServer(option, app).listen(sslport, async () => {
332 console.log(`[HTTPS] Server is started on port ${sslport}`); 349 console.log(`[HTTPS] Server is started on port ${sslport}`);
350 + // console.log(await get_asset());
351 + await get_asset().then((result) => {
352 + krw_balance = result[0].balance;
353 + divided_money = krw_balance / 10
354 + });
333 var t1 = new Array(); 355 var t1 = new Array();
334 await (latest_repeat(t1)); 356 await (latest_repeat(t1));
335 - // console.log(await get_asset());
336 }); 357 });
337 } catch (error) { 358 } catch (error) {
338 console.log('[HTTPS] HTTPS 오류가 발생하였습니다. HTTPS 서버는 실행되지 않습니다.'); 359 console.log('[HTTPS] HTTPS 오류가 발생하였습니다. HTTPS 서버는 실행되지 않습니다.');
......
...@@ -20,7 +20,11 @@ const coinSchema=mongoose.Schema({ ...@@ -20,7 +20,11 @@ const coinSchema=mongoose.Schema({
20 type:Number, 20 type:Number,
21 required:true 21 required:true
22 }, 22 },
23 - count:{ 23 + up_count:{
24 + type:Number,
25 + default:0
26 + },
27 + down_count:{
24 type:Number, 28 type:Number,
25 default:0 29 default:0
26 } 30 }
......
...@@ -11,7 +11,7 @@ const userSchema=mongoose.Schema({ ...@@ -11,7 +11,7 @@ const userSchema=mongoose.Schema({
11 type:String, 11 type:String,
12 }, 12 },
13 count:{ 13 count:{
14 - type:Number, 14 + type:Number
15 }, 15 },
16 avg_buy_price:{ 16 avg_buy_price:{
17 type:Number 17 type:Number
......