Skip to content

BackTester

Reference information for the BackTester class.

anterior.warp.backtester.BackTester

BackTester(workers=1, **kwargs)

now

now()

Returns the timezone-aware datetime of the backtester.

RETURNS DESCRIPTION
datetime

The timezone-aware datetime of the backtester.

Notes
  • The datetime is timezone-aware and is in the timezone specified by the backtester's timezone attribute.
  • The datetime is the simulated time in the backtest if the backtester is being backtested.
  • The datetime is the current system time if the backtester is running in live mode.

on_start

on_start()

Gets called when the backtester starts.

Tip
  • Override this method to add custom behavior when the backtester starts.

on_stop

on_stop()

Gets called when the backtester stops.

Tip
  • Override this method to add custom behavior when the backtester stops.

do

do(function, name=None, log=True)

Schedules a function to run immediately during the backtester's run.

PARAMETER DESCRIPTION
function

The function to schedule.

TYPE: Callable

name

The name of the function to schedule. Defaults to the function"s name.

TYPE: str DEFAULT: None

log

Whether to log the function to the backtester's logs. Defaults to True.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
Job

The job object running the specified function.

See Also
  • Schedule.do Defines the function to run on the schedule object.

Examples:

Running a function immediately
bt = BackTester(name="do_example")

def function():
    print("Hello, world!")

bt.do(function)
bt.run()   # prints "Hello, world!" as soon as the backtester starts

after

after(delta=None, days=0, hours=0, minutes=0, seconds=0)

Creates a Schedule object that will trigger after the specified time interval.

PARAMETER DESCRIPTION
delta

The time interval to trigger after. Mutually exclusive with days, hours, minutes, and seconds.

TYPE: timedelta DEFAULT: None

days

The number of days to trigger after. Mutually exclusive with delta.

TYPE: int DEFAULT: 0

hours

The number of hours to trigger after. Mutually exclusive with delta.

TYPE: int DEFAULT: 0

minutes

The number of minutes to trigger after. Mutually exclusive with delta.

TYPE: int DEFAULT: 0

seconds

The number of seconds to trigger after. Mutually exclusive with delta.

TYPE: int DEFAULT: 0

RETURNS DESCRIPTION
Schedule

Schedule object that will trigger after the specified time interval.

RAISES DESCRIPTION
ValueError

If both a timedelta and individual time intervals are provided.

See Also
  • do_after Decorator to schedule a function to run after a time interval.
Info

The time interval can be specified either as a timedelta or as individual time intervals. For example, the following two calls are equivalent:

bt.after(datetime.timedelta(days=2)).do(...)
bt.after(days=2).do(...)

Examples:

Running a function after a time interval
bt = BackTester(name="after_example")

bt.after(days=2).do(...)
bt.after(hours=12).do(...)
bt.after(datetime.timedelta(minutes=30)).do(...)

between

between(years=None, months=None, days=None, weeks=None, days_of_week=None, hours=None, minutes=None, seconds=None, dates=None)

Creates a Schedule object that runs a function between a specified time range.

PARAMETER DESCRIPTION
years

The years to trigger between. Start and end values must represent integers.

TYPE: str | tuple[int, int] DEFAULT: None

months

The months to trigger between. Start and end values must represent integers between 1 and 12.

TYPE: Optional[str | tuple[int, int]] DEFAULT: None

days

The days to trigger between. Start and end values must represent integers between 1 and 31.

TYPE: str | tuple[int, int] DEFAULT: None

weeks

The weeks to trigger between. Start and end values must represent integers between 1 and 53.

TYPE: str | tuple[int, int] DEFAULT: None

days_of_week

The days of the week to trigger between. Start and end values must represent integers between 0 and 6, or one of the following strings: "mon", "tue", "wed", "thu", "fri", "sat", "sun".

TYPE: str | tuple[int, int] DEFAULT: None

hours

The hours to trigger between. Start and end values must represent integers between 0 and 23.

TYPE: str | tuple[int, int] DEFAULT: None

minutes

The minutes to trigger between. Start and end values must represent integers between 0 and 59.

TYPE: str | tuple[int, int] DEFAULT: None

seconds

The seconds to trigger between. Start and end values must represent integers between 0 and 59.

TYPE: str | tuple[int, int] DEFAULT: None

dates

The dates to trigger between. Start and end values must be datetime objects.

TYPE: tuple[datetime, datetime] DEFAULT: None

RETURNS DESCRIPTION
Schedule

