70 lines
3.0 KiB
TypeScript
70 lines
3.0 KiB
TypeScript
import { supabaseService } from '../src/services/SupabaseService.js';
|
|
import { AutoTrader } from '../src/services/AutoTrader.js';
|
|
import { TradeExecutor } from '../src/services/TradeExecutor.js';
|
|
import { AlpacaConnector } from '../src/connectors/alpaca.js';
|
|
import { config } from '../src/config/index.js';
|
|
import { SignalDirection, MarketContext, RuleResult } from '../src/strategies/rules/types.js';
|
|
import logger from '../src/utils/logger.js';
|
|
|
|
async function testProfileExecution() {
|
|
logger.info('--- PROFILE-BASED E2E TEST STARTING ---');
|
|
|
|
const profiles = await supabaseService.getActiveProfiles();
|
|
if (profiles.length === 0) {
|
|
logger.error('No profiles found.'); return;
|
|
}
|
|
|
|
const testProfile = profiles[0];
|
|
const user = testProfile.users;
|
|
const symbols = testProfile.symbols ? testProfile.symbols.split(',').map(s => s.trim()).filter(s => s !== "") : ['BTC/USDT'];
|
|
const testSymbol = symbols[0];
|
|
|
|
logger.info(`Profile: ${testProfile.name} | Symbol: ${testSymbol} | Capital: ${testProfile.allocated_capital}`);
|
|
|
|
const userKey = config.PAPER_TRADING ? user.ALPACA_API_KEY : user.REAL_ALPACA_API_KEY;
|
|
const userSecret = config.PAPER_TRADING ? user.ALPACA_SECRET_KEY : user.REAL_ALPACA_SECRET_KEY;
|
|
const exchange = new AlpacaConnector(userKey, userSecret);
|
|
const executor = new TradeExecutor(exchange, undefined, user.user_id, testProfile.id);
|
|
|
|
// IMPORTANT: Inject global config for trading enabled
|
|
config.ENABLE_TRADING = true;
|
|
|
|
const trader = new AutoTrader(
|
|
executor,
|
|
exchange,
|
|
parseFloat(testProfile.allocated_capital.toString()),
|
|
parseFloat(testProfile.risk_per_trade_percent?.toString() || '1'),
|
|
symbols
|
|
);
|
|
|
|
const mockResult: RuleResult = {
|
|
ruleName: 'TEST', passed: true, signal: SignalDirection.BUY, reason: 'E2E_TEST', metadata: {}
|
|
};
|
|
|
|
const mockContext: MarketContext = {
|
|
symbol: testSymbol, currentPrice: 50000, candles1h: [], candles15m: [], candles4h: [],
|
|
rsi_1h: 40, ema20_1h: 49000, change24h: 2, changeToday: 1, volatility: 'Low', session: 'NY',
|
|
isMajorSession: true, latestSignal: SignalDirection.NONE
|
|
};
|
|
|
|
logger.info('Simulating Signal...');
|
|
await trader.handleSignal(testSymbol, mockResult, mockContext);
|
|
|
|
const pos = executor.getActivePosition(testSymbol);
|
|
if (pos) {
|
|
logger.info(`✅ SUCCESS: Position found! ProfileID: ${pos.profileId} | Qty: ${pos.size}`);
|
|
await executor.closePosition(testSymbol, 'E2E CLEANUP');
|
|
} else {
|
|
logger.error('❌ FAILED: Position not created. Checking why...');
|
|
// Manually try openPosition to see exchange error
|
|
const direct = await executor.openPosition(testSymbol, SignalDirection.BUY, 0.001);
|
|
if (!direct.success) {
|
|
logger.error(`Direct Open Error: ${direct.error}`);
|
|
} else {
|
|
logger.info('Direct open worked. Something is wrong in AutoTrader logic.');
|
|
}
|
|
}
|
|
}
|
|
|
|
testProfileExecution().catch(console.error);
|