Timeframe
1h
Direction
Long & Short
Stoploss
-99.0%
Trailing Stop
No
ROI
N/A
Interface Version
N/A
Startup Candles
N/A
Indicators
1
freqtrade/freqtrade-strategies
freqtrade/freqtrade-strategies
this is an example class, implementing a PSAR based trailing stop loss you are supposed to take the `custom_stoploss()` and `populate_indicators()` parts and adapt it to your own strategy
freqtrade/freqtrade-strategies
freqtrade/freqtrade-strategies
This strategy uses custom_stoploss() to enforce a fixed risk/reward ratio by first calculating a dynamic initial stoploss via ATR - last negative peak
# --- ScorpionStrike.py (Final All-in-One Version) ---
# A self-contained tool for a single, high-leverage, manually-configured trade.
import os
from freqtrade.strategy import IStrategy, DecimalParameter
from pandas import DataFrame
from freqtrade.persistence import Trade
import talib.abstract as ta
class ScorpionStrike(IStrategy):
# === MANUAL TRADE CONFIGURATION ===
#
# 1. Set your target pair
MANUAL_TARGET_PAIR = 'SOL/USDT:USDT'
# 2. Set your trade direction ('long' or 'short')
MANUAL_TRADE_SIDE = 'long'
# 3. Set your absolute stop-loss price
MANUAL_STOP_PRICE = 162.50
#
# =================================
# --- Strategy Configuration ---
timeframe = '1h'
stoploss = -0.99
can_short = True
# --- Hyperparameters ---
# This now ONLY controls the trailing stop when in profit.
atr_multiplier = DecimalParameter(3.0, 8.0, default=5.0, space='sell')
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe['atr'] = ta.ATR(dataframe, timeperiod=14)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# The entry signal is now read from the internal configuration.
if metadata['pair'] == self.MANUAL_TARGET_PAIR:
if self.MANUAL_TRADE_SIDE == 'long':
dataframe.loc[dataframe.index[-1], ['enter_long', 'enter_tag']] = (1, f'strike_{self.MANUAL_STOP_PRICE}')
elif self.MANUAL_TRADE_SIDE == 'short':
dataframe.loc[dataframe.index[-1], ['enter_short', 'enter_tag']] = (1, f'strike_{self.MANUAL_STOP_PRICE}')
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
return dataframe
def custom_stake_amount(self, pair: str, current_time, current_rate: float,
proposed_stake: float, min_stake: float, max_stake: float,
leverage: float, entry_tag: str, side: str, **kwargs) -> float:
RISK_PER_TRADE_USD = 20.0
stop_price = float(entry_tag.split('_')[1])
stoploss_distance = abs(current_rate - stop_price)
if stoploss_distance == 0: return 0
position_size_coins = RISK_PER_TRADE_USD / stoploss_distance
stake_amount_usd = position_size_coins * current_rate
return stake_amount_usd
def custom_stoploss(self, pair: str, trade: 'Trade', current_time,
current_rate: float, current_profit: float, **kwargs) -> float:
stop_price = float(trade.enter_tag.split('_')[1])
initial_stop = (stop_price / trade.open_rate) - 1.0
if current_profit > 0:
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle_atr = dataframe.iloc[-1]['atr']
trailing_stop_price = current_rate - (last_candle_atr * self.atr_multiplier.value)
trailing_stop_relative = (trailing_stop_price / trade.open_rate) - 1.0
return max(initial_stop, trailing_stop_relative)
return initial_stop
def leverage(self, pair: str, current_time, current_rate: float,
proposed_leverage: float, max_leverage: float, entry_tag: str, side: str,
**kwargs) -> float:
return max_leverage