Schedule object that will trigger between the specified time intervals.

RAISES DESCRIPTION
ValueError

If the time intervals are not in the correct format.

See Also
  • do_between Decorator to schedule a function to run between a specified time range.

Examples:

Running a function between a time range with tuples
bt = BackTester(name="between_example_with_tuples")

# runs a function every weekday between January and May
bt.between(months=("jan", "may"), days_of_week=(0, 4)).do(...)

# runs a function every 15 minutes between 9 AM and 5 PM
(bt.between(hours=(9, 17)) & bt.every(minutes=15)).do(...)
Running a function between a time range with strings
bt = BackTester(name="between_example_with_strings")

# runs a function every weekday between January and May
bt.between(months="1-5", days_of_week="mon-fri").do(...)

# runs a function every 15 minutes between 9 AM and 5 PM
(bt.between(hours="9-17") & bt.every(minutes=15)).do(...)

cron

cron(expression)

Creates a Schedule object that runs a function on a cron schedule.

PARAMETER DESCRIPTION
expression

The cron expression to trigger on.

TYPE: str

RETURNS DESCRIPTION
Schedule

Schedule object that will trigger according to the specified cron expression.

See Also
  • do_cron Decorator to schedule a function to run on a cron schedule.
Info

Check out crontab.guru for more information on cron expressions.

Examples:

Running functions with cron expressions
bt = BackTester(name="cron_example")

bt.cron("* */5 * 0 0 0").do(...)   # runs a function every 5 minutes
bt.cron("0 0 1 1 0 0").do(...)     # runs a function every January 1st

on

on(dt=None, year=None, month=None, day=None, weekday=None, day_of_week=None, hour=None, minute=None, second=None)

Creates a Schedule object that will trigger on a specific date or datetime.

PARAMETER DESCRIPTION
dt

The datetime to trigger on. Mutually exclusive with year, month, day, weekday, day_of_week, hour, minute, and second. Must be a string in the format "YYYY-MM-DD HH:MM:SS", a datetime object, or a date object.

TYPE: str | datetime | date DEFAULT: None

year

The year to trigger on. Mutually exclusive with dt.

TYPE: int DEFAULT: None

month

The month to trigger on. Mutually exclusive with dt.

TYPE: int DEFAULT: None

day

The day to trigger on. Mutually exclusive with dt.

TYPE: int DEFAULT: None

weekday

The weekday to trigger on. Mutually exclusive with dt.

TYPE: int DEFAULT: None

day_of_week

The day of the week to trigger on. Mutually exclusive with dt.

TYPE: int DEFAULT: None

hour

The hour to trigger on. Mutually exclusive with dt.

TYPE: int DEFAULT: None

minute

The minute to trigger on. Mutually exclusive with dt.

TYPE: int DEFAULT: None

second

The second to trigger on. Mutually exclusive with dt.

TYPE: int DEFAULT: None

RETURNS DESCRIPTION
Schedule

Schedule object that will trigger on the specified date and time.

RAISES DESCRIPTION
ValueError

If both a dt and individual date components are provided.

See Also
  • do_on Decorator to schedule a function to run on a specific date or datetime.
Example
import datetime

bt = BackTester(name="on_example")

# both schedules run a function on January 1st, 2023 at 10:00 AM
bt.on(dt=datetime.datetime(2023, 1, 1, 10, 0)).do(...)
bt.on(year=2023, month=1, day=1, hour=10, minute=0).do()

every

every(years=None, months=None, days=None, weeks=None, hours=None, minutes=None, seconds=None)

Creates a Schedule object that will run every x years/months/days/weeks/hours/minutes/seconds.

PARAMETER DESCRIPTION
years

The number of years to trigger every. Defaults to None.

TYPE: int DEFAULT: None

months

The number of months to trigger every. Defaults to None.

TYPE: int DEFAULT: None

days

The number of days to trigger every. Defaults to None.

TYPE: int DEFAULT: None

weeks

The number of weeks to trigger every. Defaults to None.

TYPE: int DEFAULT: None

hours

The number of hours to trigger every. Defaults to None.

TYPE: int DEFAULT: None

minutes

The number of minutes to trigger every. Defaults to None.

TYPE: int DEFAULT: None

seconds

The number of seconds to trigger every. Defaults to None.

TYPE: int DEFAULT: None

RETURNS DESCRIPTION
Schedule

Schedule object that will trigger every x years/months/days/weeks/hours/minutes/seconds.

