merged with lev-exchange

This commit is contained in:
Sam Germain 2021-09-13 00:00:22 -06:00
commit 49acfc887f
9 changed files with 28 additions and 24 deletions

View File

@ -102,3 +102,4 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None:
HyperoptTools.show_epoch_details(val, total_epochs, print_json, no_header,
header_str="Epoch details")
# TODO-lev: Hyperopt optimal leverage

View File

@ -148,6 +148,7 @@ def start_list_markets(args: Dict[str, Any], pairs_only: bool = False) -> None:
quote_currencies = args.get('quote_currencies', [])
try:
# TODO-lev: Add leverage amount to get markets that support a certain leverage
pairs = exchange.get_markets(base_currencies=base_currencies,
quote_currencies=quote_currencies,
pairs_only=pairs_only,

View File

@ -371,7 +371,7 @@ class FreqtradeBot(LoggingMixin):
def enter_positions(self) -> int:
"""
Tries to execute long buy/short sell orders for new trades (positions)
Tries to execute entry orders for new trades (positions)
"""
trades_created = 0
@ -534,10 +534,6 @@ class FreqtradeBot(LoggingMixin):
# is_short=is_short
# )
if self.trading_mode == TradingMode.FUTURES:
self.exchange.set_leverage(pair, leverage)
self.exchange.set_margin_mode(pair, self.collateral_type)
return interest_rate, isolated_liq
def execute_entry(
@ -708,7 +704,7 @@ class FreqtradeBot(LoggingMixin):
def _notify_enter(self, trade: Trade, order_type: str) -> None:
"""
Sends rpc notification when a buy/short occurred.
Sends rpc notification when a entry order occurred.
"""
msg = {
'trade_id': trade.id,
@ -731,7 +727,7 @@ class FreqtradeBot(LoggingMixin):
def _notify_enter_cancel(self, trade: Trade, order_type: str, reason: str) -> None:
"""
Sends rpc notification when a buy/short cancel occurred.
Sends rpc notification when a entry order cancel occurred.
"""
current_rate = self.exchange.get_rate(trade.pair, refresh=False, side=trade.enter_side)
msg_type = RPCMessageType.SHORT_CANCEL if trade.is_short else RPCMessageType.BUY_CANCEL
@ -778,7 +774,7 @@ class FreqtradeBot(LoggingMixin):
def exit_positions(self, trades: List[Any]) -> int:
"""
Tries to execute sell/exit_short orders for open trades (positions)
Tries to execute exit orders for open trades (positions)
"""
trades_closed = 0
for trade in trades:
@ -1149,7 +1145,7 @@ class FreqtradeBot(LoggingMixin):
def handle_cancel_exit(self, trade: Trade, order: Dict, reason: str) -> str:
"""
Sell/exit_short cancel - cancel order and update trade
exit order cancel - cancel order and update trade
:return: Reason for cancel
"""
# if trade is not partially completed, just cancel the order
@ -1275,7 +1271,7 @@ class FreqtradeBot(LoggingMixin):
if not strategy_safe_wrapper(self.strategy.confirm_trade_exit, default_retval=True)(
pair=trade.pair, trade=trade, order_type=order_type, amount=amount, rate=limit,
time_in_force=time_in_force, sell_reason=sell_reason.sell_reason,
current_time=datetime.now(timezone.utc)):
current_time=datetime.now(timezone.utc)): # TODO-lev: Update to exit
logger.info(f"User requested abortion of exiting {trade.pair}")
return False
@ -1284,10 +1280,10 @@ class FreqtradeBot(LoggingMixin):
order = self.exchange.create_order(
pair=trade.pair,
ordertype=order_type,
side="sell",
amount=amount,
rate=limit,
time_in_force=time_in_force,
side=trade.exit_side
time_in_force=time_in_force
)
except InsufficientFundsError as e:
logger.warning(f"Unable to place order {e}.")

View File

@ -18,6 +18,7 @@ class PrecisionFilter(IPairList):
pairlist_pos: int) -> None:
super().__init__(exchange, pairlistmanager, config, pairlistconfig, pairlist_pos)
# TODO-lev: Liquidation price?
if 'stoploss' not in self._config:
raise OperationalException(
'PrecisionFilter can only work with stoploss defined. Please add the '

View File

@ -36,6 +36,7 @@ class MaxDrawdown(IProtection):
"""
LockReason to use
"""
# TODO-lev: < for shorts?
return (f'{drawdown} > {self._max_allowed_drawdown} in {self.lookback_period_str}, '
f'locking for {self.stop_duration_str}.')

View File

@ -32,6 +32,7 @@ class StoplossGuard(IProtection):
def _reason(self) -> str:
"""
LockReason to use
#TODO-lev: check if min is the right word for shorts
"""
return (f'{self._trade_limit} stoplosses in {self._lookback_period} min, '
f'locking for {self._stop_duration} min.')
@ -51,6 +52,7 @@ class StoplossGuard(IProtection):
# if pair:
# filters.append(Trade.pair == pair)
# trades = Trade.get_trades(filters).all()
# TODO-lev: Liquidation price?
trades1 = Trade.get_trades_proxy(pair=pair, is_open=False, close_date=look_back_until)
trades = [trade for trade in trades1 if (str(trade.sell_reason) in (

View File

@ -168,7 +168,7 @@ class IStrategy(ABC, HyperStrategyMixin):
"""
Check buy timeout function callback.
This method can be used to override the enter-timeout.
It is called whenever a limit buy/short order has been created,
It is called whenever a limit entry order has been created,
and is not yet fully filled.
Configuration options in `unfilledtimeout` will be verified before this,
so ensure to set these timeouts high enough.
@ -178,7 +178,7 @@ class IStrategy(ABC, HyperStrategyMixin):
:param trade: trade object.
:param order: Order dictionary as returned from CCXT.
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
:return bool: When True is returned, then the buy/short-order is cancelled.
:return bool: When True is returned, then the entry order is cancelled.
"""
return False
@ -213,7 +213,7 @@ class IStrategy(ABC, HyperStrategyMixin):
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float,
time_in_force: str, current_time: datetime, **kwargs) -> bool:
"""
Called right before placing a buy/short order.
Called right before placing a entry order.
Timing for this function is critical, so avoid doing heavy computations or
network requests in this method.
@ -237,7 +237,7 @@ class IStrategy(ABC, HyperStrategyMixin):
rate: float, time_in_force: str, sell_reason: str,
current_time: datetime, **kwargs) -> bool:
"""
Called right before placing a regular sell/exit_short order.
Called right before placing a regular exit order.
Timing for this function is critical, so avoid doing heavy computations or
network requests in this method.
@ -412,7 +412,7 @@ class IStrategy(ABC, HyperStrategyMixin):
Checks if a pair is currently locked
The 2nd, optional parameter ensures that locks are applied until the new candle arrives,
and not stop at 14:00:00 - while the next candle arrives at 14:00:02 leaving a gap
of 2 seconds for a buy/short to happen on an old signal.
of 2 seconds for an entry order to happen on an old signal.
:param pair: "Pair to check"
:param candle_date: Date of the last candle. Optional, defaults to current date
:returns: locking state of the pair in question.
@ -428,7 +428,7 @@ class IStrategy(ABC, HyperStrategyMixin):
def analyze_ticker(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Parses the given candle (OHLCV) data and returns a populated DataFrame
add several TA indicators and buy/short signal to it
add several TA indicators and entry order signal to it
:param dataframe: Dataframe containing data from exchange
:param metadata: Metadata dictionary with additional data (e.g. 'pair')
:return: DataFrame of candle (OHLCV) data with indicator data and signals added
@ -547,7 +547,9 @@ class IStrategy(ABC, HyperStrategyMixin):
dataframe: DataFrame,
) -> Tuple[Optional[DataFrame], Optional[arrow.Arrow]]:
"""
Get the latest candle. Used only during real mode
Calculates current signal based based on the entry order or exit order
columns of the dataframe.
Used by Bot to get the signal to buy, sell, short, or exit_short
:param pair: pair in format ANT/BTC
:param timeframe: timeframe to use
:param dataframe: Analyzed dataframe to get signal from.
@ -672,7 +674,7 @@ class IStrategy(ABC, HyperStrategyMixin):
low: float = None, high: float = None,
force_stoploss: float = 0) -> SellCheckTuple:
"""
This function evaluates if one of the conditions required to trigger a sell/exit_short
This function evaluates if one of the conditions required to trigger an exit order
has been reached, which can either be a stop-loss, ROI or exit-signal.
:param low: Only used during backtesting to simulate (long)stoploss/(short)ROI
:param high: Only used during backtesting, to simulate (short)stoploss/(long)ROI
@ -884,7 +886,7 @@ class IStrategy(ABC, HyperStrategyMixin):
def advise_buy(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Based on TA indicators, populates the buy/short signal for the given dataframe
Based on TA indicators, populates the entry order signal for the given dataframe
This method should not be overridden.
:param dataframe: DataFrame
:param metadata: Additional information dictionary, with details like the
@ -907,7 +909,7 @@ class IStrategy(ABC, HyperStrategyMixin):
def advise_sell(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Based on TA indicators, populates the sell/exit_short signal for the given dataframe
Based on TA indicators, populates the exit order signal for the given dataframe
This method should not be overridden.
:param dataframe: DataFrame
:param metadata: Additional information dictionary, with details like the

View File

@ -3379,7 +3379,7 @@ def test__safe_exit_amount_error(default_conf, fee, caplog, mocker):
)
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)
with pytest.raises(DependencyException, match=r"Not enough amount to exit trade."):
with pytest.raises(DependencyException, match=r"Not enough amount to exit."):
assert freqtrade._safe_exit_amount(trade.pair, trade.amount)

View File

@ -90,7 +90,7 @@ def test_enter_exit_side(fee):
@pytest.mark.usefixtures("init_persistence")
def test__set_stop_loss_isolated_liq(fee):
def test_set_stop_loss_isolated_liq(fee):
trade = Trade(
id=2,
pair='ADA/USDT',