Initial steps to change bid/ask pricing to enter/exit
This commit is contained in:
parent
d1f61c4cf9
commit
bcf326a035
@ -13,7 +13,8 @@
|
|||||||
"exit_timeout_count": 0,
|
"exit_timeout_count": 0,
|
||||||
"unit": "minutes"
|
"unit": "minutes"
|
||||||
},
|
},
|
||||||
"bid_strategy": {
|
"entry_pricing": {
|
||||||
|
"price_side": "same",
|
||||||
"ask_last_balance": 0.0,
|
"ask_last_balance": 0.0,
|
||||||
"use_order_book": true,
|
"use_order_book": true,
|
||||||
"order_book_top": 1,
|
"order_book_top": 1,
|
||||||
@ -22,7 +23,8 @@
|
|||||||
"bids_to_ask_delta": 1
|
"bids_to_ask_delta": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ask_strategy": {
|
"exit_pricing": {
|
||||||
|
"price_side": "same",
|
||||||
"use_order_book": true,
|
"use_order_book": true,
|
||||||
"order_book_top": 1
|
"order_book_top": 1
|
||||||
},
|
},
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
"exit_timeout_count": 0,
|
"exit_timeout_count": 0,
|
||||||
"unit": "minutes"
|
"unit": "minutes"
|
||||||
},
|
},
|
||||||
"bid_strategy": {
|
"entry_pricing": {
|
||||||
|
"price_side": "same",
|
||||||
"use_order_book": true,
|
"use_order_book": true,
|
||||||
"ask_last_balance": 0.0,
|
"ask_last_balance": 0.0,
|
||||||
"order_book_top": 1,
|
"order_book_top": 1,
|
||||||
@ -22,7 +23,8 @@
|
|||||||
"bids_to_ask_delta": 1
|
"bids_to_ask_delta": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ask_strategy":{
|
"exit_pricing":{
|
||||||
|
"price_side": "same",
|
||||||
"use_order_book": true,
|
"use_order_book": true,
|
||||||
"order_book_top": 1
|
"order_book_top": 1
|
||||||
},
|
},
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
"exit_timeout_count": 0,
|
"exit_timeout_count": 0,
|
||||||
"unit": "minutes"
|
"unit": "minutes"
|
||||||
},
|
},
|
||||||
"bid_strategy": {
|
"entry_pricing": {
|
||||||
|
"price_side": "same",
|
||||||
"ask_last_balance": 0.0,
|
"ask_last_balance": 0.0,
|
||||||
"use_order_book": true,
|
"use_order_book": true,
|
||||||
"order_book_top": 1,
|
"order_book_top": 1,
|
||||||
@ -22,7 +23,8 @@
|
|||||||
"bids_to_ask_delta": 1
|
"bids_to_ask_delta": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ask_strategy": {
|
"exit_pricing": {
|
||||||
|
"price_side": "same",
|
||||||
"use_order_book": true,
|
"use_order_book": true,
|
||||||
"order_book_top": 1
|
"order_book_top": 1
|
||||||
},
|
},
|
||||||
|
@ -35,18 +35,18 @@
|
|||||||
"exit_timeout_count": 0,
|
"exit_timeout_count": 0,
|
||||||
"unit": "minutes"
|
"unit": "minutes"
|
||||||
},
|
},
|
||||||
"bid_strategy": {
|
"entry_pricing": {
|
||||||
"price_side": "bid",
|
"price_side": "same",
|
||||||
"use_order_book": true,
|
"use_order_book": true,
|
||||||
"ask_last_balance": 0.0,
|
|
||||||
"order_book_top": 1,
|
"order_book_top": 1,
|
||||||
|
"ask_last_balance": 0.0,
|
||||||
"check_depth_of_market": {
|
"check_depth_of_market": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"bids_to_ask_delta": 1
|
"bids_to_ask_delta": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ask_strategy":{
|
"exit_pricing":{
|
||||||
"price_side": "ask",
|
"price_side": "same",
|
||||||
"use_order_book": true,
|
"use_order_book": true,
|
||||||
"order_book_top": 1
|
"order_book_top": 1
|
||||||
},
|
},
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
"exit_timeout_count": 0,
|
"exit_timeout_count": 0,
|
||||||
"unit": "minutes"
|
"unit": "minutes"
|
||||||
},
|
},
|
||||||
"bid_strategy": {
|
"entry_pricing": {
|
||||||
|
"price_side": "same",
|
||||||
"use_order_book": true,
|
"use_order_book": true,
|
||||||
"ask_last_balance": 0.0,
|
"ask_last_balance": 0.0,
|
||||||
"order_book_top": 1,
|
"order_book_top": 1,
|
||||||
@ -22,7 +23,8 @@
|
|||||||
"bids_to_ask_delta": 1
|
"bids_to_ask_delta": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ask_strategy":{
|
"exit_pricing":{
|
||||||
|
"price_side": "same",
|
||||||
"use_order_book": true,
|
"use_order_book": true,
|
||||||
"order_book_top": 1
|
"order_book_top": 1
|
||||||
},
|
},
|
||||||
|
@ -36,12 +36,12 @@ By default, loop runs every few seconds (`internals.process_throttle_secs`) and
|
|||||||
* Calls `check_exit_timeout()` strategy callback for open exit orders.
|
* Calls `check_exit_timeout()` strategy callback for open exit orders.
|
||||||
* Verifies existing positions and eventually places exit orders.
|
* Verifies existing positions and eventually places exit orders.
|
||||||
* Considers stoploss, ROI and exit-signal, `custom_exit()` and `custom_stoploss()`.
|
* Considers stoploss, ROI and exit-signal, `custom_exit()` and `custom_stoploss()`.
|
||||||
* Determine exit-price based on `ask_strategy` configuration setting or by using the `custom_exit_price()` callback.
|
* Determine exit-price based on `exit_pricing` configuration setting or by using the `custom_exit_price()` callback.
|
||||||
* Before a exit order is placed, `confirm_trade_exit()` strategy callback is called.
|
* Before a exit order is placed, `confirm_trade_exit()` strategy callback is called.
|
||||||
* Check position adjustments for open trades if enabled by calling `adjust_trade_position()` and place additional order if required.
|
* Check position adjustments for open trades if enabled by calling `adjust_trade_position()` and place additional order if required.
|
||||||
* Check if trade-slots are still available (if `max_open_trades` is reached).
|
* Check if trade-slots are still available (if `max_open_trades` is reached).
|
||||||
* Verifies entry signal trying to enter new positions.
|
* Verifies entry signal trying to enter new positions.
|
||||||
* Determine entry-price based on `bid_strategy` configuration setting, or by using the `custom_entry_price()` callback.
|
* Determine entry-price based on `entry_pricing` configuration setting, or by using the `custom_entry_price()` callback.
|
||||||
* In Margin and Futures mode, `leverage()` strategy callback is called to determine the desired leverage.
|
* In Margin and Futures mode, `leverage()` strategy callback is called to determine the desired leverage.
|
||||||
* Determine stake size by calling the `custom_stake_amount()` callback.
|
* Determine stake size by calling the `custom_stake_amount()` callback.
|
||||||
* Before an entry order is placed, `confirm_trade_entry()` strategy callback is called.
|
* Before an entry order is placed, `confirm_trade_entry()` strategy callback is called.
|
||||||
|
@ -106,16 +106,16 @@ Mandatory parameters are marked as **Required**, which means that they are requi
|
|||||||
| `unfilledtimeout.exit` | **Required.** How long (in minutes or seconds) the bot will wait for an unfilled exit order to complete, after which the order will be cancelled and repeated at current (new) price, as long as there is a signal. [Strategy Override](#parameters-in-the-strategy).<br> **Datatype:** Integer
|
| `unfilledtimeout.exit` | **Required.** How long (in minutes or seconds) the bot will wait for an unfilled exit order to complete, after which the order will be cancelled and repeated at current (new) price, as long as there is a signal. [Strategy Override](#parameters-in-the-strategy).<br> **Datatype:** Integer
|
||||||
| `unfilledtimeout.unit` | Unit to use in unfilledtimeout setting. Note: If you set unfilledtimeout.unit to "seconds", "internals.process_throttle_secs" must be inferior or equal to timeout [Strategy Override](#parameters-in-the-strategy). <br> *Defaults to `minutes`.* <br> **Datatype:** String
|
| `unfilledtimeout.unit` | Unit to use in unfilledtimeout setting. Note: If you set unfilledtimeout.unit to "seconds", "internals.process_throttle_secs" must be inferior or equal to timeout [Strategy Override](#parameters-in-the-strategy). <br> *Defaults to `minutes`.* <br> **Datatype:** String
|
||||||
| `unfilledtimeout.exit_timeout_count` | How many times can exit orders time out. Once this number of timeouts is reached, an emergency sell is triggered. 0 to disable and allow unlimited order cancels. [Strategy Override](#parameters-in-the-strategy).<br>*Defaults to `0`.* <br> **Datatype:** Integer
|
| `unfilledtimeout.exit_timeout_count` | How many times can exit orders time out. Once this number of timeouts is reached, an emergency sell is triggered. 0 to disable and allow unlimited order cancels. [Strategy Override](#parameters-in-the-strategy).<br>*Defaults to `0`.* <br> **Datatype:** Integer
|
||||||
| `bid_strategy.price_side` | Select the side of the spread the bot should look at to get the buy rate. [More information below](#buy-price-side).<br> *Defaults to `bid`.* <br> **Datatype:** String (either `ask` or `bid`).
|
| `enter_pricing.price_side` | Select the side of the spread the bot should look at to get the entry rate. [More information below](#buy-price-side).<br> *Defaults to `same`.* <br> **Datatype:** String (either `ask`, `bid`, `same` or `other`).
|
||||||
| `bid_strategy.ask_last_balance` | **Required.** Interpolate the bidding price. More information [below](#buy-price-without-orderbook-enabled).
|
| `enter_pricing.ask_last_balance` | **Required.** Interpolate the bidding price. More information [below](#buy-price-without-orderbook-enabled).
|
||||||
| `bid_strategy.use_order_book` | Enable buying using the rates in [Order Book Bids](#buy-price-with-orderbook-enabled). <br> **Datatype:** Boolean
|
| `enter_pricing.use_order_book` | Enable entering using the rates in [Order Book Bids](#buy-price-with-orderbook-enabled). <br> *Defaults to `True`.*<br> **Datatype:** Boolean
|
||||||
| `bid_strategy.order_book_top` | Bot will use the top N rate in Order Book "price_side" to buy. I.e. a value of 2 will allow the bot to pick the 2nd bid rate in [Order Book Bids](#buy-price-with-orderbook-enabled). <br>*Defaults to `1`.* <br> **Datatype:** Positive Integer
|
| `enter_pricing.order_book_top` | Bot will use the top N rate in Order Book "price_side" to enter a trade. I.e. a value of 2 will allow the bot to pick the 2nd entry in [Order Book Bids](#buy-price-with-orderbook-enabled). <br>*Defaults to `1`.* <br> **Datatype:** Positive Integer
|
||||||
| `bid_strategy. check_depth_of_market.enabled` | Do not buy if the difference of buy orders and sell orders is met in Order Book. [Check market depth](#check-depth-of-market). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
|
| `enter_pricing. check_depth_of_market.enabled` | Do not enter if the difference of buy orders and sell orders is met in Order Book. [Check market depth](#check-depth-of-market). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
|
||||||
| `bid_strategy. check_depth_of_market.bids_to_ask_delta` | The difference ratio of buy orders and sell orders found in Order Book. A value below 1 means sell order size is greater, while value greater than 1 means buy order size is higher. [Check market depth](#check-depth-of-market) <br> *Defaults to `0`.* <br> **Datatype:** Float (as ratio)
|
| `enter_pricing. check_depth_of_market.bids_to_ask_delta` | The difference ratio of buy orders and sell orders found in Order Book. A value below 1 means sell order size is greater, while value greater than 1 means buy order size is higher. [Check market depth](#check-depth-of-market) <br> *Defaults to `0`.* <br> **Datatype:** Float (as ratio)
|
||||||
| `ask_strategy.price_side` | Select the side of the spread the bot should look at to get the sell rate. [More information below](#sell-price-side).<br> *Defaults to `ask`.* <br> **Datatype:** String (either `ask` or `bid`).
|
| `exit_pricing.price_side` | Select the side of the spread the bot should look at to get the exit rate. [More information below](#sell-price-side).<br> *Defaults to `same`.* <br> **Datatype:** String (either `ask`, `bid`, `same` or `other`).
|
||||||
| `ask_strategy.bid_last_balance` | Interpolate the selling price. More information [below](#sell-price-without-orderbook-enabled).
|
| `exit_pricing.bid_last_balance` | Interpolate the exiting price. More information [below](#sell-price-without-orderbook-enabled).
|
||||||
| `ask_strategy.use_order_book` | Enable selling of open trades using [Order Book Asks](#sell-price-with-orderbook-enabled). <br> **Datatype:** Boolean
|
| `exit_pricing.use_order_book` | Enable exiting of open trades using [Order Book Asks](#sell-price-with-orderbook-enabled). <br> *Defaults to `True`.*<br> **Datatype:** Boolean
|
||||||
| `ask_strategy.order_book_top` | Bot will use the top N rate in Order Book "price_side" to sell. I.e. a value of 2 will allow the bot to pick the 2nd ask rate in [Order Book Asks](#sell-price-with-orderbook-enabled)<br>*Defaults to `1`.* <br> **Datatype:** Positive Integer
|
| `exit_pricing.order_book_top` | Bot will use the top N rate in Order Book "price_side" to sell. I.e. a value of 2 will allow the bot to pick the 2nd ask rate in [Order Book Asks](#sell-price-with-orderbook-enabled)<br>*Defaults to `1`.* <br> **Datatype:** Positive Integer
|
||||||
| `use_sell_signal` | Use sell signals produced by the strategy in addition to the `minimal_roi`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `true`.* <br> **Datatype:** Boolean
|
| `use_sell_signal` | Use sell signals produced by the strategy in addition to the `minimal_roi`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `true`.* <br> **Datatype:** Boolean
|
||||||
| `sell_profit_only` | Wait until the bot reaches `sell_profit_offset` before taking a sell decision. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
|
| `sell_profit_only` | Wait until the bot reaches `sell_profit_offset` before taking a sell decision. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `false`.* <br> **Datatype:** Boolean
|
||||||
| `sell_profit_offset` | Sell-signal is only active above this value. Only active in combination with `sell_profit_only=True`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `0.0`.* <br> **Datatype:** Float (as ratio)
|
| `sell_profit_offset` | Sell-signal is only active above this value. Only active in combination with `sell_profit_only=True`. [Strategy Override](#parameters-in-the-strategy). <br>*Defaults to `0.0`.* <br> **Datatype:** Float (as ratio)
|
||||||
|
@ -108,12 +108,12 @@ To mitigate this, you can try to match the first order on the opposite orderbook
|
|||||||
"exit": "limit"
|
"exit": "limit"
|
||||||
// ...
|
// ...
|
||||||
},
|
},
|
||||||
"bid_strategy": {
|
"entry_pricing": {
|
||||||
"price_side": "ask",
|
"price_side": "other",
|
||||||
// ...
|
// ...
|
||||||
},
|
},
|
||||||
"ask_strategy":{
|
"exit_pricing":{
|
||||||
"price_side": "bid",
|
"price_side": "other",
|
||||||
// ...
|
// ...
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
@ -160,7 +160,7 @@ class AwesomeStrategy(IStrategy):
|
|||||||
:param pair: Pair that's currently analyzed
|
:param pair: Pair that's currently analyzed
|
||||||
:param trade: trade object.
|
:param trade: trade object.
|
||||||
:param current_time: datetime object, containing the current datetime
|
:param current_time: datetime object, containing the current datetime
|
||||||
:param current_rate: Rate, calculated based on pricing settings in ask_strategy.
|
:param current_rate: Rate, calculated based on pricing settings in exit_pricing.
|
||||||
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
||||||
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
||||||
:return float: New stoploss value, relative to the current rate
|
:return float: New stoploss value, relative to the current rate
|
||||||
@ -707,7 +707,7 @@ class AwesomeStrategy(IStrategy):
|
|||||||
|
|
||||||
:param pair: Pair that's currently analyzed
|
:param pair: Pair that's currently analyzed
|
||||||
:param current_time: datetime object, containing the current datetime
|
:param current_time: datetime object, containing the current datetime
|
||||||
:param current_rate: Rate, calculated based on pricing settings in ask_strategy.
|
:param current_rate: Rate, calculated based on pricing settings in exit_pricing.
|
||||||
:param proposed_leverage: A leverage proposed by the bot.
|
:param proposed_leverage: A leverage proposed by the bot.
|
||||||
:param max_leverage: Max leverage allowed on this pair
|
:param max_leverage: Max leverage allowed on this pair
|
||||||
:param side: 'long' or 'short' - indicating the direction of the proposed trade
|
:param side: 'long' or 'short' - indicating the direction of the proposed trade
|
||||||
|
@ -242,6 +242,8 @@ This should be given the value of `trade.is_short`.
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
``` python hl_lines="5 7"
|
``` python hl_lines="5 7"
|
||||||
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
|
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
|
||||||
current_rate: float, current_profit: float, **kwargs) -> float:
|
current_rate: float, current_profit: float, **kwargs) -> float:
|
||||||
@ -267,6 +269,8 @@ This should be given the value of `trade.is_short`.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
``` python hl_lines="2 3"
|
``` python hl_lines="2 3"
|
||||||
order_time_in_force: Dict = {
|
order_time_in_force: Dict = {
|
||||||
"entry": "gtc",
|
"entry": "gtc",
|
||||||
@ -291,6 +295,8 @@ This should be given the value of `trade.is_short`.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
``` python hl_lines="2-6"
|
``` python hl_lines="2-6"
|
||||||
order_types = {
|
order_types = {
|
||||||
"entry": "limit",
|
"entry": "limit",
|
||||||
@ -317,6 +323,8 @@ unfilledtimeout = {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
``` python hl_lines="2-3"
|
``` python hl_lines="2-3"
|
||||||
unfilledtimeout = {
|
unfilledtimeout = {
|
||||||
"entry": 10,
|
"entry": 10,
|
||||||
@ -325,3 +333,51 @@ unfilledtimeout = {
|
|||||||
"unit": "minutes"
|
"unit": "minutes"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `order pricing`
|
||||||
|
|
||||||
|
Order pricing changed in 2 ways. `bid_strategy` was renamed to `entry_strategy` and `ask_strategy` was renamed to `exit_strategy`.
|
||||||
|
Also, price-side can now be defined as `ask`, `bid`, `same` or `other`.
|
||||||
|
Please refer to the [pricing documentation](configuration.md) for more information.
|
||||||
|
|
||||||
|
``` json hl_lines="2-3 12-13"
|
||||||
|
{
|
||||||
|
"bid_strategy": {
|
||||||
|
"price_side": "bid",
|
||||||
|
"use_order_book": true,
|
||||||
|
"order_book_top": 1,
|
||||||
|
"ask_last_balance": 0.0,
|
||||||
|
"check_depth_of_market": {
|
||||||
|
"enabled": false,
|
||||||
|
"bids_to_ask_delta": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ask_strategy":{
|
||||||
|
"price_side": "ask",
|
||||||
|
"use_order_book": true,
|
||||||
|
"order_book_top": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
after:
|
||||||
|
|
||||||
|
``` json hl_lines="2-3 12-13"
|
||||||
|
{
|
||||||
|
"entry_pricing": {
|
||||||
|
"price_side": "same",
|
||||||
|
"use_order_book": true,
|
||||||
|
"order_book_top": 1,
|
||||||
|
"ask_last_balance": 0.0,
|
||||||
|
"check_depth_of_market": {
|
||||||
|
"enabled": false,
|
||||||
|
"bids_to_ask_delta": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"exit_pricing":{
|
||||||
|
"price_side": "same",
|
||||||
|
"use_order_book": true,
|
||||||
|
"order_book_top": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
@ -105,8 +105,8 @@ def _validate_price_config(conf: Dict[str, Any]) -> None:
|
|||||||
"""
|
"""
|
||||||
# TODO-lev: check this again when determining how to migrate pricing strategies!
|
# TODO-lev: check this again when determining how to migrate pricing strategies!
|
||||||
if (conf.get('order_types', {}).get('entry') == 'market'
|
if (conf.get('order_types', {}).get('entry') == 'market'
|
||||||
and conf.get('bid_strategy', {}).get('price_side') != 'ask'):
|
and conf.get('entry_pricing', {}).get('price_side') != 'ask'):
|
||||||
raise OperationalException('Market buy orders require bid_strategy.price_side = "ask".')
|
raise OperationalException('Market buy orders require entry_pricing.price_side = "ask".')
|
||||||
|
|
||||||
if (conf.get('order_types', {}).get('exit') == 'market'
|
if (conf.get('order_types', {}).get('exit') == 'market'
|
||||||
and conf.get('ask_strategy', {}).get('price_side') != 'bid'):
|
and conf.get('ask_strategy', {}).get('price_side') != 'bid'):
|
||||||
|
@ -81,8 +81,6 @@ class Configuration:
|
|||||||
# Normalize config
|
# Normalize config
|
||||||
if 'internals' not in config:
|
if 'internals' not in config:
|
||||||
config['internals'] = {}
|
config['internals'] = {}
|
||||||
if 'ask_strategy' not in config:
|
|
||||||
config['ask_strategy'] = {}
|
|
||||||
|
|
||||||
if 'pairlists' not in config:
|
if 'pairlists' not in config:
|
||||||
config['pairlists'] = []
|
config['pairlists'] = []
|
||||||
|
@ -21,7 +21,7 @@ UNLIMITED_STAKE_AMOUNT = 'unlimited'
|
|||||||
DEFAULT_AMOUNT_RESERVE_PERCENT = 0.05
|
DEFAULT_AMOUNT_RESERVE_PERCENT = 0.05
|
||||||
REQUIRED_ORDERTIF = ['entry', 'exit']
|
REQUIRED_ORDERTIF = ['entry', 'exit']
|
||||||
REQUIRED_ORDERTYPES = ['entry', 'exit', 'stoploss', 'stoploss_on_exchange']
|
REQUIRED_ORDERTYPES = ['entry', 'exit', 'stoploss', 'stoploss_on_exchange']
|
||||||
ORDERBOOK_SIDES = ['ask', 'bid']
|
PRICING_SIDES = ['ask', 'bid', 'same', 'other']
|
||||||
ORDERTYPE_POSSIBILITIES = ['limit', 'market']
|
ORDERTYPE_POSSIBILITIES = ['limit', 'market']
|
||||||
ORDERTIF_POSSIBILITIES = ['gtc', 'fok', 'ioc']
|
ORDERTIF_POSSIBILITIES = ['gtc', 'fok', 'ioc']
|
||||||
HYPEROPT_LOSS_BUILTIN = ['ShortTradeDurHyperOptLoss', 'OnlyProfitHyperOptLoss',
|
HYPEROPT_LOSS_BUILTIN = ['ShortTradeDurHyperOptLoss', 'OnlyProfitHyperOptLoss',
|
||||||
@ -171,7 +171,7 @@ CONF_SCHEMA = {
|
|||||||
'unit': {'type': 'string', 'enum': TIMEOUT_UNITS, 'default': 'minutes'}
|
'unit': {'type': 'string', 'enum': TIMEOUT_UNITS, 'default': 'minutes'}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'bid_strategy': {
|
'entry_pricing': {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'properties': {
|
'properties': {
|
||||||
'ask_last_balance': {
|
'ask_last_balance': {
|
||||||
@ -180,7 +180,7 @@ CONF_SCHEMA = {
|
|||||||
'maximum': 1,
|
'maximum': 1,
|
||||||
'exclusiveMaximum': False,
|
'exclusiveMaximum': False,
|
||||||
},
|
},
|
||||||
'price_side': {'type': 'string', 'enum': ORDERBOOK_SIDES, 'default': 'bid'},
|
'price_side': {'type': 'string', 'enum': PRICING_SIDES, 'default': 'bid'},
|
||||||
'use_order_book': {'type': 'boolean'},
|
'use_order_book': {'type': 'boolean'},
|
||||||
'order_book_top': {'type': 'integer', 'minimum': 1, 'maximum': 50, },
|
'order_book_top': {'type': 'integer', 'minimum': 1, 'maximum': 50, },
|
||||||
'check_depth_of_market': {
|
'check_depth_of_market': {
|
||||||
@ -193,10 +193,10 @@ CONF_SCHEMA = {
|
|||||||
},
|
},
|
||||||
'required': ['price_side']
|
'required': ['price_side']
|
||||||
},
|
},
|
||||||
'ask_strategy': {
|
'exit_pricing': {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'properties': {
|
'properties': {
|
||||||
'price_side': {'type': 'string', 'enum': ORDERBOOK_SIDES, 'default': 'ask'},
|
'price_side': {'type': 'string', 'enum': PRICING_SIDES, 'default': 'ask'},
|
||||||
'bid_last_balance': {
|
'bid_last_balance': {
|
||||||
'type': 'number',
|
'type': 'number',
|
||||||
'minimum': 0,
|
'minimum': 0,
|
||||||
@ -445,8 +445,8 @@ SCHEMA_TRADE_REQUIRED = [
|
|||||||
'last_stake_amount_min_ratio',
|
'last_stake_amount_min_ratio',
|
||||||
'dry_run',
|
'dry_run',
|
||||||
'dry_run_wallet',
|
'dry_run_wallet',
|
||||||
'ask_strategy',
|
'exit_pricing',
|
||||||
'bid_strategy',
|
'entry_pricing',
|
||||||
'stoploss',
|
'stoploss',
|
||||||
'minimal_roi',
|
'minimal_roi',
|
||||||
'internals',
|
'internals',
|
||||||
|
@ -184,8 +184,8 @@ class Exchange:
|
|||||||
self.required_candle_call_count = self.validate_required_startup_candles(
|
self.required_candle_call_count = self.validate_required_startup_candles(
|
||||||
config.get('startup_candle_count', 0), config.get('timeframe', ''))
|
config.get('startup_candle_count', 0), config.get('timeframe', ''))
|
||||||
self.validate_trading_mode_and_margin_mode(self.trading_mode, self.margin_mode)
|
self.validate_trading_mode_and_margin_mode(self.trading_mode, self.margin_mode)
|
||||||
self.validate_pricing(config['ask_strategy'])
|
self.validate_pricing(config['exit_pricing'])
|
||||||
self.validate_pricing(config['bid_strategy'])
|
self.validate_pricing(config['entry_pricing'])
|
||||||
|
|
||||||
# Converts the interval provided in minutes in config to seconds
|
# Converts the interval provided in minutes in config to seconds
|
||||||
self.markets_refresh_interval: int = exchange_config.get(
|
self.markets_refresh_interval: int = exchange_config.get(
|
||||||
|
@ -459,7 +459,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
if signal:
|
if signal:
|
||||||
stake_amount = self.wallets.get_trade_stake_amount(pair, self.edge)
|
stake_amount = self.wallets.get_trade_stake_amount(pair, self.edge)
|
||||||
|
|
||||||
bid_check_dom = self.config.get('bid_strategy', {}).get('check_depth_of_market', {})
|
bid_check_dom = self.config.get('entry_pricing', {}).get('check_depth_of_market', {})
|
||||||
if ((bid_check_dom.get('enabled', False)) and
|
if ((bid_check_dom.get('enabled', False)) and
|
||||||
(bid_check_dom.get('bids_to_ask_delta', 0) > 0)):
|
(bid_check_dom.get('bids_to_ask_delta', 0) > 0)):
|
||||||
if self._check_depth_of_market(pair, bid_check_dom, side=signal):
|
if self._check_depth_of_market(pair, bid_check_dom, side=signal):
|
||||||
|
@ -115,9 +115,9 @@ class Hyperopt:
|
|||||||
|
|
||||||
if HyperoptTools.has_space(self.config, 'sell'):
|
if HyperoptTools.has_space(self.config, 'sell'):
|
||||||
# Make sure use_sell_signal is enabled
|
# Make sure use_sell_signal is enabled
|
||||||
if 'ask_strategy' not in self.config:
|
if 'exit_pricing' not in self.config:
|
||||||
self.config['ask_strategy'] = {}
|
self.config['exit_pricing'] = {}
|
||||||
self.config['ask_strategy']['use_sell_signal'] = True
|
self.config['exit_pricing']['use_sell_signal'] = True
|
||||||
|
|
||||||
self.print_all = self.config.get('print_all', False)
|
self.print_all = self.config.get('print_all', False)
|
||||||
self.hyperopt_table_header = 0
|
self.hyperopt_table_header = 0
|
||||||
|
@ -175,8 +175,8 @@ class ShowConfig(BaseModel):
|
|||||||
exchange: str
|
exchange: str
|
||||||
strategy: Optional[str]
|
strategy: Optional[str]
|
||||||
forcebuy_enabled: bool
|
forcebuy_enabled: bool
|
||||||
ask_strategy: Dict[str, Any]
|
exit_pricing: Dict[str, Any]
|
||||||
bid_strategy: Dict[str, Any]
|
entry_pricing: Dict[str, Any]
|
||||||
bot_name: str
|
bot_name: str
|
||||||
state: str
|
state: str
|
||||||
runmode: str
|
runmode: str
|
||||||
|
@ -136,8 +136,8 @@ class RPC:
|
|||||||
'exchange': config['exchange']['name'],
|
'exchange': config['exchange']['name'],
|
||||||
'strategy': config['strategy'],
|
'strategy': config['strategy'],
|
||||||
'forcebuy_enabled': config.get('forcebuy_enable', False),
|
'forcebuy_enabled': config.get('forcebuy_enable', False),
|
||||||
'ask_strategy': config.get('ask_strategy', {}),
|
'exit_pricing': config.get('exit_pricing', {}),
|
||||||
'bid_strategy': config.get('bid_strategy', {}),
|
'entry_pricing': config.get('entry_pricing', {}),
|
||||||
'state': str(botstate),
|
'state': str(botstate),
|
||||||
'runmode': config['runmode'].value,
|
'runmode': config['runmode'].value,
|
||||||
'position_adjustment_enable': config.get('position_adjustment_enable', False),
|
'position_adjustment_enable': config.get('position_adjustment_enable', False),
|
||||||
|
@ -1490,8 +1490,8 @@ class Telegram(RPCHandler):
|
|||||||
f"*Stake per trade:* `{val['stake_amount']} {val['stake_currency']}`\n"
|
f"*Stake per trade:* `{val['stake_amount']} {val['stake_currency']}`\n"
|
||||||
f"*Max open Trades:* `{val['max_open_trades']}`\n"
|
f"*Max open Trades:* `{val['max_open_trades']}`\n"
|
||||||
f"*Minimum ROI:* `{val['minimal_roi']}`\n"
|
f"*Minimum ROI:* `{val['minimal_roi']}`\n"
|
||||||
f"*Ask strategy:* ```\n{json.dumps(val['ask_strategy'])}```\n"
|
f"*Entry strategy:* ```\n{json.dumps(val['entry_pricing'])}```\n"
|
||||||
f"*Bid strategy:* ```\n{json.dumps(val['bid_strategy'])}```\n"
|
f"*Exit strategy:* ```\n{json.dumps(val['exit_strategy'])}```\n"
|
||||||
f"{sl_info}"
|
f"{sl_info}"
|
||||||
f"{pa_info}"
|
f"{pa_info}"
|
||||||
f"*Timeframe:* `{val['timeframe']}`\n"
|
f"*Timeframe:* `{val['timeframe']}`\n"
|
||||||
|
@ -331,7 +331,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
:param pair: Pair that's currently analyzed
|
:param pair: Pair that's currently analyzed
|
||||||
:param trade: trade object.
|
:param trade: trade object.
|
||||||
:param current_time: datetime object, containing the current datetime
|
:param current_time: datetime object, containing the current datetime
|
||||||
:param current_rate: Rate, calculated based on pricing settings in ask_strategy.
|
:param current_rate: Rate, calculated based on pricing settings in exit_pricing.
|
||||||
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
||||||
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
||||||
:return float: New stoploss value, relative to the current_rate
|
:return float: New stoploss value, relative to the current_rate
|
||||||
@ -349,7 +349,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
|
|
||||||
:param pair: Pair that's currently analyzed
|
:param pair: Pair that's currently analyzed
|
||||||
:param current_time: datetime object, containing the current datetime
|
:param current_time: datetime object, containing the current datetime
|
||||||
:param proposed_rate: Rate, calculated based on pricing settings in ask_strategy.
|
:param proposed_rate: Rate, calculated based on pricing settings in exit_pricing.
|
||||||
:param entry_tag: Optional entry_tag (buy_tag) if provided with the buy signal.
|
:param entry_tag: Optional entry_tag (buy_tag) if provided with the buy signal.
|
||||||
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
||||||
:return float: New entry price value if provided
|
:return float: New entry price value if provided
|
||||||
@ -369,7 +369,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
:param pair: Pair that's currently analyzed
|
:param pair: Pair that's currently analyzed
|
||||||
:param trade: trade object.
|
:param trade: trade object.
|
||||||
:param current_time: datetime object, containing the current datetime
|
:param current_time: datetime object, containing the current datetime
|
||||||
:param proposed_rate: Rate, calculated based on pricing settings in ask_strategy.
|
:param proposed_rate: Rate, calculated based on pricing settings in exit_pricing.
|
||||||
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
||||||
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
||||||
:return float: New exit price value if provided
|
:return float: New exit price value if provided
|
||||||
@ -393,7 +393,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
:param pair: Pair that's currently analyzed
|
:param pair: Pair that's currently analyzed
|
||||||
:param trade: trade object.
|
:param trade: trade object.
|
||||||
:param current_time: datetime object, containing the current datetime
|
:param current_time: datetime object, containing the current datetime
|
||||||
:param current_rate: Rate, calculated based on pricing settings in ask_strategy.
|
:param current_rate: Rate, calculated based on pricing settings in exit_pricing.
|
||||||
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
||||||
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
||||||
:return: To execute exit, return a string with custom sell reason or True. Otherwise return
|
:return: To execute exit, return a string with custom sell reason or True. Otherwise return
|
||||||
@ -417,7 +417,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
:param pair: Pair that's currently analyzed
|
:param pair: Pair that's currently analyzed
|
||||||
:param trade: trade object.
|
:param trade: trade object.
|
||||||
:param current_time: datetime object, containing the current datetime
|
:param current_time: datetime object, containing the current datetime
|
||||||
:param current_rate: Rate, calculated based on pricing settings in ask_strategy.
|
:param current_rate: Rate, calculated based on pricing settings in exit_pricing.
|
||||||
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
||||||
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
||||||
:return: To execute exit, return a string with custom sell reason or True. Otherwise return
|
:return: To execute exit, return a string with custom sell reason or True. Otherwise return
|
||||||
@ -433,7 +433,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
|
|
||||||
:param pair: Pair that's currently analyzed
|
:param pair: Pair that's currently analyzed
|
||||||
:param current_time: datetime object, containing the current datetime
|
:param current_time: datetime object, containing the current datetime
|
||||||
:param current_rate: Rate, calculated based on pricing settings in ask_strategy.
|
:param current_rate: Rate, calculated based on pricing settings in exit_pricing.
|
||||||
:param proposed_stake: A stake amount proposed by the bot.
|
:param proposed_stake: A stake amount proposed by the bot.
|
||||||
:param min_stake: Minimal stake size allowed by exchange.
|
:param min_stake: Minimal stake size allowed by exchange.
|
||||||
:param max_stake: Balance available for trading.
|
:param max_stake: Balance available for trading.
|
||||||
@ -474,7 +474,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
|
|
||||||
:param pair: Pair that's currently analyzed
|
:param pair: Pair that's currently analyzed
|
||||||
:param current_time: datetime object, containing the current datetime
|
:param current_time: datetime object, containing the current datetime
|
||||||
:param current_rate: Rate, calculated based on pricing settings in ask_strategy.
|
:param current_rate: Rate, calculated based on pricing settings in exit_pricing.
|
||||||
:param proposed_leverage: A leverage proposed by the bot.
|
:param proposed_leverage: A leverage proposed by the bot.
|
||||||
:param max_leverage: Max leverage allowed on this pair
|
:param max_leverage: Max leverage allowed on this pair
|
||||||
:param side: 'long' or 'short' - indicating the direction of the proposed trade
|
:param side: 'long' or 'short' - indicating the direction of the proposed trade
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
"exit_timeout_count": 0,
|
"exit_timeout_count": 0,
|
||||||
"unit": "minutes"
|
"unit": "minutes"
|
||||||
},
|
},
|
||||||
"bid_strategy": {
|
"entry_pricing": {
|
||||||
"price_side": "bid",
|
"price_side": "same",
|
||||||
"ask_last_balance": 0.0,
|
"ask_last_balance": 0.0,
|
||||||
"use_order_book": true,
|
"use_order_book": true,
|
||||||
"order_book_top": 1,
|
"order_book_top": 1,
|
||||||
@ -31,8 +31,8 @@
|
|||||||
"bids_to_ask_delta": 1
|
"bids_to_ask_delta": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ask_strategy": {
|
"exit_pricing":{
|
||||||
"price_side": "ask",
|
"price_side": "same",
|
||||||
"use_order_book": true,
|
"use_order_book": true,
|
||||||
"order_book_top": 1
|
"order_book_top": 1
|
||||||
},
|
},
|
||||||
|
@ -64,7 +64,7 @@ class {{ strategy }}(IStrategy):
|
|||||||
# Run "populate_indicators()" only for new candle.
|
# Run "populate_indicators()" only for new candle.
|
||||||
process_only_new_candles = False
|
process_only_new_candles = False
|
||||||
|
|
||||||
# These values can be overridden in the "ask_strategy" section in the config.
|
# These values can be overridden in the config.
|
||||||
use_sell_signal = True
|
use_sell_signal = True
|
||||||
sell_profit_only = False
|
sell_profit_only = False
|
||||||
ignore_roi_if_buy_signal = False
|
ignore_roi_if_buy_signal = False
|
||||||
|
@ -64,7 +64,7 @@ class SampleStrategy(IStrategy):
|
|||||||
# Run "populate_indicators()" only for new candle.
|
# Run "populate_indicators()" only for new candle.
|
||||||
process_only_new_candles = False
|
process_only_new_candles = False
|
||||||
|
|
||||||
# These values can be overridden in the "ask_strategy" section in the config.
|
# These values can be overridden in the config.
|
||||||
use_sell_signal = True
|
use_sell_signal = True
|
||||||
sell_profit_only = False
|
sell_profit_only = False
|
||||||
ignore_roi_if_buy_signal = False
|
ignore_roi_if_buy_signal = False
|
||||||
|
@ -23,7 +23,7 @@ def custom_entry_price(self, pair: str, current_time: 'datetime', proposed_rate:
|
|||||||
|
|
||||||
:param pair: Pair that's currently analyzed
|
:param pair: Pair that's currently analyzed
|
||||||
:param current_time: datetime object, containing the current datetime
|
:param current_time: datetime object, containing the current datetime
|
||||||
:param proposed_rate: Rate, calculated based on pricing settings in ask_strategy.
|
:param proposed_rate: Rate, calculated based on pricing settings in exit_pricing.
|
||||||
:param entry_tag: Optional entry_tag (buy_tag) if provided with the buy signal.
|
:param entry_tag: Optional entry_tag (buy_tag) if provided with the buy signal.
|
||||||
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
||||||
:return float: New entry price value if provided
|
:return float: New entry price value if provided
|
||||||
@ -43,7 +43,7 @@ def custom_exit_price(self, pair: str, trade: 'Trade',
|
|||||||
:param pair: Pair that's currently analyzed
|
:param pair: Pair that's currently analyzed
|
||||||
:param trade: trade object.
|
:param trade: trade object.
|
||||||
:param current_time: datetime object, containing the current datetime
|
:param current_time: datetime object, containing the current datetime
|
||||||
:param proposed_rate: Rate, calculated based on pricing settings in ask_strategy.
|
:param proposed_rate: Rate, calculated based on pricing settings in exit_pricing.
|
||||||
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
||||||
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
||||||
:return float: New exit price value if provided
|
:return float: New exit price value if provided
|
||||||
@ -58,7 +58,7 @@ def custom_stake_amount(self, pair: str, current_time: 'datetime', current_rate:
|
|||||||
|
|
||||||
:param pair: Pair that's currently analyzed
|
:param pair: Pair that's currently analyzed
|
||||||
:param current_time: datetime object, containing the current datetime
|
:param current_time: datetime object, containing the current datetime
|
||||||
:param current_rate: Rate, calculated based on pricing settings in ask_strategy.
|
:param current_rate: Rate, calculated based on pricing settings in exit_pricing.
|
||||||
:param proposed_stake: A stake amount proposed by the bot.
|
:param proposed_stake: A stake amount proposed by the bot.
|
||||||
:param min_stake: Minimal stake size allowed by exchange.
|
:param min_stake: Minimal stake size allowed by exchange.
|
||||||
:param max_stake: Balance available for trading.
|
:param max_stake: Balance available for trading.
|
||||||
@ -85,7 +85,7 @@ def custom_stoploss(self, pair: str, trade: 'Trade', current_time: 'datetime',
|
|||||||
:param pair: Pair that's currently analyzed
|
:param pair: Pair that's currently analyzed
|
||||||
:param trade: trade object.
|
:param trade: trade object.
|
||||||
:param current_time: datetime object, containing the current datetime
|
:param current_time: datetime object, containing the current datetime
|
||||||
:param current_rate: Rate, calculated based on pricing settings in ask_strategy.
|
:param current_rate: Rate, calculated based on pricing settings in exit_pricing.
|
||||||
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
||||||
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
||||||
:return float: New stoploss value, relative to the current_rate
|
:return float: New stoploss value, relative to the current_rate
|
||||||
@ -108,7 +108,7 @@ def custom_exit(self, pair: str, trade: 'Trade', current_time: 'datetime', curre
|
|||||||
:param pair: Pair that's currently analyzed
|
:param pair: Pair that's currently analyzed
|
||||||
:param trade: trade object.
|
:param trade: trade object.
|
||||||
:param current_time: datetime object, containing the current datetime
|
:param current_time: datetime object, containing the current datetime
|
||||||
:param current_rate: Rate, calculated based on pricing settings in ask_strategy.
|
:param current_rate: Rate, calculated based on pricing settings in exit_pricing.
|
||||||
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
||||||
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
||||||
:return: To execute sell, return a string with custom sell reason or True. Otherwise return
|
:return: To execute sell, return a string with custom sell reason or True. Otherwise return
|
||||||
@ -241,7 +241,7 @@ def leverage(self, pair: str, current_time: datetime, current_rate: float,
|
|||||||
|
|
||||||
:param pair: Pair that's currently analyzed
|
:param pair: Pair that's currently analyzed
|
||||||
:param current_time: datetime object, containing the current datetime
|
:param current_time: datetime object, containing the current datetime
|
||||||
:param current_rate: Rate, calculated based on pricing settings in ask_strategy.
|
:param current_rate: Rate, calculated based on pricing settings in exit_pricing.
|
||||||
:param proposed_leverage: A leverage proposed by the bot.
|
:param proposed_leverage: A leverage proposed by the bot.
|
||||||
:param max_leverage: Max leverage allowed on this pair
|
:param max_leverage: Max leverage allowed on this pair
|
||||||
:param side: 'long' or 'short' - indicating the direction of the proposed trade
|
:param side: 'long' or 'short' - indicating the direction of the proposed trade
|
||||||
|
@ -419,7 +419,7 @@ def get_default_conf(testdatadir):
|
|||||||
"entry": 10,
|
"entry": 10,
|
||||||
"exit": 30
|
"exit": 30
|
||||||
},
|
},
|
||||||
"bid_strategy": {
|
"entry_pricing": {
|
||||||
"ask_last_balance": 0.0,
|
"ask_last_balance": 0.0,
|
||||||
"use_order_book": False,
|
"use_order_book": False,
|
||||||
"order_book_top": 1,
|
"order_book_top": 1,
|
||||||
@ -428,7 +428,7 @@ def get_default_conf(testdatadir):
|
|||||||
"bids_to_ask_delta": 1
|
"bids_to_ask_delta": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ask_strategy": {
|
"exit_pricing": {
|
||||||
"use_order_book": False,
|
"use_order_book": False,
|
||||||
"order_book_top": 1,
|
"order_book_top": 1,
|
||||||
},
|
},
|
||||||
|
@ -107,8 +107,8 @@ def exchange_conf():
|
|||||||
config['exchange']['key'] = ''
|
config['exchange']['key'] = ''
|
||||||
config['exchange']['secret'] = ''
|
config['exchange']['secret'] = ''
|
||||||
config['dry_run'] = False
|
config['dry_run'] = False
|
||||||
config['bid_strategy']['use_order_book'] = True
|
config['entry_pricing']['use_order_book'] = True
|
||||||
config['ask_strategy']['use_order_book'] = True
|
config['exit_pricing']['use_order_book'] = True
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
@ -971,7 +971,7 @@ def test_validate_pricing(default_conf, mocker):
|
|||||||
|
|
||||||
has.update({'fetchTicker': True})
|
has.update({'fetchTicker': True})
|
||||||
|
|
||||||
default_conf['ask_strategy']['use_order_book'] = True
|
default_conf['exit_pricing']['use_order_book'] = True
|
||||||
ExchangeResolver.load_exchange('binance', default_conf)
|
ExchangeResolver.load_exchange('binance', default_conf)
|
||||||
has.update({'fetchL2OrderBook': False})
|
has.update({'fetchL2OrderBook': False})
|
||||||
|
|
||||||
@ -2305,10 +2305,10 @@ def test_get_buy_rate(mocker, default_conf, caplog, side, ask, bid,
|
|||||||
last, last_ab, expected) -> None:
|
last, last_ab, expected) -> None:
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
if last_ab is None:
|
if last_ab is None:
|
||||||
del default_conf['bid_strategy']['ask_last_balance']
|
del default_conf['entry_pricing']['ask_last_balance']
|
||||||
else:
|
else:
|
||||||
default_conf['bid_strategy']['ask_last_balance'] = last_ab
|
default_conf['entry_pricing']['ask_last_balance'] = last_ab
|
||||||
default_conf['bid_strategy']['price_side'] = side
|
default_conf['entry_pricing']['price_side'] = side
|
||||||
exchange = get_patched_exchange(mocker, default_conf)
|
exchange = get_patched_exchange(mocker, default_conf)
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker',
|
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker',
|
||||||
return_value={'ask': ask, 'last': last, 'bid': bid})
|
return_value={'ask': ask, 'last': last, 'bid': bid})
|
||||||
@ -2349,9 +2349,9 @@ def test_get_sell_rate(default_conf, mocker, caplog, side, bid, ask,
|
|||||||
last, last_ab, expected) -> None:
|
last, last_ab, expected) -> None:
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
|
|
||||||
default_conf['ask_strategy']['price_side'] = side
|
default_conf['exit_pricing']['price_side'] = side
|
||||||
if last_ab is not None:
|
if last_ab is not None:
|
||||||
default_conf['ask_strategy']['bid_last_balance'] = last_ab
|
default_conf['exit_pricing']['bid_last_balance'] = last_ab
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker',
|
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker',
|
||||||
return_value={'ask': ask, 'bid': bid, 'last': last})
|
return_value={'ask': ask, 'bid': bid, 'last': last})
|
||||||
pair = "ETH/BTC"
|
pair = "ETH/BTC"
|
||||||
@ -2381,10 +2381,10 @@ def test_get_sell_rate(default_conf, mocker, caplog, side, bid, ask,
|
|||||||
def test_get_ticker_rate_error(mocker, entry, default_conf, caplog, side, ask, bid,
|
def test_get_ticker_rate_error(mocker, entry, default_conf, caplog, side, ask, bid,
|
||||||
last, last_ab, expected) -> None:
|
last, last_ab, expected) -> None:
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
default_conf['bid_strategy']['ask_last_balance'] = last_ab
|
default_conf['entry_pricing']['ask_last_balance'] = last_ab
|
||||||
default_conf['bid_strategy']['price_side'] = side
|
default_conf['entry_pricing']['price_side'] = side
|
||||||
default_conf['ask_strategy']['price_side'] = side
|
default_conf['exit_pricing']['price_side'] = side
|
||||||
default_conf['ask_strategy']['ask_last_balance'] = last_ab
|
default_conf['exit_pricing']['ask_last_balance'] = last_ab
|
||||||
exchange = get_patched_exchange(mocker, default_conf)
|
exchange = get_patched_exchange(mocker, default_conf)
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker',
|
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker',
|
||||||
return_value={'ask': ask, 'last': last, 'bid': bid})
|
return_value={'ask': ask, 'last': last, 'bid': bid})
|
||||||
@ -2400,9 +2400,9 @@ def test_get_ticker_rate_error(mocker, entry, default_conf, caplog, side, ask, b
|
|||||||
def test_get_sell_rate_orderbook(default_conf, mocker, caplog, side, expected, order_book_l2):
|
def test_get_sell_rate_orderbook(default_conf, mocker, caplog, side, expected, order_book_l2):
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
# Test orderbook mode
|
# Test orderbook mode
|
||||||
default_conf['ask_strategy']['price_side'] = side
|
default_conf['exit_pricing']['price_side'] = side
|
||||||
default_conf['ask_strategy']['use_order_book'] = True
|
default_conf['exit_pricing']['use_order_book'] = True
|
||||||
default_conf['ask_strategy']['order_book_top'] = 1
|
default_conf['exit_pricing']['order_book_top'] = 1
|
||||||
pair = "ETH/BTC"
|
pair = "ETH/BTC"
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_l2_order_book', order_book_l2)
|
mocker.patch('freqtrade.exchange.Exchange.fetch_l2_order_book', order_book_l2)
|
||||||
exchange = get_patched_exchange(mocker, default_conf)
|
exchange = get_patched_exchange(mocker, default_conf)
|
||||||
@ -2417,9 +2417,9 @@ def test_get_sell_rate_orderbook(default_conf, mocker, caplog, side, expected, o
|
|||||||
|
|
||||||
def test_get_sell_rate_orderbook_exception(default_conf, mocker, caplog):
|
def test_get_sell_rate_orderbook_exception(default_conf, mocker, caplog):
|
||||||
# Test orderbook mode
|
# Test orderbook mode
|
||||||
default_conf['ask_strategy']['price_side'] = 'ask'
|
default_conf['exit_pricing']['price_side'] = 'ask'
|
||||||
default_conf['ask_strategy']['use_order_book'] = True
|
default_conf['exit_pricing']['use_order_book'] = True
|
||||||
default_conf['ask_strategy']['order_book_top'] = 1
|
default_conf['exit_pricing']['order_book_top'] = 1
|
||||||
pair = "ETH/BTC"
|
pair = "ETH/BTC"
|
||||||
# Test What happens if the exchange returns an empty orderbook.
|
# Test What happens if the exchange returns an empty orderbook.
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_l2_order_book',
|
mocker.patch('freqtrade.exchange.Exchange.fetch_l2_order_book',
|
||||||
@ -2433,7 +2433,7 @@ def test_get_sell_rate_orderbook_exception(default_conf, mocker, caplog):
|
|||||||
|
|
||||||
def test_get_sell_rate_exception(default_conf, mocker, caplog):
|
def test_get_sell_rate_exception(default_conf, mocker, caplog):
|
||||||
# Ticker on one side can be empty in certain circumstances.
|
# Ticker on one side can be empty in certain circumstances.
|
||||||
default_conf['ask_strategy']['price_side'] = 'ask'
|
default_conf['exit_pricing']['price_side'] = 'ask'
|
||||||
pair = "ETH/BTC"
|
pair = "ETH/BTC"
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker',
|
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker',
|
||||||
return_value={'ask': None, 'bid': 0.12, 'last': None})
|
return_value={'ask': None, 'bid': 0.12, 'last': None})
|
||||||
@ -2441,7 +2441,7 @@ def test_get_sell_rate_exception(default_conf, mocker, caplog):
|
|||||||
with pytest.raises(PricingError, match=r"Sell-Rate for ETH/BTC was empty."):
|
with pytest.raises(PricingError, match=r"Sell-Rate for ETH/BTC was empty."):
|
||||||
exchange.get_rate(pair, refresh=True, side="sell")
|
exchange.get_rate(pair, refresh=True, side="sell")
|
||||||
|
|
||||||
exchange._config['ask_strategy']['price_side'] = 'bid'
|
exchange._config['exit_pricing']['price_side'] = 'bid'
|
||||||
assert exchange.get_rate(pair, refresh=True, side="sell") == 0.12
|
assert exchange.get_rate(pair, refresh=True, side="sell") == 0.12
|
||||||
# Reverse sides
|
# Reverse sides
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker',
|
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker',
|
||||||
@ -2449,7 +2449,7 @@ def test_get_sell_rate_exception(default_conf, mocker, caplog):
|
|||||||
with pytest.raises(PricingError, match=r"Sell-Rate for ETH/BTC was empty."):
|
with pytest.raises(PricingError, match=r"Sell-Rate for ETH/BTC was empty."):
|
||||||
exchange.get_rate(pair, refresh=True, side="sell")
|
exchange.get_rate(pair, refresh=True, side="sell")
|
||||||
|
|
||||||
exchange._config['ask_strategy']['price_side'] = 'ask'
|
exchange._config['exit_pricing']['price_side'] = 'ask'
|
||||||
assert exchange.get_rate(pair, refresh=True, side="sell") == 0.13
|
assert exchange.get_rate(pair, refresh=True, side="sell") == 0.13
|
||||||
|
|
||||||
|
|
||||||
|
@ -543,8 +543,8 @@ def test_api_show_config(botclient):
|
|||||||
assert response['trading_mode'] == 'spot'
|
assert response['trading_mode'] == 'spot'
|
||||||
assert response['strategy_version'] is None
|
assert response['strategy_version'] is None
|
||||||
assert not response['trailing_stop']
|
assert not response['trailing_stop']
|
||||||
assert 'bid_strategy' in response
|
assert 'entry_pricing' in response
|
||||||
assert 'ask_strategy' in response
|
assert 'exit_pricing' in response
|
||||||
assert 'unfilledtimeout' in response
|
assert 'unfilledtimeout' in response
|
||||||
assert 'version' in response
|
assert 'version' in response
|
||||||
assert 'api_version' in response
|
assert 'api_version' in response
|
||||||
|
@ -809,21 +809,21 @@ def test_validate_price_side(default_conf):
|
|||||||
conf = deepcopy(default_conf)
|
conf = deepcopy(default_conf)
|
||||||
conf['order_types']['entry'] = 'market'
|
conf['order_types']['entry'] = 'market'
|
||||||
with pytest.raises(OperationalException,
|
with pytest.raises(OperationalException,
|
||||||
match='Market buy orders require bid_strategy.price_side = "ask".'):
|
match='Market buy orders require entry_pricing.price_side = "ask".'):
|
||||||
validate_config_consistency(conf)
|
validate_config_consistency(conf)
|
||||||
|
|
||||||
conf = deepcopy(default_conf)
|
conf = deepcopy(default_conf)
|
||||||
conf['order_types']['exit'] = 'market'
|
conf['order_types']['exit'] = 'market'
|
||||||
with pytest.raises(OperationalException,
|
with pytest.raises(OperationalException,
|
||||||
match='Market sell orders require ask_strategy.price_side = "bid".'):
|
match='Market sell orders require exit_pricing.price_side = "bid".'):
|
||||||
validate_config_consistency(conf)
|
validate_config_consistency(conf)
|
||||||
|
|
||||||
# Validate inversed case
|
# Validate inversed case
|
||||||
conf = deepcopy(default_conf)
|
conf = deepcopy(default_conf)
|
||||||
conf['order_types']['exit'] = 'market'
|
conf['order_types']['exit'] = 'market'
|
||||||
conf['order_types']['entry'] = 'market'
|
conf['order_types']['entry'] = 'market'
|
||||||
conf['ask_strategy']['price_side'] = 'bid'
|
conf['exit_pricing']['price_side'] = 'bid'
|
||||||
conf['bid_strategy']['price_side'] = 'ask'
|
conf['entry_pricing']['price_side'] = 'ask'
|
||||||
|
|
||||||
validate_config_consistency(conf)
|
validate_config_consistency(conf)
|
||||||
|
|
||||||
@ -926,18 +926,18 @@ def test_validate_protections(default_conf, protconf, expected):
|
|||||||
|
|
||||||
def test_validate_ask_orderbook(default_conf, caplog) -> None:
|
def test_validate_ask_orderbook(default_conf, caplog) -> None:
|
||||||
conf = deepcopy(default_conf)
|
conf = deepcopy(default_conf)
|
||||||
conf['ask_strategy']['use_order_book'] = True
|
conf['exit_pricing']['use_order_book'] = True
|
||||||
conf['ask_strategy']['order_book_min'] = 2
|
conf['exit_pricing']['order_book_min'] = 2
|
||||||
conf['ask_strategy']['order_book_max'] = 2
|
conf['exit_pricing']['order_book_max'] = 2
|
||||||
|
|
||||||
validate_config_consistency(conf)
|
validate_config_consistency(conf)
|
||||||
assert log_has_re(r"DEPRECATED: Please use `order_book_top` instead of.*", caplog)
|
assert log_has_re(r"DEPRECATED: Please use `order_book_top` instead of.*", caplog)
|
||||||
assert conf['ask_strategy']['order_book_top'] == 2
|
assert conf['exit_pricing']['order_book_top'] == 2
|
||||||
|
|
||||||
conf['ask_strategy']['order_book_max'] = 5
|
conf['exit_pricing']['order_book_max'] = 5
|
||||||
|
|
||||||
with pytest.raises(OperationalException,
|
with pytest.raises(OperationalException,
|
||||||
match=r"Using order_book_max != order_book_min in ask_strategy.*"):
|
match=r"Using order_book_max != order_book_min in exit_pricing.*"):
|
||||||
validate_config_consistency(conf)
|
validate_config_consistency(conf)
|
||||||
|
|
||||||
|
|
||||||
@ -1200,15 +1200,15 @@ def test_pairlist_resolving_fallback(mocker):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("setting", [
|
@pytest.mark.parametrize("setting", [
|
||||||
("ask_strategy", "use_sell_signal", True,
|
("exit_pricing", "use_sell_signal", True,
|
||||||
None, "use_sell_signal", False),
|
None, "use_sell_signal", False),
|
||||||
("ask_strategy", "sell_profit_only", True,
|
("exit_pricing", "sell_profit_only", True,
|
||||||
None, "sell_profit_only", False),
|
None, "sell_profit_only", False),
|
||||||
("ask_strategy", "sell_profit_offset", 0.1,
|
("exit_pricing", "sell_profit_offset", 0.1,
|
||||||
None, "sell_profit_offset", 0.01),
|
None, "sell_profit_offset", 0.01),
|
||||||
("ask_strategy", "ignore_roi_if_buy_signal", True,
|
("exit_pricing", "ignore_roi_if_buy_signal", True,
|
||||||
None, "ignore_roi_if_buy_signal", False),
|
None, "ignore_roi_if_buy_signal", False),
|
||||||
("ask_strategy", "ignore_buying_expired_candle_after", 5,
|
("exit_pricing", "ignore_buying_expired_candle_after", 5,
|
||||||
None, "ignore_buying_expired_candle_after", 6),
|
None, "ignore_buying_expired_candle_after", 6),
|
||||||
])
|
])
|
||||||
def test_process_temporary_deprecated_settings(mocker, default_conf, setting, caplog):
|
def test_process_temporary_deprecated_settings(mocker, default_conf, setting, caplog):
|
||||||
@ -1434,15 +1434,15 @@ def test_flat_vars_to_nested_dict(caplog):
|
|||||||
'FREQTRADE__EXCHANGE__SOME_SETTING': 'true',
|
'FREQTRADE__EXCHANGE__SOME_SETTING': 'true',
|
||||||
'FREQTRADE__EXCHANGE__SOME_FALSE_SETTING': 'false',
|
'FREQTRADE__EXCHANGE__SOME_FALSE_SETTING': 'false',
|
||||||
'FREQTRADE__EXCHANGE__CONFIG__whatever': 'sometime',
|
'FREQTRADE__EXCHANGE__CONFIG__whatever': 'sometime',
|
||||||
'FREQTRADE__ASK_STRATEGY__PRICE_SIDE': 'bid',
|
'FREQTRADE__EXIT_PRICING__PRICE_SIDE': 'bid',
|
||||||
'FREQTRADE__ASK_STRATEGY__cccc': '500',
|
'FREQTRADE__EXIT_PRICING__cccc': '500',
|
||||||
'FREQTRADE__STAKE_AMOUNT': '200.05',
|
'FREQTRADE__STAKE_AMOUNT': '200.05',
|
||||||
'FREQTRADE__TELEGRAM__CHAT_ID': '2151',
|
'FREQTRADE__TELEGRAM__CHAT_ID': '2151',
|
||||||
'NOT_RELEVANT': '200.0', # Will be ignored
|
'NOT_RELEVANT': '200.0', # Will be ignored
|
||||||
}
|
}
|
||||||
expected = {
|
expected = {
|
||||||
'stake_amount': 200.05,
|
'stake_amount': 200.05,
|
||||||
'ask_strategy': {
|
'exit_pricing': {
|
||||||
'price_side': 'bid',
|
'price_side': 'bid',
|
||||||
'cccc': 500,
|
'cccc': 500,
|
||||||
},
|
},
|
||||||
|
@ -96,7 +96,7 @@ def test_order_dict(default_conf_usdt, mocker, runmode, caplog) -> None:
|
|||||||
'stoploss': 'limit',
|
'stoploss': 'limit',
|
||||||
'stoploss_on_exchange': True,
|
'stoploss_on_exchange': True,
|
||||||
}
|
}
|
||||||
conf['bid_strategy']['price_side'] = 'ask'
|
conf['entry_pricing']['price_side'] = 'ask'
|
||||||
|
|
||||||
freqtrade = FreqtradeBot(conf)
|
freqtrade = FreqtradeBot(conf)
|
||||||
if runmode == RunMode.LIVE:
|
if runmode == RunMode.LIVE:
|
||||||
@ -4052,7 +4052,7 @@ def test_disable_ignore_roi_if_buy_signal(default_conf_usdt, limit_order, limit_
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
_is_dry_limit_order_filled=MagicMock(return_value=False),
|
_is_dry_limit_order_filled=MagicMock(return_value=False),
|
||||||
)
|
)
|
||||||
default_conf_usdt['ask_strategy'] = {
|
default_conf_usdt['exit_pricing'] = {
|
||||||
'ignore_roi_if_buy_signal': False
|
'ignore_roi_if_buy_signal': False
|
||||||
}
|
}
|
||||||
freqtrade = FreqtradeBot(default_conf_usdt)
|
freqtrade = FreqtradeBot(default_conf_usdt)
|
||||||
@ -4432,8 +4432,8 @@ def test_order_book_depth_of_market(
|
|||||||
):
|
):
|
||||||
ticker_side = 'ask' if is_short else 'bid'
|
ticker_side = 'ask' if is_short else 'bid'
|
||||||
|
|
||||||
default_conf_usdt['bid_strategy']['check_depth_of_market']['enabled'] = True
|
default_conf_usdt['entry_pricing']['check_depth_of_market']['enabled'] = True
|
||||||
default_conf_usdt['bid_strategy']['check_depth_of_market']['bids_to_ask_delta'] = delta
|
default_conf_usdt['entry_pricing']['check_depth_of_market']['bids_to_ask_delta'] = delta
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_l2_order_book', order_book_l2)
|
mocker.patch('freqtrade.exchange.Exchange.fetch_l2_order_book', order_book_l2)
|
||||||
@ -4476,7 +4476,7 @@ def test_order_book_depth_of_market(
|
|||||||
(False, 0.045, 0.046, 2, None),
|
(False, 0.045, 0.046, 2, None),
|
||||||
(True, 0.042, 0.046, 1, {'bids': [[]], 'asks': [[]]})
|
(True, 0.042, 0.046, 1, {'bids': [[]], 'asks': [[]]})
|
||||||
])
|
])
|
||||||
def test_order_book_bid_strategy1(mocker, default_conf_usdt, order_book_l2, exception_thrown,
|
def test_order_book_entry_pricing1(mocker, default_conf_usdt, order_book_l2, exception_thrown,
|
||||||
ask, last, order_book_top, order_book, caplog) -> None:
|
ask, last, order_book_top, order_book, caplog) -> None:
|
||||||
"""
|
"""
|
||||||
test if function get_rate will return the order book price instead of the ask rate
|
test if function get_rate will return the order book price instead of the ask rate
|
||||||
@ -4489,9 +4489,9 @@ def test_order_book_bid_strategy1(mocker, default_conf_usdt, order_book_l2, exce
|
|||||||
fetch_ticker=ticker_usdt_mock,
|
fetch_ticker=ticker_usdt_mock,
|
||||||
)
|
)
|
||||||
default_conf_usdt['exchange']['name'] = 'binance'
|
default_conf_usdt['exchange']['name'] = 'binance'
|
||||||
default_conf_usdt['bid_strategy']['use_order_book'] = True
|
default_conf_usdt['entry_pricing']['use_order_book'] = True
|
||||||
default_conf_usdt['bid_strategy']['order_book_top'] = order_book_top
|
default_conf_usdt['entry_pricing']['order_book_top'] = order_book_top
|
||||||
default_conf_usdt['bid_strategy']['ask_last_balance'] = 0
|
default_conf_usdt['entry_pricing']['ask_last_balance'] = 0
|
||||||
default_conf_usdt['telegram']['enabled'] = False
|
default_conf_usdt['telegram']['enabled'] = False
|
||||||
|
|
||||||
freqtrade = FreqtradeBot(default_conf_usdt)
|
freqtrade = FreqtradeBot(default_conf_usdt)
|
||||||
@ -4516,17 +4516,17 @@ def test_check_depth_of_market(default_conf_usdt, mocker, order_book_l2) -> None
|
|||||||
)
|
)
|
||||||
default_conf_usdt['telegram']['enabled'] = False
|
default_conf_usdt['telegram']['enabled'] = False
|
||||||
default_conf_usdt['exchange']['name'] = 'binance'
|
default_conf_usdt['exchange']['name'] = 'binance'
|
||||||
default_conf_usdt['bid_strategy']['check_depth_of_market']['enabled'] = True
|
default_conf_usdt['entry_pricing']['check_depth_of_market']['enabled'] = True
|
||||||
# delta is 100 which is impossible to reach. hence function will return false
|
# delta is 100 which is impossible to reach. hence function will return false
|
||||||
default_conf_usdt['bid_strategy']['check_depth_of_market']['bids_to_ask_delta'] = 100
|
default_conf_usdt['entry_pricing']['check_depth_of_market']['bids_to_ask_delta'] = 100
|
||||||
freqtrade = FreqtradeBot(default_conf_usdt)
|
freqtrade = FreqtradeBot(default_conf_usdt)
|
||||||
|
|
||||||
conf = default_conf_usdt['bid_strategy']['check_depth_of_market']
|
conf = default_conf_usdt['entry_pricing']['check_depth_of_market']
|
||||||
assert freqtrade._check_depth_of_market('ETH/BTC', conf, side=SignalDirection.LONG) is False
|
assert freqtrade._check_depth_of_market('ETH/BTC', conf, side=SignalDirection.LONG) is False
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('is_short', [False, True])
|
@pytest.mark.parametrize('is_short', [False, True])
|
||||||
def test_order_book_ask_strategy(
|
def test_order_book_exit_pricing(
|
||||||
default_conf_usdt, limit_buy_order_usdt_open, limit_buy_order_usdt, fee, is_short,
|
default_conf_usdt, limit_buy_order_usdt_open, limit_buy_order_usdt, fee, is_short,
|
||||||
limit_sell_order_usdt_open, mocker, order_book_l2, caplog) -> None:
|
limit_sell_order_usdt_open, mocker, order_book_l2, caplog) -> None:
|
||||||
"""
|
"""
|
||||||
@ -4534,8 +4534,8 @@ def test_order_book_ask_strategy(
|
|||||||
"""
|
"""
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_l2_order_book', order_book_l2)
|
mocker.patch('freqtrade.exchange.Exchange.fetch_l2_order_book', order_book_l2)
|
||||||
default_conf_usdt['exchange']['name'] = 'binance'
|
default_conf_usdt['exchange']['name'] = 'binance'
|
||||||
default_conf_usdt['ask_strategy']['use_order_book'] = True
|
default_conf_usdt['exit_pricing']['use_order_book'] = True
|
||||||
default_conf_usdt['ask_strategy']['order_book_top'] = 1
|
default_conf_usdt['exit_pricing']['order_book_top'] = 1
|
||||||
default_conf_usdt['telegram']['enabled'] = False
|
default_conf_usdt['telegram']['enabled'] = False
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
|
Loading…
Reference in New Issue
Block a user