See Also
  • do_every Decorator to schedule a function to run every x years/months/days/weeks/hours/minutes/seconds.

Examples:

Running functions periodically
bt = BackTester(name="every_example")

bt.every(days=1).do(...)       # runs a function every day
bt.every(minutes=15).do(...)   # runs a function every 15 minutes

when

when(condition)

Creates a Schedule object that will trigger when the specified condition function returns True.

PARAMETER DESCRIPTION
condition

The condition function to trigger on. Must return a boolean value when called.

TYPE: Callable

RETURNS DESCRIPTION
Schedule

Schedule object that will trigger when the specified condition function returns True.

Info
  • By default, once checks the condition function every second. To override this, combine the when schedule. with an every schedule:

    (bt.when(condition) & bt.every(minutes=15)).do(...)     # checks every 15 minutes
    (bt.when(condition) & bt.after(days=2)).do(...)         # checks every 2 days
    

Examples:

Running a function when a condition is met
import random

bt = BackTester(name="when_example")

def condition():
    return random.randint(0, 1)  # returns True 50% of the time

bt.when(condition).do(lambda: print("Conditional second!"))
(bt.when(condition) & bt.every(hours=1)).do(lambda: print("Conditional hour!"))

once

once(condition_function)

Creates a Schedule object that will trigger only once when the specified condition function returns True.

PARAMETER DESCRIPTION
condition_function

The condition function to trigger on. Must return a boolean value when called.

TYPE: Callable

RETURNS DESCRIPTION
Schedule

Schedule object that will trigger only once when the specified condition function returns True.

Info
  • The difference between the once and when schedules is that the once schedule will only trigger once, and then remove itself from the scheduler. The when schedule will continue to trigger as long as the condition function returns true.

  • By default, once checks the condition function every second. To override this, combine the when schedule. with an every schedule:

(bt.once(condition) & bt.every(minutes=15)).do(...)     # checks every 15 minutes
(bt.once(condition) & bt.after(days=2)).do(...)         # checks every 2 days

Examples:

Running a function once a condition is met
import random

bt = BackTester(name="once_example")

def condition():
    # returns True 50% of the time
    return random.randint(0, 1)

bt.once(condition).do(lambda: print("Hello, condition!"))

