diff --git a/freqtrade/freqai/RL/BaseReinforcementLearningModel.py b/freqtrade/freqai/RL/BaseReinforcementLearningModel.py index 9481f8f7e..db9fba85a 100644 --- a/freqtrade/freqai/RL/BaseReinforcementLearningModel.py +++ b/freqtrade/freqai/RL/BaseReinforcementLearningModel.py @@ -3,7 +3,7 @@ import importlib import logging from abc import abstractmethod from collections.abc import Callable -from datetime import datetime, timezone +from datetime import UTC, datetime from pathlib import Path from typing import Any @@ -239,7 +239,7 @@ class BaseReinforcementLearningModel(IFreqaiModel): pair, refresh=False, side="exit", is_short=trade.is_short ) - now = datetime.now(timezone.utc).timestamp() + now = datetime.now(UTC).timestamp() trade_duration = int((now - trade.open_date_utc.timestamp()) / self.base_tf_seconds) current_profit = trade.calc_profit_ratio(current_rate) if trade.is_short: diff --git a/freqtrade/ft_types/plot_annotation_type.py b/freqtrade/ft_types/plot_annotation_type.py index b08db3c57..4da4102c4 100644 --- a/freqtrade/ft_types/plot_annotation_type.py +++ b/freqtrade/ft_types/plot_annotation_type.py @@ -1,8 +1,8 @@ from datetime import datetime -from typing import Literal +from typing import Literal, Required from pydantic import TypeAdapter -from typing_extensions import Required, TypedDict +from typing_extensions import TypedDict class AnnotationType(TypedDict, total=False): diff --git a/freqtrade/optimize/base_analysis.py b/freqtrade/optimize/base_analysis.py index a2fe53867..7e75137ec 100644 --- a/freqtrade/optimize/base_analysis.py +++ b/freqtrade/optimize/base_analysis.py @@ -1,6 +1,6 @@ import logging from copy import deepcopy -from datetime import datetime, timezone +from datetime import UTC, datetime from typing import Any from pandas import DataFrame @@ -38,7 +38,7 @@ class BaseAnalysis: @staticmethod def dt_to_timestamp(dt: datetime): - timestamp = int(dt.replace(tzinfo=timezone.utc).timestamp()) + timestamp = int(dt.replace(tzinfo=UTC).timestamp()) return timestamp def fill_full_varholder(self): @@ -48,12 +48,12 @@ class BaseAnalysis: parsed_timerange = TimeRange.parse_timerange(self.local_config["timerange"]) if parsed_timerange.startdt is None: - self.full_varHolder.from_dt = datetime.fromtimestamp(0, tz=timezone.utc) + self.full_varHolder.from_dt = datetime.fromtimestamp(0, tz=UTC) else: self.full_varHolder.from_dt = parsed_timerange.startdt if parsed_timerange.stopdt is None: - self.full_varHolder.to_dt = datetime.now(timezone.utc) + self.full_varHolder.to_dt = datetime.now(UTC) else: self.full_varHolder.to_dt = parsed_timerange.stopdt diff --git a/freqtrade/optimize/hyperopt/hyperopt_optimizer.py b/freqtrade/optimize/hyperopt/hyperopt_optimizer.py index 94be5e50e..7f56dfb81 100644 --- a/freqtrade/optimize/hyperopt/hyperopt_optimizer.py +++ b/freqtrade/optimize/hyperopt/hyperopt_optimizer.py @@ -6,7 +6,7 @@ and will be sent to the hyperopt worker processes. import logging import sys import warnings -from datetime import datetime, timezone +from datetime import UTC, datetime from pathlib import Path from typing import Any @@ -273,7 +273,7 @@ class HyperOptimizer: Keep this function as optimized as possible! """ HyperoptStateContainer.set_state(HyperoptState.OPTIMIZE) - backtest_start_time = datetime.now(timezone.utc) + backtest_start_time = datetime.now(UTC) # Apply parameters if HyperoptTools.has_space(self.config, "buy"): @@ -330,7 +330,7 @@ class HyperOptimizer: bt_results = self.backtesting.backtest( processed=processed, start_date=self.min_date, end_date=self.max_date ) - backtest_end_time = datetime.now(timezone.utc) + backtest_end_time = datetime.now(UTC) bt_results.update( { "backtest_start_time": int(backtest_start_time.timestamp()), diff --git a/freqtrade/optimize/hyperopt_tools.py b/freqtrade/optimize/hyperopt_tools.py index 2ecc5a73f..4cb9887eb 100644 --- a/freqtrade/optimize/hyperopt_tools.py +++ b/freqtrade/optimize/hyperopt_tools.py @@ -1,7 +1,7 @@ import logging from collections.abc import Iterator from copy import deepcopy -from datetime import datetime, timezone +from datetime import UTC, datetime from pathlib import Path from typing import Any @@ -71,7 +71,7 @@ class HyperoptTools: "strategy_name": strategy_name, "params": final_params, "ft_stratparam_v": 1, - "export_time": datetime.now(timezone.utc), + "export_time": datetime.now(UTC), } logger.info(f"Dumping parameters to {filename}") with filename.open("w") as f: diff --git a/freqtrade/optimize/optimize_reports/optimize_reports.py b/freqtrade/optimize/optimize_reports/optimize_reports.py index d35e96605..77d2c5a79 100644 --- a/freqtrade/optimize/optimize_reports/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports/optimize_reports.py @@ -1,6 +1,6 @@ import logging from copy import deepcopy -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from typing import Any, Literal import numpy as np @@ -652,9 +652,9 @@ def generate_strategy_stats( "max_drawdown_abs": 0.0, "max_drawdown_low": 0.0, "max_drawdown_high": 0.0, - "drawdown_start": datetime(1970, 1, 1, tzinfo=timezone.utc), + "drawdown_start": datetime(1970, 1, 1, tzinfo=UTC), "drawdown_start_ts": 0, - "drawdown_end": datetime(1970, 1, 1, tzinfo=timezone.utc), + "drawdown_end": datetime(1970, 1, 1, tzinfo=UTC), "drawdown_end_ts": 0, "csum_min": 0, "csum_max": 0, diff --git a/freqtrade/persistence/key_value_store.py b/freqtrade/persistence/key_value_store.py index 814748da6..0d5a97fa1 100644 --- a/freqtrade/persistence/key_value_store.py +++ b/freqtrade/persistence/key_value_store.py @@ -1,4 +1,4 @@ -from datetime import datetime, timezone +from datetime import UTC, datetime from enum import Enum from typing import ClassVar, Literal @@ -114,7 +114,7 @@ class KeyValueStore: if kv.value_type == ValueTypesEnum.STRING: return kv.string_value if kv.value_type == ValueTypesEnum.DATETIME and kv.datetime_value is not None: - return kv.datetime_value.replace(tzinfo=timezone.utc) + return kv.datetime_value.replace(tzinfo=UTC) if kv.value_type == ValueTypesEnum.FLOAT: return kv.float_value if kv.value_type == ValueTypesEnum.INT: @@ -156,7 +156,7 @@ class KeyValueStore: ) if kv is None or kv.datetime_value is None: return None - return kv.datetime_value.replace(tzinfo=timezone.utc) + return kv.datetime_value.replace(tzinfo=UTC) @staticmethod def get_float_value(key: KeyStoreKeys) -> float | None: @@ -207,5 +207,5 @@ def set_startup_time() -> None: if t is not None: KeyValueStore.store_value("bot_start_time", t.open_date_utc) else: - KeyValueStore.store_value("bot_start_time", datetime.now(timezone.utc)) - KeyValueStore.store_value("startup_time", datetime.now(timezone.utc)) + KeyValueStore.store_value("bot_start_time", datetime.now(UTC)) + KeyValueStore.store_value("startup_time", datetime.now(UTC)) diff --git a/freqtrade/persistence/pairlock.py b/freqtrade/persistence/pairlock.py index 6c98a607d..db88bd878 100644 --- a/freqtrade/persistence/pairlock.py +++ b/freqtrade/persistence/pairlock.py @@ -1,4 +1,4 @@ -from datetime import datetime, timezone +from datetime import UTC, datetime from typing import Any, ClassVar from sqlalchemy import ScalarResult, String, or_, select @@ -69,10 +69,10 @@ class PairLock(ModelBase): "id": self.id, "pair": self.pair, "lock_time": self.lock_time.strftime(DATETIME_PRINT_FORMAT), - "lock_timestamp": int(self.lock_time.replace(tzinfo=timezone.utc).timestamp() * 1000), + "lock_timestamp": int(self.lock_time.replace(tzinfo=UTC).timestamp() * 1000), "lock_end_time": self.lock_end_time.strftime(DATETIME_PRINT_FORMAT), "lock_end_timestamp": int( - self.lock_end_time.replace(tzinfo=timezone.utc).timestamp() * 1000 + self.lock_end_time.replace(tzinfo=UTC).timestamp() * 1000 ), "reason": self.reason, "side": self.side, diff --git a/freqtrade/persistence/pairlock_middleware.py b/freqtrade/persistence/pairlock_middleware.py index 0adbcc8be..02642c463 100644 --- a/freqtrade/persistence/pairlock_middleware.py +++ b/freqtrade/persistence/pairlock_middleware.py @@ -1,6 +1,6 @@ import logging from collections.abc import Sequence -from datetime import datetime, timezone +from datetime import UTC, datetime from sqlalchemy import select @@ -52,7 +52,7 @@ class PairLocks: """ lock = PairLock( pair=pair, - lock_time=now or datetime.now(timezone.utc), + lock_time=now or datetime.now(UTC), lock_end_time=timeframe_to_next_date(PairLocks.timeframe, until), reason=reason, side=side, @@ -77,7 +77,7 @@ class PairLocks: :param side: Side get locks for, can be 'long', 'short', '*' or None """ if not now: - now = datetime.now(timezone.utc) + now = datetime.now(UTC) if PairLocks.use_db: return PairLock.query_pair_locks(pair, now, side).all() @@ -114,7 +114,7 @@ class PairLocks: defaults to datetime.now(timezone.utc) """ if not now: - now = datetime.now(timezone.utc) + now = datetime.now(UTC) logger.info(f"Releasing all locks for {pair}.") locks = PairLocks.get_pair_locks(pair, now, side=side) @@ -132,7 +132,7 @@ class PairLocks: defaults to datetime.now(timezone.utc) """ if not now: - now = datetime.now(timezone.utc) + now = datetime.now(UTC) if PairLocks.use_db: # used in live modes @@ -161,7 +161,7 @@ class PairLocks: defaults to datetime.now(timezone.utc) """ if not now: - now = datetime.now(timezone.utc) + now = datetime.now(UTC) return len(PairLocks.get_pair_locks("*", now, side)) > 0 @@ -173,7 +173,7 @@ class PairLocks: defaults to datetime.now(timezone.utc) """ if not now: - now = datetime.now(timezone.utc) + now = datetime.now(UTC) return len(PairLocks.get_pair_locks(pair, now, side)) > 0 or PairLocks.is_global_lock( now, side diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index 9c7234d35..44cd06baf 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -6,9 +6,9 @@ import logging from collections import defaultdict from collections.abc import Sequence from dataclasses import dataclass -from datetime import datetime, timezone +from datetime import UTC, datetime from math import isclose -from typing import Any, ClassVar, Optional, cast +from typing import Any, ClassVar, Optional, Self, cast from sqlalchemy import ( Enum, @@ -25,7 +25,6 @@ from sqlalchemy import ( select, ) from sqlalchemy.orm import Mapped, lazyload, mapped_column, relationship, validates -from typing_extensions import Self from freqtrade.constants import ( CANCELED_EXCHANGE_STATES, @@ -121,13 +120,13 @@ class Order(ModelBase): @property def order_date_utc(self) -> datetime: """Order-date with UTC timezoneinfo""" - return self.order_date.replace(tzinfo=timezone.utc) + return self.order_date.replace(tzinfo=UTC) @property def order_filled_utc(self) -> datetime | None: """last order-date with UTC timezoneinfo""" return ( - self.order_filled_date.replace(tzinfo=timezone.utc) if self.order_filled_date else None + self.order_filled_date.replace(tzinfo=UTC) if self.order_filled_date else None ) @property @@ -229,7 +228,7 @@ class Order(ModelBase): self.order_filled_date = dt_from_ts( safe_value_fallback(order, "lastTradeTimestamp", default_value=dt_ts()) ) - self.order_update_date = datetime.now(timezone.utc) + self.order_update_date = datetime.now(UTC) def to_ccxt_object(self, stopPriceName: str = "stopPrice") -> dict[str, Any]: order: dict[str, Any] = { @@ -286,7 +285,7 @@ class Order(ModelBase): self.order_date.strftime(DATETIME_PRINT_FORMAT) if self.order_date else None ), "order_timestamp": ( - int(self.order_date.replace(tzinfo=timezone.utc).timestamp() * 1000) + int(self.order_date.replace(tzinfo=UTC).timestamp() * 1000) if self.order_date else None ), @@ -533,7 +532,7 @@ class LocalTrade: @property def open_date_utc(self): - return self.open_date.replace(tzinfo=timezone.utc) + return self.open_date.replace(tzinfo=UTC) @property def stoploss_last_update_utc(self): @@ -543,7 +542,7 @@ class LocalTrade: @property def close_date_utc(self): - return self.close_date.replace(tzinfo=timezone.utc) if self.close_date else None + return self.close_date.replace(tzinfo=UTC) if self.close_date else None @property def entry_side(self) -> str: @@ -1056,7 +1055,7 @@ class LocalTrade: return zero open_date = self.open_date.replace(tzinfo=None) - now = (self.close_date or datetime.now(timezone.utc)).replace(tzinfo=None) + now = (self.close_date or datetime.now(UTC)).replace(tzinfo=None) sec_per_hour = FtPrecise(3600) total_seconds = FtPrecise((now - open_date).total_seconds()) hours = total_seconds / sec_per_hour or zero @@ -1572,12 +1571,12 @@ class LocalTrade: fee_close=data["fee_close"], fee_close_cost=data.get("fee_close_cost"), fee_close_currency=data.get("fee_close_currency"), - open_date=datetime.fromtimestamp(data["open_timestamp"] // 1000, tz=timezone.utc), + open_date=datetime.fromtimestamp(data["open_timestamp"] // 1000, tz=UTC), open_rate=data["open_rate"], open_rate_requested=data.get("open_rate_requested", data["open_rate"]), open_trade_value=data.get("open_trade_value"), close_date=( - datetime.fromtimestamp(data["close_timestamp"] // 1000, tz=timezone.utc) + datetime.fromtimestamp(data["close_timestamp"] // 1000, tz=UTC) if data["close_timestamp"] else None ), @@ -1622,7 +1621,7 @@ class LocalTrade: if order.get("order_date") else None, order_filled_date=( - datetime.fromtimestamp(order["order_filled_timestamp"] // 1000, tz=timezone.utc) + datetime.fromtimestamp(order["order_filled_timestamp"] // 1000, tz=UTC) if order["order_filled_timestamp"] else None ), diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 6419ab0c2..5c43ee404 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -1,5 +1,5 @@ import logging -from datetime import datetime, timezone +from datetime import UTC, datetime from pathlib import Path import pandas as pd @@ -638,7 +638,7 @@ def load_and_plot_trades(config: Config): exchange = ExchangeResolver.load_exchange(config) IStrategy.dp = DataProvider(config, exchange) strategy.ft_bot_start() - strategy_safe_wrapper(strategy.bot_loop_start)(current_time=datetime.now(timezone.utc)) + strategy_safe_wrapper(strategy.bot_loop_start)(current_time=datetime.now(UTC)) plot_elements = init_plotscript(config, list(exchange.markets), strategy.startup_candle_count) timerange = plot_elements["timerange"] trades = plot_elements["trades"] diff --git a/freqtrade/plugins/protectionmanager.py b/freqtrade/plugins/protectionmanager.py index 187b9ee63..0eda8422f 100644 --- a/freqtrade/plugins/protectionmanager.py +++ b/freqtrade/plugins/protectionmanager.py @@ -3,7 +3,7 @@ Protection manager class """ import logging -from datetime import datetime, timezone +from datetime import UTC, datetime from typing import Any from freqtrade.constants import Config, LongShort @@ -49,7 +49,7 @@ class ProtectionManager: def global_stop(self, now: datetime | None = None, side: LongShort = "long") -> PairLock | None: if not now: - now = datetime.now(timezone.utc) + now = datetime.now(UTC) result = None for protection_handler in self._protection_handlers: if protection_handler.has_global_stop: @@ -65,7 +65,7 @@ class ProtectionManager: self, pair, now: datetime | None = None, side: LongShort = "long" ) -> PairLock | None: if not now: - now = datetime.now(timezone.utc) + now = datetime.now(UTC) result = None for protection_handler in self._protection_handlers: if protection_handler.has_local_stop: diff --git a/freqtrade/plugins/protections/iprotection.py b/freqtrade/plugins/protections/iprotection.py index 38a726dcc..8f2f51729 100644 --- a/freqtrade/plugins/protections/iprotection.py +++ b/freqtrade/plugins/protections/iprotection.py @@ -1,7 +1,7 @@ import logging from abc import ABC, abstractmethod from dataclasses import dataclass -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from typing import Any from freqtrade.constants import Config, LongShort @@ -127,7 +127,7 @@ class IProtection(LoggingMixin, ABC): max_date: datetime = max([trade.close_date for trade in trades if trade.close_date]) # coming from Database, tzinfo is not set. if max_date.tzinfo is None: - max_date = max_date.replace(tzinfo=timezone.utc) + max_date = max_date.replace(tzinfo=UTC) if self._unlock_at is not None: # unlock_at case with fixed hour of the day