# --- Do not remove these libs --- from freqtrade.strategy.interface import IStrategy from typing import Dict, List from functools import reduce from pandas import DataFrame # -------------------------------- import talib.abstract as ta import freqtrade.vendor.qtpylib.indicators as qtpylib from scipy.signal import argrelextrema import numpy as np class Minmax(IStrategy): INTERFACE_VERSION = 3 minimal_roi = {'0': 10} stoploss = -0.05 timeframe = '1h' trailing_stop = False process_only_new_candles = False def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe_copy = dataframe.copy() frame_size = 500 len_df = len(dataframe) dataframe['entry_signal'] = False dataframe['exit_signal'] = False lookback_size = 100 # Let's calculate argrelextrema on separated data slices and get only last result to avoid lookahead bias! for i in range(len_df): if i + frame_size < len_df: slice = dataframe_copy[i:i + frame_size] min_peaks = argrelextrema(slice['close'].values, np.less, order=lookback_size) max_peaks = argrelextrema(slice['close'].values, np.greater, order=lookback_size) # Somehow we never getting last index of a frame as min or max. What a surprise :) # So lets take penultimate result and use it as a signal to entry/exit. if len(min_peaks[0]) and min_peaks[0][-1] == frame_size - 2: # signal that penultimate candle is min # lets entry here dataframe.at[i + frame_size, 'entry_signal'] = True if len(max_peaks[0]) and max_peaks[0][-1] == frame_size - 2: # oh it seams that penultimate candle is max # lets exit ASAP dataframe.at[i + frame_size, 'exit_signal'] = True if i + frame_size == len_df - 1: print(min_peaks) # A # Wow what a pathetic results!!!Where is my Trillions of BTC?!?!?! | # Let's make it in a lookahead way to make more numbers in backtesting!! | # | # | # Comment this section!! ------------------------------------------------------| # Uncomment this section ASAP! # | # | # | # | # V # min_peaks = argrelextrema(dataframe['close'].values, np.less, order=loockback_size) # max_peaks = argrelextrema(dataframe['close'].values, np.greater, order=loockback_size) # # # for mp in min_peaks[0]: # dataframe.at[mp, 'entry_signal'] = True # # for mp in max_peaks[0]: # dataframe.at[mp, 'exit_signal'] = True # Uhhh that's better! Ordering Lambo now! return dataframe def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: print(dataframe.tail(30)) dataframe.loc[dataframe['entry_signal'], 'entry'] = 1 return dataframe def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[dataframe['exit_signal'], 'exit'] = 1 return dataframe