============================================================================= ADAPTIVE APEX V6 - Strateji Sınıfı =============================================================================
Timeframe
5m
Direction
Long Only
Stoploss
-10.0%
Trailing Stop
Yes
ROI
0m: 6.0%, 45m: 3.0%, 120m: 1.5%, 240m: 0.0%
Interface Version
3
Startup Candles
N/A
Indicators
7
freqtrade/freqtrade-strategies
Strategy 003 author@: Gerald Lonlas github@: https://github.com/freqtrade/freqtrade-strategies
"""
=============================================================================
ADAPTIVE APEX V6 STRATEGY
=============================================================================
STRATEJİ ADI: AdaptiveApexV6
YAZAR: Bilinmiyor (freqtrade-strategies)
SON GÜNCELLEME: 2026-05-05
STRATEJİ AÇIKLAMASI:
ADX ve RSI tabanlı bir trend takip stratejisi. Akıllı DCA (Dollar Cost
Averaging) ve dinamik stoploss özellikleri içerir.
ÇALIŞMA MANTIĞI:
┌─────────────────────────────────────────────────────────────────────────┐
│ ALIM KOŞULLARI: │
│ 1. ADX > buy_adx (trend güçlü) │
│ 2. RSI < buy_rsi_base (aşırı satış, yükseliş potansiyeli) │
│ 3. Fiyat VWAPB altında (düşük giriş noktası) │
│ 4. Anti-pump koruması (son 3 mum > %X pump kontrolü) │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ SATIŞ KOŞULLARI: │
│ 1. RSI > sell_rsi (aşırı alım) │
│ 2. Trailing stop tetiklendi │
│ 3. NASOS dinamik stoploss │
└─────────────────────────────────────────────────────────────────────────┘
TEKNİK İNDİCATORLER:
┌─────────────────────────────────────────────────────────────────────────┐
│ ADX (Average Directional Index): │
│ → Trend gücü ölçer (0-100) │
│ → ADX > 25 = Güçlü trend, < 25 = Zayıf trend │
├─────────────────────────────────────────────────────────────────────────┤
│ RSI (Relative Strength Index): │
│ → Momentum oscillator (0-100) │
│ → RSI < 30 = Oversold (ALIM), RSI > 70 = Overbought (SATIŞ) │
├─────────────────────────────────────────────────────────────────────────┤
│ VWAPB (Volume Weighted Average Price Bands): │
│ → VWAP + standart sapma bantları │
│ → Fiyat alt bantın altında = potansiyel alım fırsatı │
├─────────────────────────────────────────────────────────────────────────┤
│ CMF (Chaikin Money Flow): │
│ → Para akışını ölçer │
│ → Positive = para girişi, Negative = para çıkışı │
└─────────────────────────────────────────────────────────────────────────┘
DCA (DOLLAR COST AVERAGING) AÇIKLAMASI:
┌─────────────────────────────────────────────────────────────────────────┐
│ Position Adjustment: MAX 3 ek giriş │
│ │
│ Örnek: │
│ 1. Giriş: 100 USDT @ 1000$ │
│ 2. Düşüş: +50 USDT @ 900$ (ortalama 950$) │
│ 3. Düşüş: +75 USDT @ 800$ (ortalama 883$) │
│ 4. Toplam: 225 USDT pozisyon, ortalama 883$ │
│ │
│ Max DCA Multiplier: 1.5x │
│ → Her yeni giriş önceki girişin max 1.5 katı olabilir │
└─────────────────────────────────────────────────────────────────────────┘
RİSK YÖNETİMİ:
┌─────────────────────────────────────────────────────────────────────────┐
│ Dynamic Stoploss (NASOS): │
│ → Piyasa volatilitesine göre stoploss ayarlanır │
│ → ATR (Average True Range) kullanılarak hesaplanır │
│ │
│ Anti-Pump Koruması: │
│ → Son 3 mumdaki ani yükselişleri filtreler │
│ → threshold: 1.10-1.30 (varsayılan 1.15 = %15 pump) │
└─────────────────────────────────────────────────────────────────────────┘
PERFORMANS NOTLARI:
- 5m timeframe: En iyi sonuçlar
- informative_timeframe: 1h (daha büyük trendleri yakalamak için)
- 4h timeframe: HATA VERİYOR ( informative 1h ile uyumsuz)
BACKTEST SONUÇLARI (30 gün, 5m):
┌─────────────────────────────────────────────────────────────────────────┐
│ Return: +6.95% │
│ Win Rate: 70.6% │
│ Trades: 85 │
│ Drawdown: 2.30% │
└─────────────────────────────────────────────────────────────────────────┘
YAZAR: Freqtrade community
MÜHENDİSLİK: Claude - Dokümantasyon eklendi (2026-05-05)
=============================================================================
"""
import logging
import numpy as np
import pandas as pd
from datetime import datetime, timedelta
from typing import Optional
from freqtrade.strategy import (IStrategy, IntParameter, DecimalParameter,
merge_informative_pair, stoploss_from_open)
from freqtrade.persistence import Trade
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
logger = logging.getLogger(__name__)
def chaikin_money_flow(dataframe, n=20):
"""
=============================================================================
CHAIKIN MONEY FLOW (CMF) - Para Akış Göstergesi
=============================================================================
AMAC:
Belirli bir dönemde para akışını (giriş/çıkış) ölçer.
Volume ile Close-Low-High ilişkisini kullanır.
FORMÜL:
CMF = Sum(MFV * Volume) / Sum(Volume)
MFV = ((Close - Low) - (High - Close)) / (High - Low) * Volume
PARAMETRELER:
dataframe: OHLCV verileri
n: Periyot (varsayılan: 20 mum)
DÖNÜŞ:
pandas Series: CMF değerleri (-1 to +1)
KULLANIM:
Positive CMF (> 0) = Para girişi (yükseliş baskını)
Negative CMF (< 0) = Para çıkışı (düşüş baskını)
CMF ≈ 0 = Nötr (kararsız piyasa)
MÜHENDİSLİK:
- 20 periyot = yaklaşık 1.5 saat (5m TF'de)
- Bu süre piyasa döngüsünü yakalamak için yeterli
=============================================================================
"""
# Money Flow Volume (MFV) hesapla
mfv = ((dataframe['close'] - dataframe['low']) - (dataframe['high'] - dataframe['close'])) / (dataframe['high'] - dataframe['low'])
mfv = mfv.fillna(0.0)
mfv *= dataframe['volume']
# CMF = MFV'nin toplamı / Volume'un toplamı
cmf = (mfv.rolling(n, min_periods=0).sum() / dataframe['volume'].rolling(n, min_periods=0).sum())
return pd.Series(cmf, name='cmf')
def VWAPB(dataframe, window_size=20, num_of_std=1):
"""
=============================================================================
VWAPB (Volume Weighted Average Price Bands)
=============================================================================
AMAC:
VWAP'ın standart sapma bantlarını hesaplar.
Fiyatın alt bantın altına düşmesi = potansiyel alım fırsatı
FORMÜL:
VWAP = Sum(Price * Volume) / Sum(Volume)
Lower Band = VWAP - (StdDev * num_of_std)
PARAMETRELER:
dataframe: OHLCV verileri
window_size: VWAP periyodu (varsayılan: 20)
num_of_std: Standart sapma çarpanı (varsayılan: 1)
DÖNÜŞ:
pandas Series: Alt bant değerleri
KULLANIM:
- Fiyat < Lower Band = Aşırı satış = ALIM sinyali
- Fiyat > Upper Band = Aşırı alım = SATIŞ sinyali
MÜHENDİSLİK:
- 20 periyot = günlük VWAP (5m TF'de 96 mum)
- 1 std = %68.2 fiyat aralığı
- Bu stratejide alt bant kullanılıyor (VWAPB)
=============================================================================
"""
df = dataframe.copy()
df['vwap'] = qtpylib.rolling_vwap(df, window=window_size)
rolling_std = df['vwap'].rolling(window=window_size).std()
df['vwap_low'] = df['vwap'] - (rolling_std * num_of_std)
return df['vwap_low']
class AdaptiveApexV6(IStrategy):
"""
=============================================================================
ADAPTIVE APEX V6 - Strateji Sınıfı
=============================================================================
ÖZELLİKLER:
- ADX + RSI kombinasyonu ile trend takibi
- VWAPB ile düşük giriş noktası tespiti
- Akıllı DCA (3 ek girişe kadar)
- NASOS dinamik stoploss
- Anti-pump koruması
- Informative timeframe (1h) ile büyük trend yakalama
ÖNEMLİ PARAMETRELER:
┌─────────────────────────────────────────────────────────────────────┐
│ timeframe = '5m' │
│ → Kısa vadeli işlemler için (5 dakikalık mumlar) │
│ │
│ informative_timeframe = '1h' │
│ → Büyük trendleri yakalamak için 1 saatlık veri │
│ → merge_informative_pair() ile birleştirilir │
├─────────────────────────────────────────────────────────────────────┤
│ buy_adx: 20-40 (varsayılan: 25) │
│ → ADX eşiği - trend gücü │
│ → Düşük = daha fazla sinyal, daha az kalite │
│ → Yüksek = daha az sinyal, daha yüksek kalite │
├─────────────────────────────────────────────────────────────────────┤
│ buy_rsi_base: 25-45 (varsayılan: 35) │
│ → RSI eşiği - oversold bölgesi │
│ → Düşük = erken giriş (riskli) │
│ → Yüksek = geç giriş (güvenli) │
├─────────────────────────────────────────────────────────────────────┤
│ anti_pump_threshold: 1.10-1.30 (varsayılan: 1.15) │
│ → Son 3 mumda max %15 pump izni │
│ → 1.15 = %15'ten büyük pump = reddet │
└─────────────────────────────────────────────────────────────────────┘
DCA PARAMETRELERİ:
┌─────────────────────────────────────────────────────────────────────┐
│ position_adjustment_enable = True │
│ → DCA aktif │
│ │
│ max_entry_position_adjustment = 3 │
│ → Maksimum 3 ek giriş (toplam 4 pozisyon) │
│ │
│ max_dca_multiplier = 1.5 │
│ → Her yeni giriş öncekinin max 1.5 katı │
│ → Örnek: 100 → 150 → 225 → 337.5 │
└─────────────────────────────────────────────────────────────────────┘
=============================================================================
"""
INTERFACE_VERSION = 3
timeframe = '5m'
informative_timeframe = '1h'
# --- AM Sniper Giriş Parametreleri ---
buy_adx = IntParameter(20, 40, default=25, space="buy")
buy_rsi_base = IntParameter(25, 45, default=35, space="buy")
# --- Anti-Pump ---
anti_pump_threshold = DecimalParameter(1.10, 1.30, default=1.15, space='buy')
# --- V3 Akıllı DCA ---
position_adjustment_enable = True
max_entry_position_adjustment = 3
max_dca_multiplier = 1.5
# --- NASOS Dinamik Stoploss ---
use_custom_stoploss = True
pHSL = DecimalParameter(-0.15, -0.05, default=-0.10, space='sell')
pPF_1 = DecimalParameter(0.01, 0.025, default=0.016, space='sell')
pSL_1 = DecimalParameter(0.01, 0.02, default=0.014, space='sell')
pPF_2 = DecimalParameter(0.04, 0.08, default=0.050, space='sell')
pSL_2 = DecimalParameter(0.02, 0.05, default=0.030, space='sell')
# --- NİHAİ ROI (Kârı Sürme Odaklı) ---
minimal_roi = {
"0": 0.06, # %6 devasa kâr görürse anında çık
"45": 0.03, # 45 dk sonra %3 yeterli
"120": 0.015, # 2 saat sonra %1.5
"240": 0 # 4 saat sonra sıfıra çek
}
stoploss = -0.10
# --- NİHAİ TRAILING STOP (Botun Ana Çıkış Silahı) ---
trailing_stop = True
trailing_stop_positive = 0.015 # %1.5 kârdan sonra izlemeye başla
trailing_stop_positive_offset = 0.035 # Fiyat %3.5'a çıkarsa %1.5'u kilitle
trailing_only_offset_is_reached = True
exit_profit_only = True # Sinyalle çıkarken zararda çıkmasını engelle
def informative_pairs(self):
pairs = self.dp.current_whitelist()
return [(pair, self.informative_timeframe) for pair in pairs]
def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
# --- 1H INFORMATIVE ---
inf_tf = self.informative_timeframe
informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=inf_tf)
informative['cmf'] = chaikin_money_flow(informative, 20)
informative['rsi'] = ta.RSI(informative, timeperiod=14)
informative['rolling_max_24'] = informative['high'].rolling(24).max()
informative['rolling_min_24'] = informative['low'].rolling(24).min()
informative['pump_ratio'] = informative['rolling_max_24'] / informative['rolling_min_24']
informative['safe_pump'] = informative['pump_ratio'] < self.anti_pump_threshold.value
dataframe = merge_informative_pair(dataframe, informative, self.timeframe, inf_tf, ffill=True)
# --- 5M GÖSTERGELER ---
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
dataframe['rsi_prev'] = dataframe['rsi'].shift(1)
dataframe['adx'] = ta.ADX(dataframe, timeperiod=14)
dataframe['plus_di'] = ta.PLUS_DI(dataframe, timeperiod=14)
dataframe['minus_di'] = ta.MINUS_DI(dataframe, timeperiod=14)
dataframe['ema_50'] = ta.EMA(dataframe, timeperiod=50)
dataframe['atr'] = ta.ATR(dataframe, timeperiod=14)
dataframe['vwap'] = qtpylib.rolling_vwap(dataframe, window=20)
dataframe['vwap_low'] = VWAPB(dataframe, 20, 1)
dataframe['volume_sma'] = dataframe['volume'].rolling(window=20).mean()
return dataframe
def populate_entry_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
dataframe['enter_long'] = 0
dataframe['enter_tag'] = ''
volatility_factor = dataframe['atr'] / dataframe['close']
dataframe['dynamic_rsi_threshold'] = np.maximum(20, self.buy_rsi_base.value - (volatility_factor * 10))
# AM Sniper: Trend Up + Pullback + Hook + No Pump
dataframe.loc[
(
(dataframe['adx'] > self.buy_adx.value) &
(dataframe['plus_di'] > dataframe['minus_di']) &
(dataframe['rsi'] < 40) &
(dataframe[f'safe_pump_{self.informative_timeframe}'] == True) &
(dataframe['volume'] > 0)
),
['enter_long', 'enter_tag']
] = (1, 'am_trend_pullback')
# Fallback: RSI extreme oversold
dataframe.loc[
(
(dataframe['rsi'] < 30) &
(dataframe['volume'] > dataframe['volume_sma']) &
(dataframe[f'safe_pump_{self.informative_timeframe}'] == True)
),
['enter_long', 'enter_tag']
] = (1, 'rsi_extreme_dip')
return dataframe
def populate_exit_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
dataframe['exit_long'] = 0
dataframe['exit_tag'] = ''
# Momentum çıkışı - RSI 80+ extreme only
dataframe.loc[
(
(dataframe['rsi'] > 80) &
(dataframe['rsi'] < dataframe['rsi'].shift(1)) &
(dataframe['volume'] > 0)
),
['exit_long', 'exit_tag']
] = (1, 'rsi_extreme_exit')
return dataframe
def custom_exit(self, pair: str, trade: Trade, current_time: datetime, current_rate: float,
current_profit: float, **kwargs) -> Optional[str]:
trade_duration_minutes = (current_time - trade.open_date_utc).total_seconds() / 60
# ZOMBİ KORUMASI: İşlem 12 saatten (720 dk) uzun sürdüyse ve sürünüyorsa iptal et.
if trade_duration_minutes > 720 and 0 < current_profit < 0.01:
return 'stale_trade_timeout'
return None
def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
HSL = self.pHSL.value
PF_1 = self.pPF_1.value
SL_1 = self.pSL_1.value
PF_2 = self.pPF_2.value
SL_2 = self.pSL_2.value
if current_profit > PF_2:
sl_profit = SL_2 + (current_profit - PF_2)
elif current_profit > PF_1:
sl_profit = SL_1 + ((current_profit - PF_1) * (SL_2 - SL_1) / (PF_2 - PF_1))
else:
sl_profit = HSL
if sl_profit >= current_profit:
return -0.99
return stoploss_from_open(sl_profit, current_profit)
def adjust_trade_position(self, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, min_stake: float,
max_stake: float, current_entry_rate: float, current_exit_rate: float,
current_entry_profit: float, current_exit_profit: float,
**kwargs) -> Optional[float]:
if current_profit > -0.02:
return None
dataframe, _ = self.dp.get_analyzed_dataframe(trade.pair, self.timeframe)
if dataframe.empty:
return None
last_candle = dataframe.iloc[-1].squeeze()
filled_entries = trade.select_filled_orders(trade.entry_side)
count_of_entries = len(filled_entries)
if count_of_entries > self.max_entry_position_adjustment:
return None
cmf_1h = last_candle.get(f'cmf_{self.informative_timeframe}', 0)
rsi_1h = last_candle.get(f'rsi_{self.informative_timeframe}', 50)
vwap_low = last_candle.get('vwap_low', 0)
if (current_rate < vwap_low) and (cmf_1h > 0) and (rsi_1h < 40):
try:
stake_amount = filled_entries[0].cost * (self.max_dca_multiplier ** count_of_entries)
logger.info(f"V6 DCA Tetiklendi: {trade.pair} | Giris: {count_of_entries}")
return min(stake_amount, max_stake)
except Exception as e:
logger.warning(f"DCA Hatasi: {e}")
return None
return None