454 lines
23 KiB
Python
454 lines
23 KiB
Python
# pr#agma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
|
|
# isort: skip_file
|
|
# --- Do not remove these libs ---
|
|
from datetime import datetime
|
|
|
|
import numpy
|
|
import numpy as np # noqa
|
|
import pandas as pd # noqa
|
|
from freqtrade.strategy.parameters import DecimalParameter, BooleanParameter, IntParameter
|
|
from pandas import DataFrame
|
|
import math
|
|
from functools import reduce
|
|
|
|
from freqtrade.strategy.interface import IStrategy
|
|
|
|
# --------------------------------
|
|
|
|
# Add your lib to import here
|
|
import ta
|
|
from functools import reduce
|
|
import numpy as np
|
|
import talib.abstract as talib
|
|
from freqtrade.strategy.strategy_helper import merge_informative_pair
|
|
import freqtrade.vendor.qtpylib.indicators as qtpylib
|
|
|
|
|
|
# This class is a sample. Feel free to customize it.
|
|
class StrategyPierrick41221(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 = 2
|
|
|
|
# valeur de bbwidth pour démarrer
|
|
buy_bollinger = DecimalParameter(0.00, 0.18, decimals=2, default=0.075, space="buy")
|
|
# Valeur de la deuxième condition bollinger avec condition sma200
|
|
# buy_bollinger_2 = DecimalParameter(0.0, 0.08, decimals=2, default=0.04, space="buy")
|
|
# buy_min = DecimalParameter(1, 1.1, decimals=2, default=1.01, space="buy")
|
|
# buy_percent = DecimalParameter(1, 1.1, decimals=2, default=1.01, space="buy")
|
|
# volume à atteindre
|
|
buy_volume = DecimalParameter(0, 50, decimals=1, default=18, space="buy")
|
|
|
|
buy_step = IntParameter(1, 8, default=3, space="buy")
|
|
buy_rolling = IntParameter(-20, 0, default=-6, space="buy")
|
|
# buy_rsi = IntParameter(20, 40, default=30, space="buy")
|
|
# buy_adx_enabled = BooleanParameter(default=True, space="buy")
|
|
# buy_rsi_enabled = CategoricalParameter([True, False], default=False, space="buy")
|
|
# buy_trigger = CategoricalParameter(["bb_lower", "macd_cross_signal"], default="bb_lower", space="buy")
|
|
|
|
# ROI table:
|
|
minimal_roi = {
|
|
"0": 100
|
|
# "0": 0.015,
|
|
# "5": 0.01,
|
|
# "10": 0.005,
|
|
}
|
|
|
|
# Stoploss:
|
|
stoploss = -1
|
|
trailing_stop = True
|
|
trailing_stop_positive = 0.02
|
|
trailing_stop_positive_offset = 0.0275 # 0.015
|
|
trailing_only_offset_is_reached = True
|
|
|
|
# max_open_trades = 3
|
|
|
|
# Optimal ticker interval for the strategy.
|
|
timeframe = '1m'
|
|
|
|
# Run "populate_indicators()" only for new candle.
|
|
process_only_new_candles = False
|
|
|
|
# These values can be overridden in the "ask_strategy" section in the config.
|
|
use_sell_signal = True
|
|
sell_profit_only = False
|
|
ignore_roi_if_buy_signal = False
|
|
|
|
# Number of candles the strategy requires before producing valid signals
|
|
startup_candle_count: int = 30
|
|
|
|
# Optional order type mapping.
|
|
order_types = {
|
|
'buy': 'limit',
|
|
'sell': 'limit',
|
|
'stoploss': 'market',
|
|
'stoploss_on_exchange': False
|
|
}
|
|
|
|
# Optional order time in force.
|
|
order_time_in_force = {
|
|
'buy': 'gtc',
|
|
'sell': 'gtc'
|
|
}
|
|
|
|
plot_config = {
|
|
# Main plot indicators (Moving averages, ...)
|
|
'main_plot': {
|
|
'bb_lowerband': {'color': 'red'},
|
|
'bb_upperband': {'color': 'green'},
|
|
'sma100': {'color': 'blue'},
|
|
'sma10': {'color': 'yellow'},
|
|
'min': {'color': 'white'},
|
|
'max': {'color': 'white'},
|
|
'sma20': {'color': 'cyan'}
|
|
},
|
|
'subplots': {
|
|
# Subplots - each dict defines one additional plot
|
|
"BB": {
|
|
'bb_width': {'color': 'green'},
|
|
'bb_min': {'color': 'red'},
|
|
},
|
|
"Volume": {
|
|
'volume5': {'color': 'yellow'},
|
|
},
|
|
"Rsi": {
|
|
'rsi': {'color': 'pink'},
|
|
},
|
|
"rolling": {
|
|
'bb_rolling': {'color': '#87e470'},
|
|
"bb_rolling_min": {'color': '#ac3e2a'}
|
|
},
|
|
"percent": {
|
|
"percent": {'color': 'green'},
|
|
"percent5": {'color': 'red'}
|
|
}
|
|
}
|
|
}
|
|
trades = list()
|
|
|
|
# buy_base = DecimalParameter(0, 0.2, decimals=2, default=0.10, space='buy')
|
|
# buy_diff = DecimalParameter(0, 0.2, decimals=2, default=0.20, space='buy')
|
|
#
|
|
# buy_rsi = IntParameter(20, 80, default=42, space='buy')
|
|
# buy_rsi_max = IntParameter(60, 90, default=60, space='buy')
|
|
#
|
|
# buy_rsi_1h = IntParameter(20, 80, default=72, space='buy')
|
|
# buy_rsi_max_1h = IntParameter(60, 80, default=72, space='buy')
|
|
#
|
|
# buy_min_horizon = IntParameter(50, 200, default=72, space='buy')
|
|
#
|
|
# buy_0_percent20 = DecimalParameter(-0.1, 0.1, decimals=2, default=-0.02, space='buy')
|
|
# buy_2_percent20 = DecimalParameter(-0.1, 0.1, decimals=2, default=-0.02, space='buy')
|
|
# buy_3_percent20 = DecimalParameter(-0.1, 0.1, decimals=2, default=-0.02, space='buy')
|
|
#
|
|
# buy_0_distance = DecimalParameter(-0.1, 0.1, decimals=2, default=0.02, space='buy')
|
|
# buy_2_distance = DecimalParameter(-0.1, 0.1, decimals=2, default=0.02, space='buy')
|
|
# buy_3_distance = DecimalParameter(-0.1, 0.1, decimals=2, default=0.02, space='buy')
|
|
#
|
|
# buy_decalage_deb_0 = IntParameter(0, 3, default=5, space='buy')
|
|
# buy_decalage_deb_2 = IntParameter(0, 3, default=5, space='buy')
|
|
# buy_decalage_deb_3 = IntParameter(0, 3, default=5, space='buy')
|
|
#
|
|
# buy_real_num0 = DecimalParameter(0, 1, decimals=2, default=0.67, space='buy')
|
|
# buy_real_num1 = DecimalParameter(0, 1, decimals=2, default=0.67, space='buy')
|
|
# buy_real_num2 = DecimalParameter(0, 2, decimals=2, default=0.67, space='buy')
|
|
#
|
|
# buy_decalage0 = IntParameter(buy_decalage_deb_0.value + 1, 8, default=5, space='buy')
|
|
# buy_decalage2 = IntParameter(buy_decalage_deb_2.value + 1, 8, default=5, space='buy')
|
|
# buy_decalage3 = IntParameter(buy_decalage_deb_3.value + 1, 8, default=5, space='buy')
|
|
#
|
|
# buy_1_bb_lower_5 = DecimalParameter(0, 0.6, decimals=2, default=0.7, space='buy')
|
|
# buy_2_bb_lower_5 = DecimalParameter(0, 0.6, decimals=2, default=0.7, space='buy')
|
|
# buy_3_bb_lower_5 = DecimalParameter(0, 0.6, decimals=2, default=0.7, space='buy')
|
|
#
|
|
# buy_b_real = DecimalParameter(0.001, 0.999, decimals=4, default=0.11908, space='buy')
|
|
# buy_b_cat = CategoricalParameter([">R", "=R", "<R"], default='<R', space='buy')
|
|
# buy_b_pct = DecimalParameter(0.001, 0.02, decimals=3, default=0.005, space='buy')
|
|
# buy_b_pct_1 = DecimalParameter(-0.2, 0.2, decimals=2, default=0.005, space='buy')
|
|
# buy_b_pct_3 = DecimalParameter(-0.2, 0.2, decimals=2, default=0.005, space='buy')
|
|
# buy_b_pct_5 = DecimalParameter(-0.2, 0.2, decimals=2, default=0.005, space='buy')
|
|
# buy_b_bb_lowerband = DecimalParameter(1, 1.05, default=1, decimals=2, space='buy')
|
|
# buy_b_bb_width = DecimalParameter(0.01, 0.15, default=0.065, decimals=2, space='buy')
|
|
#
|
|
# decalage_h = IntParameter(0, 3, default=0, space='buy')
|
|
# decalage_b = IntParameter(0, 3, default=0, space='buy')
|
|
#
|
|
# buy_h_real = DecimalParameter(0.001, 0.999, decimals=4, default=0.11908, space='buy')
|
|
# buy_h_cat = CategoricalParameter([">R", "=R", "<R"], default='<R', space='buy')
|
|
# buy_h_pct = DecimalParameter(0.001, 0.02, decimals=3, default=0.005, space='buy')
|
|
# buy_h_pct_1 = DecimalParameter(-0.2, 0.2, decimals=2, default=0.005, space='buy')
|
|
# buy_h_pct_3 = DecimalParameter(-0.2, 0.2, decimals=2, default=0.005, space='buy')
|
|
# buy_h_pct_5 = DecimalParameter(-0.2, 0.2, decimals=2, default=0.005, space='buy')
|
|
# buy_h_bb_lowerband = DecimalParameter(1, 1.05, default=1, decimals=2, space='buy')
|
|
# buy_h_bb_width = DecimalParameter(0.01, 0.15, default=0.065, decimals=2, space='buy')
|
|
#
|
|
# buy_h_sma = CategoricalParameter(["sma3_1d", "sma5_1d", "sma10_1d"], default='sma10_1d', space='buy')
|
|
# buy_b_sma = CategoricalParameter(["sma3_1d", "sma5_1d", "sma10_1d"], default='sma10_1d', space='buy')
|
|
# buy_h_sma_close = CategoricalParameter(["sma3_1d", "sma5_1d", "sma10_1d"], default='sma3_1d', space='buy')
|
|
# buy_b_sma_close = CategoricalParameter(["sma3_1d", "sma5_1d", "sma10_1d"], default='sma3_1d', space='buy')
|
|
|
|
profit_b_no_change = BooleanParameter(default=True, space="sell")
|
|
profit_b_quick_lost = BooleanParameter(default=True, space="sell")
|
|
profit_b_sma5 = BooleanParameter(default=True, space="sell")
|
|
profit_b_sma10 = BooleanParameter(default=True, space="sell")
|
|
profit_b_sma20 = BooleanParameter(default=True, space="sell")
|
|
profit_b_quick_gain = BooleanParameter(default=True, space="sell")
|
|
profit_b_quick_gain_3 = BooleanParameter(default=True, space="sell")
|
|
profit_b_old_sma10 = BooleanParameter(default=True, space="sell")
|
|
profit_b_very_old_sma10 = BooleanParameter(default=True, space="sell")
|
|
profit_b_over_rsi = BooleanParameter(default=True, space="sell")
|
|
profit_b_short_loss = BooleanParameter(default=True, space="sell")
|
|
|
|
sell_b_percent = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell')
|
|
sell_b_percent3 = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell')
|
|
sell_b_candels = IntParameter(0, 48, default=12, space='sell')
|
|
|
|
sell_b_too_old_day = IntParameter(0, 10, default=5, space='sell')
|
|
sell_b_too_old_percent = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell')
|
|
|
|
sell_b_profit_no_change = DecimalParameter(0, 0.02, decimals=3, default=0.005, space='sell')
|
|
sell_b_profit_percent10 = DecimalParameter(0, 0.002, decimals=4, default=0.001, space='sell')
|
|
|
|
sell_b_RSI = IntParameter(70, 98, default=88, space='sell')
|
|
sell_b_RSI2 = IntParameter(70, 98, default=88, space='sell')
|
|
sell_b_RSI3 = IntParameter(70, 98, default=80, space='sell')
|
|
|
|
sell_b_RSI2_percent = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell')
|
|
# sell_b_expected_profit = DecimalParameter(0, 0.01, decimals=3, default=0.01, space='sell')
|
|
|
|
# profit_h_no_change = BooleanParameter(default=True, space="sell")
|
|
# profit_h_quick_lost = BooleanParameter(default=True, space="sell")
|
|
# profit_h_sma5 = BooleanParameter(default=True, space="sell")
|
|
# profit_h_sma10 = BooleanParameter(default=True, space="sell")
|
|
# profit_h_sma20 = BooleanParameter(default=True, space="sell")
|
|
# profit_h_quick_gain = BooleanParameter(default=True, space="sell")
|
|
# profit_h_quick_gain_3 = BooleanParameter(default=True, space="sell")
|
|
# profit_h_old_sma10 = BooleanParameter(default=True, space="sell")
|
|
# profit_h_very_old_sma10 = BooleanParameter(default=True, space="sell")
|
|
# profit_h_over_rsi = BooleanParameter(default=True, space="sell")
|
|
# profit_h_short_loss = BooleanParameter(default=True, space="sell")
|
|
#
|
|
# sell_h_percent = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell')
|
|
# sell_h_percent3 = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell')
|
|
# sell_h_candels = IntParameter(0, 48, default=12, space='sell')
|
|
#
|
|
# sell_h_too_old_day = IntParameter(0, 10, default=5, space='sell')
|
|
# sell_h_too_old_percent = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell')
|
|
#
|
|
# sell_h_profit_no_change = DecimalParameter(0, 0.02, decimals=3, default=0.005, space='sell')
|
|
# sell_h_profit_percent10 = DecimalParameter(0, 0.002, decimals=4, default=0.001, space='sell')
|
|
#
|
|
# sell_h_RSI = IntParameter(70, 98, default=88, space='sell')
|
|
# sell_h_RSI2 = IntParameter(70, 98, default=88, space='sell')
|
|
# sell_h_RSI3 = IntParameter(70, 98, default=80, space='sell')
|
|
|
|
sell_h_RSI2_percent = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell')
|
|
# sell_h_expected_profit = DecimalParameter(0, 0.01, decimals=3, default=0.01, space='sell')
|
|
|
|
def custom_sell(self, pair: str, trade: 'Trade', current_time: 'datetime', current_rate: float,
|
|
current_profit: float, **kwargs):
|
|
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
|
last_candle = dataframe.iloc[-1].squeeze()
|
|
previous_last_candle = dataframe.iloc[-2].squeeze()
|
|
previous_5_candle = dataframe.iloc[-5].squeeze()
|
|
|
|
expected_profit = 0.01
|
|
#print(last_candle['buy_tag'])
|
|
|
|
days = (current_time - trade.open_date_utc).days
|
|
######
|
|
|
|
if True:
|
|
if (current_profit > 0.015) & ((last_candle['percent'] < -0.005) | (last_candle['percent3'] < -0.005) | (last_candle['percent5'] < -0.005)):
|
|
return 'b_percent_quick'
|
|
|
|
if (current_profit >= - self.sell_b_too_old_percent.value) & (days >= self.sell_b_too_old_day.value)\
|
|
& (days < self.sell_b_too_old_day.value * 2)\
|
|
& (previous_last_candle['sma10'] > last_candle['sma10']) & (last_candle['percent3'] < 0):
|
|
return "b_too_old_0.01"
|
|
if (current_profit >= - self.sell_b_too_old_percent.value * 2) & (days >= self.sell_b_too_old_day.value * 2)\
|
|
& (days < self.sell_b_too_old_day.value * 3) \
|
|
& (previous_last_candle['sma10'] > last_candle['sma10']) & (last_candle['percent3'] < 0):
|
|
return "b_too_old_0.02"
|
|
if (current_profit >= - self.sell_b_too_old_percent.value * 3) & (days >= self.sell_b_too_old_day.value * 3) \
|
|
& (previous_last_candle['sma10'] > last_candle['sma10']) & (last_candle['percent3'] < 0):
|
|
return "b_too_old_0.03"
|
|
|
|
if self.profit_b_quick_lost.value and (current_profit >= 0.015) & (last_candle['percent3'] < -0.005):
|
|
return "b_quick_lost"
|
|
|
|
if self.profit_b_no_change.value and (current_profit > self.sell_b_profit_no_change.value) \
|
|
& (last_candle['percent10'] < self.sell_b_profit_percent10.value) & (last_candle['percent5'] < 0) \
|
|
& ((current_time - trade.open_date_utc).seconds >= 3600):
|
|
return "b_no_change"
|
|
|
|
if (current_profit > self.sell_b_percent.value) & (last_candle['percent3'] < - self.sell_b_percent3.value) \
|
|
& ((current_time - trade.open_date_utc).seconds <= 300 * self.sell_b_candels.value):
|
|
return "b_quick_gain_param"
|
|
|
|
if self.profit_b_sma5.value:
|
|
if (current_profit > expected_profit) \
|
|
& ((previous_5_candle['sma5'] > last_candle['sma5']) \
|
|
| (last_candle['percent3'] < -expected_profit) | (
|
|
last_candle['percent5'] < -expected_profit)) \
|
|
& ((last_candle['percent'] < 0) & (last_candle['percent3'] < 0)):
|
|
# print("over_bb_band_sma10_desc", pair, trade, " profit=", current_profit, " rate=", current_rate)
|
|
return 'b_sma5'
|
|
|
|
if self.profit_b_sma10.value:
|
|
if (current_profit > expected_profit) \
|
|
& ((previous_5_candle['sma10'] > last_candle['sma10']) \
|
|
| (last_candle['percent3'] < -expected_profit) | (
|
|
last_candle['percent5'] < -expected_profit)) \
|
|
& ((last_candle['percent'] < 0) & (last_candle['percent3'] < 0)):
|
|
# print("over_bb_band_sma10_desc", pair, trade, " profit=", current_profit, " rate=", current_rate)
|
|
return 'b_sma10'
|
|
|
|
if self.profit_b_sma20.value:
|
|
if (current_profit > last_candle['bb_width'] / 1.3) \
|
|
& (previous_last_candle['sma10'] > last_candle['sma10']) \
|
|
& ((current_time - trade.open_date_utc).seconds >= 3600) \
|
|
& ((previous_last_candle['sma20'] > last_candle['sma20']) &
|
|
((last_candle['percent5'] < 0) | (last_candle['percent10'] < 0) | (last_candle['percent20'] < 0))):
|
|
# print("over_bb_band_sma10_desc", pair, trade, " profit=", current_profit, " rate=", current_rate)
|
|
return 'b_sma20'
|
|
|
|
if self.profit_b_over_rsi.value:
|
|
if (current_profit > 0) & (previous_last_candle['rsi'] > self.sell_b_RSI.value): # & (last_candle['percent'] < 0): #| (previous_last_candle['rsi'] > 75 & last_candle['rsi'] < 70)):
|
|
# print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate)
|
|
return 'b_over_rsi'
|
|
|
|
if (current_profit > 0) & (previous_last_candle['rsi'] > self.sell_b_RSI2.value) & \
|
|
(last_candle['percent'] < - self.sell_b_RSI2_percent.value): #| (previous_last_candle['rsi'] > 75 & last_candle['rsi'] < 70)):
|
|
# print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate)
|
|
return 'b_over_rsi_2'
|
|
|
|
if (current_profit > 0) & (previous_last_candle['rsi'] > self.sell_b_RSI3.value) & \
|
|
(last_candle['close'] >= last_candle['max200']) & (last_candle['percent'] < - self.sell_b_RSI2_percent.value): #| (previous_last_candle['rsi'] > 75 & last_candle['rsi'] < 70)):
|
|
# print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate)
|
|
return 'b_over_rsi_max'
|
|
|
|
if self.profit_b_short_loss.value:
|
|
if (current_profit > -expected_profit) & (previous_last_candle['percent10'] > 0.04) & (last_candle['percent'] < 0)\
|
|
& (days >= 1): #| (previous_last_candle['rsi'] > 75 & last_candle['rsi'] < 70)):
|
|
# print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate)
|
|
return 'b_short_lost'
|
|
|
|
|
|
def informative_pairs(self):
|
|
return []
|
|
|
|
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
|
# MACD
|
|
# macd = ta.MACD(dataframe)
|
|
# dataframe['macd'] = macd['macd']
|
|
# dataframe['macdsignal'] = macd['macdsignal']
|
|
# dataframe['macdhist'] = macd['macdhist']
|
|
|
|
# # # Plus Directional Indicator / Movement
|
|
# dataframe['plus_dm'] = ta.PLUS_DM(dataframe)
|
|
# dataframe['plus_di'] = ta.PLUS_DI(dataframe)
|
|
#
|
|
# # Minus Directional Indicator / Movement
|
|
# dataframe['adx'] = ta.ADX(dataframe)
|
|
# dataframe['minus_dm'] = ta.MINUS_DM(dataframe)
|
|
# dataframe['minus_di'] = ta.MINUS_DI(dataframe)
|
|
|
|
# dataframe['min'] = ta.MIN(dataframe)
|
|
# dataframe['max'] = ta.MAX(dataframe)
|
|
|
|
# # Aroon, Aroon Oscillator
|
|
# aroon = ta.AROON(dataframe)
|
|
# dataframe['aroonup'] = aroon['aroonup']
|
|
# dataframe['aroondown'] = aroon['aroondown']
|
|
# dataframe['aroonosc'] = ta.AROONOSC(dataframe)
|
|
|
|
# RSI
|
|
dataframe['rsi'] = talib.RSI(dataframe)
|
|
dataframe['rsi5'] = talib.RSI(dataframe, timeperiod=5)
|
|
dataframe['pct_change'] = dataframe['close'].pct_change(5)
|
|
dataframe['min'] = talib.MIN(dataframe['close'], timeperiod=200)
|
|
dataframe['min10'] = talib.MIN(dataframe['close'], timeperiod=10)
|
|
dataframe['min20'] = talib.MIN(dataframe['close'], timeperiod=20)
|
|
dataframe['min50'] = talib.MIN(dataframe['close'], timeperiod=50)
|
|
dataframe['min200'] = talib.MIN(dataframe['close'], timeperiod=200)
|
|
dataframe['min200_5'] = dataframe['min200'] * 1.005
|
|
dataframe['moy200_12'] = dataframe['min200'].rolling(12).mean()
|
|
dataframe['max50'] = talib.MAX(dataframe['close'], timeperiod=50)
|
|
dataframe['max200'] = talib.MAX(dataframe['close'], timeperiod=200)
|
|
dataframe['min_max200'] = (dataframe['max200'] - dataframe['min200']) / dataframe['min200']
|
|
dataframe['min_max200_5'] = (dataframe['min200'] * (1 + dataframe['min_max200'] / 5))
|
|
dataframe['sma5'] = talib.SMA(dataframe, timeperiod=5)
|
|
dataframe['sma10'] = talib.SMA(dataframe, timeperiod=10)
|
|
dataframe['sma20'] = talib.SMA(dataframe, timeperiod=20)
|
|
dataframe['sma50'] = talib.SMA(dataframe, timeperiod=50)
|
|
dataframe['sma100'] = talib.SMA(dataframe, timeperiod=100)
|
|
dataframe["percent"] = (dataframe["close"] - dataframe["open"]) / dataframe["open"]
|
|
dataframe["percent5"] = dataframe["percent"].rolling(5).sum()
|
|
dataframe["percent3"] = dataframe["percent"].rolling(3).sum()
|
|
dataframe["percent10"] = dataframe["percent"].rolling(10).sum()
|
|
dataframe["percent20"] = dataframe["percent"].rolling(20).sum()
|
|
dataframe["percent50"] = dataframe["percent"].rolling(50).sum()
|
|
dataframe["volume10"] = dataframe["volume"].rolling(10).mean()
|
|
dataframe["volume10"] = dataframe["volume"].rolling(10).mean()
|
|
# 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"]
|
|
)
|
|
dataframe['volume5'] = dataframe["volume"].rolling(5).mean()
|
|
|
|
return dataframe
|
|
|
|
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
|
# conditions = [
|
|
# dataframe['bb_width'] >= self.buy_bollinger.value,
|
|
# (dataframe['close'] < dataframe['bb_lowerband']),
|
|
# (dataframe['close'] < dataframe['sma100'] * 0.99) #self.buy_sma_percent.value)
|
|
# ]
|
|
conditions_vol = []
|
|
conditions_vol.append(dataframe['percent5'] > 0) #self.buy_bollinger.value,
|
|
conditions_vol.append(dataframe['percent'].shift(1) > 0)
|
|
conditions_vol.append(dataframe['percent'] > 2 * dataframe['percent'].shift(1))
|
|
conditions_vol.append(dataframe['close'] > dataframe['open'])
|
|
# conditions_vol.append(dataframe['bb_width'] > dataframe['bb_width'].shift(3) * 2)
|
|
|
|
for decalage in range(5, 10):
|
|
conditions_vol.append(dataframe['bb_width'].shift(decalage) <= dataframe['bb_width'].shift(decalage - 1))
|
|
# conditions_vol.append(-0.002 <= dataframe['percent'].shift(decalage))
|
|
# conditions_vol.append(dataframe['percent'].shift(decalage) <= 0.002)
|
|
|
|
for decalage in range(2, 5):
|
|
conditions_vol.append(dataframe['volume5'].shift(decalage) <= dataframe['volume5'].shift(decalage - 1))
|
|
conditions_vol.append(dataframe['percent'].shift(decalage) <= dataframe['percent'].shift(decalage - 1))
|
|
|
|
# GUARDS AND TRENDS
|
|
|
|
dataframe.loc[
|
|
(
|
|
# (reduce(lambda x, y: x & y, conditions))
|
|
(reduce(lambda x, y: x & y, conditions_vol))
|
|
)
|
|
,
|
|
'buy'] = 1
|
|
return dataframe
|
|
|
|
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
|
# dataframe.loc[
|
|
# (
|
|
# (dataframe['close'] < dataframe['open']) &
|
|
# (dataframe['close'].shift(1) < dataframe['open'].shift(1)) &
|
|
# (dataframe['close'].shift(2) < dataframe['open'].shift(2)) &
|
|
# (dataframe['close'] < dataframe['bb_lowerband']) &
|
|
# (((dataframe['bb_lowerband'].shift(2) - dataframe['bb_lowerband']) / dataframe['bb_lowerband']) >= 0.02) &
|
|
# (((dataframe['close'].shift(1) - dataframe['close']) / dataframe['close']) >= 0.025)
|
|
# ), 'sell'] = 1
|
|
return dataframe
|