Files
trading_bot_v4/tests/integration/position-manager/tp1-detection.test.ts
copilot-swe-agent[bot] 1b6297b1e2 chore: Fix .gitignore - remove test file exclusions, add coverage folder
- Removed incorrect exclusion of *.test.ts and *.test.js files
- Added coverage/ folder to .gitignore
- Removed accidentally committed coverage files

Co-authored-by: mindesbunister <32161838+mindesbunister@users.noreply.github.com>
2025-12-05 00:16:50 +00:00

178 lines
6.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* TP1 Detection Tests
*
* Tests for Take Profit 1 detection in Position Manager.
* TP1 is calculated as ATR × 2.0 (typically ~0.86% at ATR 0.43)
*
* Key behaviors tested:
* - LONG: TP1 triggers when price >= tp1Price
* - SHORT: TP1 triggers when price <= tp1Price
* - Must NOT trigger below threshold
* - Must NOT trigger when price moves against position
*/
import {
createLongTrade,
createShortTrade,
TEST_DEFAULTS,
calculateExpectedProfitPercent
} from '../../helpers/trade-factory'
describe('TP1 Detection', () => {
// Test the shouldTakeProfit1 logic extracted from Position Manager
// We test the pure calculation logic rather than the full Position Manager
function shouldTakeProfit1(price: number, trade: { direction: 'long' | 'short', tp1Price: number }): boolean {
if (trade.direction === 'long') {
return price >= trade.tp1Price
} else {
return price <= trade.tp1Price
}
}
describe('LONG positions', () => {
it('should detect TP1 when price reaches +0.86% (ATR 0.43 × 2.0)', () => {
// Test data: entry $140, TP1 at $141.20 (+0.86%)
const trade = createLongTrade()
expect(trade.tp1Price).toBe(TEST_DEFAULTS.long.tp1)
// Price at TP1 should trigger
const result = shouldTakeProfit1(141.20, trade)
expect(result).toBe(true)
// Verify profit calculation
const profitPercent = calculateExpectedProfitPercent(140, 141.20, 'long')
expect(profitPercent).toBeCloseTo(0.857, 1) // ~0.86%
})
it('should detect TP1 when price exceeds tp1Price', () => {
const trade = createLongTrade()
// Price above TP1 should also trigger
const result = shouldTakeProfit1(142.00, trade)
expect(result).toBe(true)
})
it('should NOT detect TP1 when price is below threshold (+0.5%)', () => {
const trade = createLongTrade()
// Price at +0.5% ($140.70) should NOT trigger TP1
const result = shouldTakeProfit1(140.70, trade)
expect(result).toBe(false)
// Verify profit percent is below TP1 threshold
const profitPercent = calculateExpectedProfitPercent(140, 140.70, 'long')
expect(profitPercent).toBeCloseTo(0.5, 2)
expect(profitPercent).toBeLessThan(0.86)
})
it('should NOT detect TP1 when price moves against position (negative)', () => {
const trade = createLongTrade()
// Price drop for LONG should NOT trigger TP1
const result = shouldTakeProfit1(139.00, trade)
expect(result).toBe(false)
// Verify this is a loss
const profitPercent = calculateExpectedProfitPercent(140, 139.00, 'long')
expect(profitPercent).toBeLessThan(0)
})
it('should NOT detect TP1 at entry price', () => {
const trade = createLongTrade()
const result = shouldTakeProfit1(140.00, trade)
expect(result).toBe(false)
})
})
describe('SHORT positions', () => {
it('should detect TP1 when price reaches -0.86% (ATR 0.43 × 2.0)', () => {
// Test data: entry $140, TP1 at $138.80 (-0.86%)
const trade = createShortTrade()
expect(trade.tp1Price).toBe(TEST_DEFAULTS.short.tp1)
// Price at TP1 should trigger
const result = shouldTakeProfit1(138.80, trade)
expect(result).toBe(true)
// Verify profit calculation (SHORT profits when price drops)
const profitPercent = calculateExpectedProfitPercent(140, 138.80, 'short')
expect(profitPercent).toBeCloseTo(0.857, 1) // ~0.86%
})
it('should detect TP1 when price is below tp1Price', () => {
const trade = createShortTrade()
// Price below TP1 should also trigger (better for short)
const result = shouldTakeProfit1(138.00, trade)
expect(result).toBe(true)
})
it('should NOT detect TP1 when price is above threshold (-0.5%)', () => {
const trade = createShortTrade()
// Price at -0.5% ($139.30) should NOT trigger TP1
const result = shouldTakeProfit1(139.30, trade)
expect(result).toBe(false)
// Verify profit percent is below TP1 threshold
const profitPercent = calculateExpectedProfitPercent(140, 139.30, 'short')
expect(profitPercent).toBeCloseTo(0.5, 2)
expect(profitPercent).toBeLessThan(0.86)
})
it('should NOT detect TP1 when price moves against position (rises)', () => {
const trade = createShortTrade()
// Price rise for SHORT should NOT trigger TP1
const result = shouldTakeProfit1(141.00, trade)
expect(result).toBe(false)
// Verify this is a loss for SHORT
const profitPercent = calculateExpectedProfitPercent(140, 141.00, 'short')
expect(profitPercent).toBeLessThan(0)
})
it('should NOT detect TP1 at entry price', () => {
const trade = createShortTrade()
const result = shouldTakeProfit1(140.00, trade)
expect(result).toBe(false)
})
})
describe('Edge cases', () => {
it('should handle exact TP1 price (boundary condition)', () => {
const longTrade = createLongTrade()
const shortTrade = createShortTrade()
// Exact TP1 price should trigger
expect(shouldTakeProfit1(longTrade.tp1Price, longTrade)).toBe(true)
expect(shouldTakeProfit1(shortTrade.tp1Price, shortTrade)).toBe(true)
})
it('should handle custom TP1 prices', () => {
const trade = createLongTrade({ tp1Price: 145.00 })
expect(trade.tp1Price).toBe(145.00)
expect(shouldTakeProfit1(144.99, trade)).toBe(false)
expect(shouldTakeProfit1(145.00, trade)).toBe(true)
expect(shouldTakeProfit1(145.01, trade)).toBe(true)
})
it('should work with different entry prices', () => {
// ETH-PERP style entry at $3500
const trade = createLongTrade({
entryPrice: 3500,
tp1Price: 3530, // +0.86%
})
expect(shouldTakeProfit1(3529, trade)).toBe(false)
expect(shouldTakeProfit1(3530, trade)).toBe(true)
})
})
})