Skip to content

Commit

Permalink
Merge pull request #134 from AsyncAlgoTrading/calendar
Browse files Browse the repository at this point in the history
Trading day and misc other fixes
  • Loading branch information
timkpaine committed Dec 30, 2020
2 parents b0ac441 + 7c9db67 commit 8d6bcaf
Show file tree
Hide file tree
Showing 18 changed files with 312 additions and 94 deletions.
67 changes: 67 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1 +1,68 @@
# Contributing

Thank you for your interest in contributing to aat!


## Reporting bugs, feature requests, etc.

To report bugs, request new features or similar, please open an issue on the Github
repository.

A good bug report includes:

- Expected behavior
- Actual behavior
- Steps to reproduce (preferably as minimal as possible)

## Minor changes, typos etc.

Minor changes can be contributed by navigating to the relevant files on the Github repository,
and clicking the "edit file" icon. By following the instructions on the page you should be able to
create a pull-request proposing your changes. A repository maintainer will then review your changes,
and either merge them, propose some modifications to your changes, or reject them (with a reason for
the rejection).

## Setting up a development environment

If you want to help resolve an issue by making some changes that are larger than that covered by the above paragraph, it is recommended that you:

- Fork the repository on Github
- Clone your fork to your computer
- Run the following commands inside the cloned repository:
- `pip install -e .[dev]` - This will install the Python package in development
mode.
- Validate the install by running the tests:
- `py.test` - This command will run the Python tests.
- `flake8 aat/` - This command will run the Python linters.

Once you have such a development setup, you should:

- Make the changes you consider necessary
- Run the tests to ensure that your changes does not break anything
- Run the linters to ensure that your changes does not break anything
- Run mypy if necessary to alert for problems with type annotations
- If you add new code, preferably write one or more tests for checking that your code works as expected.
- Commit your changes and publish the branch to your github repo.
- Open a pull-request (PR) back to the main repo on Github.

## Style
### Docstrings
Docstrings are [google format](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html).


