diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 28dd1fae5..7db9c1e30 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -30,7 +30,8 @@ from freqtrade.plugins.protectionmanager import ProtectionManager from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.rpc import RPCManager from freqtrade.rpc.external_message_consumer import ExternalMessageConsumer -from freqtrade.rpc.rpc_types import RPCBuyMsg, RPCCancelMsg, RPCSellCancelMsg, RPCSellMsg +from freqtrade.rpc.rpc_types import (RPCBuyMsg, RPCCancelMsg, RPCProtectionMsg, RPCSellCancelMsg, + RPCSellMsg) from freqtrade.strategy.interface import IStrategy from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper from freqtrade.util import FtPrecise @@ -1853,14 +1854,18 @@ class FreqtradeBot(LoggingMixin): self.strategy.lock_pair(pair, datetime.now(timezone.utc), reason='Auto lock') prot_trig = self.protections.stop_per_pair(pair, side=side) if prot_trig: - msg = {'type': RPCMessageType.PROTECTION_TRIGGER, } - msg.update(prot_trig.to_json()) + msg: RPCProtectionMsg = { + 'type': RPCMessageType.PROTECTION_TRIGGER, + **prot_trig.to_json() + } self.rpc.send_msg(msg) prot_trig_glb = self.protections.global_stop(side=side) if prot_trig_glb: - msg = {'type': RPCMessageType.PROTECTION_TRIGGER_GLOBAL, } - msg.update(prot_trig_glb.to_json()) + msg = { + 'type': RPCMessageType.PROTECTION_TRIGGER_GLOBAL, + **prot_trig_glb.to_json() + } self.rpc.send_msg(msg) def apply_fee_conditional(self, trade: Trade, trade_base_currency: str, diff --git a/freqtrade/rpc/rpc_types.py b/freqtrade/rpc/rpc_types.py index bde985548..b81591954 100644 --- a/freqtrade/rpc/rpc_types.py +++ b/freqtrade/rpc/rpc_types.py @@ -1,19 +1,22 @@ from datetime import datetime -from typing import Optional, TypedDict, Union +from typing import List, Literal, Optional, TypedDict, Union from freqtrade.enums import RPCMessageType class RPCSendMsgBase(TypedDict): - type: RPCMessageType + pass + # ty1pe: Literal[RPCMessageType] class RPCStatusMsg(RPCSendMsgBase): """Used for Status, Startup and Warning messages""" + type: Literal[RPCMessageType.STATUS] status: str class RPCProtectionMsg(RPCSendMsgBase): + type: Literal[RPCMessageType.PROTECTION_TRIGGER, RPCMessageType.PROTECTION_TRIGGER_GLOBAL] id: int pair: str base_currency: Optional[str] @@ -26,7 +29,13 @@ class RPCProtectionMsg(RPCSendMsgBase): active: bool +class RPCWhitelistMsg(RPCSendMsgBase): + type: Literal[RPCMessageType.WHITELIST] + data: List[str] + + class RPCBuyMsg(RPCSendMsgBase): + type: Literal[RPCMessageType.ENTRY, RPCMessageType.ENTRY_FILL] trade_id: int buy_tag: Optional[str] enter_tag: Optional[str] @@ -47,10 +56,12 @@ class RPCBuyMsg(RPCSendMsgBase): class RPCCancelMsg(RPCBuyMsg): + type: Literal[RPCMessageType.ENTRY_CANCEL] reason: str class RPCSellMsg(RPCBuyMsg): + type: Literal[RPCMessageType.EXIT, RPCMessageType.EXIT_FILL] cumulative_profit: float gain: str # Literal["profit", "loss"] close_rate: float @@ -64,6 +75,7 @@ class RPCSellMsg(RPCBuyMsg): class RPCSellCancelMsg(RPCBuyMsg): + type: Literal[RPCMessageType.EXIT_CANCEL] reason: str gain: str # Literal["profit", "loss"] profit_amount: float @@ -76,6 +88,7 @@ class RPCSellCancelMsg(RPCBuyMsg): RPCSendMsg = Union[ RPCStatusMsg, RPCProtectionMsg, + RPCWhitelistMsg, RPCBuyMsg, RPCCancelMsg, RPCSellMsg,