70 lines
2.6 KiB
Python
70 lines
2.6 KiB
Python
from freqtrade.strategy.interface import IStrategy
|
|
import pandas as pd
|
|
import numpy as np
|
|
import talib as ta
|
|
import logging
|
|
import datetime
|
|
from freqtrade.strategy import IStrategy, IntParameter, DecimalParameter
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class MyOptimizedStrategy(IStrategy):
|
|
# --- Hyperoptables ---
|
|
buy_rsi = IntParameter(20, 50, default=30, space="buy")
|
|
sell_rsi = IntParameter(50, 80, default=70, space="sell")
|
|
|
|
# --- FreqAI 相关 ---
|
|
minimal_roi = {"0": 0.05, "30": 0.02, "60": 0}
|
|
stoploss = -0.1
|
|
trailing_stop = True
|
|
trailing_stop_positive = 0.03
|
|
trailing_stop_positive_offset = 0.05
|
|
|
|
def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
|
|
label_period = self.freqai_info["feature_parameters"]["label_period_candles"]
|
|
dataframe["up_or_down"] = np.where(
|
|
dataframe["close"].shift(-label_period) > dataframe["close"], 1, 0
|
|
)
|
|
dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)
|
|
|
|
# 添加 volume_ma
|
|
dataframe["volume_ma"] = dataframe["volume"].rolling(window=20).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.replace([np.inf, -np.inf], 0, inplace=True)
|
|
dataframe.ffill(inplace=True)
|
|
dataframe.fillna(0, inplace=True)
|
|
|
|
return dataframe
|
|
|
|
def populate_entry_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
|
|
conditions = [
|
|
(dataframe['do_predict'] == 1),
|
|
(dataframe['rsi'] < dataframe['&-buy_rsi_pred']),
|
|
(dataframe['close'] < dataframe['bb_lowerband'])
|
|
]
|
|
dataframe.loc[reduce(np.logical_and, conditions), 'enter_long'] = 1
|
|
return dataframe
|
|
|
|
def populate_exit_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
|
|
conditions = [
|
|
(dataframe['do_predict'] == 1),
|
|
(dataframe['rsi'] > dataframe['&-sell_rsi_pred'])
|
|
]
|
|
dataframe.loc[reduce(np.logical_and, conditions), 'exit_long'] = 1
|
|
return dataframe
|
|
|
|
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime, current_rate: float,
|
|
current_profit: float, **kwargs) -> float:
|
|
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
|
last_row = dataframe.iloc[-1]
|
|
if "&-stoploss" in last_row:
|
|
return float(last_row["&-stoploss"])
|
|
return self.stoploss
|
|
|