- Add advanced metrics dashboard with trade analytics - Add new trading components (EntryTypeAnalysis, MultiDayPositionTracker, NewsEventTracker, etc.) - Add strategy mode selector and trend confirmation - Add risk automation panel and slippage correlation analysis - Add daily trading plan enhancements with modal components - Add custom hooks (useApi, useLocalStorage, useAdvancedTradeMetrics) - Add broker service integration and trading API - Add test setup and vitest configuration - Include parquet data files for live market data - Add comprehensive documentation in docs/ folder
91 lines
3.0 KiB
Python
91 lines
3.0 KiB
Python
import math
|
|
|
|
from app.schemas.schemas import PriceData
|
|
from app.services.ai_context_builder import AIContextBuilder
|
|
|
|
|
|
def _build_sample_price_data(bars: int = 220) -> list[PriceData]:
|
|
base_price = 1950.0
|
|
price_data: list[PriceData] = []
|
|
for i in range(bars):
|
|
drift = i * 0.25
|
|
wave = math.sin(i / 7.0) * 3.0
|
|
close = base_price + drift + wave
|
|
high = close + 0.8
|
|
low = close - 0.8
|
|
open_price = close - math.sin(i / 11.0) * 0.5
|
|
price_data.append(
|
|
PriceData(
|
|
time=i,
|
|
open=open_price,
|
|
high=high,
|
|
low=low,
|
|
close=close,
|
|
volume=1000 + i,
|
|
)
|
|
)
|
|
return price_data
|
|
|
|
|
|
def test_build_metrics_includes_enhanced_indicators():
|
|
price_data = _build_sample_price_data()
|
|
builder = AIContextBuilder()
|
|
|
|
metrics = builder.build_metrics("XAUUSD", "1m", price_data)
|
|
|
|
assert metrics.bb_basis is not None
|
|
assert metrics.bb_upper is not None
|
|
assert metrics.bb_lower is not None
|
|
assert metrics.rsi3 is not None
|
|
assert metrics.zlsma is not None
|
|
assert metrics.chandelier_long_stop is not None
|
|
assert metrics.chandelier_short_stop is not None
|
|
assert metrics.chandelier_signal in {None, "LONG", "SHORT", "NEUTRAL"}
|
|
assert metrics.bb_signal in {None, "LONG", "SHORT"}
|
|
|
|
|
|
def test_indicator_payload_emits_enhanced_metrics():
|
|
price_data = _build_sample_price_data()
|
|
builder = AIContextBuilder()
|
|
bars = [
|
|
{
|
|
"time": item.time,
|
|
"open": item.open,
|
|
"high": item.high,
|
|
"low": item.low,
|
|
"close": item.close,
|
|
"volume": item.volume,
|
|
}
|
|
for item in price_data
|
|
]
|
|
|
|
indicator_payload = builder._build_indicators(bars) # type: ignore[attr-defined]
|
|
indicator_names = {entry["name"] for entry in indicator_payload}
|
|
|
|
assert "RSI_3" in indicator_names
|
|
assert "BB_20_BASIS" in indicator_names
|
|
assert "BB_20_UPPER" in indicator_names
|
|
assert "BB_20_LOWER" in indicator_names
|
|
assert "ZLSMA_50" in indicator_names
|
|
assert "CHAND_22_LONG" in indicator_names
|
|
assert "CHAND_22_SHORT" in indicator_names
|
|
|
|
|
|
def test_candlestick_patterns_detected():
|
|
candles = [
|
|
PriceData(time=0, open=100.0, high=101.0, low=99.0, close=99.0, volume=1000),
|
|
PriceData(time=1, open=99.2, high=100.0, low=95.2, close=95.5, volume=1005),
|
|
PriceData(time=2, open=95.0, high=101.2, low=94.8, close=100.8, volume=1010), # Bullish engulfing candle
|
|
PriceData(time=3, open=100.1, high=100.4, low=99.9, close=100.12, volume=1015), # Doji
|
|
PriceData(time=4, open=99.8, high=100.2, low=95.5, close=99.7, volume=1020), # Long lower shadow
|
|
]
|
|
|
|
builder = AIContextBuilder()
|
|
metrics = builder.build_metrics("XAUUSD", "1m", candles)
|
|
|
|
names = {signal.pattern for signal in metrics.pattern_signals}
|
|
|
|
assert "Bullish Engulfing" in names
|
|
assert "Doji" in names
|
|
assert "Long Lower Shadow" in names
|