mirror of
https://github.com/freqtrade/freqtrade.git
synced 2026-02-26 14:21:12 +00:00
Align test directory with working directory
This commit is contained in:
65
tests/util/test_binance_mig.py
Normal file
65
tests/util/test_binance_mig.py
Normal file
@@ -0,0 +1,65 @@
|
||||
import shutil
|
||||
|
||||
import pytest
|
||||
|
||||
from freqtrade.persistence import Trade
|
||||
from freqtrade.util.migrations import migrate_binance_futures_data, migrate_data
|
||||
from freqtrade.util.migrations.binance_mig import migrate_binance_futures_names
|
||||
from tests.conftest import create_mock_trades_usdt, log_has
|
||||
|
||||
|
||||
def test_binance_mig_data_conversion(default_conf_usdt, tmp_path, testdatadir):
|
||||
# call doing nothing (spot mode)
|
||||
migrate_binance_futures_data(default_conf_usdt)
|
||||
default_conf_usdt["trading_mode"] = "futures"
|
||||
pair_old = "XRP_USDT"
|
||||
pair_unified = "XRP_USDT_USDT"
|
||||
futures_src = testdatadir / "futures"
|
||||
futures_dst = tmp_path / "futures"
|
||||
futures_dst.mkdir()
|
||||
files = [
|
||||
"-1h-mark.feather",
|
||||
"-1h-futures.feather",
|
||||
"-8h-funding_rate.feather",
|
||||
"-8h-mark.feather",
|
||||
]
|
||||
|
||||
# Copy files to tmpdir and rename to old naming
|
||||
for file in files:
|
||||
fn_after = futures_dst / f"{pair_old}{file}"
|
||||
shutil.copy(futures_src / f"{pair_unified}{file}", fn_after)
|
||||
|
||||
default_conf_usdt["datadir"] = tmp_path
|
||||
# Migrate files to unified namings
|
||||
migrate_binance_futures_data(default_conf_usdt)
|
||||
|
||||
for file in files:
|
||||
fn_after = futures_dst / f"{pair_unified}{file}"
|
||||
assert fn_after.exists()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
def test_binance_mig_db_conversion(default_conf_usdt, fee, caplog):
|
||||
# Does nothing in spot mode
|
||||
migrate_binance_futures_names(default_conf_usdt)
|
||||
|
||||
create_mock_trades_usdt(fee, None)
|
||||
|
||||
for t in Trade.get_trades():
|
||||
t.trading_mode = "FUTURES"
|
||||
t.exchange = "binance"
|
||||
Trade.commit()
|
||||
|
||||
default_conf_usdt["trading_mode"] = "futures"
|
||||
migrate_binance_futures_names(default_conf_usdt)
|
||||
assert log_has("Migrating binance futures pairs in database.", caplog)
|
||||
|
||||
|
||||
def test_migration_wrapper(default_conf_usdt, mocker):
|
||||
default_conf_usdt["trading_mode"] = "futures"
|
||||
binmock = mocker.patch("freqtrade.util.migrations.migrate_binance_futures_data")
|
||||
funding_mock = mocker.patch("freqtrade.util.migrations.migrate_funding_fee_timeframe")
|
||||
migrate_data(default_conf_usdt)
|
||||
|
||||
assert binmock.call_count == 1
|
||||
assert funding_mock.call_count == 1
|
||||
82
tests/util/test_ccxt_precise.py
Normal file
82
tests/util/test_ccxt_precise.py
Normal file
@@ -0,0 +1,82 @@
|
||||
from freqtrade.util import FtPrecise
|
||||
|
||||
|
||||
ws = FtPrecise("-1.123e-6")
|
||||
ws = FtPrecise("-1.123e-6")
|
||||
xs = FtPrecise("0.00000002")
|
||||
ys = FtPrecise("69696900000")
|
||||
zs = FtPrecise("0")
|
||||
|
||||
|
||||
def test_FtPrecise():
|
||||
assert ys * xs == "1393.938"
|
||||
assert xs * ys == "1393.938"
|
||||
|
||||
assert ys + xs == "69696900000.00000002"
|
||||
assert xs + ys == "69696900000.00000002"
|
||||
assert xs - ys == "-69696899999.99999998"
|
||||
assert ys - xs == "69696899999.99999998"
|
||||
assert xs / ys == "0"
|
||||
assert ys / xs == "3484845000000000000"
|
||||
|
||||
assert ws * xs == "-0.00000000000002246"
|
||||
assert xs * ws == "-0.00000000000002246"
|
||||
|
||||
assert ws + xs == "-0.000001103"
|
||||
assert xs + ws == "-0.000001103"
|
||||
|
||||
assert xs - ws == "0.000001143"
|
||||
assert ws - xs == "-0.000001143"
|
||||
|
||||
assert xs / ws == "-0.017809439002671415"
|
||||
assert ws / xs == "-56.15"
|
||||
|
||||
assert zs * ws == "0"
|
||||
assert zs * xs == "0"
|
||||
assert zs * ys == "0"
|
||||
assert ws * zs == "0"
|
||||
assert xs * zs == "0"
|
||||
assert ys * zs == "0"
|
||||
|
||||
assert zs + ws == "-0.000001123"
|
||||
assert zs + xs == "0.00000002"
|
||||
assert zs + ys == "69696900000"
|
||||
assert ws + zs == "-0.000001123"
|
||||
assert xs + zs == "0.00000002"
|
||||
assert ys + zs == "69696900000"
|
||||
|
||||
assert abs(FtPrecise("-500.1")) == "500.1"
|
||||
assert abs(FtPrecise("213")) == "213"
|
||||
|
||||
assert abs(FtPrecise("-500.1")) == "500.1"
|
||||
assert -FtPrecise("213") == "-213"
|
||||
|
||||
assert FtPrecise("10.1") % FtPrecise("0.5") == "0.1"
|
||||
assert FtPrecise("5550") % FtPrecise("120") == "30"
|
||||
|
||||
assert FtPrecise("-0.0") == FtPrecise("0")
|
||||
assert FtPrecise("5.534000") == FtPrecise("5.5340")
|
||||
|
||||
assert min(FtPrecise("-3.1415"), FtPrecise("-2")) == "-3.1415"
|
||||
|
||||
assert max(FtPrecise("3.1415"), FtPrecise("-2")) == "3.1415"
|
||||
|
||||
assert FtPrecise("2") > FtPrecise("1.2345")
|
||||
assert not FtPrecise("-3.1415") > FtPrecise("-2")
|
||||
assert not FtPrecise("3.1415") > FtPrecise("3.1415")
|
||||
assert FtPrecise.string_gt("3.14150000000000000000001", "3.1415")
|
||||
|
||||
assert FtPrecise("3.1415") >= FtPrecise("3.1415")
|
||||
assert FtPrecise("3.14150000000000000000001") >= FtPrecise("3.1415")
|
||||
|
||||
assert not FtPrecise("3.1415") < FtPrecise("3.1415")
|
||||
|
||||
assert FtPrecise("3.1415") <= FtPrecise("3.1415")
|
||||
assert FtPrecise("3.1415") <= FtPrecise("3.14150000000000000000001")
|
||||
|
||||
assert FtPrecise(213) == "213"
|
||||
assert FtPrecise(-213) == "-213"
|
||||
assert str(FtPrecise(-213)) == "-213"
|
||||
assert FtPrecise(213.2) == "213.2"
|
||||
assert float(FtPrecise(213.2)) == 213.2
|
||||
assert float(FtPrecise(-213.2)) == -213.2
|
||||
113
tests/util/test_datetime_helpers.py
Normal file
113
tests/util/test_datetime_helpers.py
Normal file
@@ -0,0 +1,113 @@
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
import pytest
|
||||
import time_machine
|
||||
|
||||
from freqtrade.util import (
|
||||
dt_floor_day,
|
||||
dt_from_ts,
|
||||
dt_now,
|
||||
dt_ts,
|
||||
dt_ts_def,
|
||||
dt_ts_none,
|
||||
dt_utc,
|
||||
format_date,
|
||||
format_ms_time,
|
||||
shorten_date,
|
||||
)
|
||||
from freqtrade.util.datetime_helpers import dt_humanize_delta
|
||||
|
||||
|
||||
def test_dt_now():
|
||||
with time_machine.travel("2021-09-01 05:01:00 +00:00", tick=False) as t:
|
||||
now = datetime.now(timezone.utc)
|
||||
assert dt_now() == now
|
||||
assert dt_ts() == int(now.timestamp() * 1000)
|
||||
assert dt_ts(now) == int(now.timestamp() * 1000)
|
||||
|
||||
t.shift(timedelta(hours=5))
|
||||
assert dt_now() >= now
|
||||
assert dt_now() == datetime.now(timezone.utc)
|
||||
assert dt_ts() == int(dt_now().timestamp() * 1000)
|
||||
# Test with different time than now
|
||||
assert dt_ts(now) == int(now.timestamp() * 1000)
|
||||
|
||||
|
||||
def test_dt_ts_def():
|
||||
assert dt_ts_def(None) == 0
|
||||
assert dt_ts_def(None, 123) == 123
|
||||
assert dt_ts_def(datetime(2023, 5, 5, tzinfo=timezone.utc)) == 1683244800000
|
||||
assert dt_ts_def(datetime(2023, 5, 5, tzinfo=timezone.utc), 123) == 1683244800000
|
||||
|
||||
|
||||
def test_dt_ts_none():
|
||||
assert dt_ts_none(None) is None
|
||||
assert dt_ts_none(None) is None
|
||||
assert dt_ts_none(datetime(2023, 5, 5, tzinfo=timezone.utc)) == 1683244800000
|
||||
assert dt_ts_none(datetime(2023, 5, 5, tzinfo=timezone.utc)) == 1683244800000
|
||||
|
||||
|
||||
def test_dt_utc():
|
||||
assert dt_utc(2023, 5, 5) == datetime(2023, 5, 5, tzinfo=timezone.utc)
|
||||
assert dt_utc(2023, 5, 5, 0, 0, 0, 555500) == datetime(
|
||||
2023, 5, 5, 0, 0, 0, 555500, tzinfo=timezone.utc
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("as_ms", [True, False])
|
||||
def test_dt_from_ts(as_ms):
|
||||
multi = 1000 if as_ms else 1
|
||||
assert dt_from_ts(1683244800.0 * multi) == datetime(2023, 5, 5, tzinfo=timezone.utc)
|
||||
assert dt_from_ts(1683244800.5555 * multi) == datetime(
|
||||
2023, 5, 5, 0, 0, 0, 555500, tzinfo=timezone.utc
|
||||
)
|
||||
# As int
|
||||
assert dt_from_ts(1683244800 * multi) == datetime(2023, 5, 5, tzinfo=timezone.utc)
|
||||
# As milliseconds
|
||||
assert dt_from_ts(1683244800 * multi) == datetime(2023, 5, 5, tzinfo=timezone.utc)
|
||||
assert dt_from_ts(1683242400 * multi) == datetime(2023, 5, 4, 23, 20, tzinfo=timezone.utc)
|
||||
|
||||
|
||||
def test_dt_floor_day():
|
||||
now = datetime(2023, 9, 1, 5, 2, 3, 455555, tzinfo=timezone.utc)
|
||||
|
||||
assert dt_floor_day(now) == datetime(2023, 9, 1, tzinfo=timezone.utc)
|
||||
|
||||
|
||||
def test_shorten_date() -> None:
|
||||
str_data = "1 day, 2 hours, 3 minutes, 4 seconds ago"
|
||||
str_shorten_data = "1 d, 2 h, 3 min, 4 sec ago"
|
||||
assert shorten_date(str_data) == str_shorten_data
|
||||
|
||||
|
||||
def test_dt_humanize() -> None:
|
||||
assert dt_humanize_delta(dt_now()) == "now"
|
||||
assert dt_humanize_delta(dt_now() - timedelta(minutes=50)) == "50 minutes ago"
|
||||
assert dt_humanize_delta(dt_now() - timedelta(hours=16)) == "16 hours ago"
|
||||
assert dt_humanize_delta(dt_now() - timedelta(hours=16, minutes=30)) == "16 hours ago"
|
||||
assert dt_humanize_delta(dt_now() - timedelta(days=16, hours=10, minutes=25)) == "16 days ago"
|
||||
assert dt_humanize_delta(dt_now() - timedelta(minutes=50)) == "50 minutes ago"
|
||||
|
||||
|
||||
def test_format_ms_time() -> None:
|
||||
# Date 2018-04-10 18:02:01
|
||||
date_in_epoch_ms = 1523383321000
|
||||
date = format_ms_time(date_in_epoch_ms)
|
||||
assert isinstance(date, str)
|
||||
res = datetime(2018, 4, 10, 18, 2, 1, tzinfo=timezone.utc)
|
||||
assert date == res.strftime("%Y-%m-%dT%H:%M:%S")
|
||||
assert date == "2018-04-10T18:02:01"
|
||||
res = datetime(2017, 12, 13, 8, 2, 1, tzinfo=timezone.utc)
|
||||
# Date 2017-12-13 08:02:01
|
||||
date_in_epoch_ms = 1513152121000
|
||||
assert format_ms_time(date_in_epoch_ms) == res.strftime("%Y-%m-%dT%H:%M:%S")
|
||||
|
||||
|
||||
def test_format_date() -> None:
|
||||
date = datetime(2023, 9, 1, 5, 2, 3, 455555, tzinfo=timezone.utc)
|
||||
assert format_date(date) == "2023-09-01 05:02:03"
|
||||
assert format_date(None) == ""
|
||||
|
||||
date = datetime(2021, 9, 30, 22, 59, 3, 455555, tzinfo=timezone.utc)
|
||||
assert format_date(date) == "2021-09-30 22:59:03"
|
||||
assert format_date(None) == ""
|
||||
36
tests/util/test_formatters.py
Normal file
36
tests/util/test_formatters.py
Normal file
@@ -0,0 +1,36 @@
|
||||
from freqtrade.util import decimals_per_coin, fmt_coin, round_value
|
||||
|
||||
|
||||
def test_decimals_per_coin():
|
||||
assert decimals_per_coin("USDT") == 3
|
||||
assert decimals_per_coin("EUR") == 3
|
||||
assert decimals_per_coin("BTC") == 8
|
||||
assert decimals_per_coin("ETH") == 5
|
||||
|
||||
|
||||
def test_fmt_coin():
|
||||
assert fmt_coin(222.222222, "USDT") == "222.222 USDT"
|
||||
assert fmt_coin(222.2, "USDT", keep_trailing_zeros=True) == "222.200 USDT"
|
||||
assert fmt_coin(222.2, "USDT") == "222.2 USDT"
|
||||
assert fmt_coin(222.12745, "EUR") == "222.127 EUR"
|
||||
assert fmt_coin(0.1274512123, "BTC") == "0.12745121 BTC"
|
||||
assert fmt_coin(0.1274512123, "ETH") == "0.12745 ETH"
|
||||
|
||||
assert fmt_coin(222.222222, "USDT", False) == "222.222"
|
||||
assert fmt_coin(222.2, "USDT", False) == "222.2"
|
||||
assert fmt_coin(222.00, "USDT", False) == "222"
|
||||
assert fmt_coin(222.12745, "EUR", False) == "222.127"
|
||||
assert fmt_coin(0.1274512123, "BTC", False) == "0.12745121"
|
||||
assert fmt_coin(0.1274512123, "ETH", False) == "0.12745"
|
||||
assert fmt_coin(222.2, "USDT", False, True) == "222.200"
|
||||
|
||||
|
||||
def test_round_value():
|
||||
assert round_value(222.222222, 3) == "222.222"
|
||||
assert round_value(222.2, 3) == "222.2"
|
||||
assert round_value(222.00, 3) == "222"
|
||||
assert round_value(222.12745, 3) == "222.127"
|
||||
assert round_value(0.1274512123, 8) == "0.12745121"
|
||||
assert round_value(0.1274512123, 5) == "0.12745"
|
||||
assert round_value(222.2, 3, True) == "222.200"
|
||||
assert round_value(222.2, 0, True) == "222"
|
||||
28
tests/util/test_funding_rate_migration.py
Normal file
28
tests/util/test_funding_rate_migration.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from shutil import copytree
|
||||
|
||||
from freqtrade.util.migrations import migrate_funding_fee_timeframe
|
||||
|
||||
|
||||
def test_migrate_funding_rate_timeframe(default_conf_usdt, tmp_path, testdatadir):
|
||||
copytree(testdatadir / "futures", tmp_path / "futures")
|
||||
file_4h = tmp_path / "futures" / "XRP_USDT_USDT-4h-funding_rate.feather"
|
||||
file_8h = tmp_path / "futures" / "XRP_USDT_USDT-8h-funding_rate.feather"
|
||||
file_1h = tmp_path / "futures" / "XRP_USDT_USDT-1h-futures.feather"
|
||||
file_8h.rename(file_4h)
|
||||
assert file_1h.exists()
|
||||
assert file_4h.exists()
|
||||
assert not file_8h.exists()
|
||||
|
||||
default_conf_usdt["datadir"] = tmp_path
|
||||
|
||||
# Inactive on spot trading ...
|
||||
migrate_funding_fee_timeframe(default_conf_usdt, None)
|
||||
|
||||
default_conf_usdt["trading_mode"] = "futures"
|
||||
|
||||
migrate_funding_fee_timeframe(default_conf_usdt, None)
|
||||
|
||||
assert not file_4h.exists()
|
||||
assert file_8h.exists()
|
||||
# futures files is untouched.
|
||||
assert file_1h.exists()
|
||||
32
tests/util/test_measure_time.py
Normal file
32
tests/util/test_measure_time.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import time_machine
|
||||
|
||||
from freqtrade.util import MeasureTime
|
||||
|
||||
|
||||
def test_measure_time():
|
||||
callback = MagicMock()
|
||||
with time_machine.travel("2021-09-01 05:00:00 +00:00", tick=False) as t:
|
||||
measure = MeasureTime(callback, 5, ttl=60)
|
||||
with measure:
|
||||
pass
|
||||
|
||||
assert callback.call_count == 0
|
||||
|
||||
with measure:
|
||||
t.shift(10)
|
||||
|
||||
assert callback.call_count == 1
|
||||
callback.reset_mock()
|
||||
with measure:
|
||||
t.shift(10)
|
||||
assert callback.call_count == 0
|
||||
|
||||
callback.reset_mock()
|
||||
# Shift past the ttl
|
||||
t.shift(45)
|
||||
|
||||
with measure:
|
||||
t.shift(10)
|
||||
assert callback.call_count == 1
|
||||
32
tests/util/test_periodiccache.py
Normal file
32
tests/util/test_periodiccache.py
Normal file
@@ -0,0 +1,32 @@
|
||||
import time_machine
|
||||
|
||||
from freqtrade.util import PeriodicCache
|
||||
|
||||
|
||||
def test_ttl_cache():
|
||||
with time_machine.travel("2021-09-01 05:00:00 +00:00", tick=False) as t:
|
||||
cache = PeriodicCache(5, ttl=60)
|
||||
cache1h = PeriodicCache(5, ttl=3600)
|
||||
|
||||
assert cache.timer() == 1630472400.0
|
||||
cache["a"] = 1235
|
||||
cache1h["a"] = 555123
|
||||
assert "a" in cache
|
||||
assert "a" in cache1h
|
||||
|
||||
t.move_to("2021-09-01 05:00:59 +00:00")
|
||||
assert "a" in cache
|
||||
assert "a" in cache1h
|
||||
|
||||
# Cache expired
|
||||
t.move_to("2021-09-01 05:01:00 +00:00")
|
||||
assert "a" not in cache
|
||||
assert "a" in cache1h
|
||||
|
||||
t.move_to("2021-09-01 05:59:59 +00:00")
|
||||
assert "a" not in cache
|
||||
assert "a" in cache1h
|
||||
|
||||
t.move_to("2021-09-01 06:00:00 +00:00")
|
||||
assert "a" not in cache
|
||||
assert "a" not in cache1h
|
||||
20
tests/util/test_rendering_utils.py
Normal file
20
tests/util/test_rendering_utils.py
Normal file
@@ -0,0 +1,20 @@
|
||||
import pytest
|
||||
|
||||
from freqtrade.util import render_template, render_template_with_fallback
|
||||
|
||||
|
||||
def test_render_template_fallback():
|
||||
from jinja2.exceptions import TemplateNotFound
|
||||
|
||||
with pytest.raises(TemplateNotFound):
|
||||
val = render_template(
|
||||
templatefile="subtemplates/indicators_does-not-exist.j2",
|
||||
arguments={},
|
||||
)
|
||||
|
||||
val = render_template_with_fallback(
|
||||
templatefile="strategy_subtemplates/indicators_does-not-exist.j2",
|
||||
templatefallbackfile="strategy_subtemplates/indicators_minimal.j2",
|
||||
)
|
||||
assert isinstance(val, str)
|
||||
assert "if self.dp" in val
|
||||
Reference in New Issue
Block a user