Merge branch 'develop' into gateio-stoploss

This commit is contained in:
Sam Germain
2022-03-12 19:50:46 -06:00
6 changed files with 76 additions and 28 deletions

View File

@@ -9,7 +9,7 @@ import logging
from copy import deepcopy
from datetime import datetime, timedelta, timezone
from math import ceil
from typing import Any, Dict, List, Optional, Tuple
from typing import Any, Coroutine, Dict, List, Optional, Tuple
import arrow
import ccxt
@@ -1371,6 +1371,22 @@ class Exchange:
data = sorted(data, key=lambda x: x[0])
return pair, timeframe, data
def _build_coroutine(self, pair: str, timeframe: str, since_ms: Optional[int]) -> Coroutine:
if not since_ms and self.required_candle_call_count > 1:
# Multiple calls for one pair - to get more history
one_call = timeframe_to_msecs(timeframe) * self.ohlcv_candle_limit(timeframe)
move_to = one_call * self.required_candle_call_count
now = timeframe_to_next_date(timeframe)
since_ms = int((now - timedelta(seconds=move_to // 1000)).timestamp() * 1000)
if since_ms:
return self._async_get_historic_ohlcv(
pair, timeframe, since_ms=since_ms, raise_=True)
else:
# One call ... "regular" refresh
return self._async_get_candle_history(
pair, timeframe, since_ms=since_ms)
def refresh_latest_ohlcv(self, pair_list: ListPairsWithTimeframes, *,
since_ms: Optional[int] = None, cache: bool = True
) -> Dict[Tuple[str, str], DataFrame]:
@@ -1389,22 +1405,15 @@ class Exchange:
cached_pairs = []
# Gather coroutines to run
for pair, timeframe in set(pair_list):
if timeframe not in self.timeframes:
logger.warning(
f"Cannot download ({pair}, {timeframe}) combination as this timeframe is "
f"not available on {self.name}. Available timeframes are "
f"{', '.join(self.timeframes)}.")
continue
if ((pair, timeframe) not in self._klines or not cache
or self._now_is_time_to_refresh(pair, timeframe)):
if not since_ms and self.required_candle_call_count > 1:
# Multiple calls for one pair - to get more history
one_call = timeframe_to_msecs(timeframe) * self.ohlcv_candle_limit(timeframe)
move_to = one_call * self.required_candle_call_count
now = timeframe_to_next_date(timeframe)
since_ms = int((now - timedelta(seconds=move_to // 1000)).timestamp() * 1000)
if since_ms:
input_coroutines.append(self._async_get_historic_ohlcv(
pair, timeframe, since_ms=since_ms, raise_=True))
else:
# One call ... "regular" refresh
input_coroutines.append(self._async_get_candle_history(
pair, timeframe, since_ms=since_ms))
input_coroutines.append(self._build_coroutine(pair, timeframe, since_ms))
else:
logger.debug(
"Using cached candle (OHLCV) data for pair %s, timeframe %s ...",

View File

@@ -873,11 +873,15 @@ class FreqtradeBot(LoggingMixin):
stop_price = trade.open_rate * (1 + stoploss)
if self.create_stoploss_order(trade=trade, stop_price=stop_price):
# The above will return False if the placement failed and the trade was force-sold.
# in which case the trade will be closed - which we must check below.
trade.stoploss_last_update = datetime.utcnow()
return False
# If stoploss order is canceled for some reason we add it
if stoploss_order and stoploss_order['status'] in ('canceled', 'cancelled'):
if (trade.is_open
and stoploss_order
and stoploss_order['status'] in ('canceled', 'cancelled')):
if self.create_stoploss_order(trade=trade, stop_price=trade.stop_loss):
return False
else:
@@ -887,7 +891,7 @@ class FreqtradeBot(LoggingMixin):
# Finally we check if stoploss on exchange should be moved up because of trailing.
# Triggered Orders are now real orders - so don't replace stoploss anymore
if (
stoploss_order
trade.is_open and stoploss_order
and stoploss_order.get('status_stop') != 'triggered'
and (self.config.get('trailing_stop', False)
or self.config.get('use_custom_stoploss', False))

View File

@@ -23,6 +23,7 @@ coingecko_mapping = {
'eth': 'ethereum',
'bnb': 'binancecoin',
'sol': 'solana',
'usdt': 'tether',
}