Merge branch 'develop' into add-plot-feature-importance
This commit is contained in:
commit
bdeb2f9c6a
@ -57,7 +57,8 @@ This configuration enables kraken, as well as rate-limiting to avoid bans from t
|
|||||||
Binance supports [time_in_force](configuration.md#understand-order_time_in_force).
|
Binance supports [time_in_force](configuration.md#understand-order_time_in_force).
|
||||||
|
|
||||||
!!! Tip "Stoploss on Exchange"
|
!!! Tip "Stoploss on Exchange"
|
||||||
Binance supports `stoploss_on_exchange` and uses `stop-loss-limit` orders. It provides great advantages, so we recommend to benefit from it by enabling stoploss on exchange..
|
Binance supports `stoploss_on_exchange` and uses `stop-loss-limit` orders. It provides great advantages, so we recommend to benefit from it by enabling stoploss on exchange.
|
||||||
|
On futures, Binance supports both `stop-limit` as well as `stop-market` orders. You can use either `"limit"` or `"market"` in the `order_types.stoploss` configuration setting to decide which type to use.
|
||||||
|
|
||||||
### Binance Blacklist
|
### Binance Blacklist
|
||||||
|
|
||||||
|
@ -190,19 +190,6 @@ The FreqAI strategy requires the user to include the following lines of code in
|
|||||||
# passed to any single indicator)
|
# passed to any single indicator)
|
||||||
startup_candle_count: int = 20
|
startup_candle_count: int = 20
|
||||||
|
|
||||||
def informative_pairs(self):
|
|
||||||
whitelist_pairs = self.dp.current_whitelist()
|
|
||||||
corr_pairs = self.config["freqai"]["feature_parameters"]["include_corr_pairlist"]
|
|
||||||
informative_pairs = []
|
|
||||||
for tf in self.config["freqai"]["feature_parameters"]["include_timeframes"]:
|
|
||||||
for pair in whitelist_pairs:
|
|
||||||
informative_pairs.append((pair, tf))
|
|
||||||
for pair in corr_pairs:
|
|
||||||
if pair in whitelist_pairs:
|
|
||||||
continue # avoid duplication
|
|
||||||
informative_pairs.append((pair, tf))
|
|
||||||
return informative_pairs
|
|
||||||
|
|
||||||
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||||
|
|
||||||
# the model will return all labels created by user in `populate_any_indicators`
|
# the model will return all labels created by user in `populate_any_indicators`
|
||||||
|
@ -31,7 +31,7 @@ class Binance(Exchange):
|
|||||||
"ccxt_futures_name": "future"
|
"ccxt_futures_name": "future"
|
||||||
}
|
}
|
||||||
_ft_has_futures: Dict = {
|
_ft_has_futures: Dict = {
|
||||||
"stoploss_order_types": {"limit": "stop"},
|
"stoploss_order_types": {"limit": "limit", "market": "market"},
|
||||||
"tickers_have_price": False,
|
"tickers_have_price": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,13 +48,12 @@ class Binance(Exchange):
|
|||||||
Returns True if adjustment is necessary.
|
Returns True if adjustment is necessary.
|
||||||
:param side: "buy" or "sell"
|
:param side: "buy" or "sell"
|
||||||
"""
|
"""
|
||||||
|
order_types = ('stop_loss_limit', 'stop', 'stop_market')
|
||||||
ordertype = 'stop' if self.trading_mode == TradingMode.FUTURES else 'stop_loss_limit'
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
order.get('stopPrice', None) is None
|
order.get('stopPrice', None) is None
|
||||||
or (
|
or (
|
||||||
order['type'] == ordertype
|
order['type'] in order_types
|
||||||
and (
|
and (
|
||||||
(side == "sell" and stop_loss > float(order['stopPrice'])) or
|
(side == "sell" and stop_loss > float(order['stopPrice'])) or
|
||||||
(side == "buy" and stop_loss < float(order['stopPrice']))
|
(side == "buy" and stop_loss < float(order['stopPrice']))
|
||||||
|
@ -81,6 +81,104 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"1000LUNC/USDT": [
|
||||||
|
{
|
||||||
|
"tier": 1.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 0.0,
|
||||||
|
"maxNotional": 5000.0,
|
||||||
|
"maintenanceMarginRate": 0.01,
|
||||||
|
"maxLeverage": 25.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "1",
|
||||||
|
"initialLeverage": "25",
|
||||||
|
"notionalCap": "5000",
|
||||||
|
"notionalFloor": "0",
|
||||||
|
"maintMarginRatio": "0.01",
|
||||||
|
"cum": "0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 2.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 5000.0,
|
||||||
|
"maxNotional": 25000.0,
|
||||||
|
"maintenanceMarginRate": 0.025,
|
||||||
|
"maxLeverage": 20.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "2",
|
||||||
|
"initialLeverage": "20",
|
||||||
|
"notionalCap": "25000",
|
||||||
|
"notionalFloor": "5000",
|
||||||
|
"maintMarginRatio": "0.025",
|
||||||
|
"cum": "75.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 3.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 25000.0,
|
||||||
|
"maxNotional": 100000.0,
|
||||||
|
"maintenanceMarginRate": 0.05,
|
||||||
|
"maxLeverage": 10.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "3",
|
||||||
|
"initialLeverage": "10",
|
||||||
|
"notionalCap": "100000",
|
||||||
|
"notionalFloor": "25000",
|
||||||
|
"maintMarginRatio": "0.05",
|
||||||
|
"cum": "700.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 4.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 100000.0,
|
||||||
|
"maxNotional": 250000.0,
|
||||||
|
"maintenanceMarginRate": 0.1,
|
||||||
|
"maxLeverage": 5.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "4",
|
||||||
|
"initialLeverage": "5",
|
||||||
|
"notionalCap": "250000",
|
||||||
|
"notionalFloor": "100000",
|
||||||
|
"maintMarginRatio": "0.1",
|
||||||
|
"cum": "5700.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 5.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 250000.0,
|
||||||
|
"maxNotional": 1000000.0,
|
||||||
|
"maintenanceMarginRate": 0.125,
|
||||||
|
"maxLeverage": 2.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "5",
|
||||||
|
"initialLeverage": "2",
|
||||||
|
"notionalCap": "1000000",
|
||||||
|
"notionalFloor": "250000",
|
||||||
|
"maintMarginRatio": "0.125",
|
||||||
|
"cum": "11950.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 6.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 1000000.0,
|
||||||
|
"maxNotional": 5000000.0,
|
||||||
|
"maintenanceMarginRate": 0.5,
|
||||||
|
"maxLeverage": 1.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "6",
|
||||||
|
"initialLeverage": "1",
|
||||||
|
"notionalCap": "5000000",
|
||||||
|
"notionalFloor": "1000000",
|
||||||
|
"maintMarginRatio": "0.5",
|
||||||
|
"cum": "386950.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"1000SHIB/BUSD": [
|
"1000SHIB/BUSD": [
|
||||||
{
|
{
|
||||||
"tier": 1.0,
|
"tier": 1.0,
|
||||||
@ -1109,6 +1207,88 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"AMB/BUSD": [
|
||||||
|
{
|
||||||
|
"tier": 1.0,
|
||||||
|
"currency": "BUSD",
|
||||||
|
"minNotional": 0.0,
|
||||||
|
"maxNotional": 25000.0,
|
||||||
|
"maintenanceMarginRate": 0.025,
|
||||||
|
"maxLeverage": 20.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "1",
|
||||||
|
"initialLeverage": "20",
|
||||||
|
"notionalCap": "25000",
|
||||||
|
"notionalFloor": "0",
|
||||||
|
"maintMarginRatio": "0.025",
|
||||||
|
"cum": "0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 2.0,
|
||||||
|
"currency": "BUSD",
|
||||||
|
"minNotional": 25000.0,
|
||||||
|
"maxNotional": 100000.0,
|
||||||
|
"maintenanceMarginRate": 0.05,
|
||||||
|
"maxLeverage": 10.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "2",
|
||||||
|
"initialLeverage": "10",
|
||||||
|
"notionalCap": "100000",
|
||||||
|
"notionalFloor": "25000",
|
||||||
|
"maintMarginRatio": "0.05",
|
||||||
|
"cum": "625.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 3.0,
|
||||||
|
"currency": "BUSD",
|
||||||
|
"minNotional": 100000.0,
|
||||||
|
"maxNotional": 250000.0,
|
||||||
|
"maintenanceMarginRate": 0.1,
|
||||||
|
"maxLeverage": 5.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "3",
|
||||||
|
"initialLeverage": "5",
|
||||||
|
"notionalCap": "250000",
|
||||||
|
"notionalFloor": "100000",
|
||||||
|
"maintMarginRatio": "0.1",
|
||||||
|
"cum": "5625.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 4.0,
|
||||||
|
"currency": "BUSD",
|
||||||
|
"minNotional": 250000.0,
|
||||||
|
"maxNotional": 1000000.0,
|
||||||
|
"maintenanceMarginRate": 0.125,
|
||||||
|
"maxLeverage": 2.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "4",
|
||||||
|
"initialLeverage": "2",
|
||||||
|
"notionalCap": "1000000",
|
||||||
|
"notionalFloor": "250000",
|
||||||
|
"maintMarginRatio": "0.125",
|
||||||
|
"cum": "11875.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 5.0,
|
||||||
|
"currency": "BUSD",
|
||||||
|
"minNotional": 1000000.0,
|
||||||
|
"maxNotional": 5000000.0,
|
||||||
|
"maintenanceMarginRate": 0.5,
|
||||||
|
"maxLeverage": 1.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "5",
|
||||||
|
"initialLeverage": "1",
|
||||||
|
"notionalCap": "5000000",
|
||||||
|
"notionalFloor": "1000000",
|
||||||
|
"maintMarginRatio": "0.5",
|
||||||
|
"cum": "386875.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"ANC/BUSD": [
|
"ANC/BUSD": [
|
||||||
{
|
{
|
||||||
"tier": 1.0,
|
"tier": 1.0,
|
||||||
@ -3300,13 +3480,13 @@
|
|||||||
"tier": 6.0,
|
"tier": 6.0,
|
||||||
"currency": "USDT",
|
"currency": "USDT",
|
||||||
"minNotional": 1000000.0,
|
"minNotional": 1000000.0,
|
||||||
"maxNotional": 30000000.0,
|
"maxNotional": 5000000.0,
|
||||||
"maintenanceMarginRate": 0.5,
|
"maintenanceMarginRate": 0.5,
|
||||||
"maxLeverage": 1.0,
|
"maxLeverage": 1.0,
|
||||||
"info": {
|
"info": {
|
||||||
"bracket": "6",
|
"bracket": "6",
|
||||||
"initialLeverage": "1",
|
"initialLeverage": "1",
|
||||||
"notionalCap": "30000000",
|
"notionalCap": "5000000",
|
||||||
"notionalFloor": "1000000",
|
"notionalFloor": "1000000",
|
||||||
"maintMarginRatio": "0.5",
|
"maintMarginRatio": "0.5",
|
||||||
"cum": "386950.0"
|
"cum": "386950.0"
|
||||||
@ -4880,13 +5060,13 @@
|
|||||||
"tier": 6.0,
|
"tier": 6.0,
|
||||||
"currency": "USDT",
|
"currency": "USDT",
|
||||||
"minNotional": 1000000.0,
|
"minNotional": 1000000.0,
|
||||||
"maxNotional": 30000000.0,
|
"maxNotional": 5000000.0,
|
||||||
"maintenanceMarginRate": 0.5,
|
"maintenanceMarginRate": 0.5,
|
||||||
"maxLeverage": 1.0,
|
"maxLeverage": 1.0,
|
||||||
"info": {
|
"info": {
|
||||||
"bracket": "6",
|
"bracket": "6",
|
||||||
"initialLeverage": "1",
|
"initialLeverage": "1",
|
||||||
"notionalCap": "30000000",
|
"notionalCap": "5000000",
|
||||||
"notionalFloor": "1000000",
|
"notionalFloor": "1000000",
|
||||||
"maintMarginRatio": "0.5",
|
"maintMarginRatio": "0.5",
|
||||||
"cum": "386940.0"
|
"cum": "386940.0"
|
||||||
@ -8333,6 +8513,104 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"FOOTBALL/USDT": [
|
||||||
|
{
|
||||||
|
"tier": 1.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 0.0,
|
||||||
|
"maxNotional": 5000.0,
|
||||||
|
"maintenanceMarginRate": 0.01,
|
||||||
|
"maxLeverage": 25.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "1",
|
||||||
|
"initialLeverage": "25",
|
||||||
|
"notionalCap": "5000",
|
||||||
|
"notionalFloor": "0",
|
||||||
|
"maintMarginRatio": "0.01",
|
||||||
|
"cum": "0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 2.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 5000.0,
|
||||||
|
"maxNotional": 25000.0,
|
||||||
|
"maintenanceMarginRate": 0.025,
|
||||||
|
"maxLeverage": 20.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "2",
|
||||||
|
"initialLeverage": "20",
|
||||||
|
"notionalCap": "25000",
|
||||||
|
"notionalFloor": "5000",
|
||||||
|
"maintMarginRatio": "0.025",
|
||||||
|
"cum": "75.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 3.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 25000.0,
|
||||||
|
"maxNotional": 100000.0,
|
||||||
|
"maintenanceMarginRate": 0.05,
|
||||||
|
"maxLeverage": 10.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "3",
|
||||||
|
"initialLeverage": "10",
|
||||||
|
"notionalCap": "100000",
|
||||||
|
"notionalFloor": "25000",
|
||||||
|
"maintMarginRatio": "0.05",
|
||||||
|
"cum": "700.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 4.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 100000.0,
|
||||||
|
"maxNotional": 250000.0,
|
||||||
|
"maintenanceMarginRate": 0.1,
|
||||||
|
"maxLeverage": 5.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "4",
|
||||||
|
"initialLeverage": "5",
|
||||||
|
"notionalCap": "250000",
|
||||||
|
"notionalFloor": "100000",
|
||||||
|
"maintMarginRatio": "0.1",
|
||||||
|
"cum": "5700.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 5.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 250000.0,
|
||||||
|
"maxNotional": 1000000.0,
|
||||||
|
"maintenanceMarginRate": 0.125,
|
||||||
|
"maxLeverage": 2.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "5",
|
||||||
|
"initialLeverage": "2",
|
||||||
|
"notionalCap": "1000000",
|
||||||
|
"notionalFloor": "250000",
|
||||||
|
"maintMarginRatio": "0.125",
|
||||||
|
"cum": "11950.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 6.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 1000000.0,
|
||||||
|
"maxNotional": 5000000.0,
|
||||||
|
"maintenanceMarginRate": 0.5,
|
||||||
|
"maxLeverage": 1.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "6",
|
||||||
|
"initialLeverage": "1",
|
||||||
|
"notionalCap": "5000000",
|
||||||
|
"notionalFloor": "1000000",
|
||||||
|
"maintMarginRatio": "0.5",
|
||||||
|
"cum": "386950.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"FTM/BUSD": [
|
"FTM/BUSD": [
|
||||||
{
|
{
|
||||||
"tier": 1.0,
|
"tier": 1.0,
|
||||||
@ -12123,6 +12401,104 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"LUNA2/USDT": [
|
||||||
|
{
|
||||||
|
"tier": 1.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 0.0,
|
||||||
|
"maxNotional": 5000.0,
|
||||||
|
"maintenanceMarginRate": 0.015,
|
||||||
|
"maxLeverage": 25.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "1",
|
||||||
|
"initialLeverage": "25",
|
||||||
|
"notionalCap": "5000",
|
||||||
|
"notionalFloor": "0",
|
||||||
|
"maintMarginRatio": "0.015",
|
||||||
|
"cum": "0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 2.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 5000.0,
|
||||||
|
"maxNotional": 25000.0,
|
||||||
|
"maintenanceMarginRate": 0.025,
|
||||||
|
"maxLeverage": 20.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "2",
|
||||||
|
"initialLeverage": "20",
|
||||||
|
"notionalCap": "25000",
|
||||||
|
"notionalFloor": "5000",
|
||||||
|
"maintMarginRatio": "0.025",
|
||||||
|
"cum": "50.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 3.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 25000.0,
|
||||||
|
"maxNotional": 100000.0,
|
||||||
|
"maintenanceMarginRate": 0.05,
|
||||||
|
"maxLeverage": 10.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "3",
|
||||||
|
"initialLeverage": "10",
|
||||||
|
"notionalCap": "100000",
|
||||||
|
"notionalFloor": "25000",
|
||||||
|
"maintMarginRatio": "0.05",
|
||||||
|
"cum": "675.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 4.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 100000.0,
|
||||||
|
"maxNotional": 250000.0,
|
||||||
|
"maintenanceMarginRate": 0.1,
|
||||||
|
"maxLeverage": 5.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "4",
|
||||||
|
"initialLeverage": "5",
|
||||||
|
"notionalCap": "250000",
|
||||||
|
"notionalFloor": "100000",
|
||||||
|
"maintMarginRatio": "0.1",
|
||||||
|
"cum": "5675.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 5.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 250000.0,
|
||||||
|
"maxNotional": 1000000.0,
|
||||||
|
"maintenanceMarginRate": 0.125,
|
||||||
|
"maxLeverage": 2.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "5",
|
||||||
|
"initialLeverage": "2",
|
||||||
|
"notionalCap": "1000000",
|
||||||
|
"notionalFloor": "250000",
|
||||||
|
"maintMarginRatio": "0.125",
|
||||||
|
"cum": "11925.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 6.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 1000000.0,
|
||||||
|
"maxNotional": 5000000.0,
|
||||||
|
"maintenanceMarginRate": 0.5,
|
||||||
|
"maxLeverage": 1.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "6",
|
||||||
|
"initialLeverage": "1",
|
||||||
|
"notionalCap": "5000000",
|
||||||
|
"notionalFloor": "1000000",
|
||||||
|
"maintMarginRatio": "0.5",
|
||||||
|
"cum": "386925.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"MANA/USDT": [
|
"MANA/USDT": [
|
||||||
{
|
{
|
||||||
"tier": 1.0,
|
"tier": 1.0,
|
||||||
@ -13028,10 +13404,10 @@
|
|||||||
"minNotional": 0.0,
|
"minNotional": 0.0,
|
||||||
"maxNotional": 5000.0,
|
"maxNotional": 5000.0,
|
||||||
"maintenanceMarginRate": 0.01,
|
"maintenanceMarginRate": 0.01,
|
||||||
"maxLeverage": 50.0,
|
"maxLeverage": 25.0,
|
||||||
"info": {
|
"info": {
|
||||||
"bracket": "1",
|
"bracket": "1",
|
||||||
"initialLeverage": "50",
|
"initialLeverage": "25",
|
||||||
"notionalCap": "5000",
|
"notionalCap": "5000",
|
||||||
"notionalFloor": "0",
|
"notionalFloor": "0",
|
||||||
"maintMarginRatio": "0.01",
|
"maintMarginRatio": "0.01",
|
||||||
@ -13805,6 +14181,88 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"PHB/BUSD": [
|
||||||
|
{
|
||||||
|
"tier": 1.0,
|
||||||
|
"currency": "BUSD",
|
||||||
|
"minNotional": 0.0,
|
||||||
|
"maxNotional": 25000.0,
|
||||||
|
"maintenanceMarginRate": 0.025,
|
||||||
|
"maxLeverage": 20.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "1",
|
||||||
|
"initialLeverage": "20",
|
||||||
|
"notionalCap": "25000",
|
||||||
|
"notionalFloor": "0",
|
||||||
|
"maintMarginRatio": "0.025",
|
||||||
|
"cum": "0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 2.0,
|
||||||
|
"currency": "BUSD",
|
||||||
|
"minNotional": 25000.0,
|
||||||
|
"maxNotional": 100000.0,
|
||||||
|
"maintenanceMarginRate": 0.05,
|
||||||
|
"maxLeverage": 10.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "2",
|
||||||
|
"initialLeverage": "10",
|
||||||
|
"notionalCap": "100000",
|
||||||
|
"notionalFloor": "25000",
|
||||||
|
"maintMarginRatio": "0.05",
|
||||||
|
"cum": "625.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 3.0,
|
||||||
|
"currency": "BUSD",
|
||||||
|
"minNotional": 100000.0,
|
||||||
|
"maxNotional": 250000.0,
|
||||||
|
"maintenanceMarginRate": 0.1,
|
||||||
|
"maxLeverage": 5.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "3",
|
||||||
|
"initialLeverage": "5",
|
||||||
|
"notionalCap": "250000",
|
||||||
|
"notionalFloor": "100000",
|
||||||
|
"maintMarginRatio": "0.1",
|
||||||
|
"cum": "5625.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 4.0,
|
||||||
|
"currency": "BUSD",
|
||||||
|
"minNotional": 250000.0,
|
||||||
|
"maxNotional": 1000000.0,
|
||||||
|
"maintenanceMarginRate": 0.125,
|
||||||
|
"maxLeverage": 2.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "4",
|
||||||
|
"initialLeverage": "2",
|
||||||
|
"notionalCap": "1000000",
|
||||||
|
"notionalFloor": "250000",
|
||||||
|
"maintMarginRatio": "0.125",
|
||||||
|
"cum": "11875.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 5.0,
|
||||||
|
"currency": "BUSD",
|
||||||
|
"minNotional": 1000000.0,
|
||||||
|
"maxNotional": 5000000.0,
|
||||||
|
"maintenanceMarginRate": 0.5,
|
||||||
|
"maxLeverage": 1.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "5",
|
||||||
|
"initialLeverage": "1",
|
||||||
|
"notionalCap": "5000000",
|
||||||
|
"notionalFloor": "1000000",
|
||||||
|
"maintMarginRatio": "0.5",
|
||||||
|
"cum": "386875.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"QTUM/USDT": [
|
"QTUM/USDT": [
|
||||||
{
|
{
|
||||||
"tier": 1.0,
|
"tier": 1.0,
|
||||||
@ -14008,10 +14466,10 @@
|
|||||||
"minNotional": 0.0,
|
"minNotional": 0.0,
|
||||||
"maxNotional": 5000.0,
|
"maxNotional": 5000.0,
|
||||||
"maintenanceMarginRate": 0.01,
|
"maintenanceMarginRate": 0.01,
|
||||||
"maxLeverage": 50.0,
|
"maxLeverage": 25.0,
|
||||||
"info": {
|
"info": {
|
||||||
"bracket": "1",
|
"bracket": "1",
|
||||||
"initialLeverage": "50",
|
"initialLeverage": "25",
|
||||||
"notionalCap": "5000",
|
"notionalCap": "5000",
|
||||||
"notionalFloor": "0",
|
"notionalFloor": "0",
|
||||||
"maintMarginRatio": "0.01",
|
"maintMarginRatio": "0.01",
|
||||||
@ -14478,13 +14936,13 @@
|
|||||||
"tier": 6.0,
|
"tier": 6.0,
|
||||||
"currency": "USDT",
|
"currency": "USDT",
|
||||||
"minNotional": 1000000.0,
|
"minNotional": 1000000.0,
|
||||||
"maxNotional": 30000000.0,
|
"maxNotional": 5000000.0,
|
||||||
"maintenanceMarginRate": 0.5,
|
"maintenanceMarginRate": 0.5,
|
||||||
"maxLeverage": 1.0,
|
"maxLeverage": 1.0,
|
||||||
"info": {
|
"info": {
|
||||||
"bracket": "6",
|
"bracket": "6",
|
||||||
"initialLeverage": "1",
|
"initialLeverage": "1",
|
||||||
"notionalCap": "30000000",
|
"notionalCap": "5000000",
|
||||||
"notionalFloor": "1000000",
|
"notionalFloor": "1000000",
|
||||||
"maintMarginRatio": "0.5",
|
"maintMarginRatio": "0.5",
|
||||||
"cum": "386950.0"
|
"cum": "386950.0"
|
||||||
@ -14576,13 +15034,13 @@
|
|||||||
"tier": 6.0,
|
"tier": 6.0,
|
||||||
"currency": "USDT",
|
"currency": "USDT",
|
||||||
"minNotional": 1000000.0,
|
"minNotional": 1000000.0,
|
||||||
"maxNotional": 30000000.0,
|
"maxNotional": 5000000.0,
|
||||||
"maintenanceMarginRate": 0.5,
|
"maintenanceMarginRate": 0.5,
|
||||||
"maxLeverage": 1.0,
|
"maxLeverage": 1.0,
|
||||||
"info": {
|
"info": {
|
||||||
"bracket": "6",
|
"bracket": "6",
|
||||||
"initialLeverage": "1",
|
"initialLeverage": "1",
|
||||||
"notionalCap": "30000000",
|
"notionalCap": "5000000",
|
||||||
"notionalFloor": "1000000",
|
"notionalFloor": "1000000",
|
||||||
"maintMarginRatio": "0.5",
|
"maintMarginRatio": "0.5",
|
||||||
"cum": "386950.0"
|
"cum": "386950.0"
|
||||||
@ -15487,6 +15945,104 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"SPELL/USDT": [
|
||||||
|
{
|
||||||
|
"tier": 1.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 0.0,
|
||||||
|
"maxNotional": 5000.0,
|
||||||
|
"maintenanceMarginRate": 0.01,
|
||||||
|
"maxLeverage": 25.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "1",
|
||||||
|
"initialLeverage": "25",
|
||||||
|
"notionalCap": "5000",
|
||||||
|
"notionalFloor": "0",
|
||||||
|
"maintMarginRatio": "0.01",
|
||||||
|
"cum": "0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 2.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 5000.0,
|
||||||
|
"maxNotional": 25000.0,
|
||||||
|
"maintenanceMarginRate": 0.025,
|
||||||
|
"maxLeverage": 20.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "2",
|
||||||
|
"initialLeverage": "20",
|
||||||
|
"notionalCap": "25000",
|
||||||
|
"notionalFloor": "5000",
|
||||||
|
"maintMarginRatio": "0.025",
|
||||||
|
"cum": "75.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 3.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 25000.0,
|
||||||
|
"maxNotional": 100000.0,
|
||||||
|
"maintenanceMarginRate": 0.05,
|
||||||
|
"maxLeverage": 10.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "3",
|
||||||
|
"initialLeverage": "10",
|
||||||
|
"notionalCap": "100000",
|
||||||
|
"notionalFloor": "25000",
|
||||||
|
"maintMarginRatio": "0.05",
|
||||||
|
"cum": "700.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 4.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 100000.0,
|
||||||
|
"maxNotional": 250000.0,
|
||||||
|
"maintenanceMarginRate": 0.1,
|
||||||
|
"maxLeverage": 5.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "4",
|
||||||
|
"initialLeverage": "5",
|
||||||
|
"notionalCap": "250000",
|
||||||
|
"notionalFloor": "100000",
|
||||||
|
"maintMarginRatio": "0.1",
|
||||||
|
"cum": "5700.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 5.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 250000.0,
|
||||||
|
"maxNotional": 1000000.0,
|
||||||
|
"maintenanceMarginRate": 0.125,
|
||||||
|
"maxLeverage": 2.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "5",
|
||||||
|
"initialLeverage": "2",
|
||||||
|
"notionalCap": "1000000",
|
||||||
|
"notionalFloor": "250000",
|
||||||
|
"maintMarginRatio": "0.125",
|
||||||
|
"cum": "11950.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 6.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 1000000.0,
|
||||||
|
"maxNotional": 5000000.0,
|
||||||
|
"maintenanceMarginRate": 0.5,
|
||||||
|
"maxLeverage": 1.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "6",
|
||||||
|
"initialLeverage": "1",
|
||||||
|
"notionalCap": "5000000",
|
||||||
|
"notionalFloor": "1000000",
|
||||||
|
"maintMarginRatio": "0.5",
|
||||||
|
"cum": "386950.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"SRM/USDT": [
|
"SRM/USDT": [
|
||||||
{
|
{
|
||||||
"tier": 1.0,
|
"tier": 1.0,
|
||||||
@ -15585,6 +16141,104 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"STG/USDT": [
|
||||||
|
{
|
||||||
|
"tier": 1.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 0.0,
|
||||||
|
"maxNotional": 5000.0,
|
||||||
|
"maintenanceMarginRate": 0.01,
|
||||||
|
"maxLeverage": 25.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "1",
|
||||||
|
"initialLeverage": "25",
|
||||||
|
"notionalCap": "5000",
|
||||||
|
"notionalFloor": "0",
|
||||||
|
"maintMarginRatio": "0.01",
|
||||||
|
"cum": "0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 2.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 5000.0,
|
||||||
|
"maxNotional": 25000.0,
|
||||||
|
"maintenanceMarginRate": 0.025,
|
||||||
|
"maxLeverage": 20.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "2",
|
||||||
|
"initialLeverage": "20",
|
||||||
|
"notionalCap": "25000",
|
||||||
|
"notionalFloor": "5000",
|
||||||
|
"maintMarginRatio": "0.025",
|
||||||
|
"cum": "75.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 3.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 25000.0,
|
||||||
|
"maxNotional": 100000.0,
|
||||||
|
"maintenanceMarginRate": 0.05,
|
||||||
|
"maxLeverage": 10.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "3",
|
||||||
|
"initialLeverage": "10",
|
||||||
|
"notionalCap": "100000",
|
||||||
|
"notionalFloor": "25000",
|
||||||
|
"maintMarginRatio": "0.05",
|
||||||
|
"cum": "700.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 4.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 100000.0,
|
||||||
|
"maxNotional": 250000.0,
|
||||||
|
"maintenanceMarginRate": 0.1,
|
||||||
|
"maxLeverage": 5.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "4",
|
||||||
|
"initialLeverage": "5",
|
||||||
|
"notionalCap": "250000",
|
||||||
|
"notionalFloor": "100000",
|
||||||
|
"maintMarginRatio": "0.1",
|
||||||
|
"cum": "5700.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 5.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 250000.0,
|
||||||
|
"maxNotional": 1000000.0,
|
||||||
|
"maintenanceMarginRate": 0.125,
|
||||||
|
"maxLeverage": 2.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "5",
|
||||||
|
"initialLeverage": "2",
|
||||||
|
"notionalCap": "1000000",
|
||||||
|
"notionalFloor": "250000",
|
||||||
|
"maintMarginRatio": "0.125",
|
||||||
|
"cum": "11950.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tier": 6.0,
|
||||||
|
"currency": "USDT",
|
||||||
|
"minNotional": 1000000.0,
|
||||||
|
"maxNotional": 5000000.0,
|
||||||
|
"maintenanceMarginRate": 0.5,
|
||||||
|
"maxLeverage": 1.0,
|
||||||
|
"info": {
|
||||||
|
"bracket": "6",
|
||||||
|
"initialLeverage": "1",
|
||||||
|
"notionalCap": "5000000",
|
||||||
|
"notionalFloor": "1000000",
|
||||||
|
"maintMarginRatio": "0.5",
|
||||||
|
"cum": "386950.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"STMX/USDT": [
|
"STMX/USDT": [
|
||||||
{
|
{
|
||||||
"tier": 1.0,
|
"tier": 1.0,
|
||||||
@ -16176,13 +16830,13 @@
|
|||||||
"tier": 5.0,
|
"tier": 5.0,
|
||||||
"currency": "BUSD",
|
"currency": "BUSD",
|
||||||
"minNotional": 1000000.0,
|
"minNotional": 1000000.0,
|
||||||
"maxNotional": 30000000.0,
|
"maxNotional": 5000000.0,
|
||||||
"maintenanceMarginRate": 0.5,
|
"maintenanceMarginRate": 0.5,
|
||||||
"maxLeverage": 1.0,
|
"maxLeverage": 1.0,
|
||||||
"info": {
|
"info": {
|
||||||
"bracket": "5",
|
"bracket": "5",
|
||||||
"initialLeverage": "1",
|
"initialLeverage": "1",
|
||||||
"notionalCap": "30000000",
|
"notionalCap": "5000000",
|
||||||
"notionalFloor": "1000000",
|
"notionalFloor": "1000000",
|
||||||
"maintMarginRatio": "0.5",
|
"maintMarginRatio": "0.5",
|
||||||
"cum": "386875.0"
|
"cum": "386875.0"
|
||||||
@ -16470,13 +17124,13 @@
|
|||||||
"tier": 6.0,
|
"tier": 6.0,
|
||||||
"currency": "USDT",
|
"currency": "USDT",
|
||||||
"minNotional": 1000000.0,
|
"minNotional": 1000000.0,
|
||||||
"maxNotional": 30000000.0,
|
"maxNotional": 5000000.0,
|
||||||
"maintenanceMarginRate": 0.5,
|
"maintenanceMarginRate": 0.5,
|
||||||
"maxLeverage": 1.0,
|
"maxLeverage": 1.0,
|
||||||
"info": {
|
"info": {
|
||||||
"bracket": "6",
|
"bracket": "6",
|
||||||
"initialLeverage": "1",
|
"initialLeverage": "1",
|
||||||
"notionalCap": "30000000",
|
"notionalCap": "5000000",
|
||||||
"notionalFloor": "1000000",
|
"notionalFloor": "1000000",
|
||||||
"maintMarginRatio": "0.5",
|
"maintMarginRatio": "0.5",
|
||||||
"cum": "386950.0"
|
"cum": "386950.0"
|
||||||
|
@ -2304,7 +2304,7 @@ class Exchange:
|
|||||||
updated = tiers.get('updated')
|
updated = tiers.get('updated')
|
||||||
if updated:
|
if updated:
|
||||||
updated_dt = parser.parse(updated)
|
updated_dt = parser.parse(updated)
|
||||||
if updated_dt < datetime.now(timezone.utc) - timedelta(days=1):
|
if updated_dt < datetime.now(timezone.utc) - timedelta(weeks=4):
|
||||||
logger.info("Cached leverage tiers are outdated. Will update.")
|
logger.info("Cached leverage tiers are outdated. Will update.")
|
||||||
return None
|
return None
|
||||||
return tiers['data']
|
return tiers['data']
|
||||||
|
@ -1072,6 +1072,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
order_obj = Order.parse_from_ccxt_object(stoploss_order, trade.pair, 'stoploss')
|
order_obj = Order.parse_from_ccxt_object(stoploss_order, trade.pair, 'stoploss')
|
||||||
trade.orders.append(order_obj)
|
trade.orders.append(order_obj)
|
||||||
trade.stoploss_order_id = str(stoploss_order['id'])
|
trade.stoploss_order_id = str(stoploss_order['id'])
|
||||||
|
trade.stoploss_last_update = datetime.now(timezone.utc)
|
||||||
return True
|
return True
|
||||||
except InsufficientFundsError as e:
|
except InsufficientFundsError as e:
|
||||||
logger.warning(f"Unable to place stoploss order {e}.")
|
logger.warning(f"Unable to place stoploss order {e}.")
|
||||||
@ -1145,10 +1146,9 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
if self.create_stoploss_order(trade=trade, stop_price=stop_price):
|
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.
|
# 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.
|
# in which case the trade will be closed - which we must check below.
|
||||||
trade.stoploss_last_update = datetime.utcnow()
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# If stoploss order is canceled for some reason we add it
|
# If stoploss order is canceled for some reason we add it again
|
||||||
if (trade.is_open
|
if (trade.is_open
|
||||||
and stoploss_order
|
and stoploss_order
|
||||||
and stoploss_order['status'] in ('canceled', 'cancelled')):
|
and stoploss_order['status'] in ('canceled', 'cancelled')):
|
||||||
@ -1186,7 +1186,8 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
if self.exchange.stoploss_adjust(stoploss_norm, order, side=trade.exit_side):
|
if self.exchange.stoploss_adjust(stoploss_norm, order, side=trade.exit_side):
|
||||||
# we check if the update is necessary
|
# we check if the update is necessary
|
||||||
update_beat = self.strategy.order_types.get('stoploss_on_exchange_interval', 60)
|
update_beat = self.strategy.order_types.get('stoploss_on_exchange_interval', 60)
|
||||||
if (datetime.utcnow() - trade.stoploss_last_update).total_seconds() >= update_beat:
|
upd_req = datetime.now(timezone.utc) - timedelta(seconds=update_beat)
|
||||||
|
if trade.stoploss_last_update_utc and upd_req >= trade.stoploss_last_update_utc:
|
||||||
# cancelling the current stoploss on exchange first
|
# cancelling the current stoploss on exchange first
|
||||||
logger.info(f"Cancelling current stoploss on exchange for pair {trade.pair} "
|
logger.info(f"Cancelling current stoploss on exchange for pair {trade.pair} "
|
||||||
f"(orderid:{order['id']}) in order to add another one ...")
|
f"(orderid:{order['id']}) in order to add another one ...")
|
||||||
|
@ -812,14 +812,6 @@ class Backtesting:
|
|||||||
return trade
|
return trade
|
||||||
time_in_force = self.strategy.order_time_in_force['entry']
|
time_in_force = self.strategy.order_time_in_force['entry']
|
||||||
|
|
||||||
if not pos_adjust:
|
|
||||||
# Confirm trade entry:
|
|
||||||
if not strategy_safe_wrapper(self.strategy.confirm_trade_entry, default_retval=True)(
|
|
||||||
pair=pair, order_type=order_type, amount=stake_amount, rate=propose_rate,
|
|
||||||
time_in_force=time_in_force, current_time=current_time,
|
|
||||||
entry_tag=entry_tag, side=direction):
|
|
||||||
return trade
|
|
||||||
|
|
||||||
if stake_amount and (not min_stake_amount or stake_amount > min_stake_amount):
|
if stake_amount and (not min_stake_amount or stake_amount > min_stake_amount):
|
||||||
self.order_id_counter += 1
|
self.order_id_counter += 1
|
||||||
base_currency = self.exchange.get_pair_base_currency(pair)
|
base_currency = self.exchange.get_pair_base_currency(pair)
|
||||||
@ -834,6 +826,15 @@ class Backtesting:
|
|||||||
# Backcalculate actual stake amount.
|
# Backcalculate actual stake amount.
|
||||||
stake_amount = amount * propose_rate / leverage
|
stake_amount = amount * propose_rate / leverage
|
||||||
|
|
||||||
|
if not pos_adjust:
|
||||||
|
# Confirm trade entry:
|
||||||
|
if not strategy_safe_wrapper(
|
||||||
|
self.strategy.confirm_trade_entry, default_retval=True)(
|
||||||
|
pair=pair, order_type=order_type, amount=amount, rate=propose_rate,
|
||||||
|
time_in_force=time_in_force, current_time=current_time,
|
||||||
|
entry_tag=entry_tag, side=direction):
|
||||||
|
return trade
|
||||||
|
|
||||||
is_short = (direction == 'short')
|
is_short = (direction == 'short')
|
||||||
# Necessary for Margin trading. Disabled until support is enabled.
|
# Necessary for Margin trading. Disabled until support is enabled.
|
||||||
# interest_rate = self.exchange.get_interest_rate()
|
# interest_rate = self.exchange.get_interest_rate()
|
||||||
|
@ -83,7 +83,7 @@ class Order(_DECL_BASE):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def safe_price(self) -> float:
|
def safe_price(self) -> float:
|
||||||
return self.average or self.price
|
return self.average or self.price or self.stop_price
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def safe_filled(self) -> float:
|
def safe_filled(self) -> float:
|
||||||
@ -376,6 +376,12 @@ class LocalTrade():
|
|||||||
def open_date_utc(self):
|
def open_date_utc(self):
|
||||||
return self.open_date.replace(tzinfo=timezone.utc)
|
return self.open_date.replace(tzinfo=timezone.utc)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def stoploss_last_update_utc(self):
|
||||||
|
if self.stoploss_last_update:
|
||||||
|
return self.stoploss_last_update.replace(tzinfo=timezone.utc)
|
||||||
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def close_date_utc(self):
|
def close_date_utc(self):
|
||||||
return self.close_date.replace(tzinfo=timezone.utc)
|
return self.close_date.replace(tzinfo=timezone.utc)
|
||||||
@ -560,7 +566,6 @@ class LocalTrade():
|
|||||||
self.stop_loss = stop_loss_norm
|
self.stop_loss = stop_loss_norm
|
||||||
|
|
||||||
self.stop_loss_pct = -1 * abs(percent)
|
self.stop_loss_pct = -1 * abs(percent)
|
||||||
self.stoploss_last_update = datetime.utcnow()
|
|
||||||
|
|
||||||
def adjust_stop_loss(self, current_price: float, stoploss: float,
|
def adjust_stop_loss(self, current_price: float, stoploss: float,
|
||||||
initial: bool = False, refresh: bool = False) -> None:
|
initial: bool = False, refresh: bool = False) -> None:
|
||||||
|
@ -613,6 +613,22 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
# END - Intended to be overridden by strategy
|
# END - Intended to be overridden by strategy
|
||||||
###
|
###
|
||||||
|
|
||||||
|
def __informative_pairs_freqai(self) -> ListPairsWithTimeframes:
|
||||||
|
"""
|
||||||
|
Create informative-pairs needed for FreqAI
|
||||||
|
"""
|
||||||
|
if self.config.get('freqai', {}).get('enabled', False):
|
||||||
|
whitelist_pairs = self.dp.current_whitelist()
|
||||||
|
candle_type = self.config.get('candle_type_def', CandleType.SPOT)
|
||||||
|
corr_pairs = self.config["freqai"]["feature_parameters"]["include_corr_pairlist"]
|
||||||
|
informative_pairs = []
|
||||||
|
for tf in self.config["freqai"]["feature_parameters"]["include_timeframes"]:
|
||||||
|
for pair in set(whitelist_pairs + corr_pairs):
|
||||||
|
informative_pairs.append((pair, tf, candle_type))
|
||||||
|
return informative_pairs
|
||||||
|
|
||||||
|
return []
|
||||||
|
|
||||||
def gather_informative_pairs(self) -> ListPairsWithTimeframes:
|
def gather_informative_pairs(self) -> ListPairsWithTimeframes:
|
||||||
"""
|
"""
|
||||||
Internal method which gathers all informative pairs (user or automatically defined).
|
Internal method which gathers all informative pairs (user or automatically defined).
|
||||||
@ -637,6 +653,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
else:
|
else:
|
||||||
for pair in self.dp.current_whitelist():
|
for pair in self.dp.current_whitelist():
|
||||||
informative_pairs.append((pair, inf_data.timeframe, candle_type))
|
informative_pairs.append((pair, inf_data.timeframe, candle_type))
|
||||||
|
informative_pairs.extend(self.__informative_pairs_freqai())
|
||||||
return list(set(informative_pairs))
|
return list(set(informative_pairs))
|
||||||
|
|
||||||
def get_strategy_name(self) -> str:
|
def get_strategy_name(self) -> str:
|
||||||
|
@ -47,19 +47,6 @@ class FreqaiExampleStrategy(IStrategy):
|
|||||||
std_dev_multiplier_sell = CategoricalParameter(
|
std_dev_multiplier_sell = CategoricalParameter(
|
||||||
[0.1, 0.25, 0.4], space="sell", default=0.2, optimize=True)
|
[0.1, 0.25, 0.4], space="sell", default=0.2, optimize=True)
|
||||||
|
|
||||||
def informative_pairs(self):
|
|
||||||
whitelist_pairs = self.dp.current_whitelist()
|
|
||||||
corr_pairs = self.config["freqai"]["feature_parameters"]["include_corr_pairlist"]
|
|
||||||
informative_pairs = []
|
|
||||||
for tf in self.config["freqai"]["feature_parameters"]["include_timeframes"]:
|
|
||||||
for pair in whitelist_pairs:
|
|
||||||
informative_pairs.append((pair, tf))
|
|
||||||
for pair in corr_pairs:
|
|
||||||
if pair in whitelist_pairs:
|
|
||||||
continue # avoid duplication
|
|
||||||
informative_pairs.append((pair, tf))
|
|
||||||
return informative_pairs
|
|
||||||
|
|
||||||
def populate_any_indicators(
|
def populate_any_indicators(
|
||||||
self, pair, df, tf, informative=None, set_generalized_indicators=False
|
self, pair, df, tf, informative=None, set_generalized_indicators=False
|
||||||
):
|
):
|
||||||
|
@ -95,20 +95,6 @@ class FreqaiExampleHybridStrategy(IStrategy):
|
|||||||
short_rsi = IntParameter(low=51, high=100, default=70, space='sell', optimize=True, load=True)
|
short_rsi = IntParameter(low=51, high=100, default=70, space='sell', optimize=True, load=True)
|
||||||
exit_short_rsi = IntParameter(low=1, high=50, default=30, space='buy', optimize=True, load=True)
|
exit_short_rsi = IntParameter(low=1, high=50, default=30, space='buy', optimize=True, load=True)
|
||||||
|
|
||||||
# FreqAI required function, leave as is or add additional informatives to existing structure.
|
|
||||||
def informative_pairs(self):
|
|
||||||
whitelist_pairs = self.dp.current_whitelist()
|
|
||||||
corr_pairs = self.config["freqai"]["feature_parameters"]["include_corr_pairlist"]
|
|
||||||
informative_pairs = []
|
|
||||||
for tf in self.config["freqai"]["feature_parameters"]["include_timeframes"]:
|
|
||||||
for pair in whitelist_pairs:
|
|
||||||
informative_pairs.append((pair, tf))
|
|
||||||
for pair in corr_pairs:
|
|
||||||
if pair in whitelist_pairs:
|
|
||||||
continue # avoid duplication
|
|
||||||
informative_pairs.append((pair, tf))
|
|
||||||
return informative_pairs
|
|
||||||
|
|
||||||
# FreqAI required function, user can add or remove indicators, but general structure
|
# FreqAI required function, user can add or remove indicators, but general structure
|
||||||
# must stay the same.
|
# must stay the same.
|
||||||
def populate_any_indicators(
|
def populate_any_indicators(
|
||||||
|
@ -23,7 +23,7 @@ from tests.exchange.test_exchange import ccxt_exceptionhandlers
|
|||||||
def test_stoploss_order_binance(default_conf, mocker, limitratio, expected, side, trademode):
|
def test_stoploss_order_binance(default_conf, mocker, limitratio, expected, side, trademode):
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6))
|
order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6))
|
||||||
order_type = 'stop_loss_limit' if trademode == TradingMode.SPOT else 'stop'
|
order_type = 'stop_loss_limit' if trademode == TradingMode.SPOT else 'limit'
|
||||||
|
|
||||||
api_mock.create_order = MagicMock(return_value={
|
api_mock.create_order = MagicMock(return_value={
|
||||||
'id': order_id,
|
'id': order_id,
|
||||||
@ -45,12 +45,15 @@ def test_stoploss_order_binance(default_conf, mocker, limitratio, expected, side
|
|||||||
amount=1,
|
amount=1,
|
||||||
stop_price=190,
|
stop_price=190,
|
||||||
side=side,
|
side=side,
|
||||||
order_types={'stoploss_on_exchange_limit_ratio': 1.05},
|
order_types={'stoploss': 'limit', 'stoploss_on_exchange_limit_ratio': 1.05},
|
||||||
leverage=1.0
|
leverage=1.0
|
||||||
)
|
)
|
||||||
|
|
||||||
api_mock.create_order.reset_mock()
|
api_mock.create_order.reset_mock()
|
||||||
order_types = {} if limitratio is None else {'stoploss_on_exchange_limit_ratio': limitratio}
|
order_types = {'stoploss': 'limit'}
|
||||||
|
if limitratio is not None:
|
||||||
|
order_types.update({'stoploss_on_exchange_limit_ratio': limitratio})
|
||||||
|
|
||||||
order = exchange.stoploss(
|
order = exchange.stoploss(
|
||||||
pair='ETH/BTC',
|
pair='ETH/BTC',
|
||||||
amount=1,
|
amount=1,
|
||||||
|
@ -472,7 +472,7 @@ def test_load_leverage_tiers_okx(default_conf, mocker, markets, tmpdir, caplog,
|
|||||||
|
|
||||||
api_mock.fetch_market_leverage_tiers.call_count == 0
|
api_mock.fetch_market_leverage_tiers.call_count == 0
|
||||||
# 2 day passes ...
|
# 2 day passes ...
|
||||||
time_machine.move_to(datetime.now() + timedelta(days=2))
|
time_machine.move_to(datetime.now() + timedelta(weeks=5))
|
||||||
exchange.load_leverage_tiers()
|
exchange.load_leverage_tiers()
|
||||||
|
|
||||||
assert log_has(logmsg, caplog)
|
assert log_has(logmsg, caplog)
|
||||||
|
@ -8,6 +8,7 @@ import pytest
|
|||||||
from freqtrade.configuration import TimeRange
|
from freqtrade.configuration import TimeRange
|
||||||
from freqtrade.data.dataprovider import DataProvider
|
from freqtrade.data.dataprovider import DataProvider
|
||||||
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
|
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
|
||||||
|
from freqtrade.plugins.pairlistmanager import PairListManager
|
||||||
from tests.conftest import get_patched_exchange, log_has_re
|
from tests.conftest import get_patched_exchange, log_has_re
|
||||||
from tests.freqai.conftest import get_patched_freqai_strategy
|
from tests.freqai.conftest import get_patched_freqai_strategy
|
||||||
|
|
||||||
@ -350,3 +351,27 @@ def test_plot_feature_importance(mocker, freqai_conf):
|
|||||||
assert Path(freqai.dk.data_path / f"{freqai.dk.model_filename}.html")
|
assert Path(freqai.dk.data_path / f"{freqai.dk.model_filename}.html")
|
||||||
|
|
||||||
shutil.rmtree(Path(freqai.dk.full_path))
|
shutil.rmtree(Path(freqai.dk.full_path))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('timeframes,corr_pairs', [
|
||||||
|
(['5m'], ['ADA/BTC', 'DASH/BTC']),
|
||||||
|
(['5m'], ['ADA/BTC', 'DASH/BTC', 'ETH/USDT']),
|
||||||
|
(['5m', '15m'], ['ADA/BTC', 'DASH/BTC', 'ETH/USDT']),
|
||||||
|
])
|
||||||
|
def test_freqai_informative_pairs(mocker, freqai_conf, timeframes, corr_pairs):
|
||||||
|
freqai_conf['freqai']['feature_parameters'].update({
|
||||||
|
'include_timeframes': timeframes,
|
||||||
|
'include_corr_pairlist': corr_pairs,
|
||||||
|
|
||||||
|
})
|
||||||
|
strategy = get_patched_freqai_strategy(mocker, freqai_conf)
|
||||||
|
exchange = get_patched_exchange(mocker, freqai_conf)
|
||||||
|
pairlists = PairListManager(exchange, freqai_conf)
|
||||||
|
strategy.dp = DataProvider(freqai_conf, exchange, pairlists)
|
||||||
|
pairlist = strategy.dp.current_whitelist()
|
||||||
|
|
||||||
|
pairs_a = strategy.informative_pairs()
|
||||||
|
assert len(pairs_a) == 0
|
||||||
|
pairs_b = strategy.gather_informative_pairs()
|
||||||
|
# we expect unique pairs * timeframes
|
||||||
|
assert len(pairs_b) == len(set(pairlist + corr_pairs)) * len(timeframes)
|
||||||
|
@ -43,19 +43,6 @@ class freqai_test_multimodel_strat(IStrategy):
|
|||||||
)
|
)
|
||||||
max_roi_time_long = IntParameter(0, 800, default=400, space="sell", optimize=False, load=True)
|
max_roi_time_long = IntParameter(0, 800, default=400, space="sell", optimize=False, load=True)
|
||||||
|
|
||||||
def informative_pairs(self):
|
|
||||||
whitelist_pairs = self.dp.current_whitelist()
|
|
||||||
corr_pairs = self.config["freqai"]["feature_parameters"]["include_corr_pairlist"]
|
|
||||||
informative_pairs = []
|
|
||||||
for tf in self.config["freqai"]["feature_parameters"]["include_timeframes"]:
|
|
||||||
for pair in whitelist_pairs:
|
|
||||||
informative_pairs.append((pair, tf))
|
|
||||||
for pair in corr_pairs:
|
|
||||||
if pair in whitelist_pairs:
|
|
||||||
continue # avoid duplication
|
|
||||||
informative_pairs.append((pair, tf))
|
|
||||||
return informative_pairs
|
|
||||||
|
|
||||||
def populate_any_indicators(
|
def populate_any_indicators(
|
||||||
self, pair, df, tf, informative=None, set_generalized_indicators=False
|
self, pair, df, tf, informative=None, set_generalized_indicators=False
|
||||||
):
|
):
|
||||||
|
@ -43,19 +43,6 @@ class freqai_test_strat(IStrategy):
|
|||||||
)
|
)
|
||||||
max_roi_time_long = IntParameter(0, 800, default=400, space="sell", optimize=False, load=True)
|
max_roi_time_long = IntParameter(0, 800, default=400, space="sell", optimize=False, load=True)
|
||||||
|
|
||||||
def informative_pairs(self):
|
|
||||||
whitelist_pairs = self.dp.current_whitelist()
|
|
||||||
corr_pairs = self.config["freqai"]["feature_parameters"]["include_corr_pairlist"]
|
|
||||||
informative_pairs = []
|
|
||||||
for tf in self.config["freqai"]["feature_parameters"]["include_timeframes"]:
|
|
||||||
for pair in whitelist_pairs:
|
|
||||||
informative_pairs.append((pair, tf))
|
|
||||||
for pair in corr_pairs:
|
|
||||||
if pair in whitelist_pairs:
|
|
||||||
continue # avoid duplication
|
|
||||||
informative_pairs.append((pair, tf))
|
|
||||||
return informative_pairs
|
|
||||||
|
|
||||||
def populate_any_indicators(
|
def populate_any_indicators(
|
||||||
self, pair, df, tf, informative=None, set_generalized_indicators=False
|
self, pair, df, tf, informative=None, set_generalized_indicators=False
|
||||||
):
|
):
|
||||||
|
@ -1427,6 +1427,7 @@ def test_handle_stoploss_on_exchange_trailing(
|
|||||||
trade.is_open = True
|
trade.is_open = True
|
||||||
trade.open_order_id = None
|
trade.open_order_id = None
|
||||||
trade.stoploss_order_id = 100
|
trade.stoploss_order_id = 100
|
||||||
|
trade.stoploss_last_update = arrow.utcnow().shift(minutes=-20).datetime
|
||||||
|
|
||||||
stoploss_order_hanging = MagicMock(return_value={
|
stoploss_order_hanging = MagicMock(return_value={
|
||||||
'id': 100,
|
'id': 100,
|
||||||
@ -1456,7 +1457,7 @@ def test_handle_stoploss_on_exchange_trailing(
|
|||||||
)
|
)
|
||||||
|
|
||||||
cancel_order_mock = MagicMock()
|
cancel_order_mock = MagicMock()
|
||||||
stoploss_order_mock = MagicMock(return_value={'id': 13434334})
|
stoploss_order_mock = MagicMock(return_value={'id': 'so1'})
|
||||||
mocker.patch('freqtrade.exchange.Binance.cancel_stoploss_order', cancel_order_mock)
|
mocker.patch('freqtrade.exchange.Binance.cancel_stoploss_order', cancel_order_mock)
|
||||||
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss_order_mock)
|
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss_order_mock)
|
||||||
|
|
||||||
@ -1569,6 +1570,7 @@ def test_handle_stoploss_on_exchange_trailing_error(
|
|||||||
assert stoploss.call_count == 1
|
assert stoploss.call_count == 1
|
||||||
|
|
||||||
# Fail creating stoploss order
|
# Fail creating stoploss order
|
||||||
|
trade.stoploss_last_update = arrow.utcnow().shift(minutes=-601).datetime
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
cancel_mock = mocker.patch("freqtrade.exchange.Binance.cancel_stoploss_order", MagicMock())
|
cancel_mock = mocker.patch("freqtrade.exchange.Binance.cancel_stoploss_order", MagicMock())
|
||||||
mocker.patch("freqtrade.exchange.Binance.stoploss", side_effect=ExchangeError())
|
mocker.patch("freqtrade.exchange.Binance.stoploss", side_effect=ExchangeError())
|
||||||
@ -1657,6 +1659,7 @@ def test_handle_stoploss_on_exchange_custom_stop(
|
|||||||
trade.is_open = True
|
trade.is_open = True
|
||||||
trade.open_order_id = None
|
trade.open_order_id = None
|
||||||
trade.stoploss_order_id = 100
|
trade.stoploss_order_id = 100
|
||||||
|
trade.stoploss_last_update = arrow.utcnow().shift(minutes=-601).datetime
|
||||||
|
|
||||||
stoploss_order_hanging = MagicMock(return_value={
|
stoploss_order_hanging = MagicMock(return_value={
|
||||||
'id': 100,
|
'id': 100,
|
||||||
@ -1685,7 +1688,7 @@ def test_handle_stoploss_on_exchange_custom_stop(
|
|||||||
)
|
)
|
||||||
|
|
||||||
cancel_order_mock = MagicMock()
|
cancel_order_mock = MagicMock()
|
||||||
stoploss_order_mock = MagicMock(return_value={'id': 13434334})
|
stoploss_order_mock = MagicMock(return_value={'id': 'so1'})
|
||||||
mocker.patch('freqtrade.exchange.Binance.cancel_stoploss_order', cancel_order_mock)
|
mocker.patch('freqtrade.exchange.Binance.cancel_stoploss_order', cancel_order_mock)
|
||||||
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss_order_mock)
|
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss_order_mock)
|
||||||
|
|
||||||
@ -1727,8 +1730,7 @@ def test_handle_stoploss_on_exchange_custom_stop(
|
|||||||
assert freqtrade.handle_trade(trade) is True
|
assert freqtrade.handle_trade(trade) is True
|
||||||
|
|
||||||
|
|
||||||
def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,
|
def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, limit_order) -> None:
|
||||||
limit_order) -> None:
|
|
||||||
|
|
||||||
enter_order = limit_order['buy']
|
enter_order = limit_order['buy']
|
||||||
exit_order = limit_order['sell']
|
exit_order = limit_order['sell']
|
||||||
@ -1784,6 +1786,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,
|
|||||||
trade.is_open = True
|
trade.is_open = True
|
||||||
trade.open_order_id = None
|
trade.open_order_id = None
|
||||||
trade.stoploss_order_id = 100
|
trade.stoploss_order_id = 100
|
||||||
|
trade.stoploss_last_update = arrow.utcnow()
|
||||||
|
|
||||||
stoploss_order_hanging = MagicMock(return_value={
|
stoploss_order_hanging = MagicMock(return_value={
|
||||||
'id': 100,
|
'id': 100,
|
||||||
|
Loading…
Reference in New Issue
Block a user