update
This commit is contained in:
parent
e45c62215e
commit
d8f8b04943
15 changed files with 458 additions and 162 deletions
|
|
@ -1,25 +1,94 @@
|
|||
import schedule from 'node-schedule';
|
||||
import * as indicatorService from '../services/indicatorService';
|
||||
import { IndicatorService } from '../services/indicatorService';
|
||||
import { BybitService } from '../services/bybitService';
|
||||
import { KlineIntervalV3 } from 'bybit-api';
|
||||
import { sendLarkMessage } from '../services/messageService';
|
||||
import { Candle } from '../dao/candles';
|
||||
import { Order } from '../dao/order';
|
||||
|
||||
// Hàm thực hiện phân tích nến
|
||||
async function analyzeCandlesJob(symbol: string, interval: KlineIntervalV3) {
|
||||
const bybitService = new BybitService(process.env.BYBIT_API_KEY!, process.env.BYBIT_API_SECRET!, false);
|
||||
// TODO: Lấy client thật nếu cần
|
||||
const candles = await bybitService.getCandles({ symbol, interval, category: 'linear', limit: 200 });
|
||||
const analysis = indicatorService.analyze(candles);
|
||||
await sendLarkMessage('oc_f9b2e8f0309ecab0c94e3e134b0ddd29', JSON.stringify(analysis));
|
||||
// Có thể gửi kết quả qua Lark, lưu DB, ...
|
||||
const indicatorService = new IndicatorService();
|
||||
const bybitService = new BybitService(process.env.BYBIT_API_KEY!, process.env.BYBIT_API_SECRET!, false);
|
||||
|
||||
function sendMessage(message: string) {
|
||||
sendLarkMessage('oc_f9b2e8f0309ecab0c94e3e134b0ddd29', message);
|
||||
}
|
||||
|
||||
// Lập lịch chạy vào 00:00 mỗi ngày
|
||||
const rule = new schedule.RecurrenceRule();
|
||||
rule.minute = [4, 9, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59];
|
||||
rule.second = 59;
|
||||
// Hàm thực hiện phân tích nến
|
||||
export async function analyzeCandlesJob(symbol: string, interval: KlineIntervalV3, end?: number) {
|
||||
// TODO: Lấy client thật nếu cần
|
||||
const candles = await bybitService.getCandles({ symbol, interval, category: 'linear', limit: 500, end });
|
||||
const wave = await indicatorService.getWave(symbol, interval);
|
||||
console.log(wave);
|
||||
const analysis= indicatorService.analyze(candles, wave);
|
||||
indicatorService.handleEvent(analysis, candles, {
|
||||
onBuy: (order: Order, reason: string) => {
|
||||
sendMessage(`Buy ${symbol} ${interval}M ${reason}
|
||||
symbol: ${order.symbol}
|
||||
side: ${order.side}
|
||||
entry: ${order.entry}
|
||||
stopLoss: ${order.stopLoss}
|
||||
volume: ${order.volume}
|
||||
reason: ${reason}
|
||||
`);
|
||||
console.log(`Buy ${symbol} ${interval}M ${reason} ${candles[0].time}`);
|
||||
},
|
||||
onSell: (order: Order, reason: string) => {
|
||||
sendMessage(`Sell ${symbol} ${interval}M ${reason}
|
||||
symbol: ${order.symbol}
|
||||
side: ${order.side}
|
||||
entry: ${order.entry}
|
||||
stopLoss: ${order.stopLoss}
|
||||
volume: ${order.volume}
|
||||
reason: ${reason}
|
||||
`);
|
||||
console.log(`Sell ${symbol} ${interval}M ${reason} ${candles[0].time}`);
|
||||
},
|
||||
onEvent: (data: any, eventType: string) => {
|
||||
sendMessage(`${eventType} ${symbol} ${interval}M ${data.close}`)
|
||||
console.log(`${eventType} ${symbol} ${interval}M ${JSON.stringify(data)}`);
|
||||
},
|
||||
});
|
||||
analysis.symbol = symbol;
|
||||
analysis.interval = interval;
|
||||
console.log(analysis);
|
||||
await indicatorService.upsertWave({
|
||||
symbol,
|
||||
interval,
|
||||
trend: analysis.emaDirection as 'Bullish' | 'Bearish',
|
||||
numberTouchEma: analysis.numberTouch200,
|
||||
numberMacdCrossUp: analysis.numberMacdCrossUp,
|
||||
numberMacdCrossDown: analysis.numberMacdCrossDown,
|
||||
lowOrHighPrice: analysis.lowHight,
|
||||
});
|
||||
}
|
||||
|
||||
schedule.scheduleJob(rule, () => {
|
||||
// Có thể lặp qua nhiều symbol/interval nếu muốn
|
||||
analyzeCandlesJob('BTCUSDT', '5');
|
||||
});
|
||||
export function createCandleAnalysisSchedule(symbol: string, interval: KlineIntervalV3) {
|
||||
const rule = new schedule.RecurrenceRule();
|
||||
rule.tz = 'Asia/Ho_Chi_Minh';
|
||||
switch (interval) {
|
||||
case '5':
|
||||
rule.minute = [4, 9, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59];
|
||||
break;
|
||||
case '15':
|
||||
rule.minute = [14, 29, 44, 59];
|
||||
break;
|
||||
case '30':
|
||||
rule.minute = [29, 59];
|
||||
break;
|
||||
case '60':
|
||||
rule.minute = [59];
|
||||
break;
|
||||
case '240':
|
||||
rule.minute = [59];
|
||||
rule.hour = [2, 6, 10, 14, 18, 22];
|
||||
break;
|
||||
case 'D':
|
||||
rule.minute = [59];
|
||||
rule.hour = [6];
|
||||
break;
|
||||
}
|
||||
rule.second = 59;
|
||||
schedule.scheduleJob(rule, () => {
|
||||
analyzeCandlesJob(symbol, interval);
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue