mirror of
https://github.com/freqtrade/freqtrade.git
synced 2024-11-10 02:12:01 +00:00
Compare commits
14 Commits
954da3298f
...
da615699cf
Author | SHA1 | Date | |
---|---|---|---|
|
da615699cf | ||
|
f50a633f87 | ||
|
ad295946c0 | ||
|
c28446dad0 | ||
|
ff9d1f2728 | ||
|
5ec04d168e | ||
|
26afad8bc1 | ||
|
80dd586dc7 | ||
|
78d189564f | ||
|
2b0b85330e | ||
|
4257e1ca96 | ||
|
ff2eaeb3b4 | ||
|
cbc98d384e | ||
|
4ef45314dd |
|
@ -31,7 +31,7 @@ repos:
|
||||||
|
|
||||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||||
# Ruff version.
|
# Ruff version.
|
||||||
rev: 'v0.6.4'
|
rev: 'v0.6.5'
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
- id: ruff-format
|
- id: ruff-format
|
||||||
|
|
|
@ -130,20 +130,20 @@ Most properties here can be None as they are dependent on the exchange response.
|
||||||
|
|
||||||
| Attribute | DataType | Description |
|
| Attribute | DataType | Description |
|
||||||
|------------|-------------|-------------|
|
|------------|-------------|-------------|
|
||||||
`trade` | Trade | Trade object this order is attached to
|
| `trade` | Trade | Trade object this order is attached to |
|
||||||
`ft_pair` | string | Pair this order is for
|
| `ft_pair` | string | Pair this order is for |
|
||||||
`ft_is_open` | boolean | is the order filled?
|
| `ft_is_open` | boolean | is the order filled? |
|
||||||
`order_type` | string | Order type as defined on the exchange - usually market, limit or stoploss
|
| `order_type` | string | Order type as defined on the exchange - usually market, limit or stoploss |
|
||||||
`status` | string | Status as defined by ccxt. Usually open, closed, expired or canceled
|
| `status` | string | Status as defined by ccxt. Usually open, closed, expired or canceled |
|
||||||
`side` | string | Buy or Sell
|
| `side` | string | Buy or Sell |
|
||||||
`price` | float | Price the order was placed at
|
| `price` | float | Price the order was placed at |
|
||||||
`average` | float | Average price the order filled at
|
| `average` | float | Average price the order filled at |
|
||||||
`amount` | float | Amount in base currency
|
| `amount` | float | Amount in base currency |
|
||||||
`filled` | float | Filled amount (in base currency)
|
| `filled` | float | Filled amount (in base currency) |
|
||||||
`remaining` | float | Remaining amount
|
| `remaining` | float | Remaining amount |
|
||||||
`cost` | float | Cost of the order - usually average * filled (*Exchange dependent on futures, may contain the cost with or without leverage and may be in contracts.*)
|
| `cost` | float | Cost of the order - usually average * filled (*Exchange dependent on futures, may contain the cost with or without leverage and may be in contracts.*) |
|
||||||
`stake_amount` | float | Stake amount used for this order. *Added in 2023.7.*
|
| `stake_amount` | float | Stake amount used for this order. *Added in 2023.7.* |
|
||||||
`order_date` | datetime | Order creation date **use `order_date_utc` instead**
|
| `order_date` | datetime | Order creation date **use `order_date_utc` instead** |
|
||||||
`order_date_utc` | datetime | Order creation date (in UTC)
|
| `order_date_utc` | datetime | Order creation date (in UTC) |
|
||||||
`order_fill_date` | datetime | Order fill date **use `order_fill_utc` instead**
|
| `order_fill_date` | datetime | Order fill date **use `order_fill_utc` instead** |
|
||||||
`order_fill_date_utc` | datetime | Order fill date
|
| `order_fill_date_utc` | datetime | Order fill date |
|
||||||
|
|
|
@ -6,6 +6,8 @@ from pathlib import Path
|
||||||
from typing import Dict, List, Optional, Tuple
|
from typing import Dict, List, Optional, Tuple
|
||||||
|
|
||||||
import ccxt
|
import ccxt
|
||||||
|
from cachetools import TTLCache, cached
|
||||||
|
from threading import Lock
|
||||||
|
|
||||||
from freqtrade.enums import CandleType, MarginMode, PriceType, TradingMode
|
from freqtrade.enums import CandleType, MarginMode, PriceType, TradingMode
|
||||||
from freqtrade.exceptions import DDosProtection, OperationalException, TemporaryError
|
from freqtrade.exceptions import DDosProtection, OperationalException, TemporaryError
|
||||||
|
@ -53,6 +55,11 @@ class Binance(Exchange):
|
||||||
(TradingMode.FUTURES, MarginMode.ISOLATED)
|
(TradingMode.FUTURES, MarginMode.ISOLATED)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs) -> None:
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self._spot_delist_schedule_cache: TTLCache = TTLCache(maxsize=100, ttl=300)
|
||||||
|
self._spot_delist_schedule_cache_lock = Lock()
|
||||||
|
|
||||||
def get_tickers(self, symbols: Optional[List[str]] = None, cached: bool = False) -> Tickers:
|
def get_tickers(self, symbols: Optional[List[str]] = None, cached: bool = False) -> Tickers:
|
||||||
tickers = super().get_tickers(symbols=symbols, cached=cached)
|
tickers = super().get_tickers(symbols=symbols, cached=cached)
|
||||||
if self.trading_mode == TradingMode.FUTURES:
|
if self.trading_mode == TradingMode.FUTURES:
|
||||||
|
@ -214,3 +221,58 @@ class Binance(Exchange):
|
||||||
return self.get_leverage_tiers()
|
return self.get_leverage_tiers()
|
||||||
else:
|
else:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@retrier
|
||||||
|
@cached(cache=TTLCache(maxsize=100, ttl=10), lock=Lock())
|
||||||
|
def get_deslist_schedule(self):
|
||||||
|
try:
|
||||||
|
|
||||||
|
delist_schedule = self._api.sapi_get_spot_delist_schedule()
|
||||||
|
|
||||||
|
return delist_schedule
|
||||||
|
except ccxt.DDoSProtection as e:
|
||||||
|
raise DDosProtection(e) from e
|
||||||
|
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
||||||
|
raise TemporaryError(
|
||||||
|
f'Could not get delist schedule {e.__class__.__name__}. Message: {e}') from e
|
||||||
|
except ccxt.BaseError as e:
|
||||||
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
|
def get_spot_pair_delist_time(self, pair, refresh: bool = True) -> int | None:
|
||||||
|
"""
|
||||||
|
Get the delisting time for a pair if it will be delisted
|
||||||
|
:param pair: Pair to get the delisting time for
|
||||||
|
:param refresh: true if you need fresh data
|
||||||
|
:return: int: delisting time None if not delisting
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not pair:
|
||||||
|
return
|
||||||
|
|
||||||
|
cache = self._spot_delist_schedule_cache
|
||||||
|
lock = self._spot_delist_schedule_cache_lock
|
||||||
|
|
||||||
|
schedule_pair = pair.replace('/', '')
|
||||||
|
|
||||||
|
if not refresh:
|
||||||
|
with lock:
|
||||||
|
delist_time = cache[f"{schedule_pair}"]
|
||||||
|
|
||||||
|
if delist_time:
|
||||||
|
return delist_time
|
||||||
|
|
||||||
|
delist_schedule = self.get_deslist_schedule()
|
||||||
|
|
||||||
|
if delist_schedule is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
with lock:
|
||||||
|
for schedule in delist_schedule:
|
||||||
|
for symbol in schedule['symbols']:
|
||||||
|
cache[f"{symbol}"] = int(schedule['delistTime'])
|
||||||
|
|
||||||
|
|
||||||
|
with lock:
|
||||||
|
return cache.get(f"{schedule_pair}")
|
||||||
|
|
|
@ -62,7 +62,7 @@ from freqtrade.rpc.rpc_types import (
|
||||||
)
|
)
|
||||||
from freqtrade.strategy.interface import IStrategy
|
from freqtrade.strategy.interface import IStrategy
|
||||||
from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper
|
from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper
|
||||||
from freqtrade.util import MeasureTime
|
from freqtrade.util import FtPrecise, MeasureTime
|
||||||
from freqtrade.util.migrations.binance_mig import migrate_binance_futures_names
|
from freqtrade.util.migrations.binance_mig import migrate_binance_futures_names
|
||||||
from freqtrade.wallets import Wallets
|
from freqtrade.wallets import Wallets
|
||||||
|
|
||||||
|
@ -784,7 +784,14 @@ class FreqtradeBot(LoggingMixin):
|
||||||
if stake_amount is not None and stake_amount < 0.0:
|
if stake_amount is not None and stake_amount < 0.0:
|
||||||
# We should decrease our position
|
# We should decrease our position
|
||||||
amount = self.exchange.amount_to_contract_precision(
|
amount = self.exchange.amount_to_contract_precision(
|
||||||
trade.pair, abs(float(stake_amount * trade.amount / trade.stake_amount))
|
trade.pair,
|
||||||
|
abs(
|
||||||
|
float(
|
||||||
|
FtPrecise(stake_amount)
|
||||||
|
* FtPrecise(trade.amount)
|
||||||
|
/ FtPrecise(trade.stake_amount)
|
||||||
|
)
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
if amount == 0.0:
|
if amount == 0.0:
|
||||||
|
|
|
@ -723,3 +723,16 @@ def test_get_maintenance_ratio_and_amt_binance(
|
||||||
exchange._leverage_tiers = leverage_tiers
|
exchange._leverage_tiers = leverage_tiers
|
||||||
(result_ratio, result_amt) = exchange.get_maintenance_ratio_and_amt(pair, notional_value)
|
(result_ratio, result_amt) = exchange.get_maintenance_ratio_and_amt(pair, notional_value)
|
||||||
assert (round(result_ratio, 8), round(result_amt, 8)) == (mm_ratio, amt)
|
assert (round(result_ratio, 8), round(result_amt, 8)) == (mm_ratio, amt)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_spot_delist_schedule(mocker, default_conf) -> None:
|
||||||
|
exchange = get_patched_exchange(mocker, default_conf, id='binance')
|
||||||
|
return_value = [{
|
||||||
|
'delistTime': '1712113200000',
|
||||||
|
'symbols': ['DREPBTC', 'DREPUSDT', 'MOBBTC', 'MOBUSDT', 'PNTUSDT']
|
||||||
|
}]
|
||||||
|
|
||||||
|
exchange._api.sapi_get_spot_delist_schedule = MagicMock(return_value=return_value)
|
||||||
|
|
||||||
|
assert exchange.get_spot_pair_delist_time('DREP/USDT') == 1712113200000
|
||||||
|
assert exchange.get_spot_pair_delist_time('BTC/USDT') is None
|
||||||
|
|
Loading…
Reference in New Issue
Block a user