Skip to content

Commit

Permalink
fixes #45
Browse files Browse the repository at this point in the history
  • Loading branch information
timkpaine committed Jul 9, 2019
1 parent 946da76 commit e1f47a1
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 19 deletions.
14 changes: 9 additions & 5 deletions aat/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,15 +244,17 @@ def _recalculate_value(self, data: MarketData) -> None:
self._portfolio_value_by_instrument[instrument] = []
self._portfolio_value_by_instrument[instrument].append([data.time, instrument, value + pnl, pnl])

pnl = sum(x._pnl for x in self._holdings.values())
self._portfolio_value.append([data.time, self._portfolio_value[-1][1], pnl])
unrealized = sum(x._pnl for x in self._holdings.values())
realized = sum(x._realized for x in self._holdings.values())
pnl = sum(x._pnl+x._realized for x in self._holdings.values())
self._portfolio_value.append([data.time, self._portfolio_value[-1][1], unrealized, realized, pnl])

def update_holdings(self, resp: TradeResponse) -> None:
if resp.status in (TradeResult.REJECTED, TradeResult.PENDING, TradeResult.NONE):
return
if resp.instrument not in self._holdings:
self._holdings[resp.instrument] = pnl_helper()
self._holdings[resp.instrument].exec(resp.volume, resp.price)
self._holdings[resp.instrument].exec(resp.volume, resp.price, resp.side)


def sign(x): return (1, -1)[x < 0]
Expand All @@ -267,20 +269,22 @@ def __init__(self):
self._realized = 0.0
self._avg_price = self._px

def exec(self, amt, px):
def exec(self, amt, px, side):
if self._px is None:
self._px = px
self._volume = amt
self._avg_price = self._px
self._records.append({'volume': self._volume, 'px': px, 'apx': self._avg_price, 'pnl': self._pnl+self._realized, 'unrealized': self._pnl, 'realized': self._realized})
return
amt = amt if side == Side.BUY else -amt

if sign(amt) == sign(self._volume):
# increasing position
self._avg_price = (self._avg_price*self._volume + px*amt)/(self._volume + amt)
self._volume += amt
self._pnl = (self._volume * (px-self._avg_price))
else:
if abs(amt) > abs(self._shares):
if abs(amt) > abs(self._volume):
# do both
diff = self._volume
self._volume = amt + self._volume
Expand Down
35 changes: 21 additions & 14 deletions aat/strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,16 @@ def onAnalyze(self, engine):
trades.set_index(['time'], inplace=True)

# format into pandas
pd = pandas.DataFrame(portfolio_value, columns=['time', 'value', 'pnl'])
pd = pandas.DataFrame(portfolio_value, columns=['time', 'value', 'unrealized', 'realized', 'pnl'])
pd.set_index(['time'], inplace=True)

# setup charting
sns.set_style('darkgrid')
fig = plt.figure()
ax1 = fig.add_subplot(311)
ax2 = fig.add_subplot(312)
ax3 = fig.add_subplot(313)
fig = plt.figure(figsize=(13, 7))
ax1 = fig.add_subplot(411)
ax2 = fig.add_subplot(412)
ax3 = fig.add_subplot(413)
ax4 = fig.add_subplot(414)

# plot algo performance
pd.plot(ax=ax1, y=['value'], legend=False, fontsize=5, rot=0)
Expand All @@ -80,30 +82,33 @@ def onAnalyze(self, engine):
pd['pos'][pd['pos'] <= 0] = np.nan
pd['neg'][pd['neg'] > 0] = np.nan
pd.plot(ax=ax2, y=['pos', 'neg'], kind='area', stacked=False, color=['green', 'red'], legend=False, linewidth=0, fontsize=5, rot=0)
ax2.set_ylabel('Realized PnL')
ax2.set_ylabel('PnL')

pd.plot(ax=ax3, y=['unrealized', 'realized', 'pnl'], kind='line', legend=False, fontsize=5, rot=0)
ax3.legend(loc="upper left")

# annotate with key data
ax1.set_title('Performance')
ax1.set_ylabel('Portfolio value($)')
for xy in [portfolio_value[0][:2]] + [portfolio_value[-1][:2]]:
ax1.annotate('$%s' % xy[1], xy=xy, textcoords='data')
ax3.annotate('$%s' % xy[1], xy=xy, textcoords='data')
ax4.annotate('$%s' % xy[1], xy=xy, textcoords='data')

# plot trade intent/trade action
ax3.set_ylabel('Intent/Action')
ax3.set_xlabel('Date')
ax4.set_ylabel('Intent/Action')
ax4.set_xlabel('Date')

ax3.plot(trades)
ax3.plot([x.time for x in requests if x.side == Side.BUY],
ax4.plot(trades)
ax4.plot([x.time for x in requests if x.side == Side.BUY],
[x.price for x in requests if x.side == Side.BUY],
'2', color='y')
ax3.plot([x.time for x in requests if x.side == Side.SELL],
ax4.plot([x.time for x in requests if x.side == Side.SELL],
[x.price for x in requests if x.side == Side.SELL],
'1', color='y')
ax3.plot([x.time for x in responses if x.side == Side.BUY], # FIXME
ax4.plot([x.time for x in responses if x.side == Side.BUY], # FIXME
[x.price for x in responses if x.side == Side.BUY],
'^', color='g')
ax3.plot([x.time for x in responses if x.side == Side.SELL], # FIXME
ax4.plot([x.time for x in responses if x.side == Side.SELL], # FIXME
[x.price for x in responses if x.side == Side.SELL],
'v', color='r')

Expand All @@ -113,8 +118,10 @@ def onAnalyze(self, engine):
ax1.set_xlim(x_bot, x_top)
ax2.set_xlim(x_bot, x_top)
ax3.set_xlim(x_bot, x_top)
ax4.set_xlim(x_bot, x_top)
dif = (x_top-x_bot)*.01
ax1.set_xlim(x_bot-dif, x_top+dif)
ax2.set_xlim(x_bot-dif, x_top+dif)
ax3.set_xlim(x_bot-dif, x_top+dif)
ax4.set_xlim(x_bot-dif, x_top+dif)
plt.show()
2 changes: 2 additions & 0 deletions aat/ui/handlers/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ def get(self):
if self.current_user:
self.redirect('/')
else:
log.critical(f'\n**********\nLogin code: {self.application.settings["login_code"]}\n**********')

user = self.get_argument('code', '')
if user == self.application.settings['login_code']:
self.set_secure_cookie("token", user)
Expand Down

0 comments on commit e1f47a1

Please sign in to comment.