from datetime import UTC, datetime
import pytest
from freqtrade.configuration import TimeRange
from freqtrade.exceptions import OperationalException
def test_parse_timerange_incorrect():
timerange = TimeRange.parse_timerange("")
assert timerange == TimeRange(None, None, 0, 0)
timerange = TimeRange.parse_timerange("20100522-")
assert TimeRange("date", None, 1274486400, 0) == timerange
assert timerange.timerange_str == "20100522-"
timerange = TimeRange.parse_timerange("-20100522")
assert TimeRange(None, "date", 0, 1274486400) == timerange
assert timerange.timerange_str == "-20100522"
timerange = TimeRange.parse_timerange("20100522-20150730")
assert timerange == TimeRange("date", "date", 1274486400, 1438214400)
assert timerange.timerange_str == "20100522-20150730"
assert timerange.start_fmt == "2010-05-22 00:00:00"
assert timerange.stop_fmt == "2015-07-30 00:00:00"
assert TimeRange("date", None, 1231006505, 0) == TimeRange.parse_timerange("1231006505-")
assert TimeRange(None, "date", 0, 1233360000) == TimeRange.parse_timerange("-1233360000")
timerange = TimeRange.parse_timerange("1231006505-1233360000")
assert TimeRange("date", "date", 1231006505, 1233360000) == timerange
assert isinstance(timerange.startdt, datetime)
assert isinstance(timerange.stopdt, datetime)
assert timerange.startdt == datetime.fromtimestamp(1231006505, tz=UTC)
assert timerange.stopdt == datetime.fromtimestamp(1233360000, tz=UTC)
assert timerange.timerange_str == "20090103T181505-20090131"
timerange = TimeRange.parse_timerange("1231006505000-1233360000000")
assert TimeRange("date", "date", 1231006505, 1233360000) == timerange
timerange = TimeRange.parse_timerange("1231006505000-")
assert TimeRange("date", None, 1231006505, 0) == timerange
timerange = TimeRange.parse_timerange("-1231006505000")
assert TimeRange(None, "date", 0, 1231006505) == timerange
with pytest.raises(OperationalException, match=r"Incorrect syntax.*"):
TimeRange.parse_timerange("-")
with pytest.raises(
OperationalException, match=r"Start date is after stop date for timerange.*"
):
TimeRange.parse_timerange("20100523-20100522")
def test_parse_timerange_minutes():
timerange = TimeRange.parse_timerange("20100522T1030-")
assert TimeRange("date", None, 1274524200, 0) == timerange
assert timerange.timerange_str == "20100522T1030-"
assert timerange.start_fmt == "2010-05-22 10:30:00"
timerange = TimeRange.parse_timerange("-20100522T1030")
assert TimeRange(None, "date", 0, 1274524200) == timerange
assert timerange.timerange_str == "-20100522T1030"
timerange = TimeRange.parse_timerange("20100522T1030-20150730T2359")
assert TimeRange("date", "date", 1274524200, 1438300740) == timerange
assert timerange.timerange_str == "20100522T1030-20150730T2359"
timerange = TimeRange.parse_timerange("20100522T103045-20150730T235901")
assert TimeRange("date", "date", 1274524245, 1438300741) == timerange
assert timerange.timerange_str == "20100522T103045-20150730T235901"
timerange = TimeRange.parse_timerange("20100522T0000-20150730T0000")
assert TimeRange("date", "date", 1274486400, 1438214400) == timerange
assert timerange.timerange_str == "20100522-20150730"
with pytest.raises(
OperationalException, match=r"Start date is after stop date for timerange.*"
):
TimeRange.parse_timerange("20100522T1030-20100522T1029")
@pytest.mark.parametrize(
"timerange,expected,expected_str",
[
(
"20100522-20100523T1030",
TimeRange("date", "date", 1274486400, 1274610600),
"20100522-20100523T1030",
),
(
"20100522T1030-20100523",
TimeRange("date", "date", 1274524200, 1274572800),
"20100522T1030-20100523",
),
(
"1274524200-20100523T1030",
TimeRange("date", "date", 1274524200, 1274610600),
"20100522T1030-20100523T1030",
),
(
"20100522T1030-1274610600000",
TimeRange("date", "date", 1274524200, 1274610600),
"20100522T1030-20100523T1030",
),
(
"20100522T1030-",
TimeRange("date", None, 1274524200, 0),
"20100522T1030-",
),
(
"-20100522T103002",
TimeRange(None, "date", 0, 1274524202),
"-20100522T103002",
),
(
"20100522-",
TimeRange("date", None, 1274486400, 0),
"20100522-",
),
(
"-20100522",
TimeRange(None, "date", 0, 1274486400),
"-20100522",
),
(
"",
TimeRange(None, None, 0, 0),
"-",
),
],
)
def test_parse_timerange_mixed_formats(timerange, expected, expected_str):
tr = TimeRange.parse_timerange(timerange)
assert tr == expected
assert tr.timerange_str == expected_str
@pytest.mark.parametrize(
"timerange",
[
"-",
"20100522",
"20100522-20100523-20100524",
"20100522t1030-",
"20100522T103-",
"20100522T10300-",
"20100522T1060-",
"20100522T2530-",
"20100532T1030-",
"20100522 1030-",
"20100522T10:30-",
],
)
def test_parse_timerange_invalid(timerange):
with pytest.raises(OperationalException, match=r"Incorrect syntax for timerange.*"):
TimeRange.parse_timerange(timerange)
def test_subtract_start():
x = TimeRange("date", "date", 1274486400, 1438214400)
x.subtract_start(300)
assert x.startts == 1274486400 - 300
x = TimeRange(None, "date", 0, 1438214400)
x.subtract_start(300)
assert not x.startts
assert not x.startdt
x = TimeRange("date", None, 1274486400, 0)
x.subtract_start(300)
assert x.startts == 1274486400 - 300
def test_TimeRange_copy():
x = TimeRange("date", "date", 1274486400, 1438214400)
y = x.copy()
assert y == x
assert y is not x
assert isinstance(y, TimeRange)
y.subtract_start(300)
assert y.startts == 1274486400 - 300
assert x.startts == 1274486400
assert y != x
x = TimeRange(None, "date", 0, 1438214400)
y = x.copy()
assert y.starttype is None
assert y.stoptype == "date"
assert y.startts == 0
assert y.stopts == 1438214400
def test_adjust_start_if_necessary():
min_date = datetime(2017, 11, 14, 21, 15, 00, tzinfo=UTC)
x = TimeRange("date", "date", 1510694100, 1510780500)
x.adjust_start_if_necessary(300, 20, min_date)
assert x.startts == 1510694100 + (20 * 300)
x = TimeRange("date", "date", 1510700100, 1510780500)
x.adjust_start_if_necessary(300, 20, min_date)
assert x.startts == 1510694100 + (20 * 300)
x = TimeRange(None, "date", 0, 1510780500)
x.adjust_start_if_necessary(300, 20, min_date)
assert x.startts == 1510694100 + (20 * 300)