Timeframe
1d
Direction
Long Only
Stoploss
-100.0%
Trailing Stop
No
ROI
0m: 10000.0%
Interface Version
3
Startup Candles
N/A
Indicators
1
freqtrade/freqtrade-strategies
iterativv/NostalgiaForInfinity
davidzr/freqtrade-strategies
BB_RPB_TSL @author jilv220 Simple bollinger brand strategy inspired by this blog ( https://hacks-for-life.blogspot.com/2020/12/freqtrade-notes.html ) RPB, which stands for Real Pull Back, taken from ( https://github.com/GeorgeMurAlkh/freqtrade-stuff/blob/main/user_data/strategies/TheRealPullbackV2.py ) The trailing custom stoploss taken from BigZ04_TSL from Perkmeister ( modded by ilya ) I modified it to better suit my taste and added Hyperopt for this strategy.
import numpy as np
import pandas as pd
from pandas import DataFrame
from datetime import datetime
from typing import Optional, Union
from freqtrade.strategy import (
BooleanParameter,
CategoricalParameter,
DecimalParameter,
IntParameter,
IStrategy,
merge_informative_pair,
)
# --------------------------------
# Add your lib to import here
import talib.abstract as ta
import pandas_ta as pta
from technical import qtpylib
class kijun_cross_strong_s(IStrategy):
# Strategy interface version - allow new iterations of the strategy interface.
# Check the documentation or the Sample strategy to get the latest version.
INTERFACE_VERSION = 3
# Proposed timeframe for the strategy. Can be altered to your own preferred timeframe.
timeframe = "1d"
# Can this strategy go short?
can_short: bool = False
# Minimal ROI designed for the strategy.
# Set to 10000% since the exit signal determines the trade exit.
# Some crypto even got ROI triggered at 100% so had to set it to this value.
minimal_roi = {"0": 100.0}
# Optimal stoploss designed for the strategy.
# Set to 100% since the exit signal dermines the trade exit.
stoploss = -1.0
# Trailing stoploss
trailing_stop = False
# Run "populate_indicators()" only for new candle.
process_only_new_candles = True
# These values can be overridden in the config.
use_exit_signal = True
exit_profit_only = False
ignore_roi_if_entry_signal = False
# Number of candles the strategy requires before producing valid signals
# Set to the default of 30.
startup_candle_count: int = 30
# Optional order type mapping.
order_types = {
"entry": "limit",
"exit": "limit",
"stoploss": "market",
"stoploss_on_exchange": False,
}
# Optional order time in force.
order_time_in_force = {"entry": "GTC", "exit": "GTC"}
@property
def plot_config(self):
return {
"main_plot": {
"kijun": {"color": "blue"},
'senkou_a': {
'color': 'green',
'fill_to': 'senkou_b',
'fill_label': 'Ichimoku Cloud',
'fill_color': 'rgba(255,76,46,0.2)',
},
'senkou_b': {}
}
}
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# CREATE ICHIMOKU INDICATOR
# Specify the lenghts for each indicator (20, 60, 120, 60 is for crypto trading)
TS = 9
KS = 26
SS = 52
CS = 26
OS = 0
# Each column represents the output of the First Ichimoku Variable tuple and its specific column.
dataframe["tenkan"] = pta.ichimoku(
high=dataframe["high"],
low=dataframe["low"],
close=dataframe["close"],
tenkan=TS,
kijun=KS,
senkou=SS,
offset=OS,
)[0][f"ITS_{TS}"]
dataframe["kijun"] = pta.ichimoku(
high=dataframe["high"],
low=dataframe["low"],
close=dataframe["close"],
tenkan=TS,
kijun=KS,
senkou=SS,
offset=OS,
)[0][f"IKS_{KS}"]
dataframe["senkou_a"] = pta.ichimoku(
high=dataframe["high"],
low=dataframe["low"],
close=dataframe["close"],
tenkan=TS,
kijun=KS,
senkou=SS,
offset=OS,
)[0][f"ISA_{TS}"]
dataframe["senkou_b"] = pta.ichimoku(
high=dataframe["high"],
low=dataframe["low"],
close=dataframe["close"],
tenkan=TS,
kijun=KS,
senkou=SS,
offset=OS,
)[0][f"ISB_{KS}"]
dataframe["chikou"] = pta.ichimoku(
high=dataframe["high"],
low=dataframe["low"],
close=dataframe["close"],
tenkan=TS,
kijun=KS,
senkou=SS,
offset=OS,
)[0][f"ICS_{KS}"]
# Buy long singals are enhanced by explanations
# Kijun should be above senkou_a AND kijun should be above senkou_b to make the signal TRUE
dataframe["kijun_above_cloud"] = (dataframe["kijun"] > dataframe["senkou_a"]) & (dataframe["kijun"] > dataframe["senkou_b"])
# Close price should also be above senkou_a AND senkou_b to let the signal be TRUE
dataframe["close_above_cloud"] = (dataframe["close"] > dataframe["senkou_a"]) & (dataframe["close"] > dataframe["senkou_b"])
# The third part of the total buy signal is when the close price is above the kijun
dataframe["close_above_kijun"] = dataframe["close"] > dataframe["kijun"]
# The buy long signal can only be True if the kijun_above_kumo, close_above_kumo and close_above_kijun are all True
dataframe["buy_long"] = (
(dataframe["kijun_above_cloud"] == True)
& (dataframe["close_above_cloud"] == True)
& (dataframe["close_above_kijun"] == True)
)
# The sell short signals are similar to buy long, but reversed
dataframe["kijun_below_cloud"] = (dataframe["kijun"] < dataframe["senkou_a"]) & (dataframe["kijun"] < dataframe["senkou_b"])
dataframe["close_below_cloud"] = (dataframe["close"] < dataframe["senkou_a"]) & (dataframe["close"] < dataframe["senkou_b"])
dataframe["close_below_kijun"] = dataframe["close"] < dataframe["kijun"]
dataframe["sell_short"] = (
(dataframe["kijun_below_cloud"] == True)
& (dataframe["close_below_cloud"] == True)
& (dataframe["close_below_kijun"] == True)
)
# first check if dataprovider is available
if self.dp:
if self.dp.runmode.value in ("live", "dry_run"):
ob = self.dp.orderbook(metadata["pair"], 1)
dataframe["best_bid"] = ob["bids"][0][0]
dataframe["best_ask"] = ob["asks"][0][0]
# print(self)
print(metadata)
# print(dataframe)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
# If buy long signal is True, then enter a long trade
(dataframe["buy_long"] == True) & (dataframe["volume"] > 0) # Guard
),
["enter_long", "enter_tag"],
] = (1, "Strong_long_signal")
# For short trades, use the section below
dataframe.loc[
(
# If sell short signal is True, then enter a short trade
(dataframe["sell_short"] == True) & (dataframe["volume"] > 0) # Guard
),
["enter_short", "enter_tag"],
] = (1, "Strong_short_signal")
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
# The exit signal for long trades is pretty straightforward.
# Sell when the close price is below the kijun sen
(dataframe["close"] < dataframe["kijun"]) & (dataframe["volume"] > 0) # Guard
),
["exit_long", "exit_tag"],
] = (1, "Close_below_kijun")
# For short trades, use the section below
dataframe.loc[
(
# The exit signal for shorts trades is pretty straightforward.
# Sell when the close price is above the kijun sen
(dataframe["close"] > dataframe["kijun"]) & (dataframe["volume"] > 0) # Guard
),
["exit_short", "exit_tag"],
] = (1, "Close_above_kijun")
return dataframe