mirror of
https://github.com/freqtrade/freqtrade.git
synced 2024-11-10 10:21:59 +00:00
feat: add buy signal name
This commit is contained in:
parent
e9dbd57da4
commit
9e63bdbac9
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user