Add some strategies for binance futures

This commit is contained in:
caglarylmz
2022-05-12 19:51:33 +03:00
parent 190e145cba
commit a217a7c75d
5 changed files with 872 additions and 0 deletions
@@ -0,0 +1,130 @@
# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
# flake8: noqa: F401
# isort: skip_file
# --- Do not remove these libs ---
from functools import reduce
import numpy as np # noqa
import pandas as pd # noqa
from pandas import DataFrame
from freqtrade.strategy import (
BooleanParameter,
CategoricalParameter,
DecimalParameter,
IStrategy,
IntParameter,
)
# --------------------------------
# Add your lib to import here
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
# This class is a sample. Feel free to customize it.
class FAdxSmaStrategy(IStrategy):
INTERFACE_VERSION = 3
timeframe = "1h"
# Minimal ROI designed for the strategy.
# This attribute will be overridden if the config file contains "minimal_roi".
minimal_roi = {"60": 0.075, "30": 0.1, "0": 0.05}
# minimal_roi = {"0": 1}
stoploss = -0.05
can_short = True
# Trailing stoploss
trailing_stop = False
# trailing_only_offset_is_reached = False
# trailing_stop_positive = 0.01
# trailing_stop_positive_offset = 0.0 # Disabled / not configured
# Run "populate_indicators()" only for new candle.
process_only_new_candles = False
# Number of candles the strategy requires before producing valid signals
startup_candle_count: int = 14
# Hyperoptable parameters
# Define the guards spaces
pos_entry_adx = DecimalParameter(15, 40, decimals=1, default=30.0, space="buy")
pos_exit_adx = DecimalParameter(15, 40, decimals=1, default=30.0, space="sell")
# Define the parameter spaces
adx_period = IntParameter(4, 24, default=14)
sma_short_period = IntParameter(4, 24, default=12)
sma_long_period = IntParameter(12, 175, default=48)
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Calculate all adx values
for val in self.adx_period.range:
dataframe[f"adx_{val}"] = ta.ADX(dataframe, timeperiod=val)
# Calculate all sma_short values
for val in self.sma_short_period.range:
dataframe[f"sma_short_{val}"] = ta.SMA(dataframe, timeperiod=val)
# Calculate all sma_long values
for val in self.sma_long_period.range:
dataframe[f"sma_long_{val}"] = ta.SMA(dataframe, timeperiod=val)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions_long = []
conditions_short = []
# GUARDS AND TRIGGERS
conditions_long.append(
dataframe[f"adx_{self.adx_period.value}"] > self.pos_entry_adx.value
)
conditions_short.append(
dataframe[f"adx_{self.adx_period.value}"] > self.pos_entry_adx.value
)
conditions_long.append(
qtpylib.crossed_above(
dataframe[f"sma_short_{self.sma_short_period.value}"],
dataframe[f"sma_long_{self.sma_long_period.value}"],
)
)
conditions_short.append(
qtpylib.crossed_below(
dataframe[f"sma_short_{self.sma_short_period.value}"],
dataframe[f"sma_long_{self.sma_long_period.value}"],
)
)
dataframe.loc[
reduce(lambda x, y: x & y, conditions_long),
"enter_long",
] = 1
dataframe.loc[
reduce(lambda x, y: x & y, conditions_short),
"enter_short",
] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions_close = []
conditions_close.append(
dataframe[f"adx_{self.adx_period.value}"] < self.pos_entry_adx.value
)
dataframe.loc[
reduce(lambda x, y: x & y, conditions_close),
"exit_long",
] = 1
dataframe.loc[
reduce(lambda x, y: x & y, conditions_close),
"exit_short",
] = 1
return dataframe
@@ -0,0 +1,187 @@
import logging
from numpy.lib import math
from freqtrade.strategy.interface import IStrategy
from freqtrade.strategy.hyper import IntParameter
from pandas import DataFrame
import talib.abstract as ta
import numpy as np
import freqtrade.vendor.qtpylib.indicators as qtpylib
class FOttStrategy(IStrategy):
# Buy params, Sell params, ROI, Stoploss and Trailing Stop are values generated by 'freqtrade hyperopt --strategy Supertrend --hyperopt-loss ShortTradeDurHyperOptLoss --timerange=20210101- --timeframe=1h --spaces all'
# It's encourage you find the values that better suites your needs and risk management strategies
# ROI table:
minimal_roi = {"0": 0.1, "30": 0.75, "60": 0.05, "120": 0.025}
# minimal_roi = {"0": 1}
# Stoploss:
stoploss = -0.265
# Trailing stop:
trailing_stop = True
trailing_stop_positive = 0.05
trailing_stop_positive_offset = 0.1
trailing_only_offset_is_reached = False
timeframe = "1h"
startup_candle_count = 18
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe["ott"] = self.ott(dataframe)["OTT"]
dataframe["var"] = self.ott(dataframe)["VAR"]
dataframe["adx"] = ta.ADX(dataframe, timeperiod=14)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(qtpylib.crossed_above(dataframe["var"], dataframe["ott"])),
"enter_long",
] = 1
dataframe.loc[
(qtpylib.crossed_below(dataframe["var"], dataframe["ott"])),
"enter_short",
] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
dataframe["adx"]>60
),
"exit_long",
] = 1
dataframe.loc[
(
dataframe["adx"]>60
),
"exit_short",
] = 1
return dataframe
"""
Supertrend Indicator; adapted for freqtrade
from: https://github.com/freqtrade/freqtrade-strategies/issues/30
"""
def ott(self, dataframe: DataFrame):
df = dataframe.copy()
pds = 2
percent = 1.4
alpha = 2 / (pds + 1)
df["ud1"] = np.where(
df["close"] > df["close"].shift(1), (df["close"] - df["close"].shift()), 0
)
df["dd1"] = np.where(
df["close"] < df["close"].shift(1), (df["close"].shift() - df["close"]), 0
)
df["UD"] = df["ud1"].rolling(9).sum()
df["DD"] = df["dd1"].rolling(9).sum()
df["CMO"] = ((df["UD"] - df["DD"]) / (df["UD"] + df["DD"])).fillna(0).abs()
# df['Var'] = talib.EMA(df['close'], timeperiod=5)
df["Var"] = 0.0
for i in range(pds, len(df)):
df["Var"].iat[i] = (alpha * df["CMO"].iat[i] * df["close"].iat[i]) + (
1 - alpha * df["CMO"].iat[i]
) * df["Var"].iat[i - 1]
df["fark"] = df["Var"] * percent * 0.01
df["newlongstop"] = df["Var"] - df["fark"]
df["newshortstop"] = df["Var"] + df["fark"]
df["longstop"] = 0.0
df["shortstop"] = 999999999999999999
# df['dir'] = 1
for i in df["UD"]:
def maxlongstop():
df.loc[(df["newlongstop"] > df["longstop"].shift(1)), "longstop"] = df[
"newlongstop"
]
df.loc[(df["longstop"].shift(1) > df["newlongstop"]), "longstop"] = df[
"longstop"
].shift(1)
return df["longstop"]
def minshortstop():
df.loc[
(df["newshortstop"] < df["shortstop"].shift(1)), "shortstop"
] = df["newshortstop"]
df.loc[
(df["shortstop"].shift(1) < df["newshortstop"]), "shortstop"
] = df["shortstop"].shift(1)
return df["shortstop"]
df["longstop"] = np.where(
((df["Var"] > df["longstop"].shift(1))),
maxlongstop(),
df["newlongstop"],
)
df["shortstop"] = np.where(
((df["Var"] < df["shortstop"].shift(1))),
minshortstop(),
df["newshortstop"],
)
# get xover
df["xlongstop"] = np.where(
(
(df["Var"].shift(1) > df["longstop"].shift(1))
& (df["Var"] < df["longstop"].shift(1))
),
1,
0,
)
df["xshortstop"] = np.where(
(
(df["Var"].shift(1) < df["shortstop"].shift(1))
& (df["Var"] > df["shortstop"].shift(1))
),
1,
0,
)
df["trend"] = 0
df["dir"] = 0
for i in df["UD"]:
df["trend"] = np.where(
((df["xshortstop"] == 1)),
1,
(np.where((df["xlongstop"] == 1), -1, df["trend"].shift(1))),
)
df["dir"] = np.where(
((df["xshortstop"] == 1)),
1,
(np.where((df["xlongstop"] == 1), -1, df["dir"].shift(1).fillna(1))),
)
# get OTT
df["MT"] = np.where(df["dir"] == 1, df["longstop"], df["shortstop"])
df["OTT"] = np.where(
df["Var"] > df["MT"],
(df["MT"] * (200 + percent) / 200),
(df["MT"] * (200 - percent) / 200),
)
df["OTT"] = df["OTT"].shift(2)
return DataFrame(index=df.index, data={"OTT": df["OTT"], "VAR": df["Var"]})
@@ -0,0 +1,144 @@
# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
# flake8: noqa: F401
# isort: skip_file
# --- Do not remove these libs ---
from functools import reduce
import numpy as np # noqa
import pandas as pd # noqa
from pandas import DataFrame
from freqtrade.strategy import (
BooleanParameter,
CategoricalParameter,
DecimalParameter,
IStrategy,
IntParameter,
)
# --------------------------------
# Add your lib to import here
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
from freqtrade.exchange import timeframe_to_minutes
from technical.util import resample_to_interval, resampled_merge
# This class is a sample. Feel free to customize it.
class FReinforcedStrategy(IStrategy):
INTERFACE_VERSION = 3
timeframe = "5m"
# Minimal ROI designed for the strategy.
# This attribute will be overridden if the config file contains "minimal_roi".
minimal_roi = {"60": 0.075, "30": 0.1, "0": 0.05}
# minimal_roi = {"0": 1}
stoploss = -0.05
can_short = True
# Trailing stoploss
trailing_stop = False
# trailing_only_offset_is_reached = False
# trailing_stop_positive = 0.01
# trailing_stop_positive_offset = 0.0 # Disabled / not configured
# Run "populate_indicators()" only for new candle.
process_only_new_candles = False
# Number of candles the strategy requires before producing valid signals
startup_candle_count: int = 14
# Hyperoptable parameters
# Define the guards spaces
pos_entry_adx = DecimalParameter(15, 40, decimals=1, default=30.0, space="buy")
pos_exit_adx = DecimalParameter(15, 40, decimals=1, default=30.0, space="sell")
# Define the parameter spaces
adx_period = IntParameter(4, 24, default=14)
ema_short_period = IntParameter(4, 24, default=8)
ema_long_period = IntParameter(12, 175, default=21)
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Calculate all adx values
for val in self.adx_period.range:
dataframe[f"adx_{val}"] = ta.ADX(dataframe, timeperiod=val)
# Calculate all ema_short values
for val in self.ema_short_period.range:
dataframe[f"ema_short_{val}"] = ta.EMA(dataframe, timeperiod=val)
# Calculate all ema_long values
for val in self.ema_long_period.range:
dataframe[f"ema_long_{val}"] = ta.EMA(dataframe, timeperiod=val)
# required for graphing
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"]
self.resample_interval = timeframe_to_minutes(self.timeframe) * 12
dataframe_long = resample_to_interval(dataframe, self.resample_interval)
dataframe_long["sma"] = ta.SMA(dataframe_long, timeperiod=50, price="close")
dataframe = resampled_merge(dataframe, dataframe_long, fill_na=True)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions_long = []
conditions_short = []
# GUARDS AND TRIGGERS
conditions_long.append(
dataframe["close"] > dataframe[f"resample_{self.resample_interval}_sma"]
)
conditions_short.append(
dataframe["close"] < dataframe[f"resample_{self.resample_interval}_sma"]
)
conditions_long.append(
qtpylib.crossed_above(
dataframe[f"ema_short_{self.ema_short_period.value}"],
dataframe[f"ema_long_{self.ema_long_period.value}"],
)
)
conditions_short.append(
qtpylib.crossed_below(
dataframe[f"ema_short_{self.ema_short_period.value}"],
dataframe[f"ema_long_{self.ema_long_period.value}"],
)
)
dataframe.loc[
reduce(lambda x, y: x & y, conditions_long),
"enter_long",
] = 1
dataframe.loc[
reduce(lambda x, y: x & y, conditions_short),
"enter_short",
] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions_close = []
conditions_close.append(
dataframe[f"adx_{self.adx_period.value}"] < self.pos_entry_adx.value
)
dataframe.loc[
reduce(lambda x, y: x & y, conditions_close),
"exit_long",
] = 1
dataframe.loc[
reduce(lambda x, y: x & y, conditions_close),
"exit_short",
] = 1
return dataframe
@@ -0,0 +1,162 @@
# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
# flake8: noqa: F401
# isort: skip_file
# --- Do not remove these libs ---
import numpy as np # noqa
import pandas as pd # noqa
from pandas import DataFrame
from freqtrade.strategy import (
BooleanParameter,
CategoricalParameter,
DecimalParameter,
IStrategy,
IntParameter,
)
# --------------------------------
# Add your lib to import here
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
# This class is a sample. Feel free to customize it.
class FSampleStrategy(IStrategy):
INTERFACE_VERSION = 3
timeframe = "1h"
# Minimal ROI designed for the strategy.
# This attribute will be overridden if the config file contains "minimal_roi".
# minimal_roi = {"60": 0.1, "30": 0.2, "0": 0.2}
minimal_roi = {"0": 1}
stoploss = -0.05
can_short = True
# Trailing stoploss
trailing_stop = False
# trailing_only_offset_is_reached = False
# trailing_stop_positive = 0.01
# trailing_stop_positive_offset = 0.0 # Disabled / not configured
# Run "populate_indicators()" only for new candle.
process_only_new_candles = False
# Number of candles the strategy requires before producing valid signals
startup_candle_count: int = 30
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe["adx"] = ta.ADX(dataframe)
# RSI
dataframe["rsi"] = ta.RSI(dataframe)
# Stochastic Fast
stoch_fast = ta.STOCHF(dataframe)
dataframe["fastd"] = stoch_fast["fastd"]
dataframe["fastk"] = stoch_fast["fastk"]
# MACD
macd = ta.MACD(dataframe)
dataframe["macd"] = macd["macd"]
dataframe["macdsignal"] = macd["macdsignal"]
dataframe["macdhist"] = macd["macdhist"]
# MFI
dataframe["mfi"] = ta.MFI(dataframe)
# Bollinger Bands
bollinger = qtpylib.bollinger_bands(
qtpylib.typical_price(dataframe), window=20, stds=2
)
dataframe["bb_lowerband"] = bollinger["lower"]
dataframe["bb_middleband"] = bollinger["mid"]
dataframe["bb_upperband"] = bollinger["upper"]
dataframe["bb_percent"] = (dataframe["close"] - dataframe["bb_lowerband"]) / (
dataframe["bb_upperband"] - dataframe["bb_lowerband"]
)
dataframe["bb_width"] = (
dataframe["bb_upperband"] - dataframe["bb_lowerband"]
) / dataframe["bb_middleband"]
# Parabolic SAR
dataframe["sar"] = ta.SAR(dataframe)
# TEMA - Triple Exponential Moving Average
dataframe["tema"] = ta.TEMA(dataframe, timeperiod=9)
# Cycle Indicator
# ------------------------------------
# Hilbert Transform Indicator - SineWave
hilbert = ta.HT_SINE(dataframe)
dataframe["htsine"] = hilbert["sine"]
dataframe["htleadsine"] = hilbert["leadsine"]
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
# Signal: RSI crosses above 30
(qtpylib.crossed_above(dataframe["rsi"], 30))
& (dataframe["tema"] <= dataframe["bb_middleband"])
& ( # Guard: tema below BB middle
dataframe["tema"] > dataframe["tema"].shift(1)
)
& ( # Guard: tema is raising
dataframe["volume"] > 0
) # Make sure Volume is not 0
),
"enter_long",
] = 1
dataframe.loc[
(
# Signal: RSI crosses above 70
(qtpylib.crossed_above(dataframe["rsi"], 70))
& (dataframe["tema"] > dataframe["bb_middleband"])
& ( # Guard: tema above BB middle
dataframe["tema"] < dataframe["tema"].shift(1)
)
& ( # Guard: tema is falling
dataframe["volume"] > 0
) # Make sure Volume is not 0
),
"enter_short",
] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
# Signal: RSI crosses above 70
(qtpylib.crossed_above(dataframe["rsi"], 70))
& (dataframe["tema"] > dataframe["bb_middleband"])
& ( # Guard: tema above BB middle
dataframe["tema"] < dataframe["tema"].shift(1)
)
& ( # Guard: tema is falling
dataframe["volume"] > 0
) # Make sure Volume is not 0
),
"exit_long",
] = 1
dataframe.loc[
(
# Signal: RSI crosses above 30
(qtpylib.crossed_above(dataframe["rsi"], 30))
&
# Guard: tema below BB middle
(dataframe["tema"] <= dataframe["bb_middleband"])
& (dataframe["tema"] > dataframe["tema"].shift(1))
& ( # Guard: tema is raising
dataframe["volume"] > 0
) # Make sure Volume is not 0
),
"exit_short",
] = 1
return dataframe
@@ -0,0 +1,249 @@
"""
Supertrend strategy:
* Description: Generate a 3 supertrend indicators for 'buy' strategies & 3 supertrend indicators for 'sell' strategies
Buys if the 3 'buy' indicators are 'up'
Sells if the 3 'sell' indicators are 'down'
* Author: @juankysoriano (Juan Carlos Soriano)
* github: https://github.com/juankysoriano/
*** NOTE: This Supertrend strategy is just one of many possible strategies using `Supertrend` as indicator. It should on any case used at your own risk.
It comes with at least a couple of caveats:
1. The implementation for the `supertrend` indicator is based on the following discussion: https://github.com/freqtrade/freqtrade-strategies/issues/30 . Concretelly https://github.com/freqtrade/freqtrade-strategies/issues/30#issuecomment-853042401
2. The implementation for `supertrend` on this strategy is not validated; meaning this that is not proven to match the results by the paper where it was originally introduced or any other trusted academic resources
"""
import logging
from numpy.lib import math
from freqtrade.strategy.interface import IStrategy
from freqtrade.strategy.hyper import IntParameter
from pandas import DataFrame
import talib.abstract as ta
import numpy as np
class FSupertrendStrategy(IStrategy):
# Buy params, Sell params, ROI, Stoploss and Trailing Stop are values generated by 'freqtrade hyperopt --strategy Supertrend --hyperopt-loss ShortTradeDurHyperOptLoss --timerange=20210101- --timeframe=1h --spaces all'
# It's encourage you find the values that better suites your needs and risk management strategies
# Buy hyperspace params:
buy_params = {
"buy_m1": 4,
"buy_m2": 7,
"buy_m3": 1,
"buy_p1": 8,
"buy_p2": 9,
"buy_p3": 8,
}
# Sell hyperspace params:
sell_params = {
"sell_m1": 1,
"sell_m2": 3,
"sell_m3": 6,
"sell_p1": 16,
"sell_p2": 18,
"sell_p3": 18,
}
# ROI table:
minimal_roi = {"0": 0.1, "30": 0.75, "60": 0.05, "120": 0.025}
# minimal_roi = {"0": 1}
# Stoploss:
stoploss = -0.265
# Trailing stop:
trailing_stop = True
trailing_stop_positive = 0.05
trailing_stop_positive_offset = 0.1
trailing_only_offset_is_reached = False
timeframe = "1h"
startup_candle_count = 18
buy_m1 = IntParameter(1, 7, default=1)
buy_m2 = IntParameter(1, 7, default=3)
buy_m3 = IntParameter(1, 7, default=4)
buy_p1 = IntParameter(7, 21, default=14)
buy_p2 = IntParameter(7, 21, default=10)
buy_p3 = IntParameter(7, 21, default=10)
sell_m1 = IntParameter(1, 7, default=1)
sell_m2 = IntParameter(1, 7, default=3)
sell_m3 = IntParameter(1, 7, default=4)
sell_p1 = IntParameter(7, 21, default=14)
sell_p2 = IntParameter(7, 21, default=10)
sell_p3 = IntParameter(7, 21, default=10)
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
for multiplier in self.buy_m1.range:
for period in self.buy_p1.range:
dataframe[f"supertrend_1_buy_{multiplier}_{period}"] = self.supertrend(
dataframe, multiplier, period
)["STX"]
for multiplier in self.buy_m2.range:
for period in self.buy_p2.range:
dataframe[f"supertrend_2_buy_{multiplier}_{period}"] = self.supertrend(
dataframe, multiplier, period
)["STX"]
for multiplier in self.buy_m3.range:
for period in self.buy_p3.range:
dataframe[f"supertrend_3_buy_{multiplier}_{period}"] = self.supertrend(
dataframe, multiplier, period
)["STX"]
for multiplier in self.sell_m1.range:
for period in self.sell_p1.range:
dataframe[f"supertrend_1_sell_{multiplier}_{period}"] = self.supertrend(
dataframe, multiplier, period
)["STX"]
for multiplier in self.sell_m2.range:
for period in self.sell_p2.range:
dataframe[f"supertrend_2_sell_{multiplier}_{period}"] = self.supertrend(
dataframe, multiplier, period
)["STX"]
for multiplier in self.sell_m3.range:
for period in self.sell_p3.range:
dataframe[f"supertrend_3_sell_{multiplier}_{period}"] = self.supertrend(
dataframe, multiplier, period
)["STX"]
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
dataframe[f"supertrend_1_buy_{self.buy_m1.value}_{self.buy_p1.value}"]
== "up"
)
& (
dataframe[f"supertrend_2_buy_{self.buy_m2.value}_{self.buy_p2.value}"]
== "up"
)
& (
dataframe[f"supertrend_3_buy_{self.buy_m3.value}_{self.buy_p3.value}"]
== "up"
)
& ( # The three indicators are 'up' for the current candle
dataframe["volume"] > 0
),
"enter_long",
] = 1
dataframe.loc[
(
dataframe[
f"supertrend_1_sell_{self.sell_m1.value}_{self.sell_p1.value}"
]
== "down"
)
& (
dataframe[
f"supertrend_2_sell_{self.sell_m2.value}_{self.sell_p2.value}"
]
== "down"
)
& (
dataframe[
f"supertrend_3_sell_{self.sell_m3.value}_{self.sell_p3.value}"
]
== "down"
)
& ( # The three indicators are 'down' for the current candle
dataframe["volume"] > 0
),
"enter_short",
] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
dataframe[
f"supertrend_2_sell_{self.sell_m2.value}_{self.sell_p2.value}"
]
== "down"
),
"exit_long",
] = 1
dataframe.loc[
(
dataframe[f"supertrend_2_buy_{self.buy_m2.value}_{self.buy_p2.value}"]
== "up"
),
"exit_short",
] = 1
return dataframe
"""
Supertrend Indicator; adapted for freqtrade
from: https://github.com/freqtrade/freqtrade-strategies/issues/30
"""
def supertrend(self, dataframe: DataFrame, multiplier, period):
df = dataframe.copy()
df["TR"] = ta.TRANGE(df)
df["ATR"] = ta.SMA(df["TR"], period)
st = "ST_" + str(period) + "_" + str(multiplier)
stx = "STX_" + str(period) + "_" + str(multiplier)
# Compute basic upper and lower bands
df["basic_ub"] = (df["high"] + df["low"]) / 2 + multiplier * df["ATR"]
df["basic_lb"] = (df["high"] + df["low"]) / 2 - multiplier * df["ATR"]
# Compute final upper and lower bands
df["final_ub"] = 0.00
df["final_lb"] = 0.00
for i in range(period, len(df)):
df["final_ub"].iat[i] = (
df["basic_ub"].iat[i]
if df["basic_ub"].iat[i] < df["final_ub"].iat[i - 1]
or df["close"].iat[i - 1] > df["final_ub"].iat[i - 1]
else df["final_ub"].iat[i - 1]
)
df["final_lb"].iat[i] = (
df["basic_lb"].iat[i]
if df["basic_lb"].iat[i] > df["final_lb"].iat[i - 1]
or df["close"].iat[i - 1] < df["final_lb"].iat[i - 1]
else df["final_lb"].iat[i - 1]
)
# Set the Supertrend value
df[st] = 0.00
for i in range(period, len(df)):
df[st].iat[i] = (
df["final_ub"].iat[i]
if df[st].iat[i - 1] == df["final_ub"].iat[i - 1]
and df["close"].iat[i] <= df["final_ub"].iat[i]
else df["final_lb"].iat[i]
if df[st].iat[i - 1] == df["final_ub"].iat[i - 1]
and df["close"].iat[i] > df["final_ub"].iat[i]
else df["final_lb"].iat[i]
if df[st].iat[i - 1] == df["final_lb"].iat[i - 1]
and df["close"].iat[i] >= df["final_lb"].iat[i]
else df["final_ub"].iat[i]
if df[st].iat[i - 1] == df["final_lb"].iat[i - 1]
and df["close"].iat[i] < df["final_lb"].iat[i]
else 0.00
)
# Mark the trend direction up/down
df[stx] = np.where(
(df[st] > 0.00), np.where((df["close"] < df[st]), "down", "up"), np.NaN
)
# Remove basic and final bands from the columns
df.drop(["basic_ub", "basic_lb", "final_ub", "final_lb"], inplace=True, axis=1)
df.fillna(0, inplace=True)
return DataFrame(index=df.index, data={"ST": df[st], "STX": df[stx]})