- Added explanation for logger mocking in tests/setup.ts - Removed test files from coverage collection in jest.config.js - Updated tests/README.md to clarify coverage approach and remove outdated threshold reference Co-authored-by: mindesbunister <32161838+mindesbunister@users.noreply.github.com>
225 lines
7.0 KiB
Markdown
225 lines
7.0 KiB
Markdown
# Position Manager Tests
|
|
|
|
## Overview
|
|
|
|
Comprehensive integration test suite for the Position Manager (`lib/trading/position-manager.ts`), which manages ~1,938 lines of critical trading logic handling real capital.
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# Run all tests
|
|
npm test
|
|
|
|
# Run tests in watch mode (development)
|
|
npm run test:watch
|
|
|
|
# Run tests with coverage report
|
|
npm run test:coverage
|
|
|
|
# Run tests for CI (with JUnit reporter)
|
|
npm run test:ci
|
|
```
|
|
|
|
## Test Structure
|
|
|
|
```
|
|
tests/
|
|
├── setup.ts # Global test configuration and mocks
|
|
├── helpers/
|
|
│ └── trade-factory.ts # Factory functions for creating mock trades
|
|
├── integration/
|
|
│ └── position-manager/
|
|
│ ├── tp1-detection.test.ts # Take Profit 1 detection tests
|
|
│ ├── breakeven-sl.test.ts # Breakeven SL after TP1 tests
|
|
│ ├── adx-runner-sl.test.ts # ADX-based runner SL tests
|
|
│ ├── trailing-stop.test.ts # Trailing stop functionality tests
|
|
│ ├── edge-cases.test.ts # Edge cases and common pitfalls
|
|
│ ├── price-verification.test.ts # Price verification before TP flags
|
|
│ └── decision-helpers.test.ts # Decision helper function tests
|
|
└── README.md # This file
|
|
```
|
|
|
|
## Test Coverage
|
|
|
|
These tests verify the **logic** of Position Manager functions in isolation:
|
|
|
|
- Decision helper functions (shouldStopLoss, shouldTakeProfit1, etc.)
|
|
- Price calculation functions (calculatePrice, calculateProfitPercent)
|
|
- ADX-based SL positioning logic
|
|
- Trailing stop mechanics
|
|
- Token vs USD conversion requirements
|
|
- Price verification requirements
|
|
|
|
**Note:** Coverage metrics are calculated against `lib/trading/position-manager.ts` but will be low because tests extract and validate logic patterns without importing the file directly. This avoids complex mocking while still validating critical trading logic.
|
|
|
|
The tests extract and validate the pure calculation logic without importing the actual Position Manager, avoiding complex mocking of:
|
|
- Drift blockchain connections
|
|
- Pyth price feeds
|
|
- Database operations
|
|
- WebSocket subscriptions
|
|
|
|
This approach:
|
|
1. Validates critical trading logic is correct
|
|
2. Prevents regression of known bugs (Common Pitfalls)
|
|
3. Enables safe refactoring of calculation functions
|
|
4. Runs quickly without external dependencies
|
|
|
|
## Test Data Standards
|
|
|
|
All tests use standardized test data based on actual trading conditions:
|
|
|
|
```typescript
|
|
TEST_DEFAULTS = {
|
|
entry: 140.00, // Entry price
|
|
atr: 0.43, // ATR value
|
|
adx: 26.9, // ADX (strong trend)
|
|
qualityScore: 95, // Signal quality
|
|
positionSize: 8000, // Position size USD
|
|
leverage: 15, // Leverage multiplier
|
|
|
|
// LONG targets
|
|
long: {
|
|
tp1: 141.20, // +0.86%
|
|
tp2: 142.41, // +1.72%
|
|
sl: 138.71, // -0.92%
|
|
emergencySl: 137.20, // -2%
|
|
},
|
|
|
|
// SHORT targets
|
|
short: {
|
|
tp1: 138.80, // -0.86%
|
|
tp2: 137.59, // -1.72%
|
|
sl: 141.29, // +0.92%
|
|
emergencySl: 142.80, // +2%
|
|
},
|
|
}
|
|
```
|
|
|
|
## Common Pitfalls Covered
|
|
|
|
These tests specifically prevent known bugs documented in the codebase:
|
|
|
|
| Pitfall # | Issue | Test File |
|
|
|-----------|--------------------------------------------|-----------------------------|
|
|
| #24 | Position.size as tokens, not USD | edge-cases.test.ts |
|
|
| #43 | TP1 false detection without price check | price-verification.test.ts |
|
|
| #45 | Wrong entry price for breakeven SL | breakeven-sl.test.ts |
|
|
| #52 | ADX-based runner SL positioning | adx-runner-sl.test.ts |
|
|
| #54 | MAE/MFE as percentages, not dollars | edge-cases.test.ts |
|
|
| #67 | Duplicate closures (atomic deduplication) | Covered by mock structure |
|
|
|
|
## Test Helpers
|
|
|
|
### Trade Factory (`tests/helpers/trade-factory.ts`)
|
|
|
|
```typescript
|
|
import { createLongTrade, createShortTrade, createTradeAfterTP1, createTradeAfterTP2 } from '../helpers/trade-factory'
|
|
|
|
// Create a basic LONG trade
|
|
const longTrade = createLongTrade()
|
|
|
|
// Create a SHORT trade with custom entry
|
|
const shortTrade = createShortTrade({ entryPrice: 150 })
|
|
|
|
// Create a trade after TP1 hit (40% runner remaining)
|
|
const runnerTrade = createTradeAfterTP1('long')
|
|
|
|
// Create a trade with trailing stop active
|
|
const trailingTrade = createTradeAfterTP2('short')
|
|
```
|
|
|
|
### Custom Matchers
|
|
|
|
```typescript
|
|
// Check if value is within a range
|
|
expect(0.86).toBeWithinRange(0.8, 0.9) // passes
|
|
```
|
|
|
|
## Why These Tests Matter
|
|
|
|
1. **Financial Protection**: Position Manager handles real money ($540+ capital). Bugs cost real dollars.
|
|
|
|
2. **Regression Prevention**: 71+ documented bugs in the codebase. Tests prevent reintroduction.
|
|
|
|
3. **Safe Refactoring**: With test coverage, code can be improved without fear of breaking existing functionality.
|
|
|
|
4. **Documentation**: Tests serve as executable documentation of expected behavior.
|
|
|
|
5. **CI/CD Pipeline**: Automated testing ensures changes don't break critical trading logic.
|
|
|
|
## Writing New Tests
|
|
|
|
### Guidelines
|
|
|
|
1. **Use Factories**: Always use `createLongTrade()` or `createShortTrade()` instead of manual object creation
|
|
2. **Test Both Directions**: Every price-based test should cover both LONG and SHORT positions
|
|
3. **Test Edge Cases**: Include boundary conditions and error scenarios
|
|
4. **Clear Names**: Test names should describe the exact behavior being tested
|
|
5. **Reference Pitfalls**: When testing a known bug, reference the pitfall number in comments
|
|
|
|
### Example Test
|
|
|
|
```typescript
|
|
import { createLongTrade, createShortTrade, TEST_DEFAULTS } from '../../helpers/trade-factory'
|
|
|
|
describe('New Feature', () => {
|
|
it('should handle LONG position correctly', () => {
|
|
const trade = createLongTrade()
|
|
// ... test logic
|
|
expect(result).toBe(expected)
|
|
})
|
|
|
|
it('should handle SHORT position correctly', () => {
|
|
const trade = createShortTrade()
|
|
// ... test logic
|
|
expect(result).toBe(expected)
|
|
})
|
|
|
|
// Reference known bugs
|
|
it('should NOT trigger false positive (Pitfall #XX)', () => {
|
|
// ... regression test
|
|
})
|
|
})
|
|
```
|
|
|
|
## Mocked Dependencies
|
|
|
|
The test setup mocks external dependencies to isolate tests:
|
|
|
|
- **Drift Service**: No actual blockchain calls
|
|
- **Pyth Price Monitor**: No WebSocket connections
|
|
- **Database Operations**: No actual DB queries
|
|
- **Telegram Notifications**: No actual messages sent
|
|
- **Drift Orders**: No actual order placement
|
|
|
|
## Running Specific Tests
|
|
|
|
```bash
|
|
# Run a specific test file
|
|
npm test -- tests/integration/position-manager/tp1-detection.test.ts
|
|
|
|
# Run tests matching a pattern
|
|
npm test -- --testNamePattern="LONG"
|
|
|
|
# Run tests in a specific directory
|
|
npm test -- tests/integration/position-manager/
|
|
```
|
|
|
|
## CI Integration
|
|
|
|
Tests run automatically in CI with:
|
|
- JUnit XML reports for test results
|
|
- Coverage reports in HTML and text formats
|
|
|
|
Run tests with coverage report:
|
|
|
|
```bash
|
|
npm run test:coverage
|
|
```
|
|
|
|
Run tests in CI mode with JUnit reporter:
|
|
|
|
```bash
|
|
npm run test:ci
|
|
```
|