(bt.once(condition) & bt.every(hours=1)).do(lambda: print("Hello, hourly condition!")

do_after

do_after(*args, **kwargs)

Decorator to schedule a function to run after the specified time interval. Equivalent to after schedule function.

1
2
3
4
5
6
7
8
9
from anterior.warp import BackTester

bt = BackTester()

@bt.do_after(days=2)
def update():
    print("Hello, world!")

bt.run("2020-01-01", "2024-01-01")
1
2
3
4
5
6
7
8
9
from anterior.warp import BackTester

bt = BackTester()


def update():
    print("Hello, world!")
bt.after(days=2).do(update)
bt.run("2020-01-01", "2024-01-01")
See Also
  • after: Creates a Schedule object that will trigger after the specified time interval.

do_between

do_between(*args, **kwargs)

Decorator to schedule a function to run between a specified time range. Equivalent to between schedule function.

1
2
3
4
5
6
7
8
9
from anterior.warp import BackTester

bt = BackTester()

@bt.do_between(days_of_week="mon-fri")
def update():
    print("Hello, world!")

bt.run("2020-01-01", "2024-01-01")
1
2
3
4
5
6
7
8
9
from anterior.warp import BackTester

bt = BackTester()


def update():
    print("Hello, world!")
bt.between(days_of_week="mon-fri").do(update)
bt.run("2020-01-01", "2024-01-01")
See Also
  • between: Creates a Schedule object that runs a function between a specified time range.

do_cron

do_cron(*args, **kwargs)

Decorator to schedule a function to run on a cron schedule. Equivalent to cron schedule function.

1
2
3
4
5
6
7
8
9
from anterior.warp import BackTester

bt = BackTester()

@bt.do_cron("* */5 * 0 0 0")
def update():
    print("Hello, world!")

bt.run("2020-01-01", "2024-01-01")
1
2
3
4
5
6
7
8
9
from anterior.warp import BackTester

bt = BackTester()


def update():
    print("Hello, world!")
bt.cron("* */5 * 0 0 0").do(update)
bt.run("2020-01-01", "2024-01-01")
See Also
  • cron: Creates a Schedule object that runs a function on a cron schedule.

do_on

do_on(*args, **kwargs)

Decorator to schedule a function to run on a specific date or datetime. Equivalent to on schedule function.

1
2
3
4
5
6
7
8
9
from anterior.warp import BackTester

bt = BackTester()

@bt.do_on(year=2023, month=1, day=1, hour=10, minute=0)
def update():
    print("Hello, world!")

bt.run("2020-01-01", "2024-01-01")
1
2
3
4
5
6
7
8
9
from anterior.warp import BackTester

bt = BackTester()


def update():
    print("Hello, world!")
bt.on(year=2023, month=1, day=1, hour=10, minute=0).do(update)
bt.run("2020-01-01", "2024-01-01")
See Also
  • on: Creates a Schedule object that will trigger on a specific date or datetime.

do_every

do_every(*args, **kwargs)

Decorator to schedule a function to run every x years/months/days/weeks/hours/minutes/seconds. Equivalent to every schedule function.

1
2
3
4
5
6
7
8
9
from anterior.warp import BackTester

bt = BackTester()

@bt.do_every(days=1)
def update():
    print("Hello, world!")

bt.run("2020-01-01", "2024-01-01")
1
2
3
4
5
6
7
8
9
from anterior.warp import BackTester

bt = BackTester()


def update():
    print("Hello, world!")
bt.every(days=1).do(update)
bt.run("2020-01-01", "2024-01-01")
See Also
  • every: Creates a Schedule object that will run every x years/months/days/weeks/hours/minutes/seconds.

get_scheduler

get_scheduler()

Returns the scheduler object associated with the backtester.

RETURNS DESCRIPTION
BlockingScheduler

The scheduler object associated with the backtester.

pause

pause()

Pauses the running backtester.

See Also
  • run: Runs or backtests the backtester.
  • resume: Resumes the backtester.
  • stop: Stops the running backtester.

resume

resume()

Resumes the paused backtester.

See Also
  • run: Runs or backtests the backtester.
  • pause: Pauses the running backtester.
  • stop: Stops the running backtester.

stop

stop(wait=0)

Stops the backtester.

PARAMETER DESCRIPTION
wait

The number of seconds to wait before stopping the backtester. Defaults to 0 (no wait).

TYPE: float DEFAULT: 0

See Also
  • run: Runs or backtests the backtester.
  • pause: Pauses the running backtester.
  • resume: Resumes the backtester.
Warning

We recommend specifying the wait parameter to give the backtester time to stop gracefully.

run

run(start=None, end=None, start_buffer=datetime.timedelta(), end_buffer=datetime.timedelta(), log_level=logging.INFO)

Runs the backtester from the specified start datetime to the end datetime.

PARAMETER DESCRIPTION
start

Datetime or ISO-8601 string ("YYYY-MM-DD") to start the run from (inclusive).

TYPE: datetime | date | str DEFAULT: None

end

Datetime or ISO-8601 string ("YYYY-MM-DD") to end the run at (inclusive).

TYPE: datetime | date | str DEFAULT: None

start_buffer

The data buffer to add to the start date when caching datafeeds. Defaults to 0.

TYPE: timedelta DEFAULT: timedelta()

end_buffer

The data buffer to add to the end date when caching datafeeds. Defaults to 0.

TYPE: timedelta DEFAULT: timedelta()

log_level

The logging level to use for the backtest. Defaults to logging.INFO.

TYPE: int DEFAULT: INFO

RAISES DESCRIPTION
RuntimeError

If the backtester is already running.

See Also
  • pause: Pauses the running backtester.
  • resume: Resumes the backtester.
  • stop: Stops the running backtester.

Examples:

Backtest a backtester between two past dates

Provide both the start and end dates in the past:

bt = BackTester(name="run_example_1")
...
bt.run(start="2023-01-01", end="2023-01-10")
Backtest a backtester from a past date until the present

Provide only the start date in the past:

bt = BackTester(name="run_example_2")
...
bt.run(start="2023-01-01")
Run a live backtester until a future date

Provide only the end date in the future:

bt = BackTester(name="run_example_3")
...
bt.run(end="2025-01-01")
Run a live backtester indefinitely until stopped

Leave both the start and end dates blank:

bt = BackTester(name="run_example_4")
...
bt.run()
# do something
bt.stop()
Backtest a backtester from a past date until the present, and then run live until a future date

Provide both the start and end dates where the start date is in the past and the end date is in the future:

bt = BackTester(name="run_example_5")
...
bt.run(start="2023-01-01", end="2030-01-01")