151 lines
No EOL
4 KiB
TypeScript
Executable file
151 lines
No EOL
4 KiB
TypeScript
Executable file
#!/usr/bin/env bun
|
|
|
|
/**
|
|
* Test SMA strategy directly to debug trading
|
|
*/
|
|
|
|
import { SimpleMovingAverageCrossover } from './src/strategies/examples/SimpleMovingAverageCrossover';
|
|
import { getLogger } from '@stock-bot/logger';
|
|
|
|
async function testSMAStrategy() {
|
|
console.log('=== Testing SMA Strategy Trading ===\n');
|
|
|
|
const logger = getLogger('test');
|
|
|
|
const config = {
|
|
id: 'test-sma',
|
|
name: 'Test SMA',
|
|
enabled: true,
|
|
symbols: ['AAPL'],
|
|
allocation: 1.0
|
|
};
|
|
|
|
const strategy = new SimpleMovingAverageCrossover(config, null, null);
|
|
|
|
let signalCount = 0;
|
|
let orderCount = 0;
|
|
const orders: any[] = [];
|
|
|
|
strategy.on('signal', (signal) => {
|
|
signalCount++;
|
|
console.log(`\n📊 Signal #${signalCount}:`, {
|
|
type: signal.type,
|
|
symbol: signal.symbol,
|
|
strength: signal.strength,
|
|
reason: signal.reason
|
|
});
|
|
});
|
|
|
|
strategy.on('order', (order) => {
|
|
orderCount++;
|
|
orders.push(order);
|
|
console.log(`\n📈 Order #${orderCount}:`, order);
|
|
});
|
|
|
|
await strategy.start();
|
|
|
|
// Generate clear pattern: downtrend then uptrend
|
|
console.log('Generating market data with clear trend changes...\n');
|
|
|
|
// Phase 1: Stable around 100 for first 10 days
|
|
for (let i = 0; i < 10; i++) {
|
|
const price = 100 + Math.sin(i * 0.5) * 2;
|
|
await strategy.onMarketData({
|
|
type: 'bar',
|
|
data: {
|
|
symbol: 'AAPL',
|
|
open: price,
|
|
high: price + 1,
|
|
low: price - 1,
|
|
close: price,
|
|
volume: 1000000,
|
|
timestamp: Date.now() + i * 86400000
|
|
}
|
|
});
|
|
}
|
|
|
|
// Phase 2: Clear downtrend from 100 to 80 (days 11-30)
|
|
for (let i = 10; i < 30; i++) {
|
|
const price = 100 - (i - 10); // Falls by $1 per day
|
|
await strategy.onMarketData({
|
|
type: 'bar',
|
|
data: {
|
|
symbol: 'AAPL',
|
|
open: price,
|
|
high: price + 0.5,
|
|
low: price - 0.5,
|
|
close: price,
|
|
volume: 1000000,
|
|
timestamp: Date.now() + i * 86400000
|
|
}
|
|
});
|
|
}
|
|
|
|
// Phase 3: Clear uptrend from 80 to 110 (days 31-60)
|
|
for (let i = 30; i < 60; i++) {
|
|
const price = 80 + (i - 30); // Rises by $1 per day
|
|
await strategy.onMarketData({
|
|
type: 'bar',
|
|
data: {
|
|
symbol: 'AAPL',
|
|
open: price,
|
|
high: price + 0.5,
|
|
low: price - 0.5,
|
|
close: price,
|
|
volume: 1000000,
|
|
timestamp: Date.now() + i * 86400000
|
|
}
|
|
});
|
|
|
|
// Simulate position update after first buy
|
|
if (i === 45 && orders.length > 0) {
|
|
console.log('\n🔄 Simulating position update after buy order...');
|
|
await strategy.onOrderUpdate({
|
|
orderId: 'test-order-1',
|
|
symbol: 'AAPL',
|
|
side: 'buy',
|
|
status: 'filled',
|
|
fills: [{
|
|
quantity: orders[0].quantity,
|
|
price: 95
|
|
}]
|
|
});
|
|
}
|
|
}
|
|
|
|
// Phase 4: Another downtrend from 110 to 90 (days 61-80)
|
|
for (let i = 60; i < 80; i++) {
|
|
const price = 110 - (i - 60); // Falls by $1 per day
|
|
|
|
if (i % 5 === 0) {
|
|
console.log(`\nDay ${i + 1}: Price = $${price}`);
|
|
}
|
|
|
|
await strategy.onMarketData({
|
|
type: 'bar',
|
|
data: {
|
|
symbol: 'AAPL',
|
|
open: price,
|
|
high: price + 0.5,
|
|
low: price - 0.5,
|
|
close: price,
|
|
volume: 1000000,
|
|
timestamp: Date.now() + i * 86400000
|
|
}
|
|
});
|
|
}
|
|
|
|
await strategy.stop();
|
|
|
|
console.log('\n=== Test Results ===');
|
|
console.log(`Total signals generated: ${signalCount}`);
|
|
console.log(`Total orders generated: ${orderCount}`);
|
|
console.log(`\nExpected behavior:`);
|
|
console.log(`- Golden cross around day 40-45 (when 10 SMA crosses above 20 SMA)`);
|
|
console.log(`- Death cross around day 70-75 (when 10 SMA crosses below 20 SMA)`);
|
|
|
|
const perf = strategy.getPerformance();
|
|
console.log('\nStrategy performance:', perf);
|
|
}
|
|
|
|
testSMAStrategy().catch(console.error); |