institutional-trader/backend/src/routes/reversals.js

75 lines
1.9 KiB
JavaScript

import express from 'express';
import { detectReversals } from '../services/reversalDetector.js';
import { rawQuery } from '../db.js';
const router = express.Router();
/**
* GET /api/reversals/detect
* Detects flow reversals for given symbols or all active symbols
* Query params:
* - symbols: comma-separated list of symbols (optional)
*/
router.get('/detect', async (req, res) => {
try {
const { symbols } = req.query; // comma-separated symbols
let symbolList = [];
if (symbols) {
symbolList = symbols.split(',').map(s => s.trim().toUpperCase()).filter(Boolean);
} else {
// Get symbols with flow in last hour
symbolList = await getActiveSymbols();
}
if (symbolList.length === 0) {
return res.json({
success: true,
reversals: [],
count: 0,
timestamp: new Date().toISOString()
});
}
const reversals = await detectReversals(symbolList);
res.json({
success: true,
reversals,
count: reversals.length,
timestamp: new Date().toISOString()
});
} catch (error) {
console.error('Reversal detection error:', error);
res.status(500).json({
success: false,
error: error.message,
timestamp: new Date().toISOString()
});
}
});
/**
* Get active symbols (symbols with flow in last hour)
*/
async function getActiveSymbols() {
try {
// Get active symbols from OptionsFlow_monthly
const query = `
SELECT DISTINCT UPPER(TRIM("Symbol")) as symbol_norm
FROM public."OptionsFlow_monthly"
WHERE ("CreatedDate" || ' ' || COALESCE("CreatedTime", '00:00:00'))::timestamp >= NOW() - INTERVAL '1 hour'
ORDER BY UPPER(TRIM("Symbol"))
LIMIT 100
`;
const results = await rawQuery(query);
return results.map(r => r.symbol_norm).filter(Boolean);
} catch (error) {
console.error('Error getting active symbols:', error);
return [];
}
}
export default router;