129 lines
4.8 KiB
Python
129 lines
4.8 KiB
Python
|
|
# --- 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
|
|
|
|
|
|
class InformativeSample(IStrategy):
|
|
"""
|
|
Sample strategy implementing Informative Pairs - compares stake_currency with USDT.
|
|
Not performing very well - but should serve as an example how to use a referential pair against USDT.
|
|
author@: xmatthias
|
|
github@: https://github.com/freqtrade/freqtrade-strategies
|
|
|
|
How to use it?
|
|
> python3 freqtrade -s InformativeSample
|
|
"""
|
|
|
|
# Minimal ROI designed for the strategy.
|
|
# This attribute will be overridden if the config file contains "minimal_roi"
|
|
minimal_roi = {
|
|
"60": 0.01,
|
|
"30": 0.03,
|
|
"20": 0.04,
|
|
"0": 0.05
|
|
}
|
|
|
|
# Optimal stoploss designed for the strategy
|
|
# This attribute will be overridden if the config file contains "stoploss"
|
|
stoploss = -0.10
|
|
|
|
# Optimal timeframe for the strategy
|
|
timeframe = '5m'
|
|
|
|
# trailing stoploss
|
|
trailing_stop = False
|
|
trailing_stop_positive = 0.01
|
|
trailing_stop_positive_offset = 0.02
|
|
|
|
# run "populate_indicators" only for new candle
|
|
ta_on_candle = False
|
|
|
|
# Experimental settings (configuration will overide these if set)
|
|
use_sell_signal = True
|
|
sell_profit_only = True
|
|
ignore_roi_if_buy_signal = False
|
|
|
|
# Optional order type mapping
|
|
order_types = {
|
|
'buy': 'limit',
|
|
'sell': 'limit',
|
|
'stoploss': 'market',
|
|
'stoploss_on_exchange': False
|
|
}
|
|
|
|
def informative_pairs(self):
|
|
"""
|
|
Define additional, informative pair/interval combinations to be cached from the exchange.
|
|
These pair/interval combinations are non-tradeable, unless they are part
|
|
of the whitelist as well.
|
|
For more information, please consult the documentation
|
|
:return: List of tuples in the format (pair, interval)
|
|
Sample: return [("ETH/USDT", "5m"),
|
|
("BTC/USDT", "15m"),
|
|
]
|
|
"""
|
|
return [(f"{self.config['stake_currency']}/USDT", self.timeframe)]
|
|
|
|
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
|
"""
|
|
Adds several different TA indicators to the given DataFrame
|
|
|
|
Performance Note: For the best performance be frugal on the number of indicators
|
|
you are using. Let uncomment only the indicator you are using in your strategies
|
|
or your hyperopt configuration, otherwise you will waste your memory and CPU usage.
|
|
"""
|
|
|
|
dataframe['ema20'] = ta.EMA(dataframe, timeperiod=20)
|
|
dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50)
|
|
dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100)
|
|
if self.dp:
|
|
# Get ohlcv data for informative pair.
|
|
data = self.dp.get_pair_dataframe(pair=f"{self.stake_currency}/USDT",
|
|
timeframe=self.timeframe)
|
|
# Combine the 2 dataframes using 'close'.
|
|
# This will result in a column named 'closeETH' or 'closeBTC' - depending on stake_currency.
|
|
dataframe = dataframe.merge(data[["date", "close"]], on="date", how="left", suffixes=("", self.config['stake_currency']))
|
|
|
|
# Calculate SMA20 on 'close' data for stake_currency/USDT. Resulting column is named as 'smaETH20' (if stake_currency is ETH)
|
|
dataframe[f"sma{self.config['stake_currency']}20"] = dataframe[f'close{self.stake_currency}'].rolling(20).mean()
|
|
|
|
return dataframe
|
|
|
|
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
|
"""
|
|
Based on TA indicators, populates the buy signal for the given dataframe
|
|
:param dataframe: DataFrame
|
|
:return: DataFrame with buy column
|
|
"""
|
|
dataframe.loc[
|
|
(
|
|
(dataframe['ema20'] > dataframe['ema50']) &
|
|
# stake/USDT above sma(stake/USDT, 20)
|
|
(dataframe[f'close{self.stake_currency}'] > dataframe[f'sma{self.stake_currency}20'])
|
|
),
|
|
'buy'] = 1
|
|
|
|
return dataframe
|
|
|
|
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
|
"""
|
|
Based on TA indicators, populates the sell signal for the given dataframe
|
|
:param dataframe: DataFrame
|
|
:return: DataFrame with buy column
|
|
"""
|
|
dataframe.loc[
|
|
(
|
|
(dataframe['ema20'] < dataframe['ema50']) &
|
|
# stake/USDT below sma(stake/USDT, 20)
|
|
(dataframe[f'close{self.stake_currency}'] < dataframe[f'sma{self.stake_currency}20'])
|
|
),
|
|
'sell'] = 1
|
|
return dataframe
|