Skip to content

Commit

Permalink
fixes #17
Browse files Browse the repository at this point in the history
  • Loading branch information
timkpaine committed Jun 3, 2019
1 parent 25c5c2d commit 18285b3
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 237 deletions.
8 changes: 2 additions & 6 deletions aat/order_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def oe_client(self):
'enableRateLimit': True,
})

@lru_cache(None)
def accounts(self):
client = self.oe_client()
if not client:
Expand All @@ -44,18 +45,13 @@ def accounts(self):
balance = float(jsn['amount'])

id = jsn.get('id', jsn['currency'])
# FIXME
value = balance
# value = balance if currency == CurrencyType.USD else balance*self.lastPrice(str_currency_to_currency_pair_type(currency))['last']
account = Account(id=id,
currency=currency,
balance=balance,
exchange=self.exchange(),
value=value,
value=-1,
asOf=datetime.now())
accounts.append(account)
# cache
self._accounts = accounts
return accounts

@lru_cache(None)
Expand Down
6 changes: 1 addition & 5 deletions aat/strategies/backtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def onTrade(self, data: MarketData):

# ready?
if len(self.ticks) < self.size:
return False
return

y = numpy.array(self.ticks)
z = numpy.polyfit(self.x, y, 1) # linreg
Expand Down Expand Up @@ -76,7 +76,6 @@ def onTrade(self, data: MarketData):
order_type=OrderType.MARKET,
time=data.time)
self.requestBuy(self.onBuy, req)
return True

elif self.state == 'sell' and self.prev_state != 'sell' and \
self.bought > 0.0:
Expand All @@ -87,9 +86,6 @@ def onTrade(self, data: MarketData):
order_type=OrderType.MARKET,
time=data.time)
self.requestSell(self.onSell, req)
return True

return False

def onError(self, e: MarketData):
elog.critical(e)
Expand Down
2 changes: 0 additions & 2 deletions aat/strategies/buy_and_hold.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ def onTrade(self, data: MarketData) -> bool:
time=data.time)
slog.info("requesting buy : %s", req)
self.requestBuy(self.onBuy, req)
return True
return False

def onError(self, e) -> None:
elog.critical(e)
Expand Down
6 changes: 1 addition & 5 deletions aat/strategies/sma_crosses_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def onTrade(self, data: MarketData) -> bool:
self.state = ''

if len(self.longs) < self.long or len(self.shorts) < self.short:
return False
return

if self.state == 'golden' and self.prev_state != 'golden' and \
self.bought == 0.0: # watch for floating point error
Expand All @@ -89,7 +89,6 @@ def onTrade(self, data: MarketData) -> bool:
time=data.time)
# slog.info("requesting buy : %s", req)
self.requestBuy(self.onBuy, req)
return True

elif self.state == 'death' and self.prev_state != 'death' and \
self.bought > 0.0:
Expand All @@ -102,9 +101,6 @@ def onTrade(self, data: MarketData) -> bool:
time=data.time)
# slog.info("requesting sell : %s", req)
self.requestSell(self.onSell, req)
return True

return False