### Python
Python code is formatted with [black](https://github.com/psf/black) and [flake8](https://github.com/PyCQA/flake8) and annotated for typings with [mypy](https://github.com/python/mypy).

#### Misc
- Public methods should be `camelCase`
- Public attributes should be `camelCase`
- Private methods should be `snake_case`
- Private attributes should be `snake_case`
- JSON import/export should be `snake_case`

### JS
JS Code is writted in `typescript` and formatted with `eslint` and `prettier`.

### C++
C++ Code is formateed with [cpplint](https://github.com/cpplint/cpplint) and [clang-format](https://clang.llvm.org/docs/ClangFormat.html).

12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -583,12 +583,12 @@ We can run any number of strategies against any number of exchanges, including c
| Synthetic | Yes | Yes | Simulation,Backtest | Equity |
| IEX | Yes | Fake | Live, Simulation, Sandbox, Backtest | Equity |
| InteractiveBrokers | In Progress | Yes | Live, Simulation, Sandbox | Equity, Option, Future, Commodities, Spreads, Pairs |
| TD Ameritrade | In Progress | In Progress | Equity, Option |
| Alpaca | In Progress | In Progress | |
| Coinbase | In Progress | In Progress | |
| Gemini | In Progress | In Progress | |
| Coinbase | In Progress | In Progress | |
| ccxt | In Progress | In Progress | |
| TD Ameritrade | In Progress | In Progress | In Progress | Equity, Option |
| Alpaca | In Progress | In Progress | | |
| Coinbase | In Progress | In Progress | | |
| Gemini | In Progress | In Progress | | |
| Coinbase | In Progress | In Progress | | |
| ccxt | In Progress | In Progress | | |
# TODO below here are sections that still need to be documented
Expand Down
4 changes: 4 additions & 0 deletions aat/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
import pandas as pd # type: ignore


class AATException(Exception):
pass


@functools.lru_cache()
def _in_cpp() -> bool:
_cpp = os.environ.get("AAT_USE_CPP", "").lower() in ("1", "on")
Expand Down
30 changes: 15 additions & 15 deletions aat/core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
from .exchange import ExchangeType # noqa: F401
from .data import Data, Error, Event, Order, Trade
from .exchange import ExchangeType

# from .execution import OrderManager # noqa: F401
from .handler import EventHandler, PrintHandler # noqa: F401
from .instrument import Instrument # noqa: F401
from .data import Data, Error, Event, Order, Trade # noqa: F401
from .position import Account, Position, CashPosition # noqa: F401
from .order_book import OrderBook # noqa: F401
# from .execution import OrderManager
from .handler import EventHandler, PrintHandler
from .instrument import Instrument, TradingDay
from .order_book import OrderBook
from .position import Account, CashPosition, Position

# from .portfolio import Portfolio, PortfolioManager # noqa: F401
# from .risk import RiskManager # noqa: F401
from .table import TableHandler # noqa: F401
# from .portfolio import Portfolio, PortfolioManager
# from .risk import RiskManager
from .table import TableHandler

try:
from ..binding import ( # type: ignore # noqa: F401
InstrumentCpp,
from ..binding import (
AccountCpp,
DataCpp,
EventCpp,
InstrumentCpp,
OrderBookCpp,
OrderCpp,
TradeCpp,
AccountCpp,
PositionCpp,
OrderBookCpp,
TradeCpp,
)
except ImportError:
pass
7 changes: 4 additions & 3 deletions aat/core/data/cpp.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import logging
from collections import deque
from datetime import datetime
from typing import Any, Optional, List, TYPE_CHECKING
from typing import TYPE_CHECKING, Any, List, Optional

from aat.common import _in_cpp
from aat.config import EventType, OrderFlag, OrderType, Side

from ..exchange import ExchangeType
from ..instrument import Instrument
from aat.config import OrderType, OrderFlag, EventType, Side


if TYPE_CHECKING:
from .order import Order
Expand All @@ -20,6 +20,7 @@

except ImportError:
logging.critical("Could not load C++ extension")
DataCpp, EventCpp, OrderCpp, TradeCpp = object, object, object, object
_CPP = False


Expand Down
7 changes: 3 additions & 4 deletions aat/core/data/order.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from datetime import datetime
from typing import Mapping, Union, Type, Optional, Any, cast
from typing import Any, Mapping, Optional, Type, Union, cast

from .cpp import _CPP, _make_cpp_order
from ...config import DataType, OrderFlag, OrderType, Side
from ..exchange import ExchangeType
from ..instrument import Instrument
from ...config import DataType, OrderFlag, OrderType, Side
from .cpp import _CPP, _make_cpp_order


class Order(object):
Expand Down Expand Up @@ -52,7 +52,6 @@ def __init__(
"id", 0
) # on construction, provide no ID until exchange assigns one
self.__timestamp = kwargs.get("timestamp") or datetime.now()
print(self.__timestamp)
self.__type = DataType.ORDER

assert isinstance(instrument, Instrument)
Expand Down
3 changes: 2 additions & 1 deletion aat/core/exchange/cpp.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from typing import Any
from aat.common import _in_cpp

from aat.common import _in_cpp

try:
from aat.binding import ExchangeTypeCpp # type: ignore

_CPP = _in_cpp()
except ImportError:
ExchangeTypeCpp = object
_CPP = False


Expand Down
1 change: 1 addition & 0 deletions aat/core/instrument/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from .calendar import TradingDay # noqa: F401
from .instrument import Instrument # noqa: F401
72 changes: 72 additions & 0 deletions aat/core/instrument/calendar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from datetime import time
from typing import Optional, Tuple, Union, cast

from aat.common import AATException
from pytz import UTC


class TradingDay(object):
"""Construct a representation of an instrument's trading day
Args:
open_times (Union[time, Tuple[time]]): time or tuple of times representing the time/s of market open. If missing tzinfo, will assume UTC.
close_times (Union[time, Tuple[time]]): time or tuple of times representing the time/s of market close. If missing tzinfo, will assume UTC.
"""

__slots__ = [
"_open_times",
"_close_times",
]

def __init__(
self,
open_times: Union[time, Tuple[time, ...]] = None,
close_times: Union[time, Tuple[time, ...]] = None,
):
if open_times and not isinstance(open_times, (tuple, time)):
# raise exception if wrong type
raise AATException(
"`open_times` must be time or tuple of times, got: {}".format(
type(open_times)
)
)
elif isinstance(open_times, time):
# force tuple
open_times = cast(Tuple[time, ...], (open_times,))

if open_times:
# force tz
open_times = tuple(
tm if tm.tzinfo else time(tm.hour, tm.minute, tzinfo=UTC)
for tm in open_times
)

self._open_times: Optional[Tuple[time, ...]] = open_times

if close_times and not isinstance(close_times, (tuple, time)):
# raise exception if wrong type
raise AATException(
"`close_times` must be time or tuple of times, got: {}".format(
type(close_times)
)
)
elif isinstance(close_times, time):
# force tuple
close_times = cast(Tuple[time, ...], (close_times,))

if close_times:
# force tz
close_times = tuple(
tm if tm.tzinfo else time(tm.hour, tm.minute, tzinfo=UTC)
for tm in close_times
)

self._close_times: Optional[Tuple[time, ...]] = close_times

@property
def open(self) -> Optional[Tuple[time, ...]]:
return self._open_times

@property
def close(self) -> Optional[Tuple[time, ...]]:
return self._close_times
3 changes: 2 additions & 1 deletion aat/core/instrument/cpp.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from typing import Any
from aat.common import _in_cpp

from aat.common import _in_cpp

try:
from ...binding import InstrumentCpp # type: ignore

_CPP = _in_cpp()
except ImportError:
InstrumentCpp = object
_CPP = False


Expand Down

0 comments on commit 8d6bcaf

Please sign in to comment.