Timeframe
5m
Direction
Long Only
Stoploss
-5.0%
Trailing Stop
No
ROI
0m: 10000.0%
Interface Version
3
Startup Candles
N/A
Indicators
1
freqtrade/freqtrade-strategies
Strategy 003 author@: Gerald Lonlas github@: https://github.com/freqtrade/freqtrade-strategies
# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
# flake8: noqa: F401
# isort: skip_file
# type: ignore
"""
MATRIX Strategy - FreqTrade Integration
FreqTrade-compatible strategy that bridges MATRIX prediction pipeline
to trading signals using optimized thresholds.
This is a SKELETON implementation for sandbox backtesting.
NO LIVE TRADING - all exchange interactions disabled.
"""
import logging
from typing import Dict, Optional
import pandas as pd # type: ignore
from pandas import DataFrame # type: ignore
from freqtrade.strategy.interface import IStrategy # type: ignore
from freqtrade.strategy import ( # type: ignore
BooleanParameter,
DecimalParameter,
IntParameter,
)
# MATRIX imports
from src.matrix.strategy.core import to_signals
from src.matrix.telemetry.metrics import (
log_signal_behavior_metrics,
log_performance_metrics,
print_console_summary,
)
logger = logging.getLogger(__name__)
class MatrixStrategy(IStrategy):
"""
MATRIX Strategy for FreqTrade.
Integrates MATRIX ML pipeline with FreqTrade backtesting framework.
Uses threshold-based signal generation from matrix.strategy.core.
IMPORTANT: This is a SANDBOX strategy for offline backtesting only.
NO live trading, NO API calls, NO real money at risk.
THRESHOLDS NOTE: Current hyperopt parameters use placeholder values.
Real threshold values should be determined using docs/THRESHOLDS.md
methodology after first sandbox runs and grid sweep analysis.
Current placeholder thresholds are conservative defaults for initial testing.
Follow THRESHOLDS.md 3-step optimization after validating pipeline operation.
"""
# Strategy metadata
INTERFACE_VERSION = 3
# Minimal timeframe for MATRIX (5m as per requirements)
timeframe = "5m"
# Disable live trading features
can_short = False # TODO: Enable after threshold validation
use_exit_signal = True
exit_profit_only = False
ignore_roi_if_entry_signal = False
# Startup candles for indicator calculation
startup_candle_count: int = 100
# Risk management (conservative defaults for sandbox)
stoploss = -0.05 # 5% stop loss
# ROI table (disabled - rely on signals)
minimal_roi = {
"0": 100 # Effectively disabled - use exit signals
}
# Hyperopt parameters for threshold optimization
# TODO: Integrate with docs/THRESHOLDS.md Grid Sweep methodology
# UP_THRESHOLD: Minimum prediction for long entry
buy_threshold_up = DecimalParameter(
0.001, 0.010, default=0.005, space="buy", decimals=4, optimize=True
)
# DOWN_THRESHOLD: Maximum prediction for short entry (when shorting enabled)
sell_threshold_down = DecimalParameter(
-0.010, -0.001, default=-0.005, space="sell", decimals=4, optimize=True
)
# HYSTERESIS: Buffer to prevent oscillation
hysteresis_buffer = DecimalParameter(
0.0005, 0.002, default=0.001, space="buy", decimals=4, optimize=True
)
# COOLDOWN: Minimum bars between signal changes
signal_cooldown = IntParameter(1, 10, default=3, space="buy", optimize=True)
def __init__(self, config: dict) -> None:
"""Initialize MATRIX strategy with sandbox configuration."""
super().__init__(config)
# Strategy state tracking
self.last_signal_bar = 0
self.signal_count = {"long": 0, "short": 0, "exit": 0}
# TODO: Initialize MATRIX pipeline components
# - FreqAI model loading
# - Feature engineering setup
# - Telemetry initialization
logger.info("MATRIX Strategy initialized (SANDBOX MODE)")
def informative_pairs(self):
"""
Define additional, informative pair/interval combinations.
TODO: Add informative pairs for feature engineering
- Higher timeframes for trend context
- Correlated pairs for market regime detection
"""
return []
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Populate indicators and features for MATRIX pipeline.
Args:
dataframe: OHLCV data from FreqTrade
metadata: Pair metadata
Returns:
DataFrame with added indicators and features
TODO: Integration with MATRIX feature engineering
- Call src.matrix.feature.engineering functions
- Add FreqAI prediction columns
- Implement data quality checks from METRICS_CHECKLIST.md
- Log telemetry metrics (latency, NaN ratios)
Current: SKELETON with basic indicators only
"""
# SKELETON: Add basic indicators for testing
# TODO: Replace with MATRIX feature engineering pipeline
# Simple moving averages (placeholder)
dataframe["sma_20"] = dataframe["close"].rolling(20).mean()
dataframe["sma_50"] = dataframe["close"].rolling(50).mean()
# RSI (placeholder)
delta = dataframe["close"].diff()
gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
rs = gain / loss
dataframe["rsi"] = 100 - (100 / (1 + rs))
# MATRIX prediction placeholder
# TODO: Integrate with FreqAI prediction pipeline
dataframe["matrix_prediction"] = 0.0 # Placeholder - no predictions yet
# TODO: Log data quality metrics
# missing_data_pct = dataframe.isnull().sum().sum() / (len(dataframe) * len(dataframe.columns))
# log_data_quality_metrics(missing_data_pct, ...)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Populate buy signal based on MATRIX predictions and thresholds.
Args:
dataframe: DataFrame with OHLCV and indicators
metadata: Pair metadata
Returns:
DataFrame with 'enter_long' column added
TODO: Integration with matrix.strategy.core.to_signals()
- Extract predictions from FreqAI
- Apply threshold-based signal generation
- Implement cooldown logic
- Log signal behavior metrics
"""
# SKELETON: Simple signal logic for testing
# TODO: Replace with MATRIX threshold-based signals
conditions = []
# Placeholder condition (replace with MATRIX signals)
conditions.append(
(dataframe["sma_20"] > dataframe["sma_50"]) & (dataframe["rsi"] < 70)
)
# TODO: Implement MATRIX signal logic
# predictions = dataframe['matrix_prediction']
# context = {
# 'current_price': dataframe['close'],
# 'current_position': None, # TODO: Get from FreqTrade
# 'market_conditions': {} # TODO: Add regime detection
# }
# signals = to_signals(predictions, context)
# conditions.append(signals['enter_long'])
# Apply cooldown logic
# TODO: Implement signal cooldown from THRESHOLDS.md
if conditions:
dataframe.loc[
conditions[0], # All conditions combined
"enter_long",
] = 1
# TODO: Log signal behavior metrics
# long_trigger_rate = dataframe['enter_long'].mean() * 100
# log_signal_behavior_metrics(long_trigger_rate, ...)
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Populate sell signal based on MATRIX predictions and thresholds.
Args:
dataframe: DataFrame with OHLCV and indicators
metadata: Pair metadata
Returns:
DataFrame with 'exit_long' column added
TODO: Integration with matrix.strategy.core.to_signals()
- Implement hysteresis-based exit logic
- Apply cooldown between signal changes
- Log exit signal metrics
"""
# SKELETON: Simple exit logic for testing
# TODO: Replace with MATRIX threshold-based exits
conditions = []
# Placeholder condition (replace with MATRIX signals)
conditions.append(
(dataframe["sma_20"] < dataframe["sma_50"]) | (dataframe["rsi"] > 80)
)
# TODO: Implement MATRIX exit logic with hysteresis
# Use (UP_THRESHOLD - HYSTERESIS) for exit threshold
# Apply cooldown logic from signal_cooldown parameter
if conditions:
dataframe.loc[conditions[0], "exit_long"] = 1
return dataframe
def custom_exit(
self, pair: str, trade, current_time, current_rate, current_profit, **kwargs
) -> Optional[str]:
"""
Custom exit logic for advanced MATRIX signals.
TODO: Implement advanced exit logic
- Risk-based exits using src.matrix.risk.policy
- Time-based exits for signal persistence
- Profit target exits based on prediction confidence
Args:
pair: Trading pair
trade: Current trade object
current_time: Current timestamp
current_rate: Current price
current_profit: Current profit ratio
Returns:
Exit reason string or None
"""
# TODO: Implement custom exit logic
# - Check risk policy constraints
# - Apply prediction-based exits
# - Log exit reasons for analysis
return None
def leverage(
self,
pair: str,
current_time,
current_rate,
proposed_leverage: float,
max_leverage: float,
entry_tag: str,
side: str,
**kwargs,
) -> float:
"""
Leverage calculation for MATRIX strategy.
TODO: Integration with risk management
- Use src.matrix.risk.policy for position sizing
- Apply Kelly criterion from advanced metrics
- Implement regime-based leverage adjustment
SANDBOX: Return 1.0 (no leverage) for safety
"""
return 1.0 # No leverage in sandbox mode
def confirm_trade_entry(
self,
pair: str,
order_type: str,
amount: float,
rate: float,
time_in_force: str,
current_time,
entry_tag: str,
side: str,
**kwargs,
) -> bool:
"""
Confirm trade entry with MATRIX validation.
TODO: Implement entry confirmation logic
- Validate prediction confidence
- Check risk budget availability
- Apply market condition filters
- Log entry confirmations for analysis
SANDBOX: Always confirm for testing
"""
return True # Always confirm in sandbox mode
def custom_stake_amount(
self,
pair: str,
current_time,
current_rate,
proposed_stake: float,
min_stake: float,
max_stake: float,
entry_tag: str,
side: str,
**kwargs,
) -> float:
"""
Custom stake amount calculation using MATRIX risk management.
TODO: Integration with position sizing
- Use prediction confidence for sizing
- Apply risk policy constraints
- Implement Kelly criterion sizing
- Log position sizes for analysis
SANDBOX: Use default stake amount
"""
return proposed_stake # Use default in sandbox mode