def onError(self, e) -> None:
elog.critical(e)
Expand Down
3 changes: 0 additions & 3 deletions aat/strategies/test_strat.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ def onTrade(self, data: MarketData) -> bool:
slog.info("requesting buy : %s", req)
self.requestBuy(self.onBuy, req)
self.active = True
return True
else:
if self.bought_qty:
req = TradeRequest(side=Side.SELL,
Expand All @@ -71,10 +70,8 @@ def onTrade(self, data: MarketData) -> bool:
slog.info("requesting sell : %s", req)
self.requestSell(self.onSell, req)
self.active = False
return True
else:
slog.info('None bought yet!')
return False

def onError(self, e) -> None:
elog.critical(e, type(e))
Expand Down
195 changes: 130 additions & 65 deletions aat/structs.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import datetime
from datetime import datetime
from dataclasses import dataclass, field, fields, asdict
from enum import Enum
from .enums import Side, \
ExchangeType, \
OptionSide, \
Expand All @@ -10,13 +12,43 @@
TradeResult, \
InstrumentType, \
RiskReason
from .utils import struct, NOPRINT


@struct
class Instrument:
underlying = PairType
type = InstrumentType, InstrumentType.PAIR
@dataclass(init=False)
class Struct:
def to_dict(self, serializable=False, str_timestamp=False, **kwargs) -> dict:
ret = asdict(self)
if serializable:
for item in ret:
if isinstance(ret[item], datetime):
if str_timestamp:
ret[item] = ret[item].strftime('%y-%m-%d %H:%M:%S')
else:
ret[item] = round(ret[item].timestamp())
elif isinstance(ret[item], Struct) or \
isinstance(getattr(self, item), Struct):
ret[item] = getattr(self, item).to_dict(serializable, str_timestamp, **kwargs)
elif isinstance(ret[item], Enum) or \
isinstance(getattr(self, item), Enum):
ret[item] = str(getattr(self, item))
elif isinstance(ret[item], float):
if ((ret[item] >= float('inf')) is False) and \
((ret[item] <= float('inf')) is False):
ret[item] = None
return ret


@dataclass(init=False)
class Instrument(Struct):
underlying: PairType
type: InstrumentType = InstrumentType.PAIR

def __init__(self,
underlying: PairType,
type: InstrumentType = InstrumentType.PAIR,
*args, **kwargs):
self.underlying = underlying
self.type = type

@property
def instrument(self):
Expand All @@ -39,14 +71,34 @@ def __hash__(self):
return hash(str(self.underlying))


@struct
@dataclass(init=False)
class Option(Instrument):
underlying = Instrument
type = InstrumentType, InstrumentType.OPTION
expiration = datetime.datetime
strike = float
size = float
side = OptionSide
underlying: Instrument
expiration: datetime
strike: float
size: float
side: OptionSide

def __init__(self,
underlying: PairType,
expiration: datetime,
strike: float,
size: float,
side: OptionSide,
type: InstrumentType = InstrumentType.OPTION,
*args, **kwargs):
self.underlying = underlying
self.expiration = expiration
self.strike = strike
self.size = size
self.side = side
self.type = type
super(Option, self).__init__(underlying=underlying,
type=type,
expiration=expiration,
strike=strike,
size=size,
side=side)

@property
def instrument(self):
Expand All @@ -72,12 +124,26 @@ def __str__(self):
'{0:8.2f}'.format(self.size).replace(' ', '0')


@struct
@dataclass(init=False)
class Future(Instrument):
underlying = Instrument
type = InstrumentType, InstrumentType.FUTURE
expiration = datetime.datetime
size = float
underlying: Instrument
expiration: datetime
size: float

def __init__(self,
underlying: PairType,
expiration: datetime,
size: float,
type: InstrumentType = InstrumentType.FUTURE,
*args, **kwargs):
self.underlying = underlying
self.expiration = expiration
self.size = size
self.type = type
super(Future, self).__init__(underlying=underlying,
type=type,
expiration=expiration,
size=size)

@property
def instrument(self):
Expand All @@ -98,21 +164,21 @@ def __str__(self):
return f'<{self.expiration.strftime("%y%m%d")} - {self.underlying} - ' + '{0:8.2f}'.format(self.size).replace(' ', '0') + '>'


@struct
class MarketData:
@dataclass
class MarketData(Struct):
# common
time = datetime.datetime, NOPRINT
volume = float
price = float
type = TickType
instrument = Instrument
side = Side
time: datetime
volume: float
price: float
type: TickType
instrument: Instrument
side: Side

# maybe specific
remaining = float, 0.0
sequence = int, -1
exchange = ExchangeType
order_type = OrderType, OrderType.NONE
exchange: ExchangeType
remaining: float = 0.0
sequence: int = -1
order_type: OrderType = OrderType.NONE

def __eq__(self, other):
return (self.price == other.price) and \
Expand All @@ -125,57 +191,56 @@ def __str__(self):
def __lt__(self, other):
return self.price < other.price

@dataclass
class TradeRequest(Struct):
side: Side
exchange: ExchangeType

@struct
class TradeRequest:
side = Side
exchange = ExchangeType
volume: float
price: float
instrument: Instrument

volume = float
price = float
instrument = Instrument
time: datetime

order_type = OrderType
order_sub_type = OrderSubType, OrderSubType.NONE

time = datetime.datetime
risk_check = bool, False
risk_reason = RiskReason, RiskReason.NONE
order_type: OrderType
order_sub_type: OrderSubType = OrderSubType.NONE
risk_check: bool = False
risk_reason: RiskReason = RiskReason.NONE

def __str__(self) -> str:
return f'<{self.instrument}-{self.side}:{self.volume}@{self.price}-{self.order_type}-{self.exchange}>'


@struct
class TradeResponse:
request = TradeRequest
side = Side
exchange = ExchangeType
@dataclass
class TradeResponse(Struct):
request: TradeRequest
side: Side
exchange: ExchangeType

volume = float
price = float
instrument = Instrument
volume: float
price: float
instrument: Instrument

slippage = float, 0.0
transaction_cost = float, 0.0
time: datetime
status: TradeResult
order_id: str

time = datetime.datetime
status = TradeResult
order_id = str
remaining = float, 0.0
slippage: float = 0.0
transaction_cost: float = 0.0
remaining: float = 0.0

def __str__(self) -> str:
return f'<{self.instrument}-{self.side}:{self.volume}@{self.price}-{self.status}-{self.exchange}>'


@struct
class Account:
id = str
currency = CurrencyType
balance = float
exchange = ExchangeType
value = float
asOf = datetime.datetime
@dataclass
class Account(Struct):
id: str
currency: CurrencyType
balance: float
exchange: ExchangeType
value: float
asOf: datetime

def __repr__(self) -> str:
return f'<{self.id} - {self.currency} - {self.balance} - {self.value}>'

0 comments on commit 18285b3

Please sign in to comment.