From a3cc001f1b38264ef6be1863378e709de102e325 Mon Sep 17 00:00:00 2001 From: Rahul Date: Sat, 11 Feb 2023 18:31:25 -0500 Subject: [PATCH 01/10] initial commit --- freqtrade/enums/marketstatetype.py | 26 ++++++++++++++++++++++++++ freqtrade/rpc/telegram.py | 20 ++++++++++++++++++-- freqtrade/strategy/interface.py | 5 ++++- 3 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 freqtrade/enums/marketstatetype.py diff --git a/freqtrade/enums/marketstatetype.py b/freqtrade/enums/marketstatetype.py new file mode 100644 index 000000000..5f3f219d8 --- /dev/null +++ b/freqtrade/enums/marketstatetype.py @@ -0,0 +1,26 @@ +from enum import Enum + + +class MarketDirection(Enum): + """ + Enum for various market directions. + """ + LONG = "long" + SHORT = "short" + EVEN = "even" + NONE = '' + + @staticmethod + def string_to_enum(label : str) -> str: + match label: + case "long": + return MarketDirection.LONG + case "short": + return MarketDirection.SHORT + case "even": + return MarketDirection.EVEN + case 'none': + return MarketDirection.NONE + case _: + return None + diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index fbd675d02..750f0dd5f 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -25,7 +25,7 @@ from telegram.utils.helpers import escape_markdown from freqtrade.__init__ import __version__ from freqtrade.constants import DUST_PER_COIN, Config -from freqtrade.enums import RPCMessageType, SignalDirection, TradingMode +from freqtrade.enums import MarketDirection, RPCMessageType, SignalDirection, TradingMode from freqtrade.exceptions import OperationalException from freqtrade.misc import chunks, plural, round_coin_value from freqtrade.persistence import Trade @@ -129,7 +129,7 @@ class Telegram(RPCHandler): r'/weekly$', r'/weekly \d+$', r'/monthly$', r'/monthly \d+$', r'/forcebuy$', r'/forcelong$', r'/forceshort$', r'/forcesell$', r'/forceexit$', - r'/edge$', r'/health$', r'/help$', r'/version$' + r'/edge$', r'/health$', r'/help$', r'/version$', r'/marketdir$' ] # Create keys for generation valid_keys_print = [k.replace('$', '') for k in valid_keys] @@ -197,6 +197,7 @@ class Telegram(RPCHandler): CommandHandler('health', self._health), CommandHandler('help', self._help), CommandHandler('version', self._version), + CommandHandler('marketdir', self._changemarketdir) ] callbacks = [ CallbackQueryHandler(self._status_table, pattern='update_status_table'), @@ -1677,3 +1678,18 @@ class Telegram(RPCHandler): 'TelegramError: %s! Giving up on that message.', telegram_err.message ) + + @authorized_only + def _changemarketdir(self, update: Update, context: CallbackContext) -> None: + """ + Handler for /marketdir. + Updates the bot's market_direction + :param bot: telegram bot + :param update: message update + :return: None + """ + if context.args and len(context.args) == 1: + market_dir = MarketDirection.string_to_enum(context.args[0]) + if market_dir: + self._rpc._freqtrade.strategy.market_direction = market_dir + diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 70d656199..96f8681e9 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -12,7 +12,7 @@ from pandas import DataFrame from freqtrade.constants import Config, IntOrInf, ListPairsWithTimeframes from freqtrade.data.dataprovider import DataProvider -from freqtrade.enums import (CandleType, ExitCheckTuple, ExitType, RunMode, SignalDirection, +from freqtrade.enums import (CandleType, ExitCheckTuple, ExitType, MarketDirection, RunMode, SignalDirection, SignalTagType, SignalType, TradingMode) from freqtrade.exceptions import OperationalException, StrategyError from freqtrade.exchange import timeframe_to_minutes, timeframe_to_next_date, timeframe_to_seconds @@ -122,6 +122,9 @@ class IStrategy(ABC, HyperStrategyMixin): # Definition of plot_config. See plotting documentation for more details. plot_config: Dict = {} + # A self set parameter that represents the market direction. filled from configuration + market_direction: MarketDirection = MarketDirection.NONE + def __init__(self, config: Config) -> None: self.config = config # Dict to determine if analysis is necessary From b73089deb82d15ea2db1780f9d1ebea709ce3daa Mon Sep 17 00:00:00 2001 From: Rahul Date: Thu, 16 Feb 2023 17:51:50 -0500 Subject: [PATCH 02/10] fixed a test --- freqtrade/enums/__init__.py | 1 + tests/rpc/test_rpc_telegram.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/freqtrade/enums/__init__.py b/freqtrade/enums/__init__.py index 8ef53e12d..160ebc052 100644 --- a/freqtrade/enums/__init__.py +++ b/freqtrade/enums/__init__.py @@ -12,3 +12,4 @@ from freqtrade.enums.runmode import NON_UTIL_MODES, OPTIMIZE_MODES, TRADING_MODE from freqtrade.enums.signaltype import SignalDirection, SignalTagType, SignalType from freqtrade.enums.state import State from freqtrade.enums.tradingmode import TradingMode +from freqtrade.enums.marketstatetype import MarketDirection diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index 5e3c2bd18..050d7b7c0 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -106,7 +106,7 @@ def test_telegram_init(default_conf, mocker, caplog) -> None: "['reload_config', 'reload_conf'], ['show_config', 'show_conf'], " "['stopbuy', 'stopentry'], ['whitelist'], ['blacklist'], " "['blacklist_delete', 'bl_delete'], " - "['logs'], ['edge'], ['health'], ['help'], ['version']" + "['logs'], ['edge'], ['health'], ['help'], ['version'], ['marketdir']" "]") assert log_has(message_str, caplog) From 72af1912caff5862938bd0c71eff4998314d6107 Mon Sep 17 00:00:00 2001 From: Rahul Date: Fri, 17 Feb 2023 22:01:00 +0000 Subject: [PATCH 03/10] added new text --- freqtrade/enums/__init__.py | 2 +- freqtrade/enums/marketstatetype.py | 15 --------------- freqtrade/rpc/telegram.py | 16 ++++++++++++---- freqtrade/strategy/interface.py | 4 ++-- tests/rpc/test_rpc_telegram.py | 14 +++++++++++++- 5 files changed, 28 insertions(+), 23 deletions(-) diff --git a/freqtrade/enums/__init__.py b/freqtrade/enums/__init__.py index 160ebc052..69ef345e8 100644 --- a/freqtrade/enums/__init__.py +++ b/freqtrade/enums/__init__.py @@ -5,6 +5,7 @@ from freqtrade.enums.exitchecktuple import ExitCheckTuple from freqtrade.enums.exittype import ExitType from freqtrade.enums.hyperoptstate import HyperoptState from freqtrade.enums.marginmode import MarginMode +from freqtrade.enums.marketstatetype import MarketDirection from freqtrade.enums.ordertypevalue import OrderTypeValues from freqtrade.enums.pricetype import PriceType from freqtrade.enums.rpcmessagetype import NO_ECHO_MESSAGES, RPCMessageType, RPCRequestType @@ -12,4 +13,3 @@ from freqtrade.enums.runmode import NON_UTIL_MODES, OPTIMIZE_MODES, TRADING_MODE from freqtrade.enums.signaltype import SignalDirection, SignalTagType, SignalType from freqtrade.enums.state import State from freqtrade.enums.tradingmode import TradingMode -from freqtrade.enums.marketstatetype import MarketDirection diff --git a/freqtrade/enums/marketstatetype.py b/freqtrade/enums/marketstatetype.py index 5f3f219d8..8132be74a 100644 --- a/freqtrade/enums/marketstatetype.py +++ b/freqtrade/enums/marketstatetype.py @@ -9,18 +9,3 @@ class MarketDirection(Enum): SHORT = "short" EVEN = "even" NONE = '' - - @staticmethod - def string_to_enum(label : str) -> str: - match label: - case "long": - return MarketDirection.LONG - case "short": - return MarketDirection.SHORT - case "even": - return MarketDirection.EVEN - case 'none': - return MarketDirection.NONE - case _: - return None - diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 750f0dd5f..60a5bcce6 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -1689,7 +1689,15 @@ class Telegram(RPCHandler): :return: None """ if context.args and len(context.args) == 1: - market_dir = MarketDirection.string_to_enum(context.args[0]) - if market_dir: - self._rpc._freqtrade.strategy.market_direction = market_dir - + new_market_dir = context.args[0] + match new_market_dir: + case "long": + self._rpc._freqtrade.strategy.market_direction = MarketDirection.LONG + case "short": + self._rpc._freqtrade.strategy.market_direction = MarketDirection.SHORT + case "even": + self._rpc._freqtrade.strategy.market_direction = MarketDirection.EVEN + case "none": + self._rpc._freqtrade.strategy.market_direction = MarketDirection.NONE + case _: + raise RPCException("Invalid market direction provided") diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index d53f57d17..96b2ac8ce 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -12,8 +12,8 @@ from pandas import DataFrame from freqtrade.constants import Config, IntOrInf, ListPairsWithTimeframes from freqtrade.data.dataprovider import DataProvider -from freqtrade.enums import (CandleType, ExitCheckTuple, ExitType, MarketDirection, RunMode, SignalDirection, - SignalTagType, SignalType, TradingMode) +from freqtrade.enums import (CandleType, ExitCheckTuple, ExitType, MarketDirection, RunMode, + SignalDirection, SignalTagType, SignalType, TradingMode) from freqtrade.exceptions import OperationalException, StrategyError from freqtrade.exchange import timeframe_to_minutes, timeframe_to_next_date, timeframe_to_seconds from freqtrade.misc import remove_entry_exit_signals diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index 050d7b7c0..a63d7f9be 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -20,7 +20,7 @@ from telegram.error import BadRequest, NetworkError, TelegramError from freqtrade import __version__ from freqtrade.constants import CANCEL_REASON from freqtrade.edge import PairInfo -from freqtrade.enums import ExitType, RPCMessageType, RunMode, SignalDirection, State +from freqtrade.enums import ExitType, MarketDirection, RPCMessageType, RunMode, SignalDirection, State from freqtrade.exceptions import OperationalException from freqtrade.freqtradebot import FreqtradeBot from freqtrade.loggers import setup_logging @@ -2394,3 +2394,15 @@ def test__send_msg_keyboard(default_conf, mocker, caplog) -> None: assert log_has("using custom keyboard from config.json: " "[['/daily', '/stats', '/balance', '/profit', '/profit 5'], ['/count', " "'/start', '/reload_config', '/help']]", caplog) + + +def test_change_market_direction(default_conf, mocker, update) -> None: + telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf) + assert telegram._rpc._freqtrade.strategy.market_direction == MarketDirection.NONE + context = MagicMock() + context.args = ["long"] + telegram._changemarketdir(update, context) + assert telegram._rpc._freqtrade.strategy.market_direction == MarketDirection.LONG + context = MagicMock() + context.args = ["invalid"] + assert telegram._rpc._freqtrade.strategy.market_direction == MarketDirection.LONG From ade64f25d385d8fffda81b2e6199b7185bdc239a Mon Sep 17 00:00:00 2001 From: Rahul Gudise Date: Fri, 17 Feb 2023 17:08:39 -0500 Subject: [PATCH 04/10] fixed formatting --- tests/rpc/test_rpc_telegram.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index a63d7f9be..01a598734 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -20,7 +20,8 @@ from telegram.error import BadRequest, NetworkError, TelegramError from freqtrade import __version__ from freqtrade.constants import CANCEL_REASON from freqtrade.edge import PairInfo -from freqtrade.enums import ExitType, MarketDirection, RPCMessageType, RunMode, SignalDirection, State +from freqtrade.enums import (ExitType, MarketDirection, RPCMessageType, RunMode, SignalDirection, + State) from freqtrade.exceptions import OperationalException from freqtrade.freqtradebot import FreqtradeBot from freqtrade.loggers import setup_logging From 5fb539190d99746765ad8d68b179d01ba93a11aa Mon Sep 17 00:00:00 2001 From: Rahul Date: Sat, 18 Feb 2023 23:50:02 +0000 Subject: [PATCH 05/10] addressed some issues mentioned in PR --- freqtrade/rpc/rpc.py | 5 ++++- freqtrade/rpc/telegram.py | 25 +++++++++++++------------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 83bffb779..10ea04c6c 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -20,7 +20,7 @@ from freqtrade.constants import CANCEL_REASON, DATETIME_PRINT_FORMAT, Config from freqtrade.data.history import load_data from freqtrade.data.metrics import calculate_max_drawdown from freqtrade.enums import (CandleType, ExitCheckTuple, ExitType, SignalDirection, State, - TradingMode) + TradingMode, MarketDirection) from freqtrade.exceptions import ExchangeError, PricingError from freqtrade.exchange import timeframe_to_minutes, timeframe_to_msecs from freqtrade.loggers import bufferHandler @@ -1205,3 +1205,6 @@ class RPC: 'last_process_loc': last_p.astimezone(tzlocal()).strftime(DATETIME_PRINT_FORMAT), 'last_process_ts': int(last_p.timestamp()), } + + def _update_market_direction(self, direction: MarketDirection): + self._freqtrade.strategy.market_direction = direction \ No newline at end of file diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 60a5bcce6..65ef1bb21 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -129,7 +129,7 @@ class Telegram(RPCHandler): r'/weekly$', r'/weekly \d+$', r'/monthly$', r'/monthly \d+$', r'/forcebuy$', r'/forcelong$', r'/forceshort$', r'/forcesell$', r'/forceexit$', - r'/edge$', r'/health$', r'/help$', r'/version$', r'/marketdir$' + r'/edge$', r'/health$', r'/help$', r'/version$', r'/marketdir \d+$' ] # Create keys for generation valid_keys_print = [k.replace('$', '') for k in valid_keys] @@ -1690,14 +1690,15 @@ class Telegram(RPCHandler): """ if context.args and len(context.args) == 1: new_market_dir = context.args[0] - match new_market_dir: - case "long": - self._rpc._freqtrade.strategy.market_direction = MarketDirection.LONG - case "short": - self._rpc._freqtrade.strategy.market_direction = MarketDirection.SHORT - case "even": - self._rpc._freqtrade.strategy.market_direction = MarketDirection.EVEN - case "none": - self._rpc._freqtrade.strategy.market_direction = MarketDirection.NONE - case _: - raise RPCException("Invalid market direction provided") + if new_market_dir == "long": + self._rpc._update_market_direction(MarketDirection.LONG) + elif new_market_dir == "short": + self._rpc._update_market_direction(MarketDirection.SHORT) + elif new_market_dir == "even": + self._rpc._update_market_direction(MarketDirection.EVEN) + elif new_market_dir == "none": + self._rpc._update_market_direction(MarketDirection.NONE) + else: + raise RPCException("Invalid market direction provided") + else: + raise RPCException("Invalid usage of command /marketdir.") From 8927a92eafc5d30ab106daec8bb43cfdaecd43d7 Mon Sep 17 00:00:00 2001 From: Rahul Date: Sun, 19 Feb 2023 16:11:21 +0000 Subject: [PATCH 06/10] fixed lint issue --- freqtrade/rpc/rpc.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 10ea04c6c..f1e6c15e6 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -19,8 +19,8 @@ from freqtrade.configuration.timerange import TimeRange from freqtrade.constants import CANCEL_REASON, DATETIME_PRINT_FORMAT, Config from freqtrade.data.history import load_data from freqtrade.data.metrics import calculate_max_drawdown -from freqtrade.enums import (CandleType, ExitCheckTuple, ExitType, SignalDirection, State, - TradingMode, MarketDirection) +from freqtrade.enums import (CandleType, ExitCheckTuple, ExitType, MarketDirection, SignalDirection, + State, TradingMode) from freqtrade.exceptions import ExchangeError, PricingError from freqtrade.exchange import timeframe_to_minutes, timeframe_to_msecs from freqtrade.loggers import bufferHandler @@ -1207,4 +1207,4 @@ class RPC: } def _update_market_direction(self, direction: MarketDirection): - self._freqtrade.strategy.market_direction = direction \ No newline at end of file + self._freqtrade.strategy.market_direction = direction From 3033e274660df0fa1c0eb445b0d03a459eefcdb3 Mon Sep 17 00:00:00 2001 From: Rahul Gudise Date: Mon, 20 Feb 2023 15:53:29 -0500 Subject: [PATCH 07/10] Added documentation for new telegram command --- docs/telegram-usage.md | 9 ++++++++- freqtrade/rpc/telegram.py | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/telegram-usage.md b/docs/telegram-usage.md index 4626944c5..03bbb4b87 100644 --- a/docs/telegram-usage.md +++ b/docs/telegram-usage.md @@ -152,7 +152,7 @@ You can create your own keyboard in `config.json`: !!! Note "Supported Commands" Only the following commands are allowed. Command arguments are not supported! - `/start`, `/stop`, `/status`, `/status table`, `/trades`, `/profit`, `/performance`, `/daily`, `/stats`, `/count`, `/locks`, `/balance`, `/stopentry`, `/reload_config`, `/show_config`, `/logs`, `/whitelist`, `/blacklist`, `/edge`, `/help`, `/version` + `/start`, `/stop`, `/status`, `/status table`, `/trades`, `/profit`, `/performance`, `/daily`, `/stats`, `/count`, `/locks`, `/balance`, `/stopentry`, `/reload_config`, `/show_config`, `/logs`, `/whitelist`, `/blacklist`, `/edge`, `/help`, `/version`, `/marketdir` ## Telegram commands @@ -179,6 +179,7 @@ official commands. You can ask at any moment for help with `/help`. | `/count` | Displays number of trades used and available | `/locks` | Show currently locked pairs. | `/unlock ` | Remove the lock for this pair (or for this lock id). +| `/marketdir [long | short | even | none]` | Updates the user managed variable that represents the current market direction. | **Modify Trade states** | | `/forceexit | /fx ` | Instantly exits the given trade (Ignoring `minimum_roi`). | `/forceexit all | /fx all` | Instantly exits all open trades (Ignoring `minimum_roi`). @@ -416,3 +417,9 @@ ARDR/ETH 0.366667 0.143059 -0.01 ### /version > **Version:** `0.14.3` + +### /marketdir + +Updates the user managed variable that represents the current market direction. This variable is not set +to any market direction on bot startup and must be set by the user. For example `/marketdir long` +would set the variable to be `long`. diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 65ef1bb21..5f682b436 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -129,7 +129,7 @@ class Telegram(RPCHandler): r'/weekly$', r'/weekly \d+$', r'/monthly$', r'/monthly \d+$', r'/forcebuy$', r'/forcelong$', r'/forceshort$', r'/forcesell$', r'/forceexit$', - r'/edge$', r'/health$', r'/help$', r'/version$', r'/marketdir \d+$' + r'/edge$', r'/health$', r'/help$', r'/version$', r'/marketdir (long|short|even|none)$' ] # Create keys for generation valid_keys_print = [k.replace('$', '') for k in valid_keys] @@ -1495,6 +1495,8 @@ class Telegram(RPCHandler): "*/count:* `Show number of active trades compared to allowed number of trades`\n" "*/edge:* `Shows validated pairs by Edge if it is enabled` \n" "*/health* `Show latest process timestamp - defaults to 1970-01-01 00:00:00` \n" + "*/marketdir [long | short | even | none]:* `Updates the user managed variable" + " that represents the current market direction` \n" "_Statistics_\n" "------------\n" From 2261cbd92e180779f5e234d9fb5713c33b0b1e82 Mon Sep 17 00:00:00 2001 From: Rahul Gudise Date: Mon, 20 Feb 2023 16:22:17 -0500 Subject: [PATCH 08/10] fixed command regex and updated documentation --- docs/telegram-usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/telegram-usage.md b/docs/telegram-usage.md index 03bbb4b87..a4145df02 100644 --- a/docs/telegram-usage.md +++ b/docs/telegram-usage.md @@ -421,5 +421,5 @@ ARDR/ETH 0.366667 0.143059 -0.01 ### /marketdir Updates the user managed variable that represents the current market direction. This variable is not set -to any market direction on bot startup and must be set by the user. For example `/marketdir long` +to any valid market direction on bot startup and must be set by the user. As an example `/marketdir long` would set the variable to be `long`. From 39331b59ed011d40f1d314624ee30f88cda6fdd0 Mon Sep 17 00:00:00 2001 From: Rahul Date: Mon, 27 Feb 2023 22:51:22 +0000 Subject: [PATCH 09/10] Fixed issues raised in PR --- docs/telegram-usage.md | 14 +++++++--- freqtrade/enums/marketstatetype.py | 6 ++++- freqtrade/rpc/rpc.py | 5 +++- freqtrade/rpc/telegram.py | 42 ++++++++++++++++++++---------- 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/docs/telegram-usage.md b/docs/telegram-usage.md index a4145df02..dfab3754c 100644 --- a/docs/telegram-usage.md +++ b/docs/telegram-usage.md @@ -179,7 +179,7 @@ official commands. You can ask at any moment for help with `/help`. | `/count` | Displays number of trades used and available | `/locks` | Show currently locked pairs. | `/unlock ` | Remove the lock for this pair (or for this lock id). -| `/marketdir [long | short | even | none]` | Updates the user managed variable that represents the current market direction. +| `/marketdir [long | short | even | none]` | Updates the user managed variable that represents the current market direction. If no direction is provided, the currently set direction will be displayed. | **Modify Trade states** | | `/forceexit | /fx ` | Instantly exits the given trade (Ignoring `minimum_roi`). | `/forceexit all | /fx all` | Instantly exits all open trades (Ignoring `minimum_roi`). @@ -420,6 +420,12 @@ ARDR/ETH 0.366667 0.143059 -0.01 ### /marketdir -Updates the user managed variable that represents the current market direction. This variable is not set -to any valid market direction on bot startup and must be set by the user. As an example `/marketdir long` -would set the variable to be `long`. +If a market direction is provided the command updates the user managed variable that represents the current market direction. +This variable is not set to any valid market direction on bot startup and must be set by the user. The example below is for `/marketdir long`: +``` +Successfully updated marketdirection from none to long. +``` +If no market direction is provided the command outputs the currently set market directions. The example below is for `/marketdir`: +``` +Currently set marketdirection: even +``` diff --git a/freqtrade/enums/marketstatetype.py b/freqtrade/enums/marketstatetype.py index 8132be74a..5cede32c2 100644 --- a/freqtrade/enums/marketstatetype.py +++ b/freqtrade/enums/marketstatetype.py @@ -8,4 +8,8 @@ class MarketDirection(Enum): LONG = "long" SHORT = "short" EVEN = "even" - NONE = '' + NONE = "none" + + def __str__(self): + # convert to string + return self.value diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index f1e6c15e6..d2e66cfff 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -1206,5 +1206,8 @@ class RPC: 'last_process_ts': int(last_p.timestamp()), } - def _update_market_direction(self, direction: MarketDirection): + def _update_market_direction(self, direction: MarketDirection) -> None: self._freqtrade.strategy.market_direction = direction + + def _get_market_direction(self) -> MarketDirection: + return self._freqtrade.strategy.market_direction diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 5f682b436..050dc3f31 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -129,7 +129,8 @@ class Telegram(RPCHandler): r'/weekly$', r'/weekly \d+$', r'/monthly$', r'/monthly \d+$', r'/forcebuy$', r'/forcelong$', r'/forceshort$', r'/forcesell$', r'/forceexit$', - r'/edge$', r'/health$', r'/help$', r'/version$', r'/marketdir (long|short|even|none)$' + r'/edge$', r'/health$', r'/help$', r'/version$', r'/marketdir (long|short|even|none)$', + r'/marketdir$' ] # Create keys for generation valid_keys_print = [k.replace('$', '') for k in valid_keys] @@ -1495,8 +1496,9 @@ class Telegram(RPCHandler): "*/count:* `Show number of active trades compared to allowed number of trades`\n" "*/edge:* `Shows validated pairs by Edge if it is enabled` \n" "*/health* `Show latest process timestamp - defaults to 1970-01-01 00:00:00` \n" - "*/marketdir [long | short | even | none]:* `Updates the user managed variable" - " that represents the current market direction` \n" + "*/marketdir [long | short | even | none]:* `Updates the user managed variable " + "that represents the current market direction. If no direction is provided `" + "`the currently set market direction will be output.` \n" "_Statistics_\n" "------------\n" @@ -1691,16 +1693,28 @@ class Telegram(RPCHandler): :return: None """ if context.args and len(context.args) == 1: - new_market_dir = context.args[0] - if new_market_dir == "long": - self._rpc._update_market_direction(MarketDirection.LONG) - elif new_market_dir == "short": - self._rpc._update_market_direction(MarketDirection.SHORT) - elif new_market_dir == "even": - self._rpc._update_market_direction(MarketDirection.EVEN) - elif new_market_dir == "none": - self._rpc._update_market_direction(MarketDirection.NONE) + new_market_dir_arg = context.args[0] + old_market_dir = self._rpc._get_market_direction() + new_market_dir = None + if new_market_dir_arg == "long": + new_market_dir = MarketDirection.LONG + elif new_market_dir_arg == "short": + new_market_dir = MarketDirection.SHORT + elif new_market_dir_arg == "even": + new_market_dir = MarketDirection.EVEN + elif new_market_dir_arg == "none": + new_market_dir = MarketDirection.NONE + + if new_market_dir is not None: + self._rpc._update_market_direction(new_market_dir) + self._send_msg("Successfully updated market direction" + f" from *{old_market_dir}* to *{new_market_dir}*.") else: - raise RPCException("Invalid market direction provided") + raise RPCException("Invalid market direction provided. \n" + "Valid market directions: *long, short, even, none*") + elif context.args is not None and len(context.args) == 0: + old_market_dir = self._rpc._get_market_direction() + self._send_msg(f"Currently set market direction: *{old_market_dir}*") else: - raise RPCException("Invalid usage of command /marketdir.") + raise RPCException("Invalid usage of command /marketdir. \n" + "Usage: */marketdir [short | long | even | none]*") From 0899e5cb8337adde4de58e0b80a578c4af0ed497 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 28 Feb 2023 06:41:18 +0100 Subject: [PATCH 10/10] Improve documentation wording --- docs/telegram-usage.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/telegram-usage.md b/docs/telegram-usage.md index dfab3754c..653d31ee6 100644 --- a/docs/telegram-usage.md +++ b/docs/telegram-usage.md @@ -422,10 +422,18 @@ ARDR/ETH 0.366667 0.143059 -0.01 If a market direction is provided the command updates the user managed variable that represents the current market direction. This variable is not set to any valid market direction on bot startup and must be set by the user. The example below is for `/marketdir long`: + ``` Successfully updated marketdirection from none to long. ``` + If no market direction is provided the command outputs the currently set market directions. The example below is for `/marketdir`: + ``` Currently set marketdirection: even ``` + +You can use the market direction in your strategy via `self.market_direction`. + +!!! Warning "Bot restarts" + Please note that the market direction is not persisted, and will be reset after a bot restart/reload.