skayn-trading-sdk
Version:
Professional Bitcoin trading strategy backtesting framework with institutional-grade architecture
146 lines (123 loc) • 5.1 kB
JavaScript
const { SDK } = require('../index');
describe('Skayn SDK Comprehensive Tests', () => {
test('P&L calculation accuracy', async () => {
const testStrategy = SDK.strategy(async (data) => {
if (data.length > 0) {
return { action: 'BUY', confidence: 0.8, quantity: 0.001, strategy: 'test' };
}
return { action: 'HOLD', confidence: 0, strategy: 'test' };
});
// Mock data with known price movement for P&L validation
const mockData = [
{ timestamp: Date.now() - 3600000, open: 50000, high: 50500, low: 49500, close: 50000, volume: 100 },
{ timestamp: Date.now(), open: 50000, high: 55000, low: 50000, close: 55000, volume: 120 } // 10% gain
];
const mockDataProvider = SDK.dataProvider(async () => mockData);
const results = await SDK.create()
.strategy(testStrategy)
.dataProvider(mockDataProvider)
.backtest({
startDate: '2024-01-01',
endDate: '2024-01-02',
initialBalance: 1000000 // 1M sats
});
expect(results).toBeDefined();
// With a 10% price increase, should see some positive movement (but may not be exactly 10% due to fees)
expect(results.finalBalance).toBeGreaterThanOrEqual(results.initialBalance);
expect(results.totalReturn).toBeGreaterThanOrEqual(-1); // Allow for small losses due to fees
}, 10000);
test('Risk management position sizing', async () => {
const aggressiveStrategy = SDK.strategy(async (data) => {
return { action: 'BUY', confidence: 0.9, quantity: 0.1, strategy: 'enhanced' }; // Large position
});
const mockData = [
{ timestamp: Date.now(), open: 50000, high: 50500, low: 49500, close: 50000, volume: 100 }
];
const mockDataProvider = SDK.dataProvider(async () => mockData);
const results = await SDK.create()
.strategy(aggressiveStrategy)
.dataProvider(mockDataProvider)
.backtest({
startDate: '2024-01-01',
endDate: '2024-01-02',
initialBalance: 100000 // Small portfolio
});
// Risk management should limit position size for small portfolios
expect(results).toBeDefined();
// Should not allow excessive leverage on small portfolios
}, 10000);
test('Strategy metadata completeness', () => {
const testStrategy = SDK.strategy(async (data) => {
return { action: 'HOLD', confidence: 0.5, strategy: 'test' };
}, {
name: 'Test Strategy',
version: '1.0.0',
description: 'Test strategy for validation'
});
const metadata = testStrategy.getStrategyMetadata();
expect(metadata.name).toBe('Test Strategy');
expect(metadata.version).toBe('1.0.0');
expect(metadata.description).toBe('Test strategy for validation');
});
test('Data provider error handling', async () => {
const failingProvider = SDK.dataProvider(async () => {
throw new Error('Network error');
});
const testStrategy = SDK.strategy(async () => ({ action: 'HOLD', confidence: 0 }));
// Should handle data provider failures gracefully
await expect(
SDK.create()
.strategy(testStrategy)
.dataProvider(failingProvider)
.backtest({
startDate: '2024-01-01',
endDate: '2024-01-02',
initialBalance: 10000
})
).rejects.toThrow();
});
test('Multiple strategy comparison', async () => {
const conservativeStrategy = SDK.strategy(async (data) => {
if (data.length > 10) {
return { action: 'BUY', confidence: 0.6, strategy: 'conservative' };
}
return { action: 'HOLD', confidence: 0.3, strategy: 'conservative' };
});
const aggressiveStrategy = SDK.strategy(async (data) => {
if (data.length > 5) {
return { action: 'BUY', confidence: 0.9, strategy: 'enhanced' };
}
return { action: 'HOLD', confidence: 0.1, strategy: 'enhanced' };
});
const trendData = Array.from({ length: 20 }, (_, i) => ({
timestamp: Date.now() - (20 - i) * 3600000,
open: 50000 + i * 100,
high: 50100 + i * 100,
low: 49900 + i * 100,
close: 50000 + i * 100,
volume: 100
}));
const mockDataProvider = SDK.dataProvider(async () => trendData);
const conservativeResults = await SDK.create()
.strategy(conservativeStrategy)
.dataProvider(mockDataProvider)
.backtest({
startDate: '2024-01-01',
endDate: '2024-01-02',
initialBalance: 1000000
});
const aggressiveResults = await SDK.create()
.strategy(aggressiveStrategy)
.dataProvider(mockDataProvider)
.backtest({
startDate: '2024-01-01',
endDate: '2024-01-02',
initialBalance: 1000000
});
expect(conservativeResults).toBeDefined();
expect(aggressiveResults).toBeDefined();
// Both should be profitable in uptrend, but with different risk profiles
expect(conservativeResults.totalReturn).toBeGreaterThan(-50); // Reasonable loss limit
expect(aggressiveResults.totalReturn).toBeGreaterThan(-50);
}, 15000);
});