Timeframe
5m
Direction
Long Only
Stoploss
-34.5%
Trailing Stop
Yes
ROI
0m: 35.6%, 4818m: 21.3%, 6395m: 9.0%, 22372m: 0.0%
Interface Version
N/A
Startup Candles
N/A
Indicators
0
freqtrade/freqtrade-strategies
author@: lenik
# GodStra Strategy
# Author: @Mablue (Masoud Azizi)
# github: https://github.com/mablue/
# IMPORTANT:Add to your pairlists inside config.json (Under StaticPairList):
# {
# "method": "AgeFilter",
# "min_days_listed": 30
# },
# IMPORTANT: INSTALL TA BEFOUR RUN(pip install ta)
# IMPORTANT: Use Smallest "max_open_trades" for getting best results inside config.json
# --- Do not remove these libs ---
import logging
from functools import reduce
import freqtrade.vendor.qtpylib.indicators as qtpylib
import numpy as np
# Add your lib to import here
# import talib.abstract as ta
import pandas as pd
from freqtrade.strategy import IStrategy
from numpy.lib import math
from pandas import DataFrame
# import talib.abstract as ta
from ta import add_all_ta_features
from ta.utils import dropna
from freqtrade.strategy.parameters import IntParameter, DecimalParameter, CategoricalParameter
# --------------------------------
class GodStra(IStrategy):
can_short: bool = True
# 5/66: 9 trades. 8/0/1 Wins/Draws/Losses. Avg profit 21.83%. Median profit 35.52%. Total profit 1060.11476586 USDT ( 196.50Σ%). Avg duration 3440.0 min. Objective: -7.06960
# +--------+---------+----------+------------------+--------------+-------------------------------+----------------+-------------+
# | Best | Epoch | Trades | Win Draw Loss | Avg profit | Profit | Avg duration | Objective |
# |--------+---------+----------+------------------+--------------+-------------------------------+----------------+-------------|
# | * Best | 1/500 | 11 | 2 1 8 | 5.22% | 280.74230393 USDT (57.40%) | 2,421.8 m | -2.85206 |
# | * Best | 2/500 | 10 | 7 0 3 | 18.76% | 983.46414442 USDT (187.58%) | 360.0 m | -4.32665 |
# | * Best | 5/500 | 9 | 8 0 1 | 21.83% | 1,060.11476586 USDT (196.50%) | 3,440.0 m | -7.0696 |
INTERFACE_VERSION: int = 3
# Define hyperoptable buy params so 'buy' space is present
buy_oper: CategoricalParameter = CategoricalParameter(
[">", "<", "=", "CA", "CB", ">I", "=I", "<I", ">R", "=R", "<R"],
default="<",
space="buy",
)
buy_int: IntParameter = IntParameter(0, 100, default=42, space="buy")
buy_real: DecimalParameter = DecimalParameter(-1.0, 1.0, default=0.063, decimals=3, space="buy")
# Minimal sell param to satisfy 'sell' space if included in default
sell_oper: CategoricalParameter = CategoricalParameter(
[">", "<", "=", "CA", "CB", ">I", "=I", "<I", ">R", "=R", "<R"],
default="=R",
space="sell",
)
sell_int: IntParameter = IntParameter(0, 100, default=98, space="sell")
sell_real: DecimalParameter = DecimalParameter(0.0, 1.0, default=0.878, decimals=3, space="sell")
# ROI table:
minimal_roi = {
"0": 0.3556,
"4818": 0.21275,
"6395": 0.09024,
"22372": 0
}
# Stoploss:
stoploss = -0.34549
# Trailing stop:
trailing_stop = True
trailing_stop_positive = 0.22673
trailing_stop_positive_offset = 0.2684
trailing_only_offset_is_reached = True
# Use 5m to align with config overrides in hyperopt
timeframe = '5m'
print('Add {\n\t"method": "AgeFilter",\n\t"min_days_listed": 30\n},\n to your pairlists in config (Under StaticPairList)')
def dna_size(self, dct: dict):
def int_from_str(st: str):
str_int = ''.join([d for d in st if d.isdigit()])
if str_int:
return int(str_int)
return -1 # in case if the parameter somehow doesn't have index
return len({int_from_str(digit) for digit in dct.keys()})
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Add all ta features
dataframe = dropna(dataframe)
dataframe = add_all_ta_features(
dataframe, open="open", high="high", low="low", close="close", volume="volume",
fillna=True)
# dataframe.to_csv("df.csv", index=True)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = list()
# Use hyperoptable simple gate to ensure presence of 'buy' space
OPR = self.buy_oper.value
INT = self.buy_int.value
REAL = self.buy_real.value
IND = 'trend_ichimoku_base'
CRS = 'volatility_kcc'
DFIND = dataframe[IND]
DFCRS = dataframe[CRS]
if OPR == ">":
conditions.append(DFIND > DFCRS)
elif OPR == "=":
conditions.append(np.isclose(DFIND, DFCRS))
elif OPR == "<":
conditions.append(DFIND < DFCRS)
elif OPR == "CA":
conditions.append(qtpylib.crossed_above(DFIND, DFCRS))
elif OPR == "CB":
conditions.append(qtpylib.crossed_below(DFIND, DFCRS))
elif OPR == ">I":
conditions.append(DFIND > INT)
elif OPR == "=I":
conditions.append(DFIND == INT)
elif OPR == "<I":
conditions.append(DFIND < INT)
elif OPR == ">R":
conditions.append(DFIND > REAL)
elif OPR == "=R":
conditions.append(np.isclose(DFIND, REAL))
elif OPR == "<R":
conditions.append(DFIND < REAL)
if conditions:
dataframe.loc[reduce(lambda x, y: x & y, conditions), 'enter_long'] = 1
# Simple mirrored short entry using inverse relation
s_conditions = list()
if OPR == ">":
s_conditions.append(DFIND < DFCRS)
elif OPR == "=":
s_conditions.append(np.isclose(DFIND, DFCRS))
elif OPR == "<":
s_conditions.append(DFIND > DFCRS)
elif OPR == "CA":
s_conditions.append(qtpylib.crossed_below(DFIND, DFCRS))
elif OPR == "CB":
s_conditions.append(qtpylib.crossed_above(DFIND, DFCRS))
elif OPR == ">I":
s_conditions.append(DFIND < INT)
elif OPR == "=I":
s_conditions.append(DFIND == INT)
elif OPR == "<I":
s_conditions.append(DFIND > INT)
elif OPR == ">R":
s_conditions.append(DFIND < REAL)
elif OPR == "=R":
s_conditions.append(np.isclose(DFIND, REAL))
elif OPR == "<R":
s_conditions.append(DFIND > REAL)
if s_conditions:
dataframe.loc[reduce(lambda x, y: x & y, s_conditions), 'enter_short'] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = list()
OPR = self.sell_oper.value
INT = self.sell_int.value
REAL = self.sell_real.value
IND = 'trend_kst_diff'
CRS = 'volume_mfi'
DFIND = dataframe[IND]
DFCRS = dataframe[CRS]
if OPR == ">":
conditions.append(DFIND > DFCRS)
elif OPR == "=":
conditions.append(np.isclose(DFIND, DFCRS))
elif OPR == "<":
conditions.append(DFIND < DFCRS)
elif OPR == "CA":
conditions.append(qtpylib.crossed_above(DFIND, DFCRS))
elif OPR == "CB":
conditions.append(qtpylib.crossed_below(DFIND, DFCRS))
elif OPR == ">I":
conditions.append(DFIND > INT)
elif OPR == "=I":
conditions.append(DFIND == INT)
elif OPR == "<I":
conditions.append(DFIND < INT)
elif OPR == ">R":
conditions.append(DFIND > REAL)
elif OPR == "=R":
conditions.append(np.isclose(DFIND, REAL))
elif OPR == "<R":
conditions.append(DFIND < REAL)
if conditions:
dataframe.loc[reduce(lambda x, y: x & y, conditions), 'exit_long'] = 1
# Mirrored short exit
x_conditions = list()
if OPR == ">":
x_conditions.append(DFIND < DFCRS)
elif OPR == "=":
x_conditions.append(np.isclose(DFIND, DFCRS))
elif OPR == "<":
x_conditions.append(DFIND > DFCRS)
elif OPR == "CA":
x_conditions.append(qtpylib.crossed_below(DFIND, DFCRS))
elif OPR == "CB":
x_conditions.append(qtpylib.crossed_above(DFIND, DFCRS))
elif OPR == ">I":
x_conditions.append(DFIND < INT)
elif OPR == "=I":
x_conditions.append(DFIND == INT)
elif OPR == "<I":
x_conditions.append(DFIND > INT)
elif OPR == ">R":
x_conditions.append(DFIND < REAL)
elif OPR == "=R":
x_conditions.append(np.isclose(DFIND, REAL))
elif OPR == "<R":
x_conditions.append(DFIND > REAL)
if x_conditions:
dataframe.loc[reduce(lambda x, y: x & y, x_conditions), 'exit_short'] = 1
return dataframe
def leverage(self, pair, current_time, current_rate, proposed_leverage, max_leverage, entry_tag, side, **kwargs) -> float:
try:
stop = abs(float(self.stoploss)) if getattr(self, "stoploss", None) is not None else None
base = 0.05 / stop if stop and stop > 0 else (proposed_leverage or 1.0)
except Exception:
base = proposed_leverage or 1.0
base = max(1.0, min(float(base), float(max_leverage)))
return base