Skip to content

Commit

Permalink
fixes #4
Browse files Browse the repository at this point in the history
  • Loading branch information
timkpaine committed May 28, 2019
1 parent 26f9225 commit 5d21939
Show file tree
Hide file tree
Showing 13 changed files with 86 additions and 21 deletions.
2 changes: 1 addition & 1 deletion aat/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def _joiner(l):

class _PairType(BaseEnum):
def __str__(self):
return str(self.value[0].value) + str(self.value[1].value)
return str(self.value[0].value) + '/' + str(self.value[1].value)

@staticmethod
def from_string(first, second=''):
Expand Down
15 changes: 8 additions & 7 deletions aat/execution.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from typing import List
from .config import ExecutionConfig
from .exchange import Exchange
from .enums import Side
Expand All @@ -6,18 +7,17 @@


class Execution(object):
def __init__(self, options: ExecutionConfig, exchange: Exchange) -> None:
def __init__(self, options: ExecutionConfig, exchanges: List[Exchange]) -> None:
self.trading_type = options.trading_type
self._ex = exchange
self._exs = []
self._exs = exchanges

def requestBuy(self, req: TradeRequest) -> TradeResponse:
resp = self._ex.buy(req)
resp = self._exs[req.exchange].buy(req)
exlog.info('Order info: %s' % resp)
return resp

def requestSell(self, req: TradeRequest) -> TradeResponse:
resp = self._ex.sell(req)
resp = self._exs[req.exchange].sell(req)
exlog.info('Order info: %s' % resp)
return resp

Expand All @@ -27,7 +27,8 @@ def request(self, req: TradeRequest) -> TradeResponse:
return self.requestSell(req)

def cancel(self, resp: TradeResponse): # TODO
return self._ex.cancel(resp)
return self._exs[resp.exchange].cancel(resp)

def cancelAll(self):
return self._ex.cancelAll()
for ex in self._exs.values():
ex.cancelAll()
4 changes: 4 additions & 0 deletions aat/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ def __init__(self,

self._pairs = pairs
self._instruments = instruments
self._exchanges = exchanges

self._last_price_by_exchange = {}

def query_instruments(self) -> List[PairType]:
return self._instruments

def query_exchanges(self) -> List[ExchangeType]:
return self._exchanges

def query_trades(self,
instrument: Instrument = None,
page: int = 1) -> List[MarketData]:
Expand Down
32 changes: 27 additions & 5 deletions aat/risk.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .config import RiskConfig
from .structs import TradeRequest, TradeResponse, Instrument
from .enums import Side, TradeResult, OrderType, RiskReason
from .enums import Side, TradeResult, OrderType, RiskReason, ExchangeType
from .logging import RISK as rlog


Expand All @@ -23,13 +23,14 @@ def __init__(self, options: RiskConfig) -> None:

def _constructResp(self,
side: Side,
exchange: ExchangeType,
instrument: Instrument,
order_type: OrderType,
vol: float,
price: float,
status: bool,
reason: RiskReason) -> TradeRequest:
resp = TradeRequest(side=side, instrument=instrument, order_type=order_type, volume=vol, price=price, risk_check=status, risk_reason=reason)
resp = TradeRequest(side=side, exchange=exchange, instrument=instrument, order_type=order_type, volume=vol, price=price, risk_check=status, risk_reason=reason)

if status == TradeResult.FILLED: # FIXME
self.outstanding += abs(vol * price) * (1 if side == Side.BUY else -1)
Expand All @@ -52,17 +53,38 @@ def request(self, req: TradeRequest) -> TradeRequest:
if (total + self.outstanding) <= max:
# room for full volume
rlog.info('Risk check passed for order: %s' % req)
return self._constructResp(req.side, req.instrument, req.order_type, req.volume, req.price, True, RiskReason.NONE)
return self._constructResp(side=req.side,
exchange=req.exchange,
instrument=req.instrument,
order_type=req.order_type,
vol=req.volume,
price=req.price,
status=True,
reason=RiskReason.NONE)

elif self.outstanding < max:
# room for some volume
volume = (max - self.outstanding) / req.price
rlog.info('Risk check passed for partial order: %s' % req)
return self._constructResp(req.side, req.instrument, req.order_type, volume, req.price, True, RiskReason.PARTIAL)
return self._constructResp(side=req.side,
exchange=req.exchange,
instrument=req.instrument,
order_type=req.order_type,
vol=volume,
price=req.price,
status=True,
reason=RiskReason.PARTIAL)

# no room for volume
rlog.info('Risk check failed for order: %s' % req)
return self._constructResp(req.side, req.instrument, req.order_type, req.volume, req.price, False, RiskReason.FULL)
return self._constructResp(side=req.side,
exchange=req.exchange,
instrument=req.instrument,
order_type=req.order_type,
vol=volume,
price=req.price,
status=False,
reason=RiskReason.FULL)

def requestBuy(self, req: TradeRequest):
'''precheck for risk compliance'''
Expand Down
2 changes: 2 additions & 0 deletions aat/strategies/test_strat.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def onTrade(self, data: MarketData) -> bool:
volume=1.0,
instrument=data.instrument,
order_type=OrderType.MARKET,
exchange=data.exchange,
price=data.price)
slog.info("requesting buy : %s", req)
self.requestBuy(self.onBuy, req)
Expand All @@ -62,6 +63,7 @@ def onTrade(self, data: MarketData) -> bool:
req = TradeRequest(side=Side.SELL,
volume=self.bought_qty,
instrument=data.instrument,
exchange=data.exchange,
order_type=OrderType.MARKET,
price=data.price)
slog.info("requesting sell : %s", req)
Expand Down
2 changes: 2 additions & 0 deletions aat/structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def __lt__(self, other):
@struct
class TradeRequest:
side = Side
exchange = ExchangeType

