2017-11-07 17:24:51 +00:00
|
|
|
|
# pragma pylint: disable=missing-docstring
|
2018-03-17 21:44:47 +00:00
|
|
|
|
import json
|
|
|
|
|
import logging
|
2019-02-03 12:50:03 +00:00
|
|
|
|
import re
|
2019-05-20 17:35:19 +00:00
|
|
|
|
from copy import deepcopy
|
2024-01-23 18:22:38 +00:00
|
|
|
|
from datetime import datetime, timedelta, timezone
|
2019-06-17 12:34:45 +00:00
|
|
|
|
from pathlib import Path
|
2022-03-25 15:14:18 +00:00
|
|
|
|
from typing import Optional
|
2021-03-13 14:36:34 +00:00
|
|
|
|
from unittest.mock import MagicMock, Mock, PropertyMock
|
2018-03-17 21:44:47 +00:00
|
|
|
|
|
2019-07-26 13:30:14 +00:00
|
|
|
|
import numpy as np
|
2022-10-05 16:09:26 +00:00
|
|
|
|
import pandas as pd
|
2019-10-17 17:53:01 +00:00
|
|
|
|
import pytest
|
2023-12-24 15:27:18 +00:00
|
|
|
|
from xdist.scheduler.loadscope import LoadScopeScheduling
|
2018-02-04 06:42:03 +00:00
|
|
|
|
|
2020-10-16 05:39:12 +00:00
|
|
|
|
from freqtrade import constants
|
2020-01-26 12:41:04 +00:00
|
|
|
|
from freqtrade.commands import Arguments
|
2023-08-18 05:25:51 +00:00
|
|
|
|
from freqtrade.data.converter import ohlcv_to_dataframe, trades_list_to_df
|
2021-11-15 06:09:21 +00:00
|
|
|
|
from freqtrade.edge import PairInfo
|
2022-02-01 18:53:38 +00:00
|
|
|
|
from freqtrade.enums import CandleType, MarginMode, RunMode, SignalDirection, TradingMode
|
2024-01-23 05:39:40 +00:00
|
|
|
|
from freqtrade.exchange import Exchange, timeframe_to_minutes, timeframe_to_seconds
|
2018-02-12 08:37:19 +00:00
|
|
|
|
from freqtrade.freqtradebot import FreqtradeBot
|
2022-01-30 18:25:09 +00:00
|
|
|
|
from freqtrade.persistence import LocalTrade, Order, Trade, init_db
|
2019-02-19 18:15:22 +00:00
|
|
|
|
from freqtrade.resolvers import ExchangeResolver
|
2024-01-23 18:22:38 +00:00
|
|
|
|
from freqtrade.util import dt_now, dt_ts
|
2019-04-02 21:50:33 +00:00
|
|
|
|
from freqtrade.worker import Worker
|
2024-05-12 13:08:40 +00:00
|
|
|
|
from tests.conftest_trades import (
|
|
|
|
|
leverage_trade,
|
|
|
|
|
mock_trade_1,
|
|
|
|
|
mock_trade_2,
|
|
|
|
|
mock_trade_3,
|
|
|
|
|
mock_trade_4,
|
|
|
|
|
mock_trade_5,
|
|
|
|
|
mock_trade_6,
|
|
|
|
|
short_trade,
|
|
|
|
|
)
|
|
|
|
|
from tests.conftest_trades_usdt import (
|
|
|
|
|
mock_trade_usdt_1,
|
|
|
|
|
mock_trade_usdt_2,
|
|
|
|
|
mock_trade_usdt_3,
|
|
|
|
|
mock_trade_usdt_4,
|
|
|
|
|
mock_trade_usdt_5,
|
|
|
|
|
mock_trade_usdt_6,
|
|
|
|
|
mock_trade_usdt_7,
|
|
|
|
|
)
|
2017-11-07 19:12:56 +00:00
|
|
|
|
|
2021-10-29 05:04:20 +00:00
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
logging.getLogger("").setLevel(logging.INFO)
|
2017-11-07 15:18:29 +00:00
|
|
|
|
|
|
|
|
|
|
2019-07-26 13:30:14 +00:00
|
|
|
|
# Do not mask numpy errors as warnings that no one read, raise the exсeption
|
2024-05-12 13:35:47 +00:00
|
|
|
|
np.seterr(all="raise")
|
2019-07-26 13:30:14 +00:00
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
CURRENT_TEST_STRATEGY = "StrategyTestV3"
|
|
|
|
|
TRADE_SIDES = ("long", "short")
|
|
|
|
|
EXMS = "freqtrade.exchange.exchange.Exchange"
|
2021-09-21 18:18:14 +00:00
|
|
|
|
|
2019-07-26 13:30:14 +00:00
|
|
|
|
|
2020-12-23 14:46:08 +00:00
|
|
|
|
def pytest_addoption(parser):
|
2024-05-12 13:35:47 +00:00
|
|
|
|
parser.addoption(
|
|
|
|
|
"--longrun",
|
|
|
|
|
action="store_true",
|
|
|
|
|
dest="longrun",
|
|
|
|
|
default=False,
|
|
|
|
|
help="Enable long-run tests (ccxt compat)",
|
|
|
|
|
)
|
2020-12-23 14:46:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def pytest_configure(config):
|
|
|
|
|
config.addinivalue_line(
|
2024-04-18 20:51:25 +00:00
|
|
|
|
"markers", "longrun: mark test that is running slowly and should not be run regularly"
|
2020-12-23 14:46:08 +00:00
|
|
|
|
)
|
|
|
|
|
if not config.option.longrun:
|
2024-05-12 13:35:47 +00:00
|
|
|
|
config.option.markexpr = "not longrun"
|
2020-12-23 14:46:08 +00:00
|
|
|
|
|
|
|
|
|
|
2023-12-24 15:27:18 +00:00
|
|
|
|
class FixtureScheduler(LoadScopeScheduling):
|
|
|
|
|
# Based on the suggestion in
|
|
|
|
|
# https://github.com/pytest-dev/pytest-xdist/issues/18
|
|
|
|
|
|
|
|
|
|
def _split_scope(self, nodeid):
|
2024-05-12 13:35:47 +00:00
|
|
|
|
if "exchange_online" in nodeid:
|
2023-12-24 15:27:18 +00:00
|
|
|
|
try:
|
|
|
|
|
# Extract exchange ID from nodeid
|
2024-05-12 13:35:47 +00:00
|
|
|
|
exchange_id = nodeid.split("[")[1].split("-")[0].rstrip("]")
|
2023-12-24 15:27:18 +00:00
|
|
|
|
return exchange_id
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(e)
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
return nodeid
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def pytest_xdist_make_scheduler(config, log):
|
|
|
|
|
return FixtureScheduler(config, log)
|
|
|
|
|
|
|
|
|
|
|
2018-01-10 08:09:33 +00:00
|
|
|
|
def log_has(line, logs):
|
2021-12-26 20:09:25 +00:00
|
|
|
|
"""Check if line is found on some caplog's message."""
|
|
|
|
|
return any(line == message for message in logs.messages)
|
2018-01-10 08:09:33 +00:00
|
|
|
|
|
|
|
|
|
|
2022-09-10 18:51:29 +00:00
|
|
|
|
def log_has_when(line, logs, when):
|
|
|
|
|
"""Check if line is found in caplog's messages during a specified stage"""
|
|
|
|
|
return any(line == message.message for message in logs.get_records(when))
|
|
|
|
|
|
|
|
|
|
|
2019-02-03 12:50:03 +00:00
|
|
|
|
def log_has_re(line, logs):
|
2021-12-26 20:09:25 +00:00
|
|
|
|
"""Check if line matches some caplog's message."""
|
|
|
|
|
return any(re.match(line, message) for message in logs.messages)
|
2019-02-03 12:50:03 +00:00
|
|
|
|
|
|
|
|
|
|
2021-12-26 20:09:25 +00:00
|
|
|
|
def num_log_has(line, logs):
|
|
|
|
|
"""Check how many times line is found in caplog's messages."""
|
2021-12-27 16:14:59 +00:00
|
|
|
|
return sum(line == message for message in logs.messages)
|
2021-12-26 08:49:14 +00:00
|
|
|
|
|
|
|
|
|
|
2021-12-26 20:09:25 +00:00
|
|
|
|
def num_log_has_re(line, logs):
|
|
|
|
|
"""Check how many times line matches caplog's messages."""
|
2021-12-27 16:14:59 +00:00
|
|
|
|
return sum(bool(re.match(line, message)) for message in logs.messages)
|
2021-12-26 08:49:14 +00:00
|
|
|
|
|
|
|
|
|
|
2019-07-11 18:23:23 +00:00
|
|
|
|
def get_args(args):
|
2019-09-04 14:38:33 +00:00
|
|
|
|
return Arguments(args).get_parsed_arg()
|
2019-06-16 08:13:12 +00:00
|
|
|
|
|
|
|
|
|
|
2024-01-23 18:22:38 +00:00
|
|
|
|
def generate_trades_history(n_rows, start_date: Optional[datetime] = None, days=5):
|
|
|
|
|
np.random.seed(42)
|
|
|
|
|
if not start_date:
|
|
|
|
|
start_date = datetime(2020, 1, 1, tzinfo=timezone.utc)
|
|
|
|
|
|
|
|
|
|
# Generate random data
|
|
|
|
|
end_date = start_date + timedelta(days=days)
|
|
|
|
|
_start_timestamp = start_date.timestamp()
|
|
|
|
|
_end_timestamp = pd.to_datetime(end_date).timestamp()
|
|
|
|
|
|
|
|
|
|
random_timestamps_in_seconds = np.random.uniform(_start_timestamp, _end_timestamp, n_rows)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
timestamp = pd.to_datetime(random_timestamps_in_seconds, unit="s")
|
2024-01-23 18:22:38 +00:00
|
|
|
|
|
2024-07-05 07:10:55 +00:00
|
|
|
|
trade_id = [
|
2024-05-12 13:35:47 +00:00
|
|
|
|
f"a{np.random.randint(1e6, 1e7 - 1)}cd{np.random.randint(100, 999)}" for _ in range(n_rows)
|
2024-01-24 19:25:25 +00:00
|
|
|
|
]
|
2024-01-23 18:22:38 +00:00
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
side = np.random.choice(["buy", "sell"], n_rows)
|
2024-01-23 18:22:38 +00:00
|
|
|
|
|
|
|
|
|
# Initial price and subsequent changes
|
|
|
|
|
initial_price = 0.019626
|
|
|
|
|
price_changes = np.random.normal(0, initial_price * 0.05, n_rows)
|
|
|
|
|
price = np.cumsum(np.concatenate(([initial_price], price_changes)))[:n_rows]
|
|
|
|
|
|
|
|
|
|
amount = np.random.uniform(0.011, 20, n_rows)
|
|
|
|
|
cost = price * amount
|
|
|
|
|
|
|
|
|
|
# Create DataFrame
|
2024-05-12 13:35:47 +00:00
|
|
|
|
df = pd.DataFrame(
|
|
|
|
|
{
|
|
|
|
|
"timestamp": timestamp,
|
2024-07-05 07:10:55 +00:00
|
|
|
|
"id": trade_id,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"type": None,
|
|
|
|
|
"side": side,
|
|
|
|
|
"price": price,
|
|
|
|
|
"amount": amount,
|
|
|
|
|
"cost": cost,
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
df["date"] = pd.to_datetime(df["timestamp"], unit="ms", utc=True)
|
|
|
|
|
df = df.sort_values("timestamp").reset_index(drop=True)
|
|
|
|
|
assert list(df.columns) == constants.DEFAULT_TRADES_COLUMNS + ["date"]
|
2024-01-23 18:22:38 +00:00
|
|
|
|
return df
|
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
def generate_test_data(timeframe: str, size: int, start: str = "2020-07-05", random_seed=42):
|
2024-02-24 12:30:38 +00:00
|
|
|
|
np.random.seed(random_seed)
|
2022-10-05 16:09:26 +00:00
|
|
|
|
|
|
|
|
|
base = np.random.normal(20, 2, size=size)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
if timeframe == "1y":
|
|
|
|
|
date = pd.date_range(start, periods=size, freq="1YS", tz="UTC")
|
|
|
|
|
elif timeframe == "1M":
|
|
|
|
|
date = pd.date_range(start, periods=size, freq="1MS", tz="UTC")
|
|
|
|
|
elif timeframe == "3M":
|
|
|
|
|
date = pd.date_range(start, periods=size, freq="3MS", tz="UTC")
|
|
|
|
|
elif timeframe == "1w" or timeframe == "7d":
|
|
|
|
|
date = pd.date_range(start, periods=size, freq="1W-MON", tz="UTC")
|
2023-12-02 16:37:46 +00:00
|
|
|
|
else:
|
|
|
|
|
tf_mins = timeframe_to_minutes(timeframe)
|
2024-01-23 05:39:40 +00:00
|
|
|
|
if tf_mins >= 1:
|
2024-05-12 13:35:47 +00:00
|
|
|
|
date = pd.date_range(start, periods=size, freq=f"{tf_mins}min", tz="UTC")
|
2024-01-23 05:39:40 +00:00
|
|
|
|
else:
|
|
|
|
|
tf_secs = timeframe_to_seconds(timeframe)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
date = pd.date_range(start, periods=size, freq=f"{tf_secs}s", tz="UTC")
|
|
|
|
|
df = pd.DataFrame(
|
|
|
|
|
{
|
|
|
|
|
"date": date,
|
|
|
|
|
"open": base,
|
|
|
|
|
"high": base + np.random.normal(2, 1, size=size),
|
|
|
|
|
"low": base - np.random.normal(2, 1, size=size),
|
|
|
|
|
"close": base + np.random.normal(0, 1, size=size),
|
|
|
|
|
"volume": np.random.normal(200, size=size),
|
|
|
|
|
}
|
2022-10-05 16:09:26 +00:00
|
|
|
|
)
|
|
|
|
|
df = df.dropna()
|
|
|
|
|
return df
|
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
def generate_test_data_raw(timeframe: str, size: int, start: str = "2020-07-05", random_seed=42):
|
|
|
|
|
"""Generates data in the ohlcv format used by ccxt"""
|
2024-02-24 12:30:38 +00:00
|
|
|
|
df = generate_test_data(timeframe, size, start, random_seed)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
df["date"] = df.loc[:, "date"].astype(np.int64) // 1000 // 1000
|
2022-10-05 17:39:28 +00:00
|
|
|
|
return list(list(x) for x in zip(*(df[x].values.tolist() for x in df.columns)))
|
|
|
|
|
|
|
|
|
|
|
2021-03-13 14:36:34 +00:00
|
|
|
|
# Source: https://stackoverflow.com/questions/29881236/how-to-mock-asyncio-coroutines
|
2022-05-31 11:40:14 +00:00
|
|
|
|
# TODO: This should be replaced with AsyncMock once support for python 3.7 is dropped.
|
|
|
|
|
def get_mock_coro(return_value=None, side_effect=None):
|
2021-03-13 14:36:34 +00:00
|
|
|
|
async def mock_coro(*args, **kwargs):
|
2022-05-31 11:40:14 +00:00
|
|
|
|
if side_effect:
|
|
|
|
|
if isinstance(side_effect, list):
|
|
|
|
|
effect = side_effect.pop(0)
|
|
|
|
|
else:
|
|
|
|
|
effect = side_effect
|
|
|
|
|
if isinstance(effect, Exception):
|
|
|
|
|
raise effect
|
|
|
|
|
if callable(effect):
|
|
|
|
|
return effect(*args, **kwargs)
|
|
|
|
|
return effect
|
|
|
|
|
else:
|
|
|
|
|
return return_value
|
2021-03-13 14:36:34 +00:00
|
|
|
|
|
|
|
|
|
return Mock(wraps=mock_coro)
|
|
|
|
|
|
|
|
|
|
|
2019-07-11 21:39:42 +00:00
|
|
|
|
def patched_configuration_load_config_file(mocker, config) -> None:
|
|
|
|
|
mocker.patch(
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"freqtrade.configuration.load_config.load_config_file", lambda *args, **kwargs: config
|
2019-07-11 21:39:42 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2021-09-19 23:44:12 +00:00
|
|
|
|
def patch_exchange(
|
2024-07-05 07:10:55 +00:00
|
|
|
|
mocker, api_mock=None, exchange="binance", mock_markets=True, mock_supported_modes=True
|
2021-09-19 23:44:12 +00:00
|
|
|
|
) -> None:
|
2024-05-12 13:35:47 +00:00
|
|
|
|
mocker.patch(f"{EXMS}.validate_config", MagicMock())
|
|
|
|
|
mocker.patch(f"{EXMS}.validate_timeframes", MagicMock())
|
2024-07-05 07:10:55 +00:00
|
|
|
|
mocker.patch(f"{EXMS}.id", PropertyMock(return_value=exchange))
|
|
|
|
|
mocker.patch(f"{EXMS}.name", PropertyMock(return_value=exchange.title()))
|
2024-05-12 13:35:47 +00:00
|
|
|
|
mocker.patch(f"{EXMS}.precisionMode", PropertyMock(return_value=2))
|
2024-08-13 07:20:40 +00:00
|
|
|
|
mocker.patch(f"{EXMS}.precision_mode_price", PropertyMock(return_value=2))
|
2024-05-09 18:40:43 +00:00
|
|
|
|
# Temporary patch ...
|
2024-05-12 13:35:47 +00:00
|
|
|
|
mocker.patch("freqtrade.exchange.bybit.Bybit.cache_leverage_tiers")
|
2021-09-19 23:44:12 +00:00
|
|
|
|
|
2019-10-26 08:08:23 +00:00
|
|
|
|
if mock_markets:
|
2024-06-04 17:01:21 +00:00
|
|
|
|
mocker.patch(f"{EXMS}._load_async_markets", return_value={})
|
2021-09-29 07:15:05 +00:00
|
|
|
|
if isinstance(mock_markets, bool):
|
|
|
|
|
mock_markets = get_markets()
|
2024-05-12 13:35:47 +00:00
|
|
|
|
mocker.patch(f"{EXMS}.markets", PropertyMock(return_value=mock_markets))
|
2018-11-22 18:25:26 +00:00
|
|
|
|
|
2021-09-19 23:44:12 +00:00
|
|
|
|
if mock_supported_modes:
|
|
|
|
|
mocker.patch(
|
2024-07-05 07:10:55 +00:00
|
|
|
|
f"freqtrade.exchange.{exchange}.{exchange.capitalize()}"
|
|
|
|
|
"._supported_trading_mode_margin_pairs",
|
2024-05-12 13:35:47 +00:00
|
|
|
|
PropertyMock(
|
|
|
|
|
return_value=[
|
|
|
|
|
(TradingMode.MARGIN, MarginMode.CROSS),
|
|
|
|
|
(TradingMode.MARGIN, MarginMode.ISOLATED),
|
|
|
|
|
(TradingMode.FUTURES, MarginMode.CROSS),
|
|
|
|
|
(TradingMode.FUTURES, MarginMode.ISOLATED),
|
|
|
|
|
]
|
|
|
|
|
),
|
2021-09-19 23:44:12 +00:00
|
|
|
|
)
|
|
|
|
|
|
2018-06-17 11:32:05 +00:00
|
|
|
|
if api_mock:
|
2024-05-12 13:35:47 +00:00
|
|
|
|
mocker.patch(f"{EXMS}._init_ccxt", return_value=api_mock)
|
2018-06-17 11:32:05 +00:00
|
|
|
|
else:
|
2024-05-12 13:35:47 +00:00
|
|
|
|
mocker.patch(f"{EXMS}.get_fee", return_value=0.0025)
|
|
|
|
|
mocker.patch(f"{EXMS}._init_ccxt", MagicMock())
|
|
|
|
|
mocker.patch(f"{EXMS}.timeframes", PropertyMock(return_value=["5m", "15m", "1h", "1d"]))
|
2018-06-17 19:46:56 +00:00
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
def get_patched_exchange(
|
2024-07-05 07:18:14 +00:00
|
|
|
|
mocker, config, api_mock=None, exchange="binance", mock_markets=True, mock_supported_modes=True
|
2024-05-12 13:35:47 +00:00
|
|
|
|
) -> Exchange:
|
2024-07-05 07:18:14 +00:00
|
|
|
|
patch_exchange(mocker, api_mock, exchange, mock_markets, mock_supported_modes)
|
|
|
|
|
config["exchange"]["name"] = exchange
|
2019-02-19 18:15:22 +00:00
|
|
|
|
try:
|
2023-05-13 06:27:27 +00:00
|
|
|
|
exchange = ExchangeResolver.load_exchange(config, load_leverage_tiers=True)
|
2019-02-19 18:15:22 +00:00
|
|
|
|
except ImportError:
|
|
|
|
|
exchange = Exchange(config)
|
2018-06-17 11:32:05 +00:00
|
|
|
|
return exchange
|
|
|
|
|
|
|
|
|
|
|
2018-11-24 15:37:28 +00:00
|
|
|
|
def patch_wallet(mocker, free=999.9) -> None:
|
2024-05-12 13:35:47 +00:00
|
|
|
|
mocker.patch("freqtrade.wallets.Wallets.get_free", MagicMock(return_value=free))
|
2018-11-23 09:17:10 +00:00
|
|
|
|
|
|
|
|
|
|
2019-10-26 08:08:23 +00:00
|
|
|
|
def patch_whitelist(mocker, conf) -> None:
|
2024-05-12 13:35:47 +00:00
|
|
|
|
mocker.patch(
|
|
|
|
|
"freqtrade.freqtradebot.FreqtradeBot._refresh_active_whitelist",
|
|
|
|
|
MagicMock(return_value=conf["exchange"]["pair_whitelist"]),
|
|
|
|
|
)
|
2019-10-26 08:08:23 +00:00
|
|
|
|
|
|
|
|
|
|
2018-10-04 16:05:46 +00:00
|
|
|
|
def patch_edge(mocker) -> None:
|
|
|
|
|
# "ETH/BTC",
|
|
|
|
|
# "LTC/BTC",
|
|
|
|
|
# "XRP/BTC",
|
|
|
|
|
# "NEO/BTC"
|
2018-11-25 13:36:02 +00:00
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
mocker.patch(
|
|
|
|
|
"freqtrade.edge.Edge._cached_pairs",
|
|
|
|
|
mocker.PropertyMock(
|
|
|
|
|
return_value={
|
|
|
|
|
"NEO/BTC": PairInfo(-0.20, 0.66, 3.71, 0.50, 1.71, 10, 25),
|
|
|
|
|
"LTC/BTC": PairInfo(-0.21, 0.66, 3.71, 0.50, 1.71, 11, 20),
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
mocker.patch("freqtrade.edge.Edge.calculate", MagicMock(return_value=True))
|
2018-10-04 16:05:46 +00:00
|
|
|
|
|
2018-10-04 16:07:47 +00:00
|
|
|
|
|
2018-02-12 08:37:19 +00:00
|
|
|
|
# Functions for recurrent object patching
|
2018-10-04 16:07:47 +00:00
|
|
|
|
|
|
|
|
|
|
2019-03-26 08:07:24 +00:00
|
|
|
|
def patch_freqtradebot(mocker, config) -> None:
|
2018-02-12 08:37:19 +00:00
|
|
|
|
"""
|
|
|
|
|
This function patch _init_modules() to not call dependencies
|
|
|
|
|
:param mocker: a Mocker object to apply patches
|
|
|
|
|
:param config: Config to pass to the bot
|
|
|
|
|
:return: None
|
|
|
|
|
"""
|
2024-05-12 13:35:47 +00:00
|
|
|
|
mocker.patch("freqtrade.freqtradebot.RPCManager", MagicMock())
|
2019-09-11 06:52:09 +00:00
|
|
|
|
patch_exchange(mocker)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
mocker.patch("freqtrade.freqtradebot.RPCManager._init", MagicMock())
|
|
|
|
|
mocker.patch("freqtrade.freqtradebot.RPCManager.send_msg", MagicMock())
|
2019-10-28 11:53:12 +00:00
|
|
|
|
patch_whitelist(mocker, config)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
mocker.patch("freqtrade.freqtradebot.ExternalMessageConsumer")
|
|
|
|
|
mocker.patch("freqtrade.configuration.config_validation._validate_consumers")
|
2018-02-12 08:37:19 +00:00
|
|
|
|
|
2019-03-26 08:07:24 +00:00
|
|
|
|
|
|
|
|
|
def get_patched_freqtradebot(mocker, config) -> FreqtradeBot:
|
2019-06-20 18:30:05 +00:00
|
|
|
|
"""
|
|
|
|
|
This function patches _init_modules() to not call dependencies
|
|
|
|
|
:param mocker: a Mocker object to apply patches
|
|
|
|
|
:param config: Config to pass to the bot
|
|
|
|
|
:return: FreqtradeBot
|
|
|
|
|
"""
|
2019-03-26 08:07:24 +00:00
|
|
|
|
patch_freqtradebot(mocker, config)
|
2018-06-07 03:27:55 +00:00
|
|
|
|
return FreqtradeBot(config)
|
2018-02-12 08:37:19 +00:00
|
|
|
|
|
|
|
|
|
|
2019-03-26 08:07:24 +00:00
|
|
|
|
def get_patched_worker(mocker, config) -> Worker:
|
2019-06-20 18:30:05 +00:00
|
|
|
|
"""
|
|
|
|
|
This function patches _init_modules() to not call dependencies
|
|
|
|
|
:param mocker: a Mocker object to apply patches
|
|
|
|
|
:param config: Config to pass to the bot
|
|
|
|
|
:return: Worker
|
|
|
|
|
"""
|
2019-03-26 08:07:24 +00:00
|
|
|
|
patch_freqtradebot(mocker, config)
|
|
|
|
|
return Worker(args=None, config=config)
|
|
|
|
|
|
|
|
|
|
|
2021-10-03 23:41:01 +00:00
|
|
|
|
def patch_get_signal(
|
|
|
|
|
freqtrade: FreqtradeBot,
|
|
|
|
|
enter_long=True,
|
|
|
|
|
exit_long=False,
|
|
|
|
|
enter_short=False,
|
|
|
|
|
exit_short=False,
|
2021-11-06 14:24:52 +00:00
|
|
|
|
enter_tag: Optional[str] = None,
|
|
|
|
|
exit_tag: Optional[str] = None,
|
2021-10-03 23:41:01 +00:00
|
|
|
|
) -> None:
|
2019-05-11 07:42:30 +00:00
|
|
|
|
"""
|
|
|
|
|
:param mocker: mocker to patch IStrategy class
|
|
|
|
|
:return: None
|
|
|
|
|
"""
|
2024-05-12 13:35:47 +00:00
|
|
|
|
|
2021-08-24 19:03:13 +00:00
|
|
|
|
# returns (Signal-direction, signaname)
|
2021-08-25 04:43:58 +00:00
|
|
|
|
def patched_get_entry_signal(*args, **kwargs):
|
2021-08-24 19:03:13 +00:00
|
|
|
|
direction = None
|
|
|
|
|
if enter_long and not any([exit_long, enter_short]):
|
|
|
|
|
direction = SignalDirection.LONG
|
|
|
|
|
if enter_short and not any([exit_short, enter_long]):
|
|
|
|
|
direction = SignalDirection.SHORT
|
|
|
|
|
|
|
|
|
|
return direction, enter_tag
|
|
|
|
|
|
2021-08-25 04:43:58 +00:00
|
|
|
|
freqtrade.strategy.get_entry_signal = patched_get_entry_signal
|
2021-08-24 19:03:13 +00:00
|
|
|
|
|
|
|
|
|
def patched_get_exit_signal(pair, timeframe, dataframe, is_short):
|
|
|
|
|
if is_short:
|
2021-11-06 14:24:52 +00:00
|
|
|
|
return enter_short, exit_short, exit_tag
|
2021-08-24 19:03:13 +00:00
|
|
|
|
else:
|
2021-11-06 14:24:52 +00:00
|
|
|
|
return enter_long, exit_long, exit_tag
|
2021-08-24 19:03:13 +00:00
|
|
|
|
|
|
|
|
|
# returns (enter, exit)
|
|
|
|
|
freqtrade.strategy.get_exit_signal = patched_get_exit_signal
|
|
|
|
|
|
2019-05-11 07:42:30 +00:00
|
|
|
|
freqtrade.exchange.refresh_latest_ohlcv = lambda p: None
|
|
|
|
|
|
2019-05-11 12:05:25 +00:00
|
|
|
|
|
2021-11-14 18:22:12 +00:00
|
|
|
|
def create_mock_trades(fee, is_short: Optional[bool] = False, use_db: bool = True):
|
2020-09-07 04:49:30 +00:00
|
|
|
|
"""
|
|
|
|
|
Create some fake trades ...
|
2021-11-14 18:22:12 +00:00
|
|
|
|
:param is_short: Optional bool, None creates a mix of long and short trades.
|
2020-09-07 04:49:30 +00:00
|
|
|
|
"""
|
2024-05-12 13:35:47 +00:00
|
|
|
|
|
2021-02-10 18:33:39 +00:00
|
|
|
|
def add_trade(trade):
|
|
|
|
|
if use_db:
|
2023-03-16 06:04:15 +00:00
|
|
|
|
Trade.session.add(trade)
|
2021-02-10 18:33:39 +00:00
|
|
|
|
else:
|
2021-03-13 09:16:32 +00:00
|
|
|
|
LocalTrade.add_bt_trade(trade)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
|
2021-11-14 18:22:12 +00:00
|
|
|
|
is_short1 = is_short if is_short is not None else True
|
|
|
|
|
is_short2 = is_short if is_short is not None else False
|
2020-09-07 04:49:30 +00:00
|
|
|
|
# Simulate dry_run entries
|
2021-11-14 18:22:12 +00:00
|
|
|
|
trade = mock_trade_1(fee, is_short1)
|
2021-02-10 18:33:39 +00:00
|
|
|
|
add_trade(trade)
|
2021-07-20 23:56:57 +00:00
|
|
|
|
|
2021-11-14 18:22:12 +00:00
|
|
|
|
trade = mock_trade_2(fee, is_short1)
|
2021-02-10 18:33:39 +00:00
|
|
|
|
add_trade(trade)
|
2021-07-20 23:56:57 +00:00
|
|
|
|
|
2021-11-14 18:22:12 +00:00
|
|
|
|
trade = mock_trade_3(fee, is_short2)
|
2021-02-10 18:33:39 +00:00
|
|
|
|
add_trade(trade)
|
2021-07-20 23:56:57 +00:00
|
|
|
|
|
2021-11-14 18:22:12 +00:00
|
|
|
|
trade = mock_trade_4(fee, is_short2)
|
2021-02-10 18:33:39 +00:00
|
|
|
|
add_trade(trade)
|
2021-07-20 23:56:57 +00:00
|
|
|
|
|
2021-11-14 18:22:12 +00:00
|
|
|
|
trade = mock_trade_5(fee, is_short2)
|
2021-02-10 18:33:39 +00:00
|
|
|
|
add_trade(trade)
|
2021-07-20 23:56:57 +00:00
|
|
|
|
|
2021-11-14 18:22:12 +00:00
|
|
|
|
trade = mock_trade_6(fee, is_short1)
|
2021-02-10 18:33:39 +00:00
|
|
|
|
add_trade(trade)
|
2021-07-20 23:56:57 +00:00
|
|
|
|
|
2021-07-05 05:32:55 +00:00
|
|
|
|
if use_db:
|
2021-10-12 04:53:15 +00:00
|
|
|
|
Trade.commit()
|
2021-07-02 08:48:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_mock_trades_with_leverage(fee, use_db: bool = True):
|
2020-09-07 04:49:30 +00:00
|
|
|
|
"""
|
|
|
|
|
Create some fake trades ...
|
|
|
|
|
"""
|
2022-02-23 18:17:50 +00:00
|
|
|
|
if use_db:
|
2023-03-16 06:04:15 +00:00
|
|
|
|
Trade.session.rollback()
|
2022-02-23 18:17:50 +00:00
|
|
|
|
|
2021-02-10 18:33:39 +00:00
|
|
|
|
def add_trade(trade):
|
|
|
|
|
if use_db:
|
2023-03-16 06:04:15 +00:00
|
|
|
|
Trade.session.add(trade)
|
2021-02-10 18:33:39 +00:00
|
|
|
|
else:
|
2021-03-13 09:16:32 +00:00
|
|
|
|
LocalTrade.add_bt_trade(trade)
|
2021-02-10 18:33:39 +00:00
|
|
|
|
|
2020-09-07 04:49:30 +00:00
|
|
|
|
# Simulate dry_run entries
|
2021-09-20 02:24:22 +00:00
|
|
|
|
trade = mock_trade_1(fee, False)
|
2021-02-10 18:33:39 +00:00
|
|
|
|
add_trade(trade)
|
2020-09-07 04:49:30 +00:00
|
|
|
|
|
2021-09-20 02:24:22 +00:00
|
|
|
|
trade = mock_trade_2(fee, False)
|
2021-02-10 18:33:39 +00:00
|
|
|
|
add_trade(trade)
|
2020-09-07 04:49:30 +00:00
|
|
|
|
|
2021-09-20 02:24:22 +00:00
|
|
|
|
trade = mock_trade_3(fee, False)
|
2021-02-10 18:33:39 +00:00
|
|
|
|
add_trade(trade)
|
2020-09-07 04:49:30 +00:00
|
|
|
|
|
2021-09-20 02:24:22 +00:00
|
|
|
|
trade = mock_trade_4(fee, False)
|
2021-02-10 18:33:39 +00:00
|
|
|
|
add_trade(trade)
|
2020-04-07 17:42:16 +00:00
|
|
|
|
|
2021-09-20 02:24:22 +00:00
|
|
|
|
trade = mock_trade_5(fee, False)
|
2021-02-10 18:33:39 +00:00
|
|
|
|
add_trade(trade)
|
2020-09-09 05:01:43 +00:00
|
|
|
|
|
2021-09-20 02:24:22 +00:00
|
|
|
|
trade = mock_trade_6(fee, False)
|
2021-07-02 08:48:30 +00:00
|
|
|
|
add_trade(trade)
|
2021-07-04 06:11:59 +00:00
|
|
|
|
|
2021-07-02 08:48:30 +00:00
|
|
|
|
trade = short_trade(fee)
|
|
|
|
|
add_trade(trade)
|
2021-07-20 23:56:57 +00:00
|
|
|
|
|
2021-07-02 08:48:30 +00:00
|
|
|
|
trade = leverage_trade(fee)
|
2021-02-10 18:33:39 +00:00
|
|
|
|
add_trade(trade)
|
2020-09-10 05:40:19 +00:00
|
|
|
|
|
2021-04-06 17:35:17 +00:00
|
|
|
|
if use_db:
|
2023-03-16 06:04:15 +00:00
|
|
|
|
Trade.session.flush()
|
2021-04-06 17:35:17 +00:00
|
|
|
|
|
2020-04-07 17:42:16 +00:00
|
|
|
|
|
2022-06-10 18:34:17 +00:00
|
|
|
|
def create_mock_trades_usdt(fee, is_short: Optional[bool] = False, use_db: bool = True):
|
2021-09-17 08:25:58 +00:00
|
|
|
|
"""
|
|
|
|
|
Create some fake trades ...
|
|
|
|
|
"""
|
2024-05-12 13:35:47 +00:00
|
|
|
|
|
2021-09-17 08:25:58 +00:00
|
|
|
|
def add_trade(trade):
|
|
|
|
|
if use_db:
|
2023-03-16 06:04:15 +00:00
|
|
|
|
Trade.session.add(trade)
|
2021-09-17 08:25:58 +00:00
|
|
|
|
else:
|
|
|
|
|
LocalTrade.add_bt_trade(trade)
|
|
|
|
|
|
2022-06-10 18:34:17 +00:00
|
|
|
|
is_short1 = is_short if is_short is not None else True
|
|
|
|
|
is_short2 = is_short if is_short is not None else False
|
|
|
|
|
|
2021-09-17 08:25:58 +00:00
|
|
|
|
# Simulate dry_run entries
|
2022-06-10 18:34:17 +00:00
|
|
|
|
trade = mock_trade_usdt_1(fee, is_short1)
|
2021-09-17 08:25:58 +00:00
|
|
|
|
add_trade(trade)
|
|
|
|
|
|
2022-06-10 18:34:17 +00:00
|
|
|
|
trade = mock_trade_usdt_2(fee, is_short1)
|
2021-09-17 08:25:58 +00:00
|
|
|
|
add_trade(trade)
|
|
|
|
|
|
2022-06-10 18:34:17 +00:00
|
|
|
|
trade = mock_trade_usdt_3(fee, is_short1)
|
2021-09-17 08:25:58 +00:00
|
|
|
|
add_trade(trade)
|
|
|
|
|
|
2022-06-10 18:34:17 +00:00
|
|
|
|
trade = mock_trade_usdt_4(fee, is_short2)
|
2021-09-17 08:25:58 +00:00
|
|
|
|
add_trade(trade)
|
|
|
|
|
|
2022-06-10 18:34:17 +00:00
|
|
|
|
trade = mock_trade_usdt_5(fee, is_short2)
|
2021-09-17 08:25:58 +00:00
|
|
|
|
add_trade(trade)
|
|
|
|
|
|
2022-06-10 18:34:17 +00:00
|
|
|
|
trade = mock_trade_usdt_6(fee, is_short1)
|
2021-09-17 08:25:58 +00:00
|
|
|
|
add_trade(trade)
|
|
|
|
|
|
2022-06-10 18:34:17 +00:00
|
|
|
|
trade = mock_trade_usdt_7(fee, is_short1)
|
2022-02-06 15:02:18 +00:00
|
|
|
|
add_trade(trade)
|
2021-09-17 08:25:58 +00:00
|
|
|
|
if use_db:
|
2021-10-12 04:53:15 +00:00
|
|
|
|
Trade.commit()
|
2021-09-17 08:25:58 +00:00
|
|
|
|
|
|
|
|
|
|
2022-12-13 17:14:11 +00:00
|
|
|
|
@pytest.fixture(autouse=True)
|
|
|
|
|
def patch_gc(mocker) -> None:
|
|
|
|
|
mocker.patch("freqtrade.main.gc_set_threshold")
|
|
|
|
|
|
|
|
|
|
|
2023-05-11 05:05:43 +00:00
|
|
|
|
@pytest.fixture(autouse=True)
|
2023-11-05 15:15:21 +00:00
|
|
|
|
def user_dir(mocker, tmp_path) -> Path:
|
|
|
|
|
user_dir = tmp_path / "user_data"
|
2024-05-12 13:35:47 +00:00
|
|
|
|
mocker.patch("freqtrade.configuration.configuration.create_userdata_dir", return_value=user_dir)
|
2023-05-11 05:10:34 +00:00
|
|
|
|
return user_dir
|
2023-05-11 05:05:43 +00:00
|
|
|
|
|
|
|
|
|
|
2019-03-30 12:47:09 +00:00
|
|
|
|
@pytest.fixture(autouse=True)
|
2024-04-25 08:27:16 +00:00
|
|
|
|
def patch_coingecko(mocker) -> None:
|
2018-05-13 18:04:40 +00:00
|
|
|
|
"""
|
2024-04-25 08:27:16 +00:00
|
|
|
|
Mocker to coingecko to speed up tests
|
|
|
|
|
:param mocker: mocker to patch coingecko class
|
2018-05-13 18:04:40 +00:00
|
|
|
|
:return: None
|
|
|
|
|
"""
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
tickermock = MagicMock(return_value={"bitcoin": {"usd": 12345.0}, "ethereum": {"usd": 12345.0}})
|
|
|
|
|
listmock = MagicMock(
|
|
|
|
|
return_value=[
|
|
|
|
|
{"id": "bitcoin", "name": "Bitcoin", "symbol": "btc", "website_slug": "bitcoin"},
|
|
|
|
|
{"id": "ethereum", "name": "Ethereum", "symbol": "eth", "website_slug": "ethereum"},
|
|
|
|
|
]
|
|
|
|
|
)
|
2018-05-13 18:46:02 +00:00
|
|
|
|
mocker.patch.multiple(
|
2024-05-20 12:15:53 +00:00
|
|
|
|
"freqtrade.rpc.fiat_convert.FtCoinGeckoApi",
|
2020-03-07 10:52:26 +00:00
|
|
|
|
get_price=tickermock,
|
|
|
|
|
get_coins_list=listmock,
|
2018-05-13 18:46:02 +00:00
|
|
|
|
)
|
2018-05-13 18:04:40 +00:00
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
2019-06-16 10:54:27 +00:00
|
|
|
|
def init_persistence(default_conf):
|
2024-05-12 13:35:47 +00:00
|
|
|
|
init_db(default_conf["db_url"])
|
2019-06-16 10:54:27 +00:00
|
|
|
|
|
|
|
|
|
|
2018-04-07 18:06:53 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
2020-12-13 09:31:24 +00:00
|
|
|
|
def default_conf(testdatadir):
|
|
|
|
|
return get_default_conf(testdatadir)
|
2020-10-23 18:46:01 +00:00
|
|
|
|
|
|
|
|
|
|
2021-09-26 16:09:10 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
|
|
|
|
def default_conf_usdt(testdatadir):
|
|
|
|
|
return get_default_conf_usdt(testdatadir)
|
|
|
|
|
|
|
|
|
|
|
2020-10-23 18:46:01 +00:00
|
|
|
|
def get_default_conf(testdatadir):
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"""Returns validated configuration suitable for most tests"""
|
2018-11-04 17:57:57 +00:00
|
|
|
|
configuration = {
|
2017-11-07 21:27:44 +00:00
|
|
|
|
"max_open_trades": 1,
|
2017-11-07 19:12:56 +00:00
|
|
|
|
"stake_currency": "BTC",
|
2017-12-17 21:07:56 +00:00
|
|
|
|
"stake_amount": 0.001,
|
2017-12-25 07:51:41 +00:00
|
|
|
|
"fiat_display_currency": "USD",
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"timeframe": "5m",
|
2017-11-07 19:12:56 +00:00
|
|
|
|
"dry_run": True,
|
2020-04-24 22:16:52 +00:00
|
|
|
|
"cancel_open_orders_on_exit": False,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minimal_roi": {"40": 0.0, "30": 0.01, "20": 0.02, "0": 0.04},
|
2021-02-13 08:01:05 +00:00
|
|
|
|
"dry_run_wallet": 1000,
|
2017-11-23 16:43:19 +00:00
|
|
|
|
"stoploss": -0.10,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"unfilledtimeout": {"entry": 10, "exit": 30},
|
2022-03-27 16:03:49 +00:00
|
|
|
|
"entry_pricing": {
|
2022-03-28 17:48:45 +00:00
|
|
|
|
"price_last_balance": 0.0,
|
2018-08-29 09:38:43 +00:00
|
|
|
|
"use_order_book": False,
|
|
|
|
|
"order_book_top": 1,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"check_depth_of_market": {"enabled": False, "bids_to_ask_delta": 1},
|
2018-08-29 09:38:43 +00:00
|
|
|
|
},
|
2022-03-27 16:03:49 +00:00
|
|
|
|
"exit_pricing": {
|
2018-08-29 09:38:43 +00:00
|
|
|
|
"use_order_book": False,
|
2021-06-25 18:41:41 +00:00
|
|
|
|
"order_book_top": 1,
|
2017-11-07 19:12:56 +00:00
|
|
|
|
},
|
|
|
|
|
"exchange": {
|
2021-04-20 10:54:22 +00:00
|
|
|
|
"name": "binance",
|
2017-11-07 19:12:56 +00:00
|
|
|
|
"key": "key",
|
2022-10-23 07:15:33 +00:00
|
|
|
|
"enable_ws": False,
|
2017-11-07 19:12:56 +00:00
|
|
|
|
"secret": "secret",
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"pair_whitelist": ["ETH/BTC", "LTC/BTC", "XRP/BTC", "NEO/BTC"],
|
2019-03-24 15:09:04 +00:00
|
|
|
|
"pair_blacklist": [
|
|
|
|
|
"DOGE/BTC",
|
|
|
|
|
"HOT/BTC",
|
2024-05-12 13:35:47 +00:00
|
|
|
|
],
|
2017-11-07 19:12:56 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"pairlists": [{"method": "StaticPairList"}],
|
2017-11-07 19:12:56 +00:00
|
|
|
|
"telegram": {
|
2023-04-15 15:39:23 +00:00
|
|
|
|
"enabled": False,
|
2017-11-07 19:12:56 +00:00
|
|
|
|
"token": "token",
|
2021-04-20 17:36:30 +00:00
|
|
|
|
"chat_id": "0",
|
|
|
|
|
"notification_settings": {},
|
2017-11-07 19:12:56 +00:00
|
|
|
|
},
|
2023-01-20 07:58:56 +00:00
|
|
|
|
"datadir": Path(testdatadir),
|
2018-03-02 13:47:00 +00:00
|
|
|
|
"initial_state": "running",
|
2018-06-07 03:27:55 +00:00
|
|
|
|
"db_url": "sqlite://",
|
2019-07-21 14:06:44 +00:00
|
|
|
|
"user_data_dir": Path("user_data"),
|
2019-07-06 23:53:13 +00:00
|
|
|
|
"verbosity": 3,
|
2020-02-18 19:12:10 +00:00
|
|
|
|
"strategy_path": str(Path(__file__).parent / "strategy" / "strats"),
|
2021-09-21 18:18:14 +00:00
|
|
|
|
"strategy": CURRENT_TEST_STRATEGY,
|
2021-06-29 18:57:16 +00:00
|
|
|
|
"disableparamexport": True,
|
2020-05-03 18:44:18 +00:00
|
|
|
|
"internals": {},
|
2021-06-14 17:57:24 +00:00
|
|
|
|
"export": "none",
|
2023-07-12 16:27:46 +00:00
|
|
|
|
"dataformat_ohlcv": "feather",
|
2024-05-14 16:06:57 +00:00
|
|
|
|
"dataformat_trades": "feather",
|
2024-01-06 17:07:40 +00:00
|
|
|
|
"runmode": "dry_run",
|
2024-09-06 19:15:10 +00:00
|
|
|
|
"trading_mode": "spot",
|
|
|
|
|
"margin_mode": "",
|
2021-12-08 13:10:08 +00:00
|
|
|
|
"candle_type_def": CandleType.SPOT,
|
2017-11-07 19:12:56 +00:00
|
|
|
|
}
|
|
|
|
|
return configuration
|
|
|
|
|
|
|
|
|
|
|
2021-09-26 16:09:10 +00:00
|
|
|
|
def get_default_conf_usdt(testdatadir):
|
|
|
|
|
configuration = get_default_conf(testdatadir)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
configuration.update(
|
|
|
|
|
{
|
|
|
|
|
"stake_amount": 60.0,
|
|
|
|
|
"stake_currency": "USDT",
|
|
|
|
|
"exchange": {
|
|
|
|
|
"name": "binance",
|
|
|
|
|
"enabled": True,
|
|
|
|
|
"key": "key",
|
2022-10-23 07:15:33 +00:00
|
|
|
|
"enable_ws": False,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"secret": "secret",
|
|
|
|
|
"pair_whitelist": [
|
|
|
|
|
"ETH/USDT",
|
|
|
|
|
"LTC/USDT",
|
|
|
|
|
"XRP/USDT",
|
|
|
|
|
"NEO/USDT",
|
|
|
|
|
"TKN/USDT",
|
|
|
|
|
],
|
|
|
|
|
"pair_blacklist": [
|
|
|
|
|
"DOGE/USDT",
|
|
|
|
|
"HOT/USDT",
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
)
|
2021-09-26 16:09:10 +00:00
|
|
|
|
return configuration
|
|
|
|
|
|
|
|
|
|
|
2018-04-15 10:09:12 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
def fee():
|
|
|
|
|
return MagicMock(return_value=0.0025)
|
|
|
|
|
|
|
|
|
|
|
2017-11-07 19:12:56 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
def ticker():
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return MagicMock(
|
|
|
|
|
return_value={
|
|
|
|
|
"bid": 0.00001098,
|
|
|
|
|
"ask": 0.00001099,
|
|
|
|
|
"last": 0.00001098,
|
|
|
|
|
}
|
|
|
|
|
)
|
2017-11-07 19:12:56 +00:00
|
|
|
|
|
2017-12-19 05:58:02 +00:00
|
|
|
|
|
2017-12-17 21:07:56 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
def ticker_sell_up():
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return MagicMock(
|
|
|
|
|
return_value={
|
|
|
|
|
"bid": 0.00001172,
|
|
|
|
|
"ask": 0.00001173,
|
|
|
|
|
"last": 0.00001172,
|
|
|
|
|
}
|
|
|
|
|
)
|
2017-12-17 21:07:56 +00:00
|
|
|
|
|
2017-12-19 05:58:02 +00:00
|
|
|
|
|
2017-12-17 21:07:56 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
def ticker_sell_down():
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return MagicMock(
|
|
|
|
|
return_value={
|
|
|
|
|
"bid": 0.00001044,
|
|
|
|
|
"ask": 0.00001043,
|
|
|
|
|
"last": 0.00001044,
|
|
|
|
|
}
|
|
|
|
|
)
|
2017-11-07 19:12:56 +00:00
|
|
|
|
|
|
|
|
|
|
2021-09-17 08:25:58 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
def ticker_usdt():
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return MagicMock(
|
|
|
|
|
return_value={
|
|
|
|
|
"bid": 2.0,
|
|
|
|
|
"ask": 2.02,
|
|
|
|
|
"last": 2.0,
|
|
|
|
|
}
|
|
|
|
|
)
|
2021-09-17 08:25:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def ticker_usdt_sell_up():
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return MagicMock(
|
|
|
|
|
return_value={
|
|
|
|
|
"bid": 2.2,
|
|
|
|
|
"ask": 2.3,
|
|
|
|
|
"last": 2.2,
|
|
|
|
|
}
|
|
|
|
|
)
|
2021-09-17 08:25:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def ticker_usdt_sell_down():
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return MagicMock(
|
|
|
|
|
return_value={
|
|
|
|
|
"bid": 2.01,
|
|
|
|
|
"ask": 2.0,
|
|
|
|
|
"last": 2.01,
|
|
|
|
|
}
|
|
|
|
|
)
|
2021-09-17 08:25:58 +00:00
|
|
|
|
|
|
|
|
|
|
2017-11-13 20:34:47 +00:00
|
|
|
|
@pytest.fixture
|
2018-03-25 19:51:41 +00:00
|
|
|
|
def markets():
|
2019-10-26 08:08:23 +00:00
|
|
|
|
return get_markets()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_markets():
|
2021-09-29 07:15:05 +00:00
|
|
|
|
# See get_markets_static() for immutable markets and do not modify them unless absolutely
|
|
|
|
|
# necessary!
|
2019-03-05 18:45:54 +00:00
|
|
|
|
return {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"ETH/BTC": {
|
|
|
|
|
"id": "ethbtc",
|
|
|
|
|
"symbol": "ETH/BTC",
|
|
|
|
|
"base": "ETH",
|
|
|
|
|
"quote": "BTC",
|
|
|
|
|
"active": True,
|
|
|
|
|
"spot": True,
|
|
|
|
|
"swap": False,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"precision": {
|
|
|
|
|
"price": 8,
|
|
|
|
|
"amount": 8,
|
|
|
|
|
"cost": 8,
|
|
|
|
|
},
|
|
|
|
|
"lot": 0.00000001,
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"limits": {
|
|
|
|
|
"amount": {
|
|
|
|
|
"min": 0.01,
|
|
|
|
|
"max": 100000000,
|
|
|
|
|
},
|
|
|
|
|
"price": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": 500000,
|
|
|
|
|
},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": 0.0001,
|
|
|
|
|
"max": 500000,
|
|
|
|
|
},
|
|
|
|
|
"leverage": {"min": 1.0, "max": 2.0},
|
2021-09-17 08:25:58 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"TKN/BTC": {
|
|
|
|
|
"id": "tknbtc",
|
|
|
|
|
"symbol": "TKN/BTC",
|
|
|
|
|
"base": "TKN",
|
|
|
|
|
"quote": "BTC",
|
2019-10-17 16:05:50 +00:00
|
|
|
|
# According to ccxt, markets without active item set are also active
|
|
|
|
|
# 'active': True,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"spot": True,
|
|
|
|
|
"swap": False,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"precision": {
|
|
|
|
|
"price": 8,
|
|
|
|
|
"amount": 8,
|
|
|
|
|
"cost": 8,
|
2018-03-25 19:51:41 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"lot": 0.00000001,
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"limits": {
|
|
|
|
|
"amount": {
|
|
|
|
|
"min": 0.01,
|
|
|
|
|
"max": 100000000,
|
|
|
|
|
},
|
|
|
|
|
"price": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": 500000,
|
2021-10-17 13:06:55 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"cost": {
|
|
|
|
|
"min": 0.0001,
|
|
|
|
|
"max": 500000,
|
|
|
|
|
},
|
|
|
|
|
"leverage": {"min": 1.0, "max": 5.0},
|
2018-06-16 23:23:12 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"BLK/BTC": {
|
|
|
|
|
"id": "blkbtc",
|
|
|
|
|
"symbol": "BLK/BTC",
|
|
|
|
|
"base": "BLK",
|
|
|
|
|
"quote": "BTC",
|
|
|
|
|
"active": True,
|
|
|
|
|
"spot": True,
|
|
|
|
|
"swap": False,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"precision": {
|
|
|
|
|
"price": 8,
|
|
|
|
|
"amount": 8,
|
|
|
|
|
"cost": 8,
|
|
|
|
|
},
|
|
|
|
|
"lot": 0.00000001,
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"limits": {
|
|
|
|
|
"amount": {
|
|
|
|
|
"min": 0.01,
|
|
|
|
|
"max": 1000,
|
|
|
|
|
},
|
|
|
|
|
"price": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": 500000,
|
|
|
|
|
},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": 0.0001,
|
|
|
|
|
"max": 500000,
|
|
|
|
|
},
|
|
|
|
|
"leverage": {"min": 1.0, "max": 3.0},
|
|
|
|
|
},
|
2018-06-16 23:23:12 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"LTC/BTC": {
|
|
|
|
|
"id": "ltcbtc",
|
|
|
|
|
"symbol": "LTC/BTC",
|
|
|
|
|
"base": "LTC",
|
|
|
|
|
"quote": "BTC",
|
|
|
|
|
"active": True,
|
|
|
|
|
"spot": True,
|
|
|
|
|
"swap": False,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"precision": {
|
|
|
|
|
"price": 8,
|
|
|
|
|
"amount": 8,
|
|
|
|
|
"cost": 8,
|
|
|
|
|
},
|
|
|
|
|
"lot": 0.00000001,
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"limits": {
|
|
|
|
|
"amount": {
|
|
|
|
|
"min": 0.01,
|
|
|
|
|
"max": 100000000,
|
|
|
|
|
},
|
|
|
|
|
"price": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": 500000,
|
|
|
|
|
},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": 0.0001,
|
|
|
|
|
"max": 500000,
|
|
|
|
|
},
|
|
|
|
|
"leverage": {"min": None, "max": None},
|
|
|
|
|
},
|
|
|
|
|
"info": {},
|
2019-03-02 17:53:42 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"XRP/BTC": {
|
|
|
|
|
"id": "xrpbtc",
|
|
|
|
|
"symbol": "XRP/BTC",
|
|
|
|
|
"base": "XRP",
|
|
|
|
|
"quote": "BTC",
|
|
|
|
|
"active": True,
|
|
|
|
|
"spot": True,
|
|
|
|
|
"swap": False,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"precision": {
|
|
|
|
|
"price": 8,
|
|
|
|
|
"amount": 8,
|
|
|
|
|
"cost": 8,
|
|
|
|
|
},
|
|
|
|
|
"lot": 0.00000001,
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"limits": {
|
|
|
|
|
"amount": {
|
|
|
|
|
"min": 0.01,
|
|
|
|
|
"max": 100000000,
|
|
|
|
|
},
|
|
|
|
|
"price": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": 500000,
|
|
|
|
|
},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": 0.0001,
|
|
|
|
|
"max": 500000,
|
|
|
|
|
},
|
|
|
|
|
"leverage": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
"info": {},
|
2019-03-02 17:53:42 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"NEO/BTC": {
|
|
|
|
|
"id": "neobtc",
|
|
|
|
|
"symbol": "NEO/BTC",
|
|
|
|
|
"base": "NEO",
|
|
|
|
|
"quote": "BTC",
|
|
|
|
|
"active": True,
|
|
|
|
|
"spot": True,
|
|
|
|
|
"swap": False,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"precision": {
|
|
|
|
|
"price": 8,
|
|
|
|
|
"amount": 8,
|
|
|
|
|
"cost": 8,
|
|
|
|
|
},
|
|
|
|
|
"lot": 0.00000001,
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"limits": {
|
|
|
|
|
"amount": {
|
|
|
|
|
"min": 0.01,
|
|
|
|
|
"max": 100000000,
|
|
|
|
|
},
|
|
|
|
|
"price": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": 500000,
|
|
|
|
|
},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": 0.0001,
|
|
|
|
|
"max": 500000,
|
|
|
|
|
},
|
|
|
|
|
"leverage": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
2019-03-02 17:53:42 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"info": {},
|
2019-03-02 17:53:42 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"BTT/BTC": {
|
|
|
|
|
"id": "BTTBTC",
|
|
|
|
|
"symbol": "BTT/BTC",
|
|
|
|
|
"base": "BTT",
|
|
|
|
|
"quote": "BTC",
|
|
|
|
|
"active": False,
|
|
|
|
|
"spot": True,
|
|
|
|
|
"swap": False,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"precision": {"base": 8, "quote": 8, "amount": 0, "price": 8},
|
|
|
|
|
"limits": {
|
|
|
|
|
"amount": {"min": 1.0, "max": 90000000.0},
|
|
|
|
|
"price": {"min": None, "max": None},
|
|
|
|
|
"cost": {"min": 0.0001, "max": None},
|
|
|
|
|
"leverage": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
2024-01-27 15:23:47 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"info": {},
|
2024-01-27 15:23:47 +00:00
|
|
|
|
},
|
2024-09-09 17:15:17 +00:00
|
|
|
|
"ETC/BTC": {
|
|
|
|
|
"id": "ETCBTC",
|
|
|
|
|
"symbol": "ETC/BTC",
|
|
|
|
|
"base": "ETC",
|
|
|
|
|
"quote": "BTC",
|
|
|
|
|
"active": True,
|
|
|
|
|
"spot": True,
|
|
|
|
|
"swap": False,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"precision": {"base": 8, "quote": 8, "amount": 2, "price": 7},
|
|
|
|
|
"limits": {
|
|
|
|
|
"amount": {"min": 0.01, "max": 90000000.0},
|
|
|
|
|
"price": {"min": 1e-07, "max": 1000.0},
|
|
|
|
|
"cost": {"min": 0.0001, "max": 9000000.0},
|
|
|
|
|
"leverage": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"ETH/USDT": {
|
|
|
|
|
"id": "USDT-ETH",
|
|
|
|
|
"symbol": "ETH/USDT",
|
|
|
|
|
"base": "ETH",
|
|
|
|
|
"quote": "USDT",
|
|
|
|
|
"settle": None,
|
|
|
|
|
"baseId": "ETH",
|
|
|
|
|
"quoteId": "USDT",
|
|
|
|
|
"settleId": None,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"spot": True,
|
|
|
|
|
"margin": True,
|
|
|
|
|
"swap": True,
|
|
|
|
|
"future": True,
|
|
|
|
|
"option": False,
|
|
|
|
|
"active": True,
|
|
|
|
|
"contract": None,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"inverse": None,
|
|
|
|
|
"taker": 0.0006,
|
|
|
|
|
"maker": 0.0002,
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"expiry": None,
|
|
|
|
|
"expiryDateTime": None,
|
|
|
|
|
"strike": None,
|
|
|
|
|
"optionType": None,
|
|
|
|
|
"precision": {
|
|
|
|
|
"amount": 8,
|
|
|
|
|
"price": 8,
|
|
|
|
|
},
|
|
|
|
|
"limits": {
|
|
|
|
|
"leverage": {
|
|
|
|
|
"min": 1,
|
|
|
|
|
"max": 100,
|
|
|
|
|
},
|
|
|
|
|
"amount": {
|
|
|
|
|
"min": 0.02214286,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"price": {
|
|
|
|
|
"min": 1e-08,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
"info": {
|
|
|
|
|
"maintenance_rate": "0.005",
|
|
|
|
|
},
|
2019-10-17 19:45:20 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"BTC/USDT": {
|
|
|
|
|
"id": "USDT-BTC",
|
|
|
|
|
"symbol": "BTC/USDT",
|
|
|
|
|
"base": "BTC",
|
|
|
|
|
"quote": "USDT",
|
|
|
|
|
"settle": None,
|
|
|
|
|
"baseId": "BTC",
|
|
|
|
|
"quoteId": "USDT",
|
|
|
|
|
"settleId": None,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"spot": True,
|
|
|
|
|
"margin": True,
|
|
|
|
|
"swap": False,
|
|
|
|
|
"future": False,
|
|
|
|
|
"option": False,
|
|
|
|
|
"active": True,
|
|
|
|
|
"contract": None,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"inverse": None,
|
|
|
|
|
"taker": 0.0006,
|
|
|
|
|
"maker": 0.0002,
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"expiry": None,
|
|
|
|
|
"expiryDateTime": None,
|
|
|
|
|
"strike": None,
|
|
|
|
|
"optionType": None,
|
|
|
|
|
"precision": {
|
|
|
|
|
"amount": 4,
|
|
|
|
|
"price": 4,
|
|
|
|
|
},
|
|
|
|
|
"limits": {
|
|
|
|
|
"leverage": {
|
|
|
|
|
"min": 1,
|
|
|
|
|
"max": 100,
|
|
|
|
|
},
|
|
|
|
|
"amount": {
|
|
|
|
|
"min": 0.000221,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"price": {
|
|
|
|
|
"min": 1e-02,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
"info": {
|
|
|
|
|
"maintenance_rate": "0.005",
|
|
|
|
|
},
|
2021-09-30 07:00:56 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"LTC/USDT": {
|
|
|
|
|
"id": "USDT-LTC",
|
|
|
|
|
"symbol": "LTC/USDT",
|
|
|
|
|
"base": "LTC",
|
|
|
|
|
"quote": "USDT",
|
|
|
|
|
"active": False,
|
|
|
|
|
"spot": True,
|
|
|
|
|
"future": True,
|
|
|
|
|
"swap": True,
|
|
|
|
|
"margin": True,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"inverse": False,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"taker": 0.0006,
|
|
|
|
|
"maker": 0.0002,
|
|
|
|
|
"precision": {"amount": 8, "price": 8},
|
|
|
|
|
"limits": {
|
|
|
|
|
"amount": {"min": 0.06646786, "max": None},
|
|
|
|
|
"price": {"min": 1e-08, "max": None},
|
2022-02-13 03:59:26 +00:00
|
|
|
|
"leverage": {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
2022-02-13 03:59:26 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
},
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
"XRP/USDT": {
|
|
|
|
|
"id": "xrpusdt",
|
|
|
|
|
"symbol": "XRP/USDT",
|
|
|
|
|
"base": "XRP",
|
|
|
|
|
"quote": "USDT",
|
|
|
|
|
"active": True,
|
|
|
|
|
"spot": True,
|
|
|
|
|
"swap": False,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"taker": 0.0006,
|
|
|
|
|
"maker": 0.0002,
|
|
|
|
|
"precision": {
|
|
|
|
|
"price": 8,
|
|
|
|
|
"amount": 8,
|
|
|
|
|
"cost": 8,
|
|
|
|
|
},
|
|
|
|
|
"lot": 0.00000001,
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"limits": {
|
|
|
|
|
"amount": {
|
|
|
|
|
"min": 0.01,
|
|
|
|
|
"max": 1000,
|
2021-09-30 07:00:56 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"price": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": 500000,
|
2022-01-31 09:01:44 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"cost": {
|
|
|
|
|
"min": 0.0001,
|
|
|
|
|
"max": 500000,
|
2021-09-30 07:00:56 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"info": {},
|
2021-09-30 07:00:56 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"NEO/USDT": {
|
|
|
|
|
"id": "neousdt",
|
|
|
|
|
"symbol": "NEO/USDT",
|
|
|
|
|
"base": "NEO",
|
|
|
|
|
"quote": "USDT",
|
|
|
|
|
"settle": "",
|
|
|
|
|
"baseId": "NEO",
|
|
|
|
|
"quoteId": "USDT",
|
|
|
|
|
"settleId": "",
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"spot": True,
|
|
|
|
|
"margin": True,
|
|
|
|
|
"swap": False,
|
|
|
|
|
"futures": False,
|
|
|
|
|
"option": False,
|
|
|
|
|
"active": True,
|
|
|
|
|
"contract": False,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"inverse": None,
|
|
|
|
|
"taker": 0.0006,
|
|
|
|
|
"maker": 0.0002,
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"expiry": None,
|
|
|
|
|
"expiryDatetime": None,
|
|
|
|
|
"strike": None,
|
|
|
|
|
"optionType": None,
|
|
|
|
|
"tierBased": None,
|
|
|
|
|
"percentage": None,
|
|
|
|
|
"lot": 0.00000001,
|
|
|
|
|
"precision": {
|
|
|
|
|
"price": 8,
|
|
|
|
|
"amount": 8,
|
|
|
|
|
"cost": 8,
|
|
|
|
|
},
|
|
|
|
|
"limits": {
|
|
|
|
|
"leverage": {"min": 1, "max": 10},
|
|
|
|
|
"amount": {
|
|
|
|
|
"min": 0.01,
|
|
|
|
|
"max": 1000,
|
|
|
|
|
},
|
|
|
|
|
"price": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": 500000,
|
|
|
|
|
},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": 0.0001,
|
|
|
|
|
"max": 500000,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
"info": {},
|
2021-09-30 07:00:56 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"TKN/USDT": {
|
|
|
|
|
"id": "tknusdt",
|
|
|
|
|
"symbol": "TKN/USDT",
|
|
|
|
|
"base": "TKN",
|
|
|
|
|
"quote": "USDT",
|
|
|
|
|
"active": True,
|
|
|
|
|
"spot": True,
|
|
|
|
|
"swap": False,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"taker": 0.0006,
|
|
|
|
|
"maker": 0.0002,
|
|
|
|
|
"precision": {
|
|
|
|
|
"price": 8,
|
|
|
|
|
"amount": 8,
|
|
|
|
|
"cost": 8,
|
|
|
|
|
},
|
|
|
|
|
"lot": 0.00000001,
|
|
|
|
|
"limits": {
|
|
|
|
|
"amount": {
|
|
|
|
|
"min": 0.01,
|
|
|
|
|
"max": 100000000000,
|
|
|
|
|
},
|
|
|
|
|
"price": {"min": None, "max": 500000},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": 0.0001,
|
|
|
|
|
"max": 500000,
|
|
|
|
|
},
|
|
|
|
|
"leverage": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
"LTC/USD": {
|
|
|
|
|
"id": "USD-LTC",
|
|
|
|
|
"symbol": "LTC/USD",
|
|
|
|
|
"base": "LTC",
|
|
|
|
|
"quote": "USD",
|
|
|
|
|
"active": True,
|
|
|
|
|
"spot": True,
|
|
|
|
|
"swap": False,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"precision": {"amount": 8, "price": 8},
|
|
|
|
|
"limits": {
|
|
|
|
|
"amount": {"min": 0.06646786, "max": None},
|
|
|
|
|
"price": {"min": 1e-08, "max": None},
|
|
|
|
|
"leverage": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
"info": {},
|
2019-10-17 19:45:20 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"XLTCUSDT": {
|
|
|
|
|
"id": "xLTCUSDT",
|
|
|
|
|
"symbol": "XLTCUSDT",
|
|
|
|
|
"base": "LTC",
|
|
|
|
|
"quote": "USDT",
|
|
|
|
|
"active": True,
|
|
|
|
|
"spot": False,
|
|
|
|
|
"type": "swap",
|
|
|
|
|
"contractSize": 0.01,
|
|
|
|
|
"swap": False,
|
|
|
|
|
"linear": False,
|
|
|
|
|
"taker": 0.0006,
|
|
|
|
|
"maker": 0.0002,
|
|
|
|
|
"precision": {"amount": 8, "price": 8},
|
|
|
|
|
"limits": {
|
|
|
|
|
"leverage": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"amount": {"min": 0.06646786, "max": None},
|
|
|
|
|
"price": {"min": 1e-08, "max": None},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
"info": {},
|
2020-02-24 20:50:27 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"LTC/ETH": {
|
|
|
|
|
"id": "LTCETH",
|
|
|
|
|
"symbol": "LTC/ETH",
|
|
|
|
|
"base": "LTC",
|
|
|
|
|
"quote": "ETH",
|
|
|
|
|
"active": True,
|
|
|
|
|
"spot": True,
|
|
|
|
|
"swap": False,
|
|
|
|
|
"linear": None,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"contractSize": None,
|
|
|
|
|
"precision": {"base": 8, "quote": 8, "amount": 3, "price": 5},
|
|
|
|
|
"limits": {
|
|
|
|
|
"leverage": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"amount": {"min": 0.001, "max": 10000000.0},
|
|
|
|
|
"price": {"min": 1e-05, "max": 1000.0},
|
|
|
|
|
"cost": {"min": 0.01, "max": None},
|
|
|
|
|
},
|
|
|
|
|
"info": {},
|
2020-02-24 20:50:27 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"ETH/USDT:USDT": {
|
|
|
|
|
"id": "ETH_USDT",
|
|
|
|
|
"symbol": "ETH/USDT:USDT",
|
|
|
|
|
"base": "ETH",
|
|
|
|
|
"quote": "USDT",
|
|
|
|
|
"settle": "USDT",
|
|
|
|
|
"baseId": "ETH",
|
|
|
|
|
"quoteId": "USDT",
|
|
|
|
|
"settleId": "USDT",
|
|
|
|
|
"type": "swap",
|
|
|
|
|
"spot": False,
|
|
|
|
|
"margin": False,
|
|
|
|
|
"swap": True,
|
|
|
|
|
"future": True, # Binance mode ...
|
|
|
|
|
"option": False,
|
|
|
|
|
"contract": True,
|
|
|
|
|
"linear": True,
|
|
|
|
|
"inverse": False,
|
|
|
|
|
"tierBased": False,
|
|
|
|
|
"percentage": True,
|
|
|
|
|
"taker": 0.0006,
|
|
|
|
|
"maker": 0.0002,
|
|
|
|
|
"contractSize": 10,
|
|
|
|
|
"active": True,
|
|
|
|
|
"expiry": None,
|
|
|
|
|
"expiryDatetime": None,
|
|
|
|
|
"strike": None,
|
|
|
|
|
"optionType": None,
|
|
|
|
|
"limits": {
|
|
|
|
|
"leverage": {"min": 1, "max": 100},
|
|
|
|
|
"amount": {"min": 1, "max": 300000},
|
|
|
|
|
"price": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
"precision": {"price": 0.05, "amount": 1},
|
|
|
|
|
"info": {},
|
2022-02-13 03:59:26 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"ADA/USDT:USDT": {
|
|
|
|
|
"limits": {
|
|
|
|
|
"leverage": {
|
|
|
|
|
"min": 1,
|
|
|
|
|
"max": 20,
|
|
|
|
|
},
|
|
|
|
|
"amount": {
|
|
|
|
|
"min": 1,
|
|
|
|
|
"max": 1000000,
|
|
|
|
|
},
|
|
|
|
|
"price": {
|
|
|
|
|
"min": 0.52981,
|
|
|
|
|
"max": 1.58943,
|
|
|
|
|
},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
"precision": {"amount": 1, "price": 0.00001},
|
|
|
|
|
"tierBased": True,
|
|
|
|
|
"percentage": True,
|
|
|
|
|
"taker": 0.0000075,
|
|
|
|
|
"maker": -0.0000025,
|
|
|
|
|
"feeSide": "get",
|
|
|
|
|
"tiers": {
|
|
|
|
|
"maker": [
|
|
|
|
|
[0, 0.002],
|
|
|
|
|
[1.5, 0.00185],
|
|
|
|
|
[3, 0.00175],
|
|
|
|
|
[6, 0.00165],
|
|
|
|
|
[12.5, 0.00155],
|
|
|
|
|
[25, 0.00145],
|
|
|
|
|
[75, 0.00135],
|
|
|
|
|
[200, 0.00125],
|
|
|
|
|
[500, 0.00115],
|
|
|
|
|
[1250, 0.00105],
|
|
|
|
|
[2500, 0.00095],
|
|
|
|
|
[3000, 0.00085],
|
|
|
|
|
[6000, 0.00075],
|
|
|
|
|
[11000, 0.00065],
|
|
|
|
|
[20000, 0.00055],
|
|
|
|
|
[40000, 0.00055],
|
|
|
|
|
[75000, 0.00055],
|
|
|
|
|
],
|
|
|
|
|
"taker": [
|
|
|
|
|
[0, 0.002],
|
|
|
|
|
[1.5, 0.00195],
|
|
|
|
|
[3, 0.00185],
|
|
|
|
|
[6, 0.00175],
|
|
|
|
|
[12.5, 0.00165],
|
|
|
|
|
[25, 0.00155],
|
|
|
|
|
[75, 0.00145],
|
|
|
|
|
[200, 0.00135],
|
|
|
|
|
[500, 0.00125],
|
|
|
|
|
[1250, 0.00115],
|
|
|
|
|
[2500, 0.00105],
|
|
|
|
|
[3000, 0.00095],
|
|
|
|
|
[6000, 0.00085],
|
|
|
|
|
[11000, 0.00075],
|
|
|
|
|
[20000, 0.00065],
|
|
|
|
|
[40000, 0.00065],
|
|
|
|
|
[75000, 0.00065],
|
2022-02-13 03:59:26 +00:00
|
|
|
|
],
|
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"id": "ADA_USDT",
|
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
|
|
|
|
"base": "ADA",
|
|
|
|
|
"quote": "USDT",
|
|
|
|
|
"settle": "USDT",
|
|
|
|
|
"baseId": "ADA",
|
|
|
|
|
"quoteId": "USDT",
|
|
|
|
|
"settleId": "usdt",
|
|
|
|
|
"type": "swap",
|
|
|
|
|
"spot": False,
|
|
|
|
|
"margin": False,
|
|
|
|
|
"swap": True,
|
|
|
|
|
"future": True, # Binance mode ...
|
|
|
|
|
"option": False,
|
|
|
|
|
"active": True,
|
|
|
|
|
"contract": True,
|
|
|
|
|
"linear": True,
|
|
|
|
|
"inverse": False,
|
|
|
|
|
"contractSize": 0.01,
|
|
|
|
|
"expiry": None,
|
|
|
|
|
"expiryDatetime": None,
|
|
|
|
|
"strike": None,
|
|
|
|
|
"optionType": None,
|
|
|
|
|
"info": {},
|
2022-02-14 22:53:29 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"SOL/BUSD:BUSD": {
|
|
|
|
|
"limits": {
|
|
|
|
|
"leverage": {"min": None, "max": None},
|
|
|
|
|
"amount": {"min": 1, "max": 1000000},
|
|
|
|
|
"price": {"min": 0.04, "max": 100000},
|
|
|
|
|
"cost": {"min": 5, "max": None},
|
|
|
|
|
"market": {"min": 1, "max": 1500},
|
|
|
|
|
},
|
|
|
|
|
"precision": {"amount": 0, "price": 2, "base": 8, "quote": 8},
|
|
|
|
|
"tierBased": False,
|
|
|
|
|
"percentage": True,
|
|
|
|
|
"taker": 0.0004,
|
|
|
|
|
"maker": 0.0002,
|
|
|
|
|
"feeSide": "get",
|
|
|
|
|
"id": "SOLBUSD",
|
|
|
|
|
"lowercaseId": "solbusd",
|
|
|
|
|
"symbol": "SOL/BUSD",
|
|
|
|
|
"base": "SOL",
|
|
|
|
|
"quote": "BUSD",
|
|
|
|
|
"settle": "BUSD",
|
|
|
|
|
"baseId": "SOL",
|
|
|
|
|
"quoteId": "BUSD",
|
|
|
|
|
"settleId": "BUSD",
|
|
|
|
|
"type": "future",
|
|
|
|
|
"spot": False,
|
|
|
|
|
"margin": False,
|
|
|
|
|
"future": True,
|
|
|
|
|
"delivery": False,
|
|
|
|
|
"option": False,
|
|
|
|
|
"active": True,
|
|
|
|
|
"contract": True,
|
|
|
|
|
"linear": True,
|
|
|
|
|
"inverse": False,
|
|
|
|
|
"contractSize": 1,
|
|
|
|
|
"expiry": None,
|
|
|
|
|
"expiryDatetime": None,
|
|
|
|
|
"strike": None,
|
|
|
|
|
"optionType": None,
|
|
|
|
|
"info": {
|
|
|
|
|
"symbol": "SOLBUSD",
|
|
|
|
|
"pair": "SOLBUSD",
|
|
|
|
|
"contractType": "PERPETUAL",
|
|
|
|
|
"deliveryDate": "4133404800000",
|
|
|
|
|
"onboardDate": "1630566000000",
|
|
|
|
|
"status": "TRADING",
|
|
|
|
|
"maintMarginPercent": "2.5000",
|
|
|
|
|
"requiredMarginPercent": "5.0000",
|
|
|
|
|
"baseAsset": "SOL",
|
|
|
|
|
"quoteAsset": "BUSD",
|
|
|
|
|
"marginAsset": "BUSD",
|
|
|
|
|
"pricePrecision": "4",
|
|
|
|
|
"quantityPrecision": "0",
|
|
|
|
|
"baseAssetPrecision": "8",
|
|
|
|
|
"quotePrecision": "8",
|
|
|
|
|
"underlyingType": "COIN",
|
|
|
|
|
"underlyingSubType": [],
|
|
|
|
|
"settlePlan": "0",
|
|
|
|
|
"triggerProtect": "0.0500",
|
|
|
|
|
"liquidationFee": "0.005000",
|
|
|
|
|
"marketTakeBound": "0.05",
|
|
|
|
|
"filters": [
|
2022-02-14 22:53:29 +00:00
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minPrice": "0.0400",
|
|
|
|
|
"maxPrice": "100000",
|
|
|
|
|
"filterType": "PRICE_FILTER",
|
|
|
|
|
"tickSize": "0.0100",
|
2022-02-14 22:53:29 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
{"stepSize": "1", "filterType": "LOT_SIZE", "maxQty": "1000000", "minQty": "1"},
|
2022-02-14 22:53:29 +00:00
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"stepSize": "1",
|
|
|
|
|
"filterType": "MARKET_LOT_SIZE",
|
|
|
|
|
"maxQty": "1500",
|
|
|
|
|
"minQty": "1",
|
2022-02-14 22:53:29 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
{"limit": "200", "filterType": "MAX_NUM_ORDERS"},
|
|
|
|
|
{"limit": "10", "filterType": "MAX_NUM_ALGO_ORDERS"},
|
|
|
|
|
{"notional": "5", "filterType": "MIN_NOTIONAL"},
|
2022-02-14 22:53:29 +00:00
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"multiplierDown": "0.9500",
|
|
|
|
|
"multiplierUp": "1.0500",
|
|
|
|
|
"multiplierDecimal": "4",
|
|
|
|
|
"filterType": "PERCENT_PRICE",
|
2022-02-14 22:53:29 +00:00
|
|
|
|
},
|
|
|
|
|
],
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"orderTypes": [
|
|
|
|
|
"LIMIT",
|
|
|
|
|
"MARKET",
|
|
|
|
|
"STOP",
|
|
|
|
|
"STOP_MARKET",
|
|
|
|
|
"TAKE_PROFIT",
|
|
|
|
|
"TAKE_PROFIT_MARKET",
|
|
|
|
|
"TRAILING_STOP_MARKET",
|
2022-02-14 22:53:29 +00:00
|
|
|
|
],
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"timeInForce": ["GTC", "IOC", "FOK", "GTX"],
|
|
|
|
|
},
|
2020-02-24 20:50:27 +00:00
|
|
|
|
},
|
2019-03-05 18:45:54 +00:00
|
|
|
|
}
|
2018-03-25 19:51:41 +00:00
|
|
|
|
|
|
|
|
|
|
2019-10-28 15:13:31 +00:00
|
|
|
|
@pytest.fixture
|
2021-09-29 07:15:05 +00:00
|
|
|
|
def markets_static():
|
|
|
|
|
# These markets are used in some tests that would need adaptation should anything change in
|
|
|
|
|
# market list. Do not modify this list without a good reason! Do not modify market parameters
|
|
|
|
|
# of listed pairs in get_markets() without a good reason either!
|
2024-05-12 13:35:47 +00:00
|
|
|
|
static_markets = [
|
|
|
|
|
"BLK/BTC",
|
|
|
|
|
"BTT/BTC",
|
|
|
|
|
"ETH/BTC",
|
|
|
|
|
"ETH/USDT",
|
|
|
|
|
"LTC/BTC",
|
|
|
|
|
"LTC/ETH",
|
|
|
|
|
"LTC/USD",
|
|
|
|
|
"LTC/USDT",
|
|
|
|
|
"NEO/BTC",
|
|
|
|
|
"TKN/BTC",
|
|
|
|
|
"XLTCUSDT",
|
|
|
|
|
"XRP/BTC",
|
|
|
|
|
"ADA/USDT:USDT",
|
|
|
|
|
"ETH/USDT:USDT",
|
|
|
|
|
]
|
2021-09-29 07:15:05 +00:00
|
|
|
|
all_markets = get_markets()
|
|
|
|
|
return {m: all_markets[m] for m in static_markets}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def shitcoinmarkets(markets_static):
|
2019-10-28 15:13:31 +00:00
|
|
|
|
"""
|
|
|
|
|
Fixture with shitcoin markets - used to test filters in pairlists
|
|
|
|
|
"""
|
2021-09-29 07:15:05 +00:00
|
|
|
|
shitmarkets = deepcopy(markets_static)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
shitmarkets.update(
|
|
|
|
|
{
|
|
|
|
|
"HOT/BTC": {
|
|
|
|
|
"id": "HOTBTC",
|
|
|
|
|
"symbol": "HOT/BTC",
|
|
|
|
|
"base": "HOT",
|
|
|
|
|
"quote": "BTC",
|
|
|
|
|
"active": True,
|
|
|
|
|
"spot": True,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"precision": {"base": 8, "quote": 8, "amount": 0, "price": 8},
|
|
|
|
|
"limits": {
|
|
|
|
|
"amount": {"min": 1.0, "max": 90000000.0},
|
|
|
|
|
"price": {"min": None, "max": None},
|
|
|
|
|
"cost": {"min": 0.001, "max": None},
|
2022-01-31 09:01:44 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"info": {},
|
2020-02-03 06:44:17 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"FUEL/BTC": {
|
|
|
|
|
"id": "FUELBTC",
|
|
|
|
|
"symbol": "FUEL/BTC",
|
|
|
|
|
"base": "FUEL",
|
|
|
|
|
"quote": "BTC",
|
|
|
|
|
"active": True,
|
|
|
|
|
"spot": True,
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"precision": {"base": 8, "quote": 8, "amount": 0, "price": 8},
|
|
|
|
|
"limits": {
|
|
|
|
|
"amount": {"min": 1.0, "max": 90000000.0},
|
|
|
|
|
"price": {"min": 1e-08, "max": 1000.0},
|
|
|
|
|
"cost": {"min": 0.001, "max": None},
|
2022-01-31 09:01:44 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"info": {},
|
2020-04-23 18:03:59 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"NANO/USDT": {
|
|
|
|
|
"percentage": True,
|
|
|
|
|
"tierBased": False,
|
|
|
|
|
"taker": 0.001,
|
|
|
|
|
"maker": 0.001,
|
|
|
|
|
"precision": {"base": 8, "quote": 8, "amount": 2, "price": 4},
|
|
|
|
|
"limits": {
|
|
|
|
|
"leverage": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"amount": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"price": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
2022-01-31 09:01:44 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"id": "NANOUSDT",
|
|
|
|
|
"symbol": "NANO/USDT",
|
|
|
|
|
"base": "NANO",
|
|
|
|
|
"quote": "USDT",
|
|
|
|
|
"baseId": "NANO",
|
|
|
|
|
"quoteId": "USDT",
|
|
|
|
|
"info": {},
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"spot": True,
|
|
|
|
|
"future": False,
|
|
|
|
|
"active": True,
|
|
|
|
|
},
|
|
|
|
|
"ADAHALF/USDT": {
|
|
|
|
|
"percentage": True,
|
|
|
|
|
"tierBased": False,
|
|
|
|
|
"taker": 0.001,
|
|
|
|
|
"maker": 0.001,
|
|
|
|
|
"precision": {"base": 8, "quote": 8, "amount": 2, "price": 4},
|
|
|
|
|
"limits": {
|
|
|
|
|
"leverage": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"amount": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"price": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
2022-01-31 09:01:44 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"id": "ADAHALFUSDT",
|
|
|
|
|
"symbol": "ADAHALF/USDT",
|
|
|
|
|
"base": "ADAHALF",
|
|
|
|
|
"quote": "USDT",
|
|
|
|
|
"baseId": "ADAHALF",
|
|
|
|
|
"quoteId": "USDT",
|
|
|
|
|
"info": {},
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"spot": True,
|
|
|
|
|
"future": False,
|
|
|
|
|
"active": True,
|
|
|
|
|
},
|
|
|
|
|
"ADADOUBLE/USDT": {
|
|
|
|
|
"percentage": True,
|
|
|
|
|
"tierBased": False,
|
|
|
|
|
"taker": 0.001,
|
|
|
|
|
"maker": 0.001,
|
|
|
|
|
"precision": {"base": 8, "quote": 8, "amount": 2, "price": 4},
|
|
|
|
|
"limits": {
|
|
|
|
|
"leverage": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"amount": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"price": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
|
|
|
|
"cost": {
|
|
|
|
|
"min": None,
|
|
|
|
|
"max": None,
|
|
|
|
|
},
|
2022-01-31 09:01:44 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"id": "ADADOUBLEUSDT",
|
|
|
|
|
"symbol": "ADADOUBLE/USDT",
|
|
|
|
|
"base": "ADADOUBLE",
|
|
|
|
|
"quote": "USDT",
|
|
|
|
|
"baseId": "ADADOUBLE",
|
|
|
|
|
"quoteId": "USDT",
|
|
|
|
|
"info": {},
|
|
|
|
|
"type": "spot",
|
|
|
|
|
"spot": True,
|
|
|
|
|
"future": False,
|
|
|
|
|
"active": True,
|
2020-07-21 18:34:19 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
}
|
|
|
|
|
)
|
2019-10-28 15:13:31 +00:00
|
|
|
|
return shitmarkets
|
|
|
|
|
|
|
|
|
|
|
2018-03-25 19:51:41 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
def markets_empty():
|
|
|
|
|
return MagicMock(return_value=[])
|
2017-11-13 20:34:47 +00:00
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
2020-08-13 11:33:45 +00:00
|
|
|
|
def limit_buy_order_open():
|
2017-11-07 19:12:56 +00:00
|
|
|
|
return {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"id": "mocked_limit_buy",
|
|
|
|
|
"type": "limit",
|
|
|
|
|
"side": "buy",
|
|
|
|
|
"symbol": "mocked",
|
|
|
|
|
"timestamp": dt_ts(),
|
|
|
|
|
"datetime": dt_now().isoformat(),
|
|
|
|
|
"price": 0.00001099,
|
|
|
|
|
"average": 0.00001099,
|
|
|
|
|
"amount": 90.99181073,
|
|
|
|
|
"filled": 0.0,
|
|
|
|
|
"cost": 0.0009999,
|
|
|
|
|
"remaining": 90.99181073,
|
|
|
|
|
"status": "open",
|
2018-01-04 14:39:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
2020-08-13 11:33:45 +00:00
|
|
|
|
def limit_buy_order(limit_buy_order_open):
|
|
|
|
|
order = deepcopy(limit_buy_order_open)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
order["status"] = "closed"
|
|
|
|
|
order["filled"] = order["amount"]
|
|
|
|
|
order["remaining"] = 0.0
|
2020-08-13 11:33:45 +00:00
|
|
|
|
return order
|
|
|
|
|
|
|
|
|
|
|
2018-01-04 14:39:01 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
def limit_buy_order_old():
|
|
|
|
|
return {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"id": "mocked_limit_buy_old",
|
|
|
|
|
"type": "limit",
|
|
|
|
|
"side": "buy",
|
|
|
|
|
"symbol": "mocked",
|
|
|
|
|
"datetime": (dt_now() - timedelta(minutes=601)).isoformat(),
|
|
|
|
|
"timestamp": dt_ts(dt_now() - timedelta(minutes=601)),
|
|
|
|
|
"price": 0.00001099,
|
|
|
|
|
"amount": 90.99181073,
|
|
|
|
|
"filled": 0.0,
|
|
|
|
|
"remaining": 90.99181073,
|
|
|
|
|
"status": "open",
|
2018-01-04 14:39:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def limit_sell_order_old():
|
|
|
|
|
return {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"id": "mocked_limit_sell_old",
|
|
|
|
|
"type": "limit",
|
|
|
|
|
"side": "sell",
|
|
|
|
|
"symbol": "ETH/BTC",
|
|
|
|
|
"timestamp": dt_ts(dt_now() - timedelta(minutes=601)),
|
|
|
|
|
"datetime": (dt_now() - timedelta(minutes=601)).isoformat(),
|
|
|
|
|
"price": 0.00001099,
|
|
|
|
|
"amount": 90.99181073,
|
|
|
|
|
"filled": 0.0,
|
|
|
|
|
"remaining": 90.99181073,
|
|
|
|
|
"status": "open",
|
2018-01-04 14:39:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def limit_buy_order_old_partial():
|
|
|
|
|
return {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"id": "mocked_limit_buy_old_partial",
|
|
|
|
|
"type": "limit",
|
|
|
|
|
"side": "buy",
|
|
|
|
|
"symbol": "ETH/BTC",
|
|
|
|
|
"timestamp": dt_ts(dt_now() - timedelta(minutes=601)),
|
|
|
|
|
"datetime": (dt_now() - timedelta(minutes=601)).isoformat(),
|
|
|
|
|
"price": 0.00001099,
|
|
|
|
|
"amount": 90.99181073,
|
|
|
|
|
"filled": 23.0,
|
|
|
|
|
"cost": 90.99181073 * 23.0,
|
|
|
|
|
"remaining": 67.99181073,
|
|
|
|
|
"status": "open",
|
2017-11-07 19:12:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-10-18 04:38:07 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
def limit_buy_order_old_partial_canceled(limit_buy_order_old_partial):
|
|
|
|
|
res = deepcopy(limit_buy_order_old_partial)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
res["status"] = "canceled"
|
|
|
|
|
res["fee"] = {"cost": 0.023, "currency": "ETH"}
|
2019-10-18 04:38:07 +00:00
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
2020-05-05 05:07:42 +00:00
|
|
|
|
def limit_buy_order_canceled_empty(request):
|
|
|
|
|
# Indirect fixture
|
|
|
|
|
# Documentation:
|
|
|
|
|
# https://docs.pytest.org/en/latest/example/parametrize.html#apply-indirect-on-particular-arguments
|
|
|
|
|
|
|
|
|
|
exchange_name = request.param
|
2024-05-12 13:35:47 +00:00
|
|
|
|
if exchange_name == "kraken":
|
2020-05-05 05:07:42 +00:00
|
|
|
|
return {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"info": {},
|
|
|
|
|
"id": "AZNPFF-4AC4N-7MKTAT",
|
|
|
|
|
"clientOrderId": None,
|
|
|
|
|
"timestamp": dt_ts(dt_now() - timedelta(minutes=601)),
|
|
|
|
|
"datetime": (dt_now() - timedelta(minutes=601)).isoformat(),
|
|
|
|
|
"lastTradeTimestamp": None,
|
|
|
|
|
"status": "canceled",
|
|
|
|
|
"symbol": "LTC/USDT",
|
|
|
|
|
"type": "limit",
|
|
|
|
|
"side": "buy",
|
|
|
|
|
"price": 34.3225,
|
|
|
|
|
"cost": 0.0,
|
|
|
|
|
"amount": 0.55,
|
|
|
|
|
"filled": 0.0,
|
|
|
|
|
"average": 0.0,
|
|
|
|
|
"remaining": 0.55,
|
|
|
|
|
"fee": {"cost": 0.0, "rate": None, "currency": "USDT"},
|
|
|
|
|
"trades": [],
|
2020-05-05 05:07:42 +00:00
|
|
|
|
}
|
2024-05-12 13:35:47 +00:00
|
|
|
|
elif exchange_name == "binance":
|
2020-05-05 05:07:42 +00:00
|
|
|
|
return {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"info": {},
|
|
|
|
|
"id": "1234512345",
|
|
|
|
|
"clientOrderId": "alb1234123",
|
|
|
|
|
"timestamp": dt_ts(dt_now() - timedelta(minutes=601)),
|
|
|
|
|
"datetime": (dt_now() - timedelta(minutes=601)).isoformat(),
|
|
|
|
|
"lastTradeTimestamp": None,
|
|
|
|
|
"symbol": "LTC/USDT",
|
|
|
|
|
"type": "limit",
|
|
|
|
|
"side": "buy",
|
|
|
|
|
"price": 0.016804,
|
|
|
|
|
"amount": 0.55,
|
|
|
|
|
"cost": 0.0,
|
|
|
|
|
"average": None,
|
|
|
|
|
"filled": 0.0,
|
|
|
|
|
"remaining": 0.55,
|
|
|
|
|
"status": "canceled",
|
|
|
|
|
"fee": None,
|
|
|
|
|
"trades": None,
|
2020-05-05 05:07:42 +00:00
|
|
|
|
}
|
|
|
|
|
else:
|
|
|
|
|
return {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"info": {},
|
|
|
|
|
"id": "1234512345",
|
|
|
|
|
"clientOrderId": "alb1234123",
|
|
|
|
|
"timestamp": dt_ts(dt_now() - timedelta(minutes=601)),
|
|
|
|
|
"datetime": (dt_now() - timedelta(minutes=601)).isoformat(),
|
|
|
|
|
"lastTradeTimestamp": None,
|
|
|
|
|
"symbol": "LTC/USDT",
|
|
|
|
|
"type": "limit",
|
|
|
|
|
"side": "buy",
|
|
|
|
|
"price": 0.016804,
|
|
|
|
|
"amount": 0.55,
|
|
|
|
|
"cost": 0.0,
|
|
|
|
|
"average": None,
|
|
|
|
|
"filled": 0.0,
|
|
|
|
|
"remaining": 0.55,
|
|
|
|
|
"status": "canceled",
|
|
|
|
|
"fee": None,
|
|
|
|
|
"trades": None,
|
2020-05-05 05:07:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2017-11-07 19:12:56 +00:00
|
|
|
|
@pytest.fixture
|
2020-08-13 11:33:45 +00:00
|
|
|
|
def limit_sell_order_open():
|
2017-11-07 19:12:56 +00:00
|
|
|
|
return {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"id": "mocked_limit_sell",
|
|
|
|
|
"type": "limit",
|
|
|
|
|
"side": "sell",
|
|
|
|
|
"symbol": "mocked",
|
|
|
|
|
"datetime": dt_now().isoformat(),
|
|
|
|
|
"timestamp": dt_ts(),
|
|
|
|
|
"price": 0.00001173,
|
|
|
|
|
"amount": 90.99181073,
|
|
|
|
|
"filled": 0.0,
|
|
|
|
|
"remaining": 90.99181073,
|
|
|
|
|
"status": "open",
|
2017-11-07 19:12:56 +00:00
|
|
|
|
}
|
2017-12-16 23:24:21 +00:00
|
|
|
|
|
|
|
|
|
|
2020-08-13 11:33:45 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
def limit_sell_order(limit_sell_order_open):
|
|
|
|
|
order = deepcopy(limit_sell_order_open)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
order["remaining"] = 0.0
|
|
|
|
|
order["filled"] = order["amount"]
|
|
|
|
|
order["status"] = "closed"
|
2020-08-13 11:33:45 +00:00
|
|
|
|
return order
|
|
|
|
|
|
|
|
|
|
|
2018-08-14 10:12:44 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
def order_book_l2():
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return MagicMock(
|
|
|
|
|
return_value={
|
|
|
|
|
"bids": [
|
|
|
|
|
[0.043936, 10.442],
|
|
|
|
|
[0.043935, 31.865],
|
|
|
|
|
[0.043933, 11.212],
|
|
|
|
|
[0.043928, 0.088],
|
|
|
|
|
[0.043925, 10.0],
|
|
|
|
|
[0.043921, 10.0],
|
|
|
|
|
[0.04392, 37.64],
|
|
|
|
|
[0.043899, 0.066],
|
|
|
|
|
[0.043885, 0.676],
|
|
|
|
|
[0.04387, 22.758],
|
|
|
|
|
],
|
|
|
|
|
"asks": [
|
|
|
|
|
[0.043949, 0.346],
|
|
|
|
|
[0.04395, 0.608],
|
|
|
|
|
[0.043951, 3.948],
|
|
|
|
|
[0.043954, 0.288],
|
|
|
|
|
[0.043958, 9.277],
|
|
|
|
|
[0.043995, 1.566],
|
|
|
|
|
[0.044, 0.588],
|
|
|
|
|
[0.044002, 0.992],
|
|
|
|
|
[0.044003, 0.095],
|
|
|
|
|
[0.04402, 37.64],
|
|
|
|
|
],
|
|
|
|
|
"timestamp": None,
|
|
|
|
|
"datetime": None,
|
|
|
|
|
"nonce": 288004540,
|
|
|
|
|
}
|
|
|
|
|
)
|
2018-08-14 10:12:44 +00:00
|
|
|
|
|
|
|
|
|
|
2021-06-04 04:44:51 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
def order_book_l2_usd():
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return MagicMock(
|
|
|
|
|
return_value={
|
|
|
|
|
"symbol": "LTC/USDT",
|
|
|
|
|
"bids": [
|
|
|
|
|
[25.563, 49.269],
|
|
|
|
|
[25.562, 83.0],
|
|
|
|
|
[25.56, 106.0],
|
|
|
|
|
[25.559, 15.381],
|
|
|
|
|
[25.558, 29.299],
|
|
|
|
|
[25.557, 34.624],
|
|
|
|
|
[25.556, 10.0],
|
|
|
|
|
[25.555, 14.684],
|
|
|
|
|
[25.554, 45.91],
|
|
|
|
|
[25.553, 50.0],
|
|
|
|
|
],
|
|
|
|
|
"asks": [
|
|
|
|
|
[25.566, 14.27],
|
|
|
|
|
[25.567, 48.484],
|
|
|
|
|
[25.568, 92.349],
|
|
|
|
|
[25.572, 31.48],
|
|
|
|
|
[25.573, 23.0],
|
|
|
|
|
[25.574, 20.0],
|
|
|
|
|
[25.575, 89.606],
|
|
|
|
|
[25.576, 262.016],
|
|
|
|
|
[25.577, 178.557],
|
|
|
|
|
[25.578, 78.614],
|
|
|
|
|
],
|
|
|
|
|
"timestamp": None,
|
|
|
|
|
"datetime": None,
|
|
|
|
|
"nonce": 2372149736,
|
|
|
|
|
}
|
|
|
|
|
)
|
2021-06-04 04:44:51 +00:00
|
|
|
|
|
|
|
|
|
|
2018-04-06 07:57:08 +00:00
|
|
|
|
@pytest.fixture
|
2020-03-08 10:35:31 +00:00
|
|
|
|
def ohlcv_history_list():
|
2018-04-06 07:57:08 +00:00
|
|
|
|
return [
|
|
|
|
|
[
|
|
|
|
|
1511686200000, # unix timestamp ms
|
2024-05-12 13:35:47 +00:00
|
|
|
|
8.794e-05, # open
|
|
|
|
|
8.948e-05, # high
|
|
|
|
|
8.794e-05, # low
|
|
|
|
|
8.88e-05, # close
|
|
|
|
|
0.0877869, # volume (in quote currency)
|
2018-04-06 07:57:08 +00:00
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
1511686500000,
|
|
|
|
|
8.88e-05,
|
|
|
|
|
8.942e-05,
|
|
|
|
|
8.88e-05,
|
|
|
|
|
8.893e-05,
|
|
|
|
|
0.05874751,
|
|
|
|
|
],
|
2024-05-12 13:35:47 +00:00
|
|
|
|
[1511686800000, 8.891e-05, 8.893e-05, 8.875e-05, 8.877e-05, 0.7039405],
|
2018-04-06 07:57:08 +00:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
2018-12-11 18:48:36 +00:00
|
|
|
|
@pytest.fixture
|
2020-03-08 10:35:31 +00:00
|
|
|
|
def ohlcv_history(ohlcv_history_list):
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return ohlcv_to_dataframe(
|
|
|
|
|
ohlcv_history_list, "5m", pair="UNITTEST/BTC", fill_missing=True, drop_incomplete=False
|
|
|
|
|
)
|
2018-12-11 18:48:36 +00:00
|
|
|
|
|
|
|
|
|
|
2018-03-26 09:24:20 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
def tickers():
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return MagicMock(
|
|
|
|
|
return_value={
|
|
|
|
|
"ETH/BTC": {
|
|
|
|
|
"symbol": "ETH/BTC",
|
|
|
|
|
"timestamp": 1522014806207,
|
|
|
|
|
"datetime": "2018-03-25T21:53:26.207Z",
|
|
|
|
|
"high": 0.061697,
|
|
|
|
|
"low": 0.060531,
|
|
|
|
|
"bid": 0.061588,
|
|
|
|
|
"bidVolume": 3.321,
|
|
|
|
|
"ask": 0.061655,
|
|
|
|
|
"askVolume": 0.212,
|
|
|
|
|
"vwap": 0.06105296,
|
|
|
|
|
"open": 0.060809,
|
|
|
|
|
"close": 0.060761,
|
|
|
|
|
"first": None,
|
|
|
|
|
"last": 0.061588,
|
|
|
|
|
"change": 1.281,
|
|
|
|
|
"percentage": None,
|
|
|
|
|
"average": None,
|
|
|
|
|
"baseVolume": 111649.001,
|
|
|
|
|
"quoteVolume": 6816.50176926,
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
"TKN/BTC": {
|
|
|
|
|
"symbol": "TKN/BTC",
|
|
|
|
|
"timestamp": 1522014806169,
|
|
|
|
|
"datetime": "2018-03-25T21:53:26.169Z",
|
|
|
|
|
"high": 0.01885,
|
|
|
|
|
"low": 0.018497,
|
|
|
|
|
"bid": 0.018799,
|
|
|
|
|
"bidVolume": 8.38,
|
|
|
|
|
"ask": 0.018802,
|
|
|
|
|
"askVolume": 15.0,
|
|
|
|
|
"vwap": 0.01869197,
|
|
|
|
|
"open": 0.018585,
|
|
|
|
|
"close": 0.018573,
|
|
|
|
|
"last": 0.018799,
|
|
|
|
|
"baseVolume": 81058.66,
|
|
|
|
|
"quoteVolume": 2247.48374509,
|
|
|
|
|
},
|
|
|
|
|
"BLK/BTC": {
|
|
|
|
|
"symbol": "BLK/BTC",
|
|
|
|
|
"timestamp": 1522014806072,
|
|
|
|
|
"datetime": "2018-03-25T21:53:26.072Z",
|
|
|
|
|
"high": 0.007745,
|
|
|
|
|
"low": 0.007512,
|
|
|
|
|
"bid": 0.007729,
|
|
|
|
|
"bidVolume": 0.01,
|
|
|
|
|
"ask": 0.007743,
|
|
|
|
|
"askVolume": 21.37,
|
|
|
|
|
"vwap": 0.00761466,
|
|
|
|
|
"open": 0.007653,
|
|
|
|
|
"close": 0.007652,
|
|
|
|
|
"first": None,
|
|
|
|
|
"last": 0.007743,
|
|
|
|
|
"change": 1.176,
|
|
|
|
|
"percentage": None,
|
|
|
|
|
"average": None,
|
|
|
|
|
"baseVolume": 295152.26,
|
|
|
|
|
"quoteVolume": 1515.14631229,
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
"LTC/BTC": {
|
|
|
|
|
"symbol": "LTC/BTC",
|
|
|
|
|
"timestamp": 1523787258992,
|
|
|
|
|
"datetime": "2018-04-15T10:14:19.992Z",
|
|
|
|
|
"high": 0.015978,
|
|
|
|
|
"low": 0.0157,
|
|
|
|
|
"bid": 0.015954,
|
|
|
|
|
"bidVolume": 12.83,
|
|
|
|
|
"ask": 0.015957,
|
|
|
|
|
"askVolume": 0.49,
|
|
|
|
|
"vwap": 0.01581636,
|
|
|
|
|
"open": 0.015823,
|
|
|
|
|
"close": 0.01582,
|
|
|
|
|
"first": None,
|
|
|
|
|
"last": 0.015951,
|
|
|
|
|
"change": 0.809,
|
|
|
|
|
"percentage": None,
|
|
|
|
|
"average": None,
|
|
|
|
|
"baseVolume": 88620.68,
|
|
|
|
|
"quoteVolume": 1401.65697943,
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
"BTT/BTC": {
|
|
|
|
|
"symbol": "BTT/BTC",
|
|
|
|
|
"timestamp": 1550936557206,
|
|
|
|
|
"datetime": "2019-02-23T15:42:37.206Z",
|
|
|
|
|
"high": 0.00000026,
|
|
|
|
|
"low": 0.00000024,
|
|
|
|
|
"bid": 0.00000024,
|
|
|
|
|
"bidVolume": 2446894197.0,
|
|
|
|
|
"ask": 0.00000025,
|
|
|
|
|
"askVolume": 2447913837.0,
|
|
|
|
|
"vwap": 0.00000025,
|
|
|
|
|
"open": 0.00000026,
|
|
|
|
|
"close": 0.00000024,
|
|
|
|
|
"last": 0.00000024,
|
|
|
|
|
"previousClose": 0.00000026,
|
|
|
|
|
"change": -0.00000002,
|
|
|
|
|
"percentage": -7.692,
|
|
|
|
|
"average": None,
|
|
|
|
|
"baseVolume": 4886464537.0,
|
|
|
|
|
"quoteVolume": 1215.14489611,
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
"HOT/BTC": {
|
|
|
|
|
"symbol": "HOT/BTC",
|
|
|
|
|
"timestamp": 1572273518661,
|
|
|
|
|
"datetime": "2019-10-28T14:38:38.661Z",
|
|
|
|
|
"high": 0.00000011,
|
|
|
|
|
"low": 0.00000009,
|
|
|
|
|
"bid": 0.0000001,
|
|
|
|
|
"bidVolume": 1476027288.0,
|
|
|
|
|
"ask": 0.00000011,
|
|
|
|
|
"askVolume": 820153831.0,
|
|
|
|
|
"vwap": 0.0000001,
|
|
|
|
|
"open": 0.00000009,
|
|
|
|
|
"close": 0.00000011,
|
|
|
|
|
"last": 0.00000011,
|
|
|
|
|
"previousClose": 0.00000009,
|
|
|
|
|
"change": 0.00000002,
|
|
|
|
|
"percentage": 22.222,
|
|
|
|
|
"average": None,
|
|
|
|
|
"baseVolume": 1442290324.0,
|
|
|
|
|
"quoteVolume": 143.78311994,
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
"FUEL/BTC": {
|
|
|
|
|
"symbol": "FUEL/BTC",
|
|
|
|
|
"timestamp": 1572340250771,
|
|
|
|
|
"datetime": "2019-10-29T09:10:50.771Z",
|
|
|
|
|
"high": 0.00000040,
|
|
|
|
|
"low": 0.00000035,
|
|
|
|
|
"bid": 0.00000036,
|
|
|
|
|
"bidVolume": 8932318.0,
|
|
|
|
|
"ask": 0.00000037,
|
|
|
|
|
"askVolume": 10140774.0,
|
|
|
|
|
"vwap": 0.00000037,
|
|
|
|
|
"open": 0.00000039,
|
|
|
|
|
"close": 0.00000037,
|
|
|
|
|
"last": 0.00000037,
|
|
|
|
|
"previousClose": 0.00000038,
|
|
|
|
|
"change": -0.00000002,
|
|
|
|
|
"percentage": -5.128,
|
|
|
|
|
"average": None,
|
|
|
|
|
"baseVolume": 168927742.0,
|
|
|
|
|
"quoteVolume": 62.68220262,
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
"BTC/USDT": {
|
|
|
|
|
"symbol": "BTC/USDT",
|
|
|
|
|
"timestamp": 1573758371399,
|
|
|
|
|
"datetime": "2019-11-14T19:06:11.399Z",
|
|
|
|
|
"high": 8800.0,
|
|
|
|
|
"low": 8582.6,
|
|
|
|
|
"bid": 8648.16,
|
|
|
|
|
"bidVolume": 0.238771,
|
|
|
|
|
"ask": 8648.72,
|
|
|
|
|
"askVolume": 0.016253,
|
|
|
|
|
"vwap": 8683.13647806,
|
|
|
|
|
"open": 8759.7,
|
|
|
|
|
"close": 8648.72,
|
|
|
|
|
"last": 8648.72,
|
|
|
|
|
"previousClose": 8759.67,
|
|
|
|
|
"change": -110.98,
|
|
|
|
|
"percentage": -1.267,
|
|
|
|
|
"average": None,
|
|
|
|
|
"baseVolume": 35025.943355,
|
|
|
|
|
"quoteVolume": 304135046.4242901,
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
"ETH/USDT": {
|
|
|
|
|
"symbol": "ETH/USDT",
|
|
|
|
|
"timestamp": 1522014804118,
|
|
|
|
|
"datetime": "2018-03-25T21:53:24.118Z",
|
|
|
|
|
"high": 530.88,
|
|
|
|
|
"low": 512.0,
|
|
|
|
|
"bid": 529.73,
|
|
|
|
|
"bidVolume": 0.2,
|
|
|
|
|
"ask": 530.21,
|
|
|
|
|
"askVolume": 0.2464,
|
|
|
|
|
"vwap": 521.02438405,
|
|
|
|
|
"open": 527.27,
|
|
|
|
|
"close": 528.42,
|
|
|
|
|
"first": None,
|
|
|
|
|
"last": 530.21,
|
|
|
|
|
"change": 0.558,
|
2024-07-25 18:03:28 +00:00
|
|
|
|
"percentage": 2.349,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"average": None,
|
|
|
|
|
"baseVolume": 72300.0659,
|
|
|
|
|
"quoteVolume": 37670097.3022171,
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
"TKN/USDT": {
|
|
|
|
|
"symbol": "TKN/USDT",
|
|
|
|
|
"timestamp": 1522014806198,
|
|
|
|
|
"datetime": "2018-03-25T21:53:26.198Z",
|
|
|
|
|
"high": 8718.0,
|
|
|
|
|
"low": 8365.77,
|
|
|
|
|
"bid": 8603.64,
|
|
|
|
|
"bidVolume": 0.15846,
|
|
|
|
|
"ask": 8603.67,
|
|
|
|
|
"askVolume": 0.069147,
|
|
|
|
|
"vwap": 8536.35621697,
|
|
|
|
|
"open": 8680.0,
|
|
|
|
|
"close": 8680.0,
|
|
|
|
|
"first": None,
|
|
|
|
|
"last": 8603.67,
|
|
|
|
|
"change": -0.879,
|
|
|
|
|
"percentage": None,
|
|
|
|
|
"average": None,
|
|
|
|
|
"baseVolume": 30414.604298,
|
|
|
|
|
"quoteVolume": 259629896.48584127,
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
"BLK/USDT": {
|
|
|
|
|
"symbol": "BLK/USDT",
|
|
|
|
|
"timestamp": 1522014806145,
|
|
|
|
|
"datetime": "2018-03-25T21:53:26.145Z",
|
|
|
|
|
"high": 66.95,
|
|
|
|
|
"low": 63.38,
|
|
|
|
|
"bid": 66.473,
|
|
|
|
|
"bidVolume": 4.968,
|
|
|
|
|
"ask": 66.54,
|
|
|
|
|
"askVolume": 2.704,
|
|
|
|
|
"vwap": 65.0526901,
|
|
|
|
|
"open": 66.43,
|
|
|
|
|
"close": 66.383,
|
|
|
|
|
"first": None,
|
|
|
|
|
"last": 66.5,
|
|
|
|
|
"change": 0.105,
|
|
|
|
|
"percentage": None,
|
|
|
|
|
"average": None,
|
|
|
|
|
"baseVolume": 294106.204,
|
|
|
|
|
"quoteVolume": 19132399.743954,
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
"LTC/USDT": {
|
|
|
|
|
"symbol": "LTC/USDT",
|
|
|
|
|
"timestamp": 1523787257812,
|
|
|
|
|
"datetime": "2018-04-15T10:14:18.812Z",
|
|
|
|
|
"high": 129.94,
|
|
|
|
|
"low": 124.0,
|
|
|
|
|
"bid": 129.28,
|
|
|
|
|
"bidVolume": 0.03201,
|
|
|
|
|
"ask": 129.52,
|
|
|
|
|
"askVolume": 0.14529,
|
|
|
|
|
"vwap": 126.92838682,
|
|
|
|
|
"open": 127.0,
|
|
|
|
|
"close": 127.1,
|
|
|
|
|
"first": None,
|
|
|
|
|
"last": 129.28,
|
|
|
|
|
"change": 1.795,
|
|
|
|
|
"percentage": None,
|
|
|
|
|
"average": None,
|
|
|
|
|
"baseVolume": 59698.79897,
|
|
|
|
|
"quoteVolume": 29132399.743954,
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
"XRP/BTC": {
|
|
|
|
|
"symbol": "XRP/BTC",
|
|
|
|
|
"timestamp": 1573758257534,
|
|
|
|
|
"datetime": "2019-11-14T19:04:17.534Z",
|
|
|
|
|
"high": 3.126e-05,
|
|
|
|
|
"low": 3.061e-05,
|
|
|
|
|
"bid": 3.093e-05,
|
|
|
|
|
"bidVolume": 27901.0,
|
|
|
|
|
"ask": 3.095e-05,
|
|
|
|
|
"askVolume": 10551.0,
|
|
|
|
|
"vwap": 3.091e-05,
|
|
|
|
|
"open": 3.119e-05,
|
|
|
|
|
"close": 3.094e-05,
|
|
|
|
|
"last": 3.094e-05,
|
|
|
|
|
"previousClose": 3.117e-05,
|
|
|
|
|
"change": -2.5e-07,
|
|
|
|
|
"percentage": -0.802,
|
|
|
|
|
"average": None,
|
|
|
|
|
"baseVolume": 37334921.0,
|
|
|
|
|
"quoteVolume": 1154.19266394,
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
"NANO/USDT": {
|
|
|
|
|
"symbol": "NANO/USDT",
|
|
|
|
|
"timestamp": 1580469388244,
|
|
|
|
|
"datetime": "2020-01-31T11:16:28.244Z",
|
|
|
|
|
"high": 0.7519,
|
|
|
|
|
"low": 0.7154,
|
|
|
|
|
"bid": 0.7305,
|
|
|
|
|
"bidVolume": 300.3,
|
|
|
|
|
"ask": 0.7342,
|
|
|
|
|
"askVolume": 15.14,
|
|
|
|
|
"vwap": 0.73645591,
|
|
|
|
|
"open": 0.7154,
|
|
|
|
|
"close": 0.7342,
|
|
|
|
|
"last": 0.7342,
|
|
|
|
|
"previousClose": 0.7189,
|
|
|
|
|
"change": 0.0188,
|
|
|
|
|
"percentage": 2.628,
|
|
|
|
|
"average": None,
|
|
|
|
|
"baseVolume": 439472.44,
|
|
|
|
|
"quoteVolume": 323652.075405,
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
# Example of leveraged pair with incomplete info
|
|
|
|
|
"ADAHALF/USDT": {
|
|
|
|
|
"symbol": "ADAHALF/USDT",
|
|
|
|
|
"timestamp": 1580469388244,
|
|
|
|
|
"datetime": "2020-01-31T11:16:28.244Z",
|
|
|
|
|
"high": None,
|
|
|
|
|
"low": None,
|
|
|
|
|
"bid": 0.7305,
|
|
|
|
|
"bidVolume": None,
|
|
|
|
|
"ask": 0.7342,
|
|
|
|
|
"askVolume": None,
|
|
|
|
|
"vwap": None,
|
|
|
|
|
"open": None,
|
|
|
|
|
"close": None,
|
|
|
|
|
"last": None,
|
|
|
|
|
"previousClose": None,
|
|
|
|
|
"change": None,
|
|
|
|
|
"percentage": 2.628,
|
|
|
|
|
"average": None,
|
|
|
|
|
"baseVolume": 0.0,
|
|
|
|
|
"quoteVolume": 0.0,
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
"ADADOUBLE/USDT": {
|
|
|
|
|
"symbol": "ADADOUBLE/USDT",
|
|
|
|
|
"timestamp": 1580469388244,
|
|
|
|
|
"datetime": "2020-01-31T11:16:28.244Z",
|
|
|
|
|
"high": None,
|
|
|
|
|
"low": None,
|
|
|
|
|
"bid": 0.7305,
|
|
|
|
|
"bidVolume": None,
|
|
|
|
|
"ask": 0.7342,
|
|
|
|
|
"askVolume": None,
|
|
|
|
|
"vwap": None,
|
|
|
|
|
"open": None,
|
|
|
|
|
"close": None,
|
|
|
|
|
"last": 0,
|
|
|
|
|
"previousClose": None,
|
|
|
|
|
"change": None,
|
|
|
|
|
"percentage": 2.628,
|
|
|
|
|
"average": None,
|
|
|
|
|
"baseVolume": 0.0,
|
|
|
|
|
"quoteVolume": 0.0,
|
|
|
|
|
"info": {},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
)
|
2018-03-26 09:24:20 +00:00
|
|
|
|
|
|
|
|
|
|
2018-01-28 07:38:41 +00:00
|
|
|
|
@pytest.fixture
|
2022-09-19 18:59:40 +00:00
|
|
|
|
def dataframe_1m(testdatadir):
|
2024-05-12 13:35:47 +00:00
|
|
|
|
with (testdatadir / "UNITTEST_BTC-1m.json").open("r") as data_file:
|
|
|
|
|
return ohlcv_to_dataframe(
|
|
|
|
|
json.load(data_file), "1m", pair="UNITTEST/BTC", fill_missing=True
|
|
|
|
|
)
|
2018-01-28 07:38:41 +00:00
|
|
|
|
|
2018-04-15 17:56:33 +00:00
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="function")
|
|
|
|
|
def trades_for_order():
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
"info": {
|
|
|
|
|
"id": 34567,
|
|
|
|
|
"orderId": 123456,
|
|
|
|
|
"price": "2.0",
|
|
|
|
|
"qty": "8.00000000",
|
|
|
|
|
"commission": "0.00800000",
|
|
|
|
|
"commissionAsset": "LTC",
|
|
|
|
|
"time": 1521663363189,
|
|
|
|
|
"isBuyer": True,
|
|
|
|
|
"isMaker": False,
|
|
|
|
|
"isBestMatch": True,
|
|
|
|
|
},
|
|
|
|
|
"timestamp": 1521663363189,
|
|
|
|
|
"datetime": "2018-03-21T20:16:03.189Z",
|
|
|
|
|
"symbol": "LTC/USDT",
|
|
|
|
|
"id": "34567",
|
|
|
|
|
"order": "123456",
|
|
|
|
|
"type": None,
|
|
|
|
|
"side": "buy",
|
|
|
|
|
"price": 2.0,
|
|
|
|
|
"cost": 16.0,
|
|
|
|
|
"amount": 8.0,
|
|
|
|
|
"fee": {"cost": 0.008, "currency": "LTC"},
|
2021-09-26 08:43:47 +00:00
|
|
|
|
}
|
2024-05-12 13:35:47 +00:00
|
|
|
|
]
|
2018-04-15 17:56:33 +00:00
|
|
|
|
|
|
|
|
|
|
2019-08-29 14:33:56 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
|
|
|
|
def trades_history():
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return [
|
|
|
|
|
[1565798389463, "12618132aa9", None, "buy", 0.019627, 0.04, 0.00078508],
|
|
|
|
|
[1565798399629, "1261813bb30", None, "buy", 0.019627, 0.244, 0.004788987999999999],
|
|
|
|
|
[1565798399752, "1261813cc31", None, "sell", 0.019626, 0.011, 0.00021588599999999999],
|
|
|
|
|
[1565798399862, "126181cc332", None, "sell", 0.019626, 0.011, 0.00021588599999999999],
|
|
|
|
|
[1565798399862, "126181cc333", None, "sell", 0.019626, 0.012, 0.00021588599999999999],
|
|
|
|
|
[1565798399872, "1261aa81334", None, "sell", 0.019626, 0.011, 0.00021588599999999999],
|
|
|
|
|
]
|
2020-04-01 04:53:04 +00:00
|
|
|
|
|
2020-04-02 06:20:50 +00:00
|
|
|
|
|
2023-08-17 07:56:31 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
|
|
|
|
def trades_history_df(trades_history):
|
2023-08-18 05:25:51 +00:00
|
|
|
|
trades = trades_list_to_df(trades_history)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
trades["date"] = pd.to_datetime(trades["timestamp"], unit="ms", utc=True)
|
2023-08-17 07:56:31 +00:00
|
|
|
|
return trades
|
2020-04-01 04:53:04 +00:00
|
|
|
|
|
2020-04-02 06:20:50 +00:00
|
|
|
|
|
2020-04-01 04:53:04 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
|
|
|
|
def fetch_trades_result():
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
"info": ["0.01962700", "0.04000000", "1565798399.4631551", "b", "m", "", "126181329"],
|
|
|
|
|
"timestamp": 1565798399463,
|
|
|
|
|
"datetime": "2019-08-14T15:59:59.463Z",
|
|
|
|
|
"symbol": "ETH/BTC",
|
|
|
|
|
"id": "126181329",
|
|
|
|
|
"order": None,
|
|
|
|
|
"type": None,
|
|
|
|
|
"takerOrMaker": None,
|
|
|
|
|
"side": "buy",
|
|
|
|
|
"price": 0.019627,
|
|
|
|
|
"amount": 0.04,
|
|
|
|
|
"cost": 0.00078508,
|
|
|
|
|
"fee": None,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"info": ["0.01962700", "0.24400000", "1565798399.6291551", "b", "m", "", "126181330"],
|
|
|
|
|
"timestamp": 1565798399629,
|
|
|
|
|
"datetime": "2019-08-14T15:59:59.629Z",
|
|
|
|
|
"symbol": "ETH/BTC",
|
|
|
|
|
"id": "126181330",
|
|
|
|
|
"order": None,
|
|
|
|
|
"type": None,
|
|
|
|
|
"takerOrMaker": None,
|
|
|
|
|
"side": "buy",
|
|
|
|
|
"price": 0.019627,
|
|
|
|
|
"amount": 0.244,
|
|
|
|
|
"cost": 0.004788987999999999,
|
|
|
|
|
"fee": None,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"info": ["0.01962600", "0.01100000", "1565798399.7521551", "s", "m", "", "126181331"],
|
|
|
|
|
"timestamp": 1565798399752,
|
|
|
|
|
"datetime": "2019-08-14T15:59:59.752Z",
|
|
|
|
|
"symbol": "ETH/BTC",
|
|
|
|
|
"id": "126181331",
|
|
|
|
|
"order": None,
|
|
|
|
|
"type": None,
|
|
|
|
|
"takerOrMaker": None,
|
|
|
|
|
"side": "sell",
|
|
|
|
|
"price": 0.019626,
|
|
|
|
|
"amount": 0.011,
|
|
|
|
|
"cost": 0.00021588599999999999,
|
|
|
|
|
"fee": None,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"info": ["0.01962600", "0.01100000", "1565798399.8621551", "s", "m", "", "126181332"],
|
|
|
|
|
"timestamp": 1565798399862,
|
|
|
|
|
"datetime": "2019-08-14T15:59:59.862Z",
|
|
|
|
|
"symbol": "ETH/BTC",
|
|
|
|
|
"id": "126181332",
|
|
|
|
|
"order": None,
|
|
|
|
|
"type": None,
|
|
|
|
|
"takerOrMaker": None,
|
|
|
|
|
"side": "sell",
|
|
|
|
|
"price": 0.019626,
|
|
|
|
|
"amount": 0.011,
|
|
|
|
|
"cost": 0.00021588599999999999,
|
|
|
|
|
"fee": None,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"info": [
|
|
|
|
|
"0.01952600",
|
|
|
|
|
"0.01200000",
|
|
|
|
|
"1565798399.8721551",
|
|
|
|
|
"s",
|
|
|
|
|
"m",
|
|
|
|
|
"",
|
|
|
|
|
"126181333",
|
|
|
|
|
1565798399872512133,
|
|
|
|
|
],
|
|
|
|
|
"timestamp": 1565798399872,
|
|
|
|
|
"datetime": "2019-08-14T15:59:59.872Z",
|
|
|
|
|
"symbol": "ETH/BTC",
|
|
|
|
|
"id": "126181333",
|
|
|
|
|
"order": None,
|
|
|
|
|
"type": None,
|
|
|
|
|
"takerOrMaker": None,
|
|
|
|
|
"side": "sell",
|
|
|
|
|
"price": 0.019626,
|
|
|
|
|
"amount": 0.011,
|
|
|
|
|
"cost": 0.00021588599999999999,
|
|
|
|
|
"fee": None,
|
|
|
|
|
},
|
|
|
|
|
]
|
2019-08-29 14:33:56 +00:00
|
|
|
|
|
|
|
|
|
|
2018-04-15 17:56:33 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
|
|
|
|
def trades_for_order2():
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
"info": {},
|
|
|
|
|
"timestamp": 1521663363189,
|
|
|
|
|
"datetime": "2018-03-21T20:16:03.189Z",
|
|
|
|
|
"symbol": "LTC/ETH",
|
|
|
|
|
"id": "34567",
|
|
|
|
|
"order": "123456",
|
|
|
|
|
"type": None,
|
|
|
|
|
"side": "buy",
|
|
|
|
|
"price": 0.245441,
|
|
|
|
|
"cost": 1.963528,
|
|
|
|
|
"amount": 4.0,
|
|
|
|
|
"fee": {"cost": 0.004, "currency": "LTC"},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"info": {},
|
|
|
|
|
"timestamp": 1521663363189,
|
|
|
|
|
"datetime": "2018-03-21T20:16:03.189Z",
|
|
|
|
|
"symbol": "LTC/ETH",
|
|
|
|
|
"id": "34567",
|
|
|
|
|
"order": "123456",
|
|
|
|
|
"type": None,
|
|
|
|
|
"side": "buy",
|
|
|
|
|
"price": 0.245441,
|
|
|
|
|
"cost": 1.963528,
|
|
|
|
|
"amount": 4.0,
|
|
|
|
|
"fee": {"cost": 0.004, "currency": "LTC"},
|
|
|
|
|
},
|
|
|
|
|
]
|
2018-04-25 06:51:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def buy_order_fee():
|
|
|
|
|
return {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"id": "mocked_limit_buy_old",
|
|
|
|
|
"type": "limit",
|
|
|
|
|
"side": "buy",
|
|
|
|
|
"symbol": "mocked",
|
|
|
|
|
"timestamp": dt_ts(dt_now() - timedelta(minutes=601)),
|
|
|
|
|
"datetime": (dt_now() - timedelta(minutes=601)).isoformat(),
|
|
|
|
|
"price": 0.245441,
|
|
|
|
|
"amount": 8.0,
|
|
|
|
|
"cost": 1.963528,
|
|
|
|
|
"remaining": 90.99181073,
|
|
|
|
|
"status": "closed",
|
|
|
|
|
"fee": None,
|
2018-04-25 06:51:31 +00:00
|
|
|
|
}
|
2018-11-09 19:51:15 +00:00
|
|
|
|
|
2018-11-10 16:20:11 +00:00
|
|
|
|
|
2018-11-09 19:51:15 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
|
|
|
|
def edge_conf(default_conf):
|
2019-05-20 17:35:19 +00:00
|
|
|
|
conf = deepcopy(default_conf)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
conf["runmode"] = RunMode.DRY_RUN
|
|
|
|
|
conf["max_open_trades"] = -1
|
|
|
|
|
conf["tradable_balance_ratio"] = 0.5
|
|
|
|
|
conf["stake_amount"] = constants.UNLIMITED_STAKE_AMOUNT
|
|
|
|
|
conf["edge"] = {
|
2018-11-10 16:20:11 +00:00
|
|
|
|
"enabled": True,
|
2018-11-09 19:51:15 +00:00
|
|
|
|
"process_throttle_secs": 1800,
|
|
|
|
|
"calculate_since_number_of_days": 14,
|
|
|
|
|
"allowed_risk": 0.01,
|
|
|
|
|
"stoploss_range_min": -0.01,
|
|
|
|
|
"stoploss_range_max": -0.1,
|
|
|
|
|
"stoploss_range_step": -0.01,
|
|
|
|
|
"maximum_winrate": 0.80,
|
|
|
|
|
"minimum_expectancy": 0.20,
|
|
|
|
|
"min_trade_number": 15,
|
|
|
|
|
"max_trade_duration_minute": 1440,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"remove_pumps": False,
|
2018-11-09 19:51:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-05-20 17:35:19 +00:00
|
|
|
|
return conf
|
2019-05-11 07:10:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def rpc_balance():
|
|
|
|
|
return {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"BTC": {"total": 12.0, "free": 12.0, "used": 0.0},
|
|
|
|
|
"ETH": {"total": 0.0, "free": 0.0, "used": 0.0},
|
|
|
|
|
"USDT": {"total": 10000.0, "free": 10000.0, "used": 0.0},
|
|
|
|
|
"LTC": {"total": 10.0, "free": 10.0, "used": 0.0},
|
|
|
|
|
"XRP": {"total": 0.1, "free": 0.01, "used": 0.0},
|
|
|
|
|
"EUR": {"total": 10.0, "free": 10.0, "used": 0.0},
|
2019-05-11 07:10:54 +00:00
|
|
|
|
}
|
2019-09-07 18:34:25 +00:00
|
|
|
|
|
|
|
|
|
|
2019-09-07 18:56:03 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
def testdatadir() -> Path:
|
2019-09-07 18:34:25 +00:00
|
|
|
|
"""Return the path where testdata files are stored"""
|
|
|
|
|
return (Path(__file__).parent / "testdata").resolve()
|
2019-09-25 09:54:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="function")
|
|
|
|
|
def import_fails() -> None:
|
|
|
|
|
# Source of this test-method:
|
|
|
|
|
# https://stackoverflow.com/questions/2481511/mocking-importerror-in-python
|
|
|
|
|
import builtins
|
2024-05-12 13:35:47 +00:00
|
|
|
|
|
2019-09-25 09:54:57 +00:00
|
|
|
|
realimport = builtins.__import__
|
|
|
|
|
|
|
|
|
|
def mockedimport(name, *args, **kwargs):
|
2024-05-12 13:35:47 +00:00
|
|
|
|
if name in ["filelock", "cysystemd.journal", "uvloop"]:
|
2019-09-25 09:54:57 +00:00
|
|
|
|
raise ImportError(f"No module named '{name}'")
|
|
|
|
|
return realimport(name, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
builtins.__import__ = mockedimport
|
|
|
|
|
|
|
|
|
|
# Run test - then cleanup
|
|
|
|
|
yield
|
|
|
|
|
|
|
|
|
|
# restore previous importfunction
|
|
|
|
|
builtins.__import__ = realimport
|
2019-10-17 17:53:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope="function")
|
|
|
|
|
def open_trade():
|
2022-01-30 18:25:09 +00:00
|
|
|
|
trade = Trade(
|
2024-05-12 13:35:47 +00:00
|
|
|
|
pair="ETH/BTC",
|
2019-10-17 17:53:01 +00:00
|
|
|
|
open_rate=0.00001099,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
exchange="binance",
|
2019-10-17 17:53:01 +00:00
|
|
|
|
amount=90.99181073,
|
|
|
|
|
fee_open=0.0,
|
|
|
|
|
fee_close=0.0,
|
|
|
|
|
stake_amount=1,
|
2023-05-14 09:28:40 +00:00
|
|
|
|
open_date=dt_now() - timedelta(minutes=601),
|
2024-05-12 13:35:47 +00:00
|
|
|
|
is_open=True,
|
2019-10-17 17:53:01 +00:00
|
|
|
|
)
|
2022-01-30 18:25:09 +00:00
|
|
|
|
trade.orders = [
|
|
|
|
|
Order(
|
2024-05-12 13:35:47 +00:00
|
|
|
|
ft_order_side="buy",
|
2022-01-30 18:25:09 +00:00
|
|
|
|
ft_pair=trade.pair,
|
2023-06-15 05:55:13 +00:00
|
|
|
|
ft_is_open=True,
|
2023-01-08 12:55:52 +00:00
|
|
|
|
ft_amount=trade.amount,
|
|
|
|
|
ft_price=trade.open_rate,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
order_id="123456789",
|
2022-01-30 18:25:09 +00:00
|
|
|
|
status="closed",
|
|
|
|
|
symbol=trade.pair,
|
|
|
|
|
order_type="market",
|
|
|
|
|
side="buy",
|
|
|
|
|
price=trade.open_rate,
|
|
|
|
|
average=trade.open_rate,
|
|
|
|
|
filled=trade.amount,
|
|
|
|
|
remaining=0,
|
|
|
|
|
cost=trade.open_rate * trade.amount,
|
|
|
|
|
order_date=trade.open_date,
|
|
|
|
|
order_filled_date=trade.open_date,
|
|
|
|
|
)
|
|
|
|
|
]
|
|
|
|
|
return trade
|
2019-12-09 01:37:58 +00:00
|
|
|
|
|
|
|
|
|
|
2021-09-17 08:25:58 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
|
|
|
|
def open_trade_usdt():
|
2022-02-11 16:02:04 +00:00
|
|
|
|
trade = Trade(
|
2024-05-12 13:35:47 +00:00
|
|
|
|
pair="ADA/USDT",
|
2021-09-17 08:25:58 +00:00
|
|
|
|
open_rate=2.0,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
exchange="binance",
|
2021-09-17 08:25:58 +00:00
|
|
|
|
amount=30.0,
|
|
|
|
|
fee_open=0.0,
|
|
|
|
|
fee_close=0.0,
|
|
|
|
|
stake_amount=60.0,
|
2023-05-14 09:28:40 +00:00
|
|
|
|
open_date=dt_now() - timedelta(minutes=601),
|
2024-05-12 13:35:47 +00:00
|
|
|
|
is_open=True,
|
2021-09-17 08:25:58 +00:00
|
|
|
|
)
|
2022-02-11 16:02:04 +00:00
|
|
|
|
trade.orders = [
|
|
|
|
|
Order(
|
2024-05-12 13:35:47 +00:00
|
|
|
|
ft_order_side="buy",
|
2022-02-11 16:02:04 +00:00
|
|
|
|
ft_pair=trade.pair,
|
|
|
|
|
ft_is_open=False,
|
2023-01-08 12:55:52 +00:00
|
|
|
|
ft_amount=trade.amount,
|
|
|
|
|
ft_price=trade.open_rate,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
order_id="123456789",
|
2022-02-11 16:02:04 +00:00
|
|
|
|
status="closed",
|
|
|
|
|
symbol=trade.pair,
|
|
|
|
|
order_type="market",
|
|
|
|
|
side="buy",
|
|
|
|
|
price=trade.open_rate,
|
|
|
|
|
average=trade.open_rate,
|
|
|
|
|
filled=trade.amount,
|
|
|
|
|
remaining=0,
|
|
|
|
|
cost=trade.open_rate * trade.amount,
|
|
|
|
|
order_date=trade.open_date,
|
|
|
|
|
order_filled_date=trade.open_date,
|
2022-07-24 08:51:13 +00:00
|
|
|
|
),
|
|
|
|
|
Order(
|
2024-05-12 13:35:47 +00:00
|
|
|
|
ft_order_side="exit",
|
2022-07-24 08:51:13 +00:00
|
|
|
|
ft_pair=trade.pair,
|
|
|
|
|
ft_is_open=True,
|
2023-01-08 12:55:52 +00:00
|
|
|
|
ft_amount=trade.amount,
|
|
|
|
|
ft_price=trade.open_rate,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
order_id="123456789_exit",
|
2022-07-24 08:51:13 +00:00
|
|
|
|
status="open",
|
|
|
|
|
symbol=trade.pair,
|
|
|
|
|
order_type="limit",
|
|
|
|
|
side="sell",
|
|
|
|
|
price=trade.open_rate,
|
|
|
|
|
average=trade.open_rate,
|
|
|
|
|
filled=trade.amount,
|
|
|
|
|
remaining=0,
|
|
|
|
|
cost=trade.open_rate * trade.amount,
|
|
|
|
|
order_date=trade.open_date,
|
|
|
|
|
order_filled_date=trade.open_date,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
),
|
2022-02-11 16:02:04 +00:00
|
|
|
|
]
|
|
|
|
|
return trade
|
2021-09-17 08:25:58 +00:00
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
2021-08-01 01:52:55 +00:00
|
|
|
|
def limit_buy_order_usdt_open():
|
|
|
|
|
return {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"id": "mocked_limit_buy_usdt",
|
|
|
|
|
"type": "limit",
|
|
|
|
|
"side": "buy",
|
|
|
|
|
"symbol": "mocked",
|
|
|
|
|
"datetime": dt_now().isoformat(),
|
|
|
|
|
"timestamp": dt_ts(),
|
|
|
|
|
"price": 2.00,
|
|
|
|
|
"average": 2.00,
|
|
|
|
|
"amount": 30.0,
|
|
|
|
|
"filled": 0.0,
|
|
|
|
|
"cost": 60.0,
|
|
|
|
|
"remaining": 30.0,
|
|
|
|
|
"status": "open",
|
2021-08-01 01:52:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
2021-08-01 01:52:55 +00:00
|
|
|
|
def limit_buy_order_usdt(limit_buy_order_usdt_open):
|
|
|
|
|
order = deepcopy(limit_buy_order_usdt_open)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
order["status"] = "closed"
|
|
|
|
|
order["filled"] = order["amount"]
|
|
|
|
|
order["remaining"] = 0.0
|
2021-08-01 01:52:55 +00:00
|
|
|
|
return order
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def limit_sell_order_usdt_open():
|
|
|
|
|
return {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"id": "mocked_limit_sell_usdt",
|
|
|
|
|
"type": "limit",
|
|
|
|
|
"side": "sell",
|
|
|
|
|
"symbol": "mocked",
|
|
|
|
|
"datetime": dt_now().isoformat(),
|
|
|
|
|
"timestamp": dt_ts(),
|
|
|
|
|
"price": 2.20,
|
|
|
|
|
"amount": 30.0,
|
|
|
|
|
"cost": 66.0,
|
|
|
|
|
"filled": 0.0,
|
|
|
|
|
"remaining": 30.0,
|
|
|
|
|
"status": "open",
|
2021-08-01 01:52:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def limit_sell_order_usdt(limit_sell_order_usdt_open):
|
|
|
|
|
order = deepcopy(limit_sell_order_usdt_open)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
order["remaining"] = 0.0
|
|
|
|
|
order["filled"] = order["amount"]
|
|
|
|
|
order["status"] = "closed"
|
2021-08-01 01:52:55 +00:00
|
|
|
|
return order
|
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
2021-08-01 01:52:55 +00:00
|
|
|
|
def market_buy_order_usdt():
|
|
|
|
|
return {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"id": "mocked_market_buy",
|
|
|
|
|
"type": "market",
|
|
|
|
|
"side": "buy",
|
|
|
|
|
"symbol": "mocked",
|
|
|
|
|
"timestamp": dt_ts(),
|
|
|
|
|
"datetime": dt_now().isoformat(),
|
|
|
|
|
"price": 2.00,
|
|
|
|
|
"amount": 30.0,
|
|
|
|
|
"filled": 30.0,
|
|
|
|
|
"remaining": 0.0,
|
|
|
|
|
"status": "closed",
|
2021-08-01 01:52:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-11-10 18:43:36 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
def market_buy_order_usdt_doublefee(market_buy_order_usdt):
|
|
|
|
|
order = deepcopy(market_buy_order_usdt)
|
2024-05-12 13:35:47 +00:00
|
|
|
|
order["fee"] = None
|
2021-11-10 18:43:36 +00:00
|
|
|
|
# Market orders filled with 2 trades can have fees in different currencies
|
|
|
|
|
# assuming the account runs out of BNB.
|
2024-05-12 13:35:47 +00:00
|
|
|
|
order["fees"] = [
|
|
|
|
|
{"cost": 0.00025125, "currency": "BNB"},
|
|
|
|
|
{"cost": 0.05030681, "currency": "USDT"},
|
|
|
|
|
]
|
|
|
|
|
order["trades"] = [
|
|
|
|
|
{
|
|
|
|
|
"timestamp": None,
|
|
|
|
|
"datetime": None,
|
|
|
|
|
"symbol": "ETH/USDT",
|
|
|
|
|
"id": None,
|
|
|
|
|
"order": "123",
|
|
|
|
|
"type": "market",
|
|
|
|
|
"side": "sell",
|
|
|
|
|
"takerOrMaker": None,
|
|
|
|
|
"price": 2.01,
|
|
|
|
|
"amount": 25.0,
|
|
|
|
|
"cost": 50.25,
|
|
|
|
|
"fee": {"cost": 0.00025125, "currency": "BNB"},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"timestamp": None,
|
|
|
|
|
"datetime": None,
|
|
|
|
|
"symbol": "ETH/USDT",
|
|
|
|
|
"id": None,
|
|
|
|
|
"order": "123",
|
|
|
|
|
"type": "market",
|
|
|
|
|
"side": "sell",
|
|
|
|
|
"takerOrMaker": None,
|
|
|
|
|
"price": 2.0,
|
|
|
|
|
"amount": 5,
|
|
|
|
|
"cost": 10,
|
|
|
|
|
"fee": {"cost": 0.0100306, "currency": "USDT"},
|
|
|
|
|
},
|
2021-11-10 18:43:36 +00:00
|
|
|
|
]
|
|
|
|
|
return order
|
|
|
|
|
|
|
|
|
|
|
2021-08-01 01:52:55 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
def market_sell_order_usdt():
|
|
|
|
|
return {
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"id": "mocked_limit_sell",
|
|
|
|
|
"type": "market",
|
|
|
|
|
"side": "sell",
|
|
|
|
|
"symbol": "mocked",
|
|
|
|
|
"timestamp": dt_ts(),
|
|
|
|
|
"datetime": dt_now().isoformat(),
|
|
|
|
|
"price": 2.20,
|
|
|
|
|
"amount": 30.0,
|
|
|
|
|
"filled": 30.0,
|
|
|
|
|
"remaining": 0.0,
|
|
|
|
|
"status": "closed",
|
2021-08-01 01:52:55 +00:00
|
|
|
|
}
|
2021-09-14 21:38:26 +00:00
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
2021-10-03 05:35:50 +00:00
|
|
|
|
def limit_order(limit_buy_order_usdt, limit_sell_order_usdt):
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return {"buy": limit_buy_order_usdt, "sell": limit_sell_order_usdt}
|
2021-09-14 21:38:26 +00:00
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
2021-10-03 05:35:50 +00:00
|
|
|
|
def limit_order_open(limit_buy_order_usdt_open, limit_sell_order_usdt_open):
|
2024-05-12 13:35:47 +00:00
|
|
|
|
return {"buy": limit_buy_order_usdt_open, "sell": limit_sell_order_usdt_open}
|
2021-11-01 07:04:42 +00:00
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
2021-11-01 07:04:42 +00:00
|
|
|
|
def mark_ohlcv():
|
|
|
|
|
return [
|
2021-11-01 12:28:03 +00:00
|
|
|
|
[1630454400000, 2.77, 2.77, 2.73, 2.73, 0],
|
|
|
|
|
[1630458000000, 2.73, 2.76, 2.72, 2.74, 0],
|
|
|
|
|
[1630461600000, 2.74, 2.76, 2.74, 2.76, 0],
|
|
|
|
|
[1630465200000, 2.76, 2.76, 2.74, 2.76, 0],
|
|
|
|
|
[1630468800000, 2.76, 2.77, 2.75, 2.77, 0],
|
|
|
|
|
[1630472400000, 2.77, 2.79, 2.75, 2.78, 0],
|
|
|
|
|
[1630476000000, 2.78, 2.80, 2.77, 2.77, 0],
|
|
|
|
|
[1630479600000, 2.78, 2.79, 2.77, 2.77, 0],
|
|
|
|
|
[1630483200000, 2.77, 2.79, 2.77, 2.78, 0],
|
|
|
|
|
[1630486800000, 2.77, 2.84, 2.77, 2.84, 0],
|
|
|
|
|
[1630490400000, 2.84, 2.85, 2.81, 2.81, 0],
|
|
|
|
|
[1630494000000, 2.81, 2.83, 2.81, 2.81, 0],
|
|
|
|
|
[1630497600000, 2.81, 2.84, 2.81, 2.82, 0],
|
|
|
|
|
[1630501200000, 2.82, 2.83, 2.81, 2.81, 0],
|
2021-11-01 07:04:42 +00:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
2021-11-13 10:45:23 +00:00
|
|
|
|
def funding_rate_history_hourly():
|
2021-11-01 07:04:42 +00:00
|
|
|
|
return [
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
"fundingRate": -0.000008,
|
|
|
|
|
"timestamp": 1630454400000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T00:00:00.000Z",
|
2021-11-01 07:04:42 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
"fundingRate": -0.000004,
|
|
|
|
|
"timestamp": 1630458000000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T01:00:00.000Z",
|
2021-11-01 07:04:42 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
"fundingRate": 0.000012,
|
|
|
|
|
"timestamp": 1630461600000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T02:00:00.000Z",
|
2021-11-01 07:04:42 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
"fundingRate": -0.000003,
|
|
|
|
|
"timestamp": 1630465200000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T03:00:00.000Z",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
"fundingRate": -0.000007,
|
|
|
|
|
"timestamp": 1630468800000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T04:00:00.000Z",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
"fundingRate": 0.000003,
|
|
|
|
|
"timestamp": 1630472400000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T05:00:00.000Z",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
"fundingRate": 0.000019,
|
|
|
|
|
"timestamp": 1630476000000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T06:00:00.000Z",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
"fundingRate": 0.000003,
|
|
|
|
|
"timestamp": 1630479600000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T07:00:00.000Z",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-01 12:28:03 +00:00
|
|
|
|
"fundingRate": -0.000003,
|
2021-11-01 08:51:59 +00:00
|
|
|
|
"timestamp": 1630483200000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T08:00:00.000Z",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-01 12:28:03 +00:00
|
|
|
|
"fundingRate": 0,
|
2021-11-01 08:51:59 +00:00
|
|
|
|
"timestamp": 1630486800000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T09:00:00.000Z",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
"fundingRate": 0.000013,
|
|
|
|
|
"timestamp": 1630490400000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T10:00:00.000Z",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
"fundingRate": 0.000077,
|
|
|
|
|
"timestamp": 1630494000000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T11:00:00.000Z",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
"fundingRate": 0.000072,
|
|
|
|
|
"timestamp": 1630497600000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T12:00:00.000Z",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
"fundingRate": 0.000097,
|
|
|
|
|
"timestamp": 1630501200000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T13:00:00.000Z",
|
2021-11-01 08:51:59 +00:00
|
|
|
|
},
|
2021-11-01 07:04:42 +00:00
|
|
|
|
]
|
2021-11-13 10:45:23 +00:00
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
2021-11-13 10:45:23 +00:00
|
|
|
|
def funding_rate_history_octohourly():
|
|
|
|
|
return [
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-13 10:45:23 +00:00
|
|
|
|
"fundingRate": -0.000008,
|
|
|
|
|
"timestamp": 1630454400000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T00:00:00.000Z",
|
2021-11-13 10:45:23 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2023-07-15 15:14:57 +00:00
|
|
|
|
"symbol": "ADA/USDT:USDT",
|
2021-11-13 10:45:23 +00:00
|
|
|
|
"fundingRate": -0.000003,
|
|
|
|
|
"timestamp": 1630483200000,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"datetime": "2021-09-01T08:00:00.000Z",
|
|
|
|
|
},
|
2021-11-13 10:45:23 +00:00
|
|
|
|
]
|
2022-02-07 10:08:30 +00:00
|
|
|
|
|
|
|
|
|
|
2024-05-12 13:35:47 +00:00
|
|
|
|
@pytest.fixture(scope="function")
|
2022-02-07 10:08:30 +00:00
|
|
|
|
def leverage_tiers():
|
|
|
|
|
return {
|
2023-01-13 19:44:45 +00:00
|
|
|
|
"1000SHIB/USDT:USDT": [
|
2022-02-07 10:08:30 +00:00
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 0,
|
|
|
|
|
"maxNotional": 50000,
|
|
|
|
|
"maintenanceMarginRate": 0.01,
|
|
|
|
|
"maxLeverage": 50,
|
|
|
|
|
"maintAmt": 0.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 50000,
|
|
|
|
|
"maxNotional": 150000,
|
|
|
|
|
"maintenanceMarginRate": 0.025,
|
|
|
|
|
"maxLeverage": 20,
|
|
|
|
|
"maintAmt": 750.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 150000,
|
|
|
|
|
"maxNotional": 250000,
|
|
|
|
|
"maintenanceMarginRate": 0.05,
|
|
|
|
|
"maxLeverage": 10,
|
|
|
|
|
"maintAmt": 4500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 250000,
|
|
|
|
|
"maxNotional": 500000,
|
|
|
|
|
"maintenanceMarginRate": 0.1,
|
|
|
|
|
"maxLeverage": 5,
|
|
|
|
|
"maintAmt": 17000.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 500000,
|
|
|
|
|
"maxNotional": 1000000,
|
|
|
|
|
"maintenanceMarginRate": 0.125,
|
|
|
|
|
"maxLeverage": 4,
|
|
|
|
|
"maintAmt": 29500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 1000000,
|
|
|
|
|
"maxNotional": 2000000,
|
|
|
|
|
"maintenanceMarginRate": 0.25,
|
|
|
|
|
"maxLeverage": 2,
|
|
|
|
|
"maintAmt": 154500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 2000000,
|
|
|
|
|
"maxNotional": 30000000,
|
|
|
|
|
"maintenanceMarginRate": 0.5,
|
|
|
|
|
"maxLeverage": 1,
|
|
|
|
|
"maintAmt": 654500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
],
|
2023-01-13 19:44:45 +00:00
|
|
|
|
"1INCH/USDT:USDT": [
|
2022-02-07 10:08:30 +00:00
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 0,
|
|
|
|
|
"maxNotional": 5000,
|
|
|
|
|
"maintenanceMarginRate": 0.012,
|
|
|
|
|
"maxLeverage": 50,
|
|
|
|
|
"maintAmt": 0.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 5000,
|
|
|
|
|
"maxNotional": 25000,
|
|
|
|
|
"maintenanceMarginRate": 0.025,
|
|
|
|
|
"maxLeverage": 20,
|
|
|
|
|
"maintAmt": 65.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 25000,
|
|
|
|
|
"maxNotional": 100000,
|
|
|
|
|
"maintenanceMarginRate": 0.05,
|
|
|
|
|
"maxLeverage": 10,
|
|
|
|
|
"maintAmt": 690.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 100000,
|
|
|
|
|
"maxNotional": 250000,
|
|
|
|
|
"maintenanceMarginRate": 0.1,
|
|
|
|
|
"maxLeverage": 5,
|
|
|
|
|
"maintAmt": 5690.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 250000,
|
|
|
|
|
"maxNotional": 1000000,
|
|
|
|
|
"maintenanceMarginRate": 0.125,
|
|
|
|
|
"maxLeverage": 2,
|
|
|
|
|
"maintAmt": 11940.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 1000000,
|
|
|
|
|
"maxNotional": 100000000,
|
|
|
|
|
"maintenanceMarginRate": 0.5,
|
|
|
|
|
"maxLeverage": 1,
|
|
|
|
|
"maintAmt": 386940.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
],
|
2023-01-13 19:44:45 +00:00
|
|
|
|
"AAVE/USDT:USDT": [
|
2022-02-07 10:08:30 +00:00
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 0,
|
|
|
|
|
"maxNotional": 5000,
|
|
|
|
|
"maintenanceMarginRate": 0.01,
|
|
|
|
|
"maxLeverage": 50,
|
|
|
|
|
"maintAmt": 0.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 5000,
|
|
|
|
|
"maxNotional": 25000,
|
|
|
|
|
"maintenanceMarginRate": 0.02,
|
|
|
|
|
"maxLeverage": 25,
|
|
|
|
|
"maintAmt": 75.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 25000,
|
|
|
|
|
"maxNotional": 100000,
|
|
|
|
|
"maintenanceMarginRate": 0.05,
|
|
|
|
|
"maxLeverage": 10,
|
|
|
|
|
"maintAmt": 700.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 100000,
|
|
|
|
|
"maxNotional": 250000,
|
|
|
|
|
"maintenanceMarginRate": 0.1,
|
|
|
|
|
"maxLeverage": 5,
|
|
|
|
|
"maintAmt": 5700.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 250000,
|
|
|
|
|
"maxNotional": 1000000,
|
|
|
|
|
"maintenanceMarginRate": 0.125,
|
|
|
|
|
"maxLeverage": 2,
|
|
|
|
|
"maintAmt": 11950.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 10000000,
|
|
|
|
|
"maxNotional": 50000000,
|
|
|
|
|
"maintenanceMarginRate": 0.5,
|
|
|
|
|
"maxLeverage": 1,
|
|
|
|
|
"maintAmt": 386950.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
],
|
2024-02-03 12:31:24 +00:00
|
|
|
|
"ADA/USDT:USDT": [
|
2022-02-07 10:08:30 +00:00
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 0,
|
|
|
|
|
"maxNotional": 100000,
|
|
|
|
|
"maintenanceMarginRate": 0.025,
|
|
|
|
|
"maxLeverage": 20,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 0.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 100000,
|
|
|
|
|
"maxNotional": 500000,
|
|
|
|
|
"maintenanceMarginRate": 0.05,
|
|
|
|
|
"maxLeverage": 10,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 2500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 500000,
|
|
|
|
|
"maxNotional": 1000000,
|
|
|
|
|
"maintenanceMarginRate": 0.1,
|
|
|
|
|
"maxLeverage": 5,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 27500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 1000000,
|
|
|
|
|
"maxNotional": 2000000,
|
|
|
|
|
"maintenanceMarginRate": 0.15,
|
|
|
|
|
"maxLeverage": 3,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 77500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 2000000,
|
|
|
|
|
"maxNotional": 5000000,
|
|
|
|
|
"maintenanceMarginRate": 0.25,
|
|
|
|
|
"maxLeverage": 2,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 277500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 5000000,
|
|
|
|
|
"maxNotional": 30000000,
|
|
|
|
|
"maintenanceMarginRate": 0.5,
|
|
|
|
|
"maxLeverage": 1,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 1527500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
],
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"XRP/USDT:USDT": [
|
2022-02-07 10:08:30 +00:00
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 0, # stake(before leverage) = 0
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"maxNotional": 100000, # max stake(before leverage) = 5000
|
|
|
|
|
"maintenanceMarginRate": 0.025,
|
|
|
|
|
"maxLeverage": 20,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 0.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 100000, # stake = 10000.0
|
|
|
|
|
"maxNotional": 500000, # max_stake = 50000.0
|
|
|
|
|
"maintenanceMarginRate": 0.05,
|
|
|
|
|
"maxLeverage": 10,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 2500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 500000, # stake = 100000.0
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"maxNotional": 1000000, # max_stake = 200000.0
|
|
|
|
|
"maintenanceMarginRate": 0.1,
|
|
|
|
|
"maxLeverage": 5,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 27500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 1000000, # stake = 333333.3333333333
|
|
|
|
|
"maxNotional": 2000000, # max_stake = 666666.6666666666
|
|
|
|
|
"maintenanceMarginRate": 0.15,
|
|
|
|
|
"maxLeverage": 3,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 77500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 2000000, # stake = 1000000.0
|
|
|
|
|
"maxNotional": 5000000, # max_stake = 2500000.0
|
|
|
|
|
"maintenanceMarginRate": 0.25,
|
|
|
|
|
"maxLeverage": 2,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 277500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 5000000, # stake = 5000000.0
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"maxNotional": 30000000, # max_stake = 30000000.0
|
|
|
|
|
"maintenanceMarginRate": 0.5,
|
|
|
|
|
"maxLeverage": 1,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 1527500.0,
|
|
|
|
|
},
|
2022-02-07 10:08:30 +00:00
|
|
|
|
],
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"BNB/USDT:USDT": [
|
2022-02-07 10:08:30 +00:00
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 0, # stake = 0.0
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"maxNotional": 10000, # max_stake = 133.33333333333334
|
|
|
|
|
"maintenanceMarginRate": 0.0065,
|
|
|
|
|
"maxLeverage": 75,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 0.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 10000, # stake = 200.0
|
|
|
|
|
"maxNotional": 50000, # max_stake = 1000.0
|
|
|
|
|
"maintenanceMarginRate": 0.01,
|
|
|
|
|
"maxLeverage": 50,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 35.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 50000, # stake = 2000.0
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"maxNotional": 250000, # max_stake = 10000.0
|
|
|
|
|
"maintenanceMarginRate": 0.02,
|
|
|
|
|
"maxLeverage": 25,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 535.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 250000, # stake = 25000.0
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"maxNotional": 1000000, # max_stake = 100000.0
|
|
|
|
|
"maintenanceMarginRate": 0.05,
|
|
|
|
|
"maxLeverage": 10,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 8035.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 1000000, # stake = 200000.0
|
|
|
|
|
"maxNotional": 2000000, # max_stake = 400000.0
|
|
|
|
|
"maintenanceMarginRate": 0.1,
|
|
|
|
|
"maxLeverage": 5,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 58035.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 2000000, # stake = 500000.0
|
|
|
|
|
"maxNotional": 5000000, # max_stake = 1250000.0
|
|
|
|
|
"maintenanceMarginRate": 0.125,
|
|
|
|
|
"maxLeverage": 4,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 108035.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 5000000, # stake = 1666666.6666666667
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"maxNotional": 10000000, # max_stake = 3333333.3333333335
|
|
|
|
|
"maintenanceMarginRate": 0.15,
|
|
|
|
|
"maxLeverage": 3,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 233035.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 10000000, # stake = 5000000.0
|
|
|
|
|
"maxNotional": 20000000, # max_stake = 10000000.0
|
|
|
|
|
"maintenanceMarginRate": 0.25,
|
|
|
|
|
"maxLeverage": 2,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 1233035.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 20000000, # stake = 20000000.0
|
|
|
|
|
"maxNotional": 50000000, # max_stake = 50000000.0
|
|
|
|
|
"maintenanceMarginRate": 0.5,
|
|
|
|
|
"maxLeverage": 1,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 6233035.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
],
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"BTC/USDT:USDT": [
|
2022-02-07 10:08:30 +00:00
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 0, # stake = 0.0
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"maxNotional": 50000, # max_stake = 400.0
|
|
|
|
|
"maintenanceMarginRate": 0.004,
|
|
|
|
|
"maxLeverage": 125,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 0.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 50000, # stake = 500.0
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"maxNotional": 250000, # max_stake = 2500.0
|
|
|
|
|
"maintenanceMarginRate": 0.005,
|
|
|
|
|
"maxLeverage": 100,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 50.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 250000, # stake = 5000.0
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"maxNotional": 1000000, # max_stake = 20000.0
|
|
|
|
|
"maintenanceMarginRate": 0.01,
|
|
|
|
|
"maxLeverage": 50,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 1300.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 1000000, # stake = 50000.0
|
|
|
|
|
"maxNotional": 7500000, # max_stake = 375000.0
|
|
|
|
|
"maintenanceMarginRate": 0.025,
|
|
|
|
|
"maxLeverage": 20,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 16300.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 7500000, # stake = 750000.0
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"maxNotional": 40000000, # max_stake = 4000000.0
|
|
|
|
|
"maintenanceMarginRate": 0.05,
|
|
|
|
|
"maxLeverage": 10,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 203800.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 40000000, # stake = 8000000.0
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"maxNotional": 100000000, # max_stake = 20000000.0
|
|
|
|
|
"maintenanceMarginRate": 0.1,
|
|
|
|
|
"maxLeverage": 5,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 2203800.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 100000000, # stake = 25000000.0
|
|
|
|
|
"maxNotional": 200000000, # max_stake = 50000000.0
|
|
|
|
|
"maintenanceMarginRate": 0.125,
|
|
|
|
|
"maxLeverage": 4,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 4703800.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 200000000, # stake = 66666666.666666664
|
|
|
|
|
"maxNotional": 400000000, # max_stake = 133333333.33333333
|
|
|
|
|
"maintenanceMarginRate": 0.15,
|
|
|
|
|
"maxLeverage": 3,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 9703800.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"minNotional": 400000000, # stake = 200000000.0
|
|
|
|
|
"maxNotional": 600000000, # max_stake = 300000000.0
|
|
|
|
|
"maintenanceMarginRate": 0.25,
|
|
|
|
|
"maxLeverage": 2,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 4.97038e7,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 600000000, # stake = 600000000.0
|
2022-08-26 17:34:51 +00:00
|
|
|
|
"maxNotional": 1000000000, # max_stake = 1000000000.0
|
|
|
|
|
"maintenanceMarginRate": 0.5,
|
|
|
|
|
"maxLeverage": 1,
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"maintAmt": 1.997038e8,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
],
|
2023-01-13 19:44:45 +00:00
|
|
|
|
"ZEC/USDT:USDT": [
|
2022-02-07 10:08:30 +00:00
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 0,
|
|
|
|
|
"maxNotional": 50000,
|
|
|
|
|
"maintenanceMarginRate": 0.01,
|
|
|
|
|
"maxLeverage": 50,
|
|
|
|
|
"maintAmt": 0.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 50000,
|
|
|
|
|
"maxNotional": 150000,
|
|
|
|
|
"maintenanceMarginRate": 0.025,
|
|
|
|
|
"maxLeverage": 20,
|
|
|
|
|
"maintAmt": 750.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 150000,
|
|
|
|
|
"maxNotional": 250000,
|
|
|
|
|
"maintenanceMarginRate": 0.05,
|
|
|
|
|
"maxLeverage": 10,
|
|
|
|
|
"maintAmt": 4500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 250000,
|
|
|
|
|
"maxNotional": 500000,
|
|
|
|
|
"maintenanceMarginRate": 0.1,
|
|
|
|
|
"maxLeverage": 5,
|
|
|
|
|
"maintAmt": 17000.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 500000,
|
|
|
|
|
"maxNotional": 1000000,
|
|
|
|
|
"maintenanceMarginRate": 0.125,
|
|
|
|
|
"maxLeverage": 4,
|
|
|
|
|
"maintAmt": 29500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 1000000,
|
|
|
|
|
"maxNotional": 2000000,
|
|
|
|
|
"maintenanceMarginRate": 0.25,
|
|
|
|
|
"maxLeverage": 2,
|
|
|
|
|
"maintAmt": 154500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
2024-05-12 13:35:47 +00:00
|
|
|
|
"minNotional": 2000000,
|
|
|
|
|
"maxNotional": 30000000,
|
|
|
|
|
"maintenanceMarginRate": 0.5,
|
|
|
|
|
"maxLeverage": 1,
|
|
|
|
|
"maintAmt": 654500.0,
|
2022-02-07 10:08:30 +00:00
|
|
|
|
},
|
2024-05-12 13:35:47 +00:00
|
|
|
|
],
|
2022-02-07 10:08:30 +00:00
|
|
|
|
}
|