Bot & Automation
Treding Forex Ai
/root/hermes-projects/Treding Forex Ai
dist/src/services/safetyFilter.js
text
"use strict";
/**
* Safety Filter — dijalankan sebelum setiap scan auto-trading.
*
* Filter ini memastikan bot tidak entry saat kondisi pasar berbahaya:
* - Spread terlalu lebar (volatilitas ekstrem)
* - Market sedang dalam rollover window (XAUUSD: 23:00–01:00 UTC)
* - Daily loss sudah melebihi batas maksimum
* - Sudah ada open posisi untuk simbol yang sama
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.SafetyFilter = void 0;
class SafetyFilter {
config;
constructor(config) {
this.config = config;
}
updateConfig(newConfig) {
Object.assign(this.config, newConfig);
}
/**
* Cek semua kondisi keamanan.
* @param symbolCode Kode simbol yang akan di-scan
* @param currentSpreadPips Spread saat ini dalam pips
* @param todayLossAmount Total kerugian hari ini (positif = rugi)
* @param openPositionCount Jumlah posisi terbuka untuk simbol ini
*/
check(symbolCode, currentSpreadPips, todayLossAmount, openPositionCount) {
const reasons = [];
// 1. Spread check
if (currentSpreadPips > this.config.maxSpreadPips) {
reasons.push(`Spread ${currentSpreadPips.toFixed(1)} pips melebihi batas ${this.config.maxSpreadPips} pips — pasar terlalu volatile.`);
}
// 2. Rollover window check (berlaku untuk semua simbol forex/gold)
if (this.config.skipRolloverWindow && isRolloverWindow()) {
reasons.push(`Market sedang dalam rollover window (23:00–01:00 UTC) — skip entry ${symbolCode}.`);
}
// 3. Daily loss limit check (hanya aktif jika maxDailyLossAmount > 0)
if (this.config.maxDailyLossAmount > 0 && todayLossAmount >= this.config.maxDailyLossAmount) {
reasons.push(`Daily loss ${todayLossAmount.toFixed(2)} sudah mencapai batas ${this.config.maxDailyLossAmount.toFixed(2)} — trading dihentikan hari ini.`);
}
// 4. Open position limit untuk simbol ini (0 = tidak ada batas)
const maxPos = this.config.maxOpenPositions;
if (maxPos > 0 && openPositionCount >= maxPos) {
reasons.push(`Sudah ada ${openPositionCount} posisi terbuka untuk ${symbolCode} (maks ${maxPos}) — skip entry baru.`);
}
return {
safe: reasons.length === 0,
reasons
};
}
/**
* Estimasi spread saat ini dari data candle terakhir (ATR-based).
* Jika tidak ada data live, gunakan defaultSpreadPips dari symbol config.
* @param atr Average True Range dari candle terakhir
* @param pipSize Ukuran 1 pip untuk simbol ini
* @param defaultSpreadPips Spread default jika ATR tidak tersedia
*/
static estimateSpreadPips(atr, pipSize, defaultSpreadPips) {
if (atr <= 0 || pipSize <= 0) {
return defaultSpreadPips;
}
// ATR yang sangat tinggi biasanya terjadi saat spread melebar juga
// Gunakan 5% dari ATR sebagai estimasi spread dalam pips
const atrBasedEstimate = (atr * 0.05) / pipSize;
return Math.max(atrBasedEstimate, defaultSpreadPips);
}
}
exports.SafetyFilter = SafetyFilter;
/**
* Cek apakah sekarang adalah rollover window XAUUSD/Forex.
* Rollover terjadi antara 23:00–01:00 UTC setiap hari kerja.
*/
function isRolloverWindow() {
const now = new Date();
const hourUtc = now.getUTCHours();
const minuteUtc = now.getUTCMinutes();
const decimalHour = hourUtc + minuteUtc / 60;
// 23:00 UTC hingga 01:00 UTC (melewati tengah malam)
return decimalHour >= 23 || decimalHour < 1;
}