volume = float
price = float
Expand All @@ -141,6 +142,7 @@ class TradeRequest:
class TradeResponse:
request = TradeRequest
side = Side
exchange = ExchangeType

volume = float
price = float
Expand Down
10 changes: 9 additions & 1 deletion aat/trading.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ def _request(self,
log.info('Trading not allowed')
resp = TradeResponse(request=req,
side=req.side,
exchange=req.exchange,
volume=0.0,
price=0.0,
instrument=req.instrument,
Expand Down Expand Up @@ -211,6 +212,7 @@ def _request(self,
log.info('Trade rejected')
resp = TradeResponse(request=resp,
side=resp.side,
exchange=req.exchange,
volume=0.0,
price=0.0,
instrument=req.instrument,
Expand All @@ -227,6 +229,7 @@ def _request(self,
# backtesting or simulation
resp = TradeResponse(request=req,
side=req.side,
exchange=req.exchange,
volume=req.volume,
price=req.price,
instrument=req.instrument,
Expand All @@ -249,6 +252,7 @@ def _request(self,
else:
log.info('Risk check failed')
resp = TradeResponse(request=resp,
exchange=req.exchange,
side=resp.side,
volume=0.0,
price=0.0,
Expand All @@ -259,7 +263,11 @@ def _request(self,
callback_failure(resp) if callback_failure and not resp.success else callback(resp)

def requestBuy(self, callback: Callable, req: TradeRequest, callback_failure=None, strat=None):
self._request(Side.BUY, callback, req, callback_failure, strat)
self._request(side=Side.BUY,
callback=callback,
req=req,
callback_failure=callback_failure,
strat=strat)

def requestSell(self, callback: Callable, req: TradeRequest, callback_failure=None, strat=None):
self._request(Side.SELL, callback, req, callback_failure, strat)
Expand Down
2 changes: 1 addition & 1 deletion aat/ui/handlers/accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
class AccountsHandler(PerspectiveHTTPMixin, HTTPHandler):
'''Server Handler
Extends:
tornado.web.RequestHandler
HTTPHandler
'''
def initialize(self, trading_engine, **psp_kwargs):
self.te = trading_engine
Expand Down
25 changes: 25 additions & 0 deletions aat/ui/handlers/exchanges.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import tornado.gen
from .base import HTTPHandler
from tornado.concurrent import run_on_executor
from perspective import PerspectiveHTTPMixin


class ExchangesHandler(PerspectiveHTTPMixin, HTTPHandler):
'''Server Handler
Extends:
HTTPHandler
'''
def initialize(self, trading_engine, **psp_kwargs):
self.te = trading_engine
self.psp_kwargs = psp_kwargs

@run_on_executor
def get_data(self, **psp_kwargs):
msgs = [{'name': x.value} for x in self.te.query().query_exchanges()]
super(ExchangesHandler, self).loadData(data=msgs, **psp_kwargs)
return super(ExchangesHandler, self).getData()

@tornado.gen.coroutine
def get(self):
dat = yield self.get_data(**self.psp_kwargs)
self.write(dat)
4 changes: 2 additions & 2 deletions aat/ui/handlers/instruments.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
class InstrumentsHandler(PerspectiveHTTPMixin, HTTPHandler):
'''Server Handler
Extends:
tornado.web.RequestHandler
HTTPHandler
'''
def initialize(self, trading_engine, psp_kwargs):
def initialize(self, trading_engine, **psp_kwargs):
self.te = trading_engine
self.psp_kwargs = psp_kwargs

Expand Down
2 changes: 1 addition & 1 deletion aat/ui/handlers/strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
class StrategiesHandler(PerspectiveHTTPMixin, HTTPHandler):
'''Server Handler
Extends:
tornado.web.RequestHandler
HTTPHandler
'''
def initialize(self, trading_engine, **psp_kwargs):
self.te = trading_engine
Expand Down
2 changes: 1 addition & 1 deletion aat/ui/handlers/trades.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class TradesHandler(PerspectiveHTTPMixin, HTTPHandler):
'''Server Handler
Extends:
tornado.web.RequestHandler
HTTPHandler
'''
def initialize(self, trading_engine, psp_kwargs):
self.te = trading_engine
Expand Down
5 changes: 3 additions & 2 deletions aat/ui/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import tornado.ioloop
import tornado.web
from .handlers.accounts import AccountsHandler
from .handlers.exchanges import ExchangesHandler
from .handlers.instruments import InstrumentsHandler
from .handlers.strategies import StrategiesHandler
from .handlers.trades import TradesHandler
Expand Down Expand Up @@ -40,8 +41,8 @@ def __init__(self,
super(ServerApplication, self).__init__(
extra_handlers + [
(r"/api/json/v1/accounts", AccountsHandler, {'trading_engine': trading_engine}),
(r"/api/json/v1/instruments", InstrumentsHandler, {'trading_engine': trading_engine,
'psp_kwargs': {'view': 'hypergrid'}}),
(r"/api/json/v1/exchanges", ExchangesHandler, {'trading_engine': trading_engine}),
(r"/api/json/v1/instruments", InstrumentsHandler, {'trading_engine': trading_engine}),
(r"/api/json/v1/strategies", StrategiesHandler, {'trading_engine': trading_engine,
'psp_kwargs': {'view': 'hypergrid'}}),
(r"/api/json/v1/trades", TradesHandler, {'trading_engine': trading_engine,
Expand Down

0 comments on commit 5d21939

Please sign in to comment.