uphold/src/bot.js
2025-11-27 14:41:21 +00:00

82 lines
2 KiB
JavaScript

import { fetchRate } from "./api.js";
import { insertIntoDB } from "./db.js";
export class Bot {
constructor(pair, interval, threshold) {
this.pair = pair;
this.interval = interval;
this.threshold = threshold;
this.lastPrice = null;
this.running = null;
this.timer = null;
}
start() {
if (!this.running) {
this.running = true;
console.log(`[STARTED] Monitoring ${this.pair}`);
this.check().catch((err) =>
console.error(
`[ERROR] Initialization failed for ${this.pair}: ${err.message}`,
),
);
this.timer = setInterval(async () => {
try {
await this.check();
} catch (err) {
console.error(`[ERROR] ${this.pair}: ${err.message}`);
}
}, this.interval);
}
}
stop() {
this.isRunning = false;
if (this.timer) {
clearInterval(this.timer);
}
}
async check() {
const currentPrice = await fetchRate(this.pair);
if (!this.lastPrice) {
this.lastPrice = currentPrice;
console.log(`[INIT] ${this.pair} set to ${currentPrice.toFixed(2)}`);
return;
}
const diff = currentPrice.minus(this.lastPrice);
const percentDiff = diff.dividedBy(this.lastPrice).multipliedBy(100);
if (percentDiff.abs().gte(this.threshold)) {
const direction = diff.isPositive() ? "UP" : "DOWN";
const priceStr = currentPrice.toFixed(2);
const prevPriceStr = this.lastPrice.toFixed(2);
const pctNum = percentDiff.toNumber();
this.alert(direction, priceStr, pctNum);
insertIntoDB({
pair: this.pair,
direction,
previousPrice: prevPriceStr,
newPrice: priceStr,
percentChange: pctNum,
interval: this.interval,
threshold: this.threshold,
});
this.lastPrice = currentPrice;
}
}
alert(direction, priceStr, percentChange) {
const sign = direction === "UP" ? "+" : "-";
console.log(
`[ALERT] ${this.pair} ${direction} ${sign}${percentChange.toFixed(2)}% | Price: ${priceStr}`,
);
}
}