brighter-trading/tests/test_paper_trading.py

252 lines
7.4 KiB
Python

"""
Tests for paper trading functionality.
"""
import pytest
from paper_strategy_instance import PaperStrategyInstance
from brokers import OrderSide, OrderType, OrderStatus
class TestPaperStrategyInstance:
"""Tests for PaperStrategyInstance."""
def test_create_instance(self):
"""Test creating a paper strategy instance."""
instance = PaperStrategyInstance(
strategy_instance_id='test-instance-1',
strategy_id='test-strategy-1',
strategy_name='Test Strategy',
user_id=1,
generated_code='def next(self): pass',
data_cache=None,
indicators=None,
trades=None,
initial_balance=10000.0,
)
assert instance.strategy_instance_id == 'test-instance-1'
assert instance.starting_balance == 10000.0
assert instance.get_current_balance() == 10000.0
assert instance.get_available_balance() == 10000.0
def test_update_prices(self):
"""Test updating prices in paper broker."""
instance = PaperStrategyInstance(
strategy_instance_id='test-1',
strategy_id='strat-1',
strategy_name='Test',
user_id=1,
generated_code='def next(self): pass',
data_cache=None,
indicators=None,
trades=None,
)
instance.update_prices({'BTC/USDT': 50000.0, 'ETH/USDT': 3000.0})
assert instance.get_current_price(symbol='BTC/USDT') == 50000.0
assert instance.get_current_price(symbol='ETH/USDT') == 3000.0
def test_trade_order_market_buy(self):
"""Test placing a market buy order."""
instance = PaperStrategyInstance(
strategy_instance_id='test-1',
strategy_id='strat-1',
strategy_name='Test',
user_id=1,
generated_code='def next(self): pass',
data_cache=None,
indicators=None,
trades=None,
initial_balance=10000.0,
commission=0.001,
)
# Set price
instance.update_prices({'BTC/USDT': 50000.0})
# Place order
result = instance.trade_order(
trade_type='buy',
size=0.1,
order_type='MARKET',
source={'symbol': 'BTC/USDT'}
)
assert result.success
assert result.status == OrderStatus.FILLED
# Check position exists
pos = instance.get_position('BTC/USDT')
assert pos is not None
assert pos.size == 0.1
# Check balance reduced
assert instance.get_available_balance() < 10000.0
def test_trade_order_sell(self):
"""Test selling a position."""
instance = PaperStrategyInstance(
strategy_instance_id='test-1',
strategy_id='strat-1',
strategy_name='Test',
user_id=1,
generated_code='def next(self): pass',
data_cache=None,
indicators=None,
trades=None,
initial_balance=10000.0,
commission=0,
slippage=0,
)
# Buy first
instance.update_prices({'BTC/USDT': 50000.0})
instance.trade_order(
trade_type='buy',
size=0.1,
order_type='MARKET',
source={'symbol': 'BTC/USDT'}
)
# Now sell at higher price
instance.update_prices({'BTC/USDT': 51000.0})
result = instance.trade_order(
trade_type='sell',
size=0.1,
order_type='MARKET',
source={'symbol': 'BTC/USDT'}
)
assert result.success
# Position should be closed
pos = instance.get_position('BTC/USDT')
assert pos is None
def test_close_position(self):
"""Test closing a position via close_position method."""
instance = PaperStrategyInstance(
strategy_instance_id='test-1',
strategy_id='strat-1',
strategy_name='Test',
user_id=1,
generated_code='def next(self): pass',
data_cache=None,
indicators=None,
trades=None,
)
instance.update_prices({'BTC/USDT': 50000.0})
instance.trade_order(
trade_type='buy',
size=0.1,
order_type='MARKET',
source={'symbol': 'BTC/USDT'}
)
result = instance.close_position('BTC/USDT')
assert result.success
def test_close_all_positions(self):
"""Test closing all positions."""
instance = PaperStrategyInstance(
strategy_instance_id='test-1',
strategy_id='strat-1',
strategy_name='Test',
user_id=1,
generated_code='def next(self): pass',
data_cache=None,
indicators=None,
trades=None,
)
instance.update_prices({'BTC/USDT': 50000.0, 'ETH/USDT': 3000.0})
instance.trade_order(
trade_type='buy',
size=0.1,
order_type='MARKET',
source={'symbol': 'BTC/USDT'}
)
instance.trade_order(
trade_type='buy',
size=1.0,
order_type='MARKET',
source={'symbol': 'ETH/USDT'}
)
assert instance.get_active_trades() == 2
results = instance.close_all_positions()
assert len(results) == 2
assert all(r.success for r in results)
assert instance.get_active_trades() == 0
def test_reset(self):
"""Test resetting paper trading state."""
instance = PaperStrategyInstance(
strategy_instance_id='test-1',
strategy_id='strat-1',
strategy_name='Test',
user_id=1,
generated_code='def next(self): pass',
data_cache=None,
indicators=None,
trades=None,
initial_balance=10000.0,
)
instance.update_prices({'BTC/USDT': 50000.0})
instance.trade_order(
trade_type='buy',
size=0.1,
order_type='MARKET',
source={'symbol': 'BTC/USDT'}
)
assert instance.get_available_balance() < 10000.0
instance.reset()
assert instance.get_available_balance() == 10000.0
assert instance.get_active_trades() == 0
def test_get_trade_history(self):
"""Test getting trade history."""
instance = PaperStrategyInstance(
strategy_instance_id='test-1',
strategy_id='strat-1',
strategy_name='Test',
user_id=1,
generated_code='def next(self): pass',
data_cache=None,
indicators=None,
trades=None,
)
instance.update_prices({'BTC/USDT': 50000.0})
instance.trade_order(
trade_type='buy',
size=0.1,
order_type='MARKET',
source={'symbol': 'BTC/USDT'}
)
history = instance.get_trade_history()
assert len(history) == 1
assert history[0]['symbol'] == 'BTC/USDT'
assert history[0]['side'] == 'buy'
class TestStrategiesModeSeletion:
"""Tests for strategy mode selection."""
def test_mode_selection_imports(self):
"""Test that mode selection imports work."""
from Strategies import Strategies
from brokers import TradingMode
assert TradingMode.PAPER == 'paper'
assert TradingMode.BACKTEST == 'backtest'
assert TradingMode.LIVE == 'live'