Skip to content

Epic

Epic

An Epic is a financial instrument.

Handling ticks

The main purpose of an Epic is to handle Ticks.

Basic

The following example show the minimal usage of handling a Tick.

import arrow

from estrade import Epic, Tick


def test_minimal_handle_tick():
    epic = Epic()
    tick = Tick(datetime=arrow.utcnow(), bid=99, ask=101)

    epic.on_new_tick(tick)

    assert epic.last_tick == tick

Note

See TickProvider to wrap the call of Epic.on_new_tick onto your data source.

Tick timezone conversion

Upon receiving a new Tick, an Epic convert the Tick datetime to its timezone.

import arrow

from estrade import Epic, Tick


def test_tick_timezone_comversion():
    # GIVEN an epic timezoned on London
    epic = Epic(timezone="Europe/London")

    # WHEN I add a tick to this epic in UTC
    tick = Tick(
        datetime=arrow.get("2020-01-01 12:34:56").replace(tzinfo="US/Pacific"),
        bid=100,
        ask=101,
    )
    epic.on_new_tick(tick)

    # THEN the tick date was converted from US/Pacific to the Epic timezone (GMT)
    assert tick.datetime.format("YYYY-MM-DD HH:mm:ss ZZZ") == "2020-01-01 20:34:56 GMT"

Epic Open periods

Upon initialization, you can set Epic open periods.

Impacts on Epic.market_open attribute

When the last Tick received by an Epic (epic.last_tick) is :

  • inside one of its open periods, the epic.market_open is True
  • out of its open periods, then the epic.market_open is False.

Usage examples

Open/close times
from datetime import time

import arrow

from estrade import Epic, Tick


def test_open_periods():
    epic = Epic(
        ref="MY_EPIC_REF",
        open_time=time(8, 30),
        close_time=time(17, 0),
    )

    # WHEN a tick is received before the opening time
    tick = Tick(datetime=arrow.get("2020-01-01 07:30:00"), bid=99, ask=100)
    epic.on_new_tick(tick)

    # THEN the epic is not open
    assert epic.market_open is False

    # WHEN a tick is received inside the opening time
    tick = Tick(datetime=arrow.get("2020-01-01 12:30:00"), bid=99, ask=100)
    epic.on_new_tick(tick)

    # THEN the epic is open
    assert epic.market_open is True

    # WHEN a tick is received after the opening time
    tick = Tick(datetime=arrow.get("2020-01-01 19:30:00"), bid=99, ask=100)
    epic.on_new_tick(tick)

    # THEN the epic is not open
    assert epic.market_open is False
Trade days

You can set that only some weekdays are available for trading.

import arrow

from estrade import Epic, Tick


def test_open_periods():
    # WHEN I create an epic tradeable only on Tuesday and Thursday
    epic = Epic(ref="MY_EPIC_REF", trade_days=[1, 3])

    # WHEN a tick is received on Monday
    fmt = r"ddd[\s+]DD[\s+]MMM[\s+]YYYY[\s+]HH:mm:ss"
    tick = Tick(datetime=arrow.get("Mon 13 Jan 2020 12:00:00", fmt), bid=99, ask=100)
    epic.on_new_tick(tick)

    # THEN the epic is not open
    assert epic.market_open is False

    # WHEN a tick is received on Tuesday
    tick = Tick(datetime=arrow.get("Tue 14 Jan 2020 12:00:00", fmt), bid=99, ask=100)
    epic.on_new_tick(tick)

    # THEN the epic is not open
    assert epic.market_open is True, epic.last_tick.datetime.weekday()

    # WHEN a tick is received on Wednesday
    tick = Tick(datetime=arrow.get("Wed 15 Jan 2020 12:00:00", fmt), bid=99, ask=100)
    epic.on_new_tick(tick)

    # THEN the epic is not open
    assert epic.market_open is False

    # WHEN a tick is received on Tuesday
    tick = Tick(datetime=arrow.get("Tue 16 Jan 2020 12:00:00", fmt), bid=99, ask=100)
    epic.on_new_tick(tick)

    # THEN the epic is open
    assert epic.market_open is True

    # WHEN a tick is received on Friday
    tick = Tick(datetime=arrow.get("Fri 17 Jan 2020 12:00:00", fmt), bid=99, ask=100)
    epic.on_new_tick(tick)

    # THEN the epic is not open
    assert epic.market_open is False

Impacts on strategy method called attribute

When the Tick received by an Epic (epic.last_tick) is out of its open periods, then the following method are called on very strategy attached to the Epic:

When the Tick received by an Epic (epic.last_tick) is inside of its open periods but the previous epic.last_tick was out of trading period, then the following method are called on very strategy attached to the Epic:

When the last Tick received by an Epic (epic.last_tick) is inside one of its open periods, then the following method are called on strategies:

When the Tick received by an Epic (epic.last_tick) is out of its open periods but the previous epic.last_tick was inside of trading period, then the following method are called on very strategy attached to the Epic: