feat: add buy signal name

This commit is contained in:
kevinjulian 2021-07-20 04:58:20 +07:00
parent e9dbd57da4
commit 9e63bdbac9
6 changed files with 25 additions and 10 deletions

View File

@ -2,5 +2,5 @@
from freqtrade.enums.rpcmessagetype import RPCMessageType from freqtrade.enums.rpcmessagetype import RPCMessageType
from freqtrade.enums.runmode import NON_UTIL_MODES, OPTIMIZE_MODES, TRADING_MODES, RunMode from freqtrade.enums.runmode import NON_UTIL_MODES, OPTIMIZE_MODES, TRADING_MODES, RunMode
from freqtrade.enums.selltype import SellType from freqtrade.enums.selltype import SellType
from freqtrade.enums.signaltype import SignalType from freqtrade.enums.signaltype import SignalType, SignalNameType
from freqtrade.enums.state import State from freqtrade.enums.state import State

View File

@ -7,3 +7,10 @@ class SignalType(Enum):
""" """
BUY = "buy" BUY = "buy"
SELL = "sell" SELL = "sell"
class SignalNameType(Enum):
"""
Enum to distinguish between buy and sell signals
"""
BUY_SIGNAL_NAME = "buy_signal_name"

View File

@ -420,7 +420,7 @@ class FreqtradeBot(LoggingMixin):
return False return False
# running get_signal on historical data fetched # running get_signal on historical data fetched
(buy, sell) = self.strategy.get_signal(pair, self.strategy.timeframe, analyzed_df) (buy, sell, buy_signal_name) = self.strategy.get_signal(pair, self.strategy.timeframe, analyzed_df)
if buy and not sell: if buy and not sell:
stake_amount = self.wallets.get_trade_stake_amount(pair, self.edge) stake_amount = self.wallets.get_trade_stake_amount(pair, self.edge)
@ -435,11 +435,11 @@ class FreqtradeBot(LoggingMixin):
if ((bid_check_dom.get('enabled', False)) and if ((bid_check_dom.get('enabled', False)) and
(bid_check_dom.get('bids_to_ask_delta', 0) > 0)): (bid_check_dom.get('bids_to_ask_delta', 0) > 0)):
if self._check_depth_of_market_buy(pair, bid_check_dom): if self._check_depth_of_market_buy(pair, bid_check_dom):
return self.execute_buy(pair, stake_amount) return self.execute_buy(pair, stake_amount, buy_signal_name=buy_signal_name)
else: else:
return False return False
return self.execute_buy(pair, stake_amount) return self.execute_buy(pair, stake_amount, buy_signal_name=buy_signal_name)
else: else:
return False return False
@ -468,7 +468,7 @@ class FreqtradeBot(LoggingMixin):
return False return False
def execute_buy(self, pair: str, stake_amount: float, price: Optional[float] = None, def execute_buy(self, pair: str, stake_amount: float, price: Optional[float] = None,
forcebuy: bool = False) -> bool: forcebuy: bool = False, buy_signal_name: str = '') -> bool:
""" """
Executes a limit buy for the given pair Executes a limit buy for the given pair
:param pair: pair for which we want to create a LIMIT_BUY :param pair: pair for which we want to create a LIMIT_BUY
@ -562,6 +562,7 @@ class FreqtradeBot(LoggingMixin):
exchange=self.exchange.id, exchange=self.exchange.id,
open_order_id=order_id, open_order_id=order_id,
strategy=self.strategy.get_strategy_name(), strategy=self.strategy.get_strategy_name(),
buy_signal_name=buy_signal_name,
timeframe=timeframe_to_minutes(self.config['timeframe']) timeframe=timeframe_to_minutes(self.config['timeframe'])
) )
trade.orders.append(order_obj) trade.orders.append(order_obj)

View File

@ -42,6 +42,7 @@ CLOSE_IDX = 3
SELL_IDX = 4 SELL_IDX = 4
LOW_IDX = 5 LOW_IDX = 5
HIGH_IDX = 6 HIGH_IDX = 6
BUY_SIGNAL_NAME_IDX = 7
class Backtesting: class Backtesting:
@ -189,7 +190,7 @@ class Backtesting:
""" """
# Every change to this headers list must evaluate further usages of the resulting tuple # Every change to this headers list must evaluate further usages of the resulting tuple
# and eventually change the constants for indexes at the top # and eventually change the constants for indexes at the top
headers = ['date', 'buy', 'open', 'close', 'sell', 'low', 'high'] headers = ['date', 'buy', 'open', 'close', 'sell', 'low', 'high', 'buy_signal_name']
data: Dict = {} data: Dict = {}
# Create dict with data # Create dict with data
for pair, pair_data in processed.items(): for pair, pair_data in processed.items():
@ -332,6 +333,7 @@ class Backtesting:
fee_open=self.fee, fee_open=self.fee,
fee_close=self.fee, fee_close=self.fee,
is_open=True, is_open=True,
buy_signal_name=row[BUY_SIGNAL_NAME_IDX],
exchange='backtesting', exchange='backtesting',
) )
return trade return trade

View File

@ -257,6 +257,7 @@ class LocalTrade():
sell_reason: str = '' sell_reason: str = ''
sell_order_status: str = '' sell_order_status: str = ''
strategy: str = '' strategy: str = ''
buy_signal_name: str = ''
timeframe: Optional[int] = None timeframe: Optional[int] = None
def __init__(self, **kwargs): def __init__(self, **kwargs):
@ -288,6 +289,7 @@ class LocalTrade():
'amount_requested': round(self.amount_requested, 8) if self.amount_requested else None, 'amount_requested': round(self.amount_requested, 8) if self.amount_requested else None,
'stake_amount': round(self.stake_amount, 8), 'stake_amount': round(self.stake_amount, 8),
'strategy': self.strategy, 'strategy': self.strategy,
'buy_signal_name': self.buy_signal_name,
'timeframe': self.timeframe, 'timeframe': self.timeframe,
'fee_open': self.fee_open, 'fee_open': self.fee_open,
@ -703,6 +705,7 @@ class Trade(_DECL_BASE, LocalTrade):
sell_reason = Column(String(100), nullable=True) sell_reason = Column(String(100), nullable=True)
sell_order_status = Column(String(100), nullable=True) sell_order_status = Column(String(100), nullable=True)
strategy = Column(String(100), nullable=True) strategy = Column(String(100), nullable=True)
buy_signal_name = Column(String(100), nullable=True)
timeframe = Column(Integer, nullable=True) timeframe = Column(Integer, nullable=True)
def __init__(self, **kwargs): def __init__(self, **kwargs):

View File

@ -13,7 +13,7 @@ from pandas import DataFrame
from freqtrade.constants import ListPairsWithTimeframes from freqtrade.constants import ListPairsWithTimeframes
from freqtrade.data.dataprovider import DataProvider from freqtrade.data.dataprovider import DataProvider
from freqtrade.enums import SellType, SignalType from freqtrade.enums import SellType, SignalType, SignalNameType
from freqtrade.exceptions import OperationalException, StrategyError from freqtrade.exceptions import OperationalException, StrategyError
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds
from freqtrade.exchange.exchange import timeframe_to_next_date from freqtrade.exchange.exchange import timeframe_to_next_date
@ -506,7 +506,9 @@ class IStrategy(ABC, HyperStrategyMixin):
) )
return False, False return False, False
(buy, sell) = latest[SignalType.BUY.value] == 1, latest[SignalType.SELL.value] == 1 (buy, sell, buy_signal_name) = latest[SignalType.BUY.value] == 1,\
latest[SignalType.SELL.value] == 1,\
latest.get(SignalNameType.BUY_SIGNAL_NAME.value, '')
logger.debug('trigger: %s (pair=%s) buy=%s sell=%s', logger.debug('trigger: %s (pair=%s) buy=%s sell=%s',
latest['date'], pair, str(buy), str(sell)) latest['date'], pair, str(buy), str(sell))
timeframe_seconds = timeframe_to_seconds(timeframe) timeframe_seconds = timeframe_to_seconds(timeframe)
@ -514,8 +516,8 @@ class IStrategy(ABC, HyperStrategyMixin):
current_time=datetime.now(timezone.utc), current_time=datetime.now(timezone.utc),
timeframe_seconds=timeframe_seconds, timeframe_seconds=timeframe_seconds,
buy=buy): buy=buy):
return False, sell return False, sell, buy_signal_name
return buy, sell return buy, sell, buy_signal_name
def ignore_expired_candle(self, latest_date: datetime, current_time: datetime, def ignore_expired_candle(self, latest_date: datetime, current_time: datetime,
timeframe_seconds: int, buy: bool): timeframe_seconds: int, buy: bool):