Estrategia de Grid Trading optimizada para $100 - Compra en niveles bajos - Vende en niveles altos - Mantiene rejilla dinámica
Timeframe
5m
Direction
Long Only
Stoploss
-5.0%
Trailing Stop
No
ROI
0m: 2.0%
Interface Version
3
Startup Candles
N/A
Indicators
4
freqtrade/freqtrade-strategies
Strategy 003 author@: Gerald Lonlas github@: https://github.com/freqtrade/freqtrade-strategies
from freqtrade.strategy.interface import IStrategy
from typing import Dict, List, Optional
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
import numpy as np
from pandas import DataFrame
class GridStrategy(IStrategy):
"""
Estrategia de Grid Trading optimizada para $100
- Compra en niveles bajos
- Vende en niveles altos
- Mantiene rejilla dinámica
"""
INTERFACE_VERSION = 3
timeframe = '5m'
# ROI y Stoploss
minimal_roi = {
"0": 0.02 # 2% ganancia por trade
}
stoploss = -0.05 # 5% stop loss máximo
# Grid Settings - AJUSTABLES
grid_spacing_percent = 2.0 # 2% entre niveles
grid_levels = 4 # 4 niveles arriba/abajo
# Configuración adicional
can_short = False
startup_candle_count: int = 30
use_exit_signal = True
exit_profit_only = False
ignore_roi_if_entry_signal = False
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Añadir indicadores técnicos para Grid Trading
"""
# SMA para determinar tendencia general
dataframe['sma_20'] = ta.SMA(dataframe, timeperiod=20)
dataframe['sma_50'] = ta.SMA(dataframe, timeperiod=50)
# RSI para evitar comprar en sobrecompra
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
# ATR para medir volatilidad
dataframe['atr'] = ta.ATR(dataframe, timeperiod=14)
# Bollinger Bands para límites de grid
bollinger = qtpylib.bollinger_bands(dataframe['close'], window=20, stds=2)
dataframe['bb_lowerband'] = bollinger['lower']
dataframe['bb_upperband'] = bollinger['upper']
dataframe['bb_middleband'] = bollinger['mid']
# Calcular niveles de grid dinámicos
dataframe['grid_buy_level'] = dataframe['close'] * (1 - self.grid_spacing_percent / 100)
dataframe['grid_sell_level'] = dataframe['close'] * (1 + self.grid_spacing_percent / 100)
# Volumen promedio
dataframe['volume_sma'] = ta.SMA(dataframe['volume'], timeperiod=20)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Condiciones de compra para Grid Trading
"""
dataframe.loc[
(
# Grid Buy Conditions
(dataframe['close'] <= dataframe['bb_lowerband']) | # Precio en banda inferior
(dataframe['rsi'] < 40) | # RSI indica sobreventa
(
(dataframe['close'] < dataframe['sma_20']) & # Precio bajo SMA
(dataframe['volume'] > dataframe['volume_sma']) # Volumen alto
)
) &
(dataframe['volume'] > 0) & # Volumen mínimo
(dataframe['close'] > 0), # Precio válido
'enter_long'
] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Condiciones de venta para Grid Trading
"""
dataframe.loc[
(
# Grid Sell Conditions
(dataframe['close'] >= dataframe['bb_upperband']) | # Precio en banda superior
(dataframe['rsi'] > 60) | # RSI indica sobrecompra
(
(dataframe['close'] > dataframe['sma_20']) & # Precio sobre SMA
(dataframe['volume'] > dataframe['volume_sma']) # Volumen alto
)
) &
(dataframe['volume'] > 0), # Volumen mínimo
'exit_long'
] = 1
return dataframe
def custom_stoploss(self, pair: str, trade: 'Trade', current_time, current_rate,
current_profit: float, **kwargs) -> float:
"""
Stop loss dinámico para Grid Trading
"""
# Si estamos ganando más del 1%, ajustar stop loss
if current_profit > 0.01:
return -0.02 # Stop loss a -2% si ya ganamos 1%
# Stop loss normal
return self.stoploss
def confirm_trade_entry(self, pair: str, order_type: str, amount: float,
rate: float, time_in_force: str, current_time,
entry_tag, side: str, **kwargs) -> bool:
"""
Confirmar entrada de trade - útil para validaciones extra
"""
# Lógica adicional si es necesaria
# Por ejemplo, no entrar si ya tenemos muchas posiciones del mismo par
return True