import tia.analysis.ta as ta
import tia.analysis.talib_wrapper as talib
import pandas as pd
from pandas.io.data import get_data_yahoo
from tia.analysis.model import SingleAssetPortfolio, PortfolioPricer
# drop adj close & volume for example sake
msft = get_data_yahoo('MSFT', start='1/1/2010')
%matplotlib inline
# build signal when 50d crosses 200d
moving_avgs = pd.DataFrame({'50': ta.sma(msft.Close, 50), '200': ta.sma(msft.Close, 200)})
signal = ta.cross_signal(moving_avgs['50'], moving_avgs['200']).dropna()
# keep only entry
entry_signal = signal.copy()
entry_signal[signal.shift(1) == signal] = 0
entry_signal = entry_signal[entry_signal != 0]
# show when the signal triggers
moving_avgs.plot(color=['b', 'k'], title='MSFT moving averages')
for i, v in entry_signal.iteritems():
if v == -1:
plt.plot(i, moving_avgs['50'][i], 'rv')
else:
plt.plot(i, moving_avgs['50'][i], 'k^')
# Can get the set of trades created by this signal
trades = ta.Signal(signal).close_to_close(msft.Close)
trades
[<Trade(1, qty=-1.0, px=25.82, ts=2010-10-18 00:00:00)>, <Trade(2, qty=1.0, px=28.07, ts=2010-12-27 00:00:00)>, <Trade(3, qty=1.0, px=28.07, ts=2010-12-27 00:00:00)>, <Trade(4, qty=-1.0, px=25.15, ts=2011-04-19 00:00:00)>, <Trade(5, qty=-1.0, px=25.15, ts=2011-04-19 00:00:00)>, <Trade(6, qty=1.0, px=26.59, ts=2011-10-26 00:00:00)>, <Trade(7, qty=1.0, px=26.59, ts=2011-10-26 00:00:00)>, <Trade(8, qty=-1.0, px=29.49, ts=2012-10-16 00:00:00)>, <Trade(9, qty=-1.0, px=29.49, ts=2012-10-16 00:00:00)>, <Trade(10, qty=1.0, px=32.61, ts=2013-04-29 00:00:00)>, <Trade(11, qty=1.0, px=32.61, ts=2013-04-29 00:00:00)>]
# construct a portfolio from the trades
pricer = PortfolioPricer(closing_pxs=msft.Close)
port = SingleAssetPortfolio(pricer, trades)
# Show each of the individial transactions
port.txn_frame.head()
dt | txn_ts | pid | tid | txn_qty | txn_px | txn_fees | txn_premium | open_val | pos | txn_intent | txn_side | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
seq | ||||||||||||
0 | 2010-10-18 | 2010-10-18 | 1 | 1 | -1 | 25.82 | 0 | 25.82 | 25.82 | -1 | 1 | 3 |
1 | 2010-12-27 | 2010-12-27 | 1 | 2 | 1 | 28.07 | 0 | -28.07 | 0.00 | 0 | 2 | 4 |
2 | 2010-12-27 | 2010-12-27 | 2 | 3 | 1 | 28.07 | 0 | -28.07 | -28.07 | 1 | 1 | 1 |
3 | 2011-04-19 | 2011-04-19 | 2 | 4 | -1 | 25.15 | 0 | 25.15 | 0.00 | 0 | 2 | 2 |
4 | 2011-04-19 | 2011-04-19 | 3 | 5 | -1 | 25.15 | 0 | 25.15 | 25.15 | -1 | 1 | 3 |
# Show the position summary
port.position_frame
pid | side | open_dt | close_dt | open_qty | open_px | close_px | open_premium | pl_min | pl_max | pl | duration | ntxns | roii | state | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | Short | 2010-10-18 | 2010-12-27 | -1 | 25.82 | 28.07 | 25.82 | -2.48 | 0.72 | -2.25 | 49 | 2 | -0.087142 | Closed |
1 | 2 | Long | 2010-12-27 | 2011-04-19 | 1 | 28.07 | 25.15 | -28.07 | -3.29 | 0.80 | -2.92 | 80 | 2 | -0.104026 | Closed |
2 | 3 | Short | 2011-04-19 | 2011-10-26 | -1 | 25.15 | 26.59 | 25.15 | -2.93 | 1.44 | -1.44 | 133 | 2 | -0.057256 | Closed |
3 | 4 | Long | 2011-10-26 | 2012-10-16 | 1 | 26.59 | 29.49 | -26.59 | -2.29 | 6.26 | 2.90 | 246 | 2 | 0.109064 | Closed |
4 | 5 | Short | 2012-10-16 | 2013-04-29 | -1 | 29.49 | 32.61 | 29.49 | -3.12 | 3.12 | -3.12 | 132 | 2 | -0.105799 | Closed |
5 | 6 | Long | 2013-04-29 | 2015-01-16 | 1 | 32.61 | NaN | -32.61 | -1.46 | 17.00 | 13.63 | 435 | 1 | 0.417970 | Open |
# Live-to-date profit & loss frame
port.ltd_pl.tail()
pos | open_val | tot_val | rpl_gross | fees | dvds | rpl | upl | pl | |
---|---|---|---|---|---|---|---|---|---|
dt | |||||||||
2015-01-12 | 1 | -32.61 | -39.44 | -6.83 | 0 | 0 | -6.83 | 13.99 | 7.16 |
2015-01-13 | 1 | -32.61 | -39.44 | -6.83 | 0 | 0 | -6.83 | 13.75 | 6.92 |
2015-01-14 | 1 | -32.61 | -39.44 | -6.83 | 0 | 0 | -6.83 | 13.35 | 6.52 |
2015-01-15 | 1 | -32.61 | -39.44 | -6.83 | 0 | 0 | -6.83 | 12.87 | 6.04 |
2015-01-16 | 1 | -32.61 | -39.44 | -6.83 | 0 | 0 | -6.83 | 13.63 | 6.80 |
# daily profit & loss frame
port.dly_pl.tail()
pos | open_val | tot_val | rpl_gross | fees | dvds | rpl | upl | pl | |
---|---|---|---|---|---|---|---|---|---|
dt | |||||||||
2015-01-12 | 1 | -32.61 | 0 | 0 | 0 | 0 | 0 | -0.59 | -0.59 |
2015-01-13 | 1 | -32.61 | 0 | 0 | 0 | 0 | 0 | -0.24 | -0.24 |
2015-01-14 | 1 | -32.61 | 0 | 0 | 0 | 0 | 0 | -0.40 | -0.40 |
2015-01-15 | 1 | -32.61 | 0 | 0 | 0 | 0 | 0 | -0.48 | -0.48 |
2015-01-16 | 1 | -32.61 | 0 | 0 | 0 | 0 | 0 | 0.76 | 0.76 |
# Show a performance summary
#
# Make simplistic assumption that portfolio is based on $100 in capital
#
dly_rets = port.dly_pl.pl / 100.
import tia.analysis.perf as perf
perf.summarize_returns(dly_rets)
daily_maxdd | daily_maxdd_dt | monthly_ret_avg | monthly_ret_cum | monthly_sharpe_ann | monthly_sortino | monthly_stdev | monthly_stdev_ann | |
---|---|---|---|---|---|---|---|---|
period | ||||||||
2010 | -0.03170088 | 2010-12-23 | -0.001980732 | -0.02404991 | -0.6901685 | -0.3173678 | 0.00994171 | 0.03443909 |
2011 | -0.07331051 | 2011-11-25 | -0.004115326 | -0.04890587 | -1.307233 | -1.234272 | 0.01090541 | 0.03777743 |
2012 | -0.04344703 | 2012-06-01 | 0.005251304 | 0.06311997 | 1.048089 | 1.263801 | 0.0173564 | 0.06012435 |
2013 | -0.07560767 | 2013-09-06 | -0.00104312 | -0.01438884 | -0.1914123 | -0.2187516 | 0.01887797 | 0.06539521 |
2014 | -0.04710624 | 2014-10-16 | 0.007348549 | 0.0911143 | 2.306281 | 2.355815 | 0.01103774 | 0.03823584 |
2015 | -0.02092591 | 2015-01-15 | -0.002319695 | -0.002319695 | NaN | -3.464102 | NaN | NaN |
LTD | -0.09348117 | 2011-11-25 | 0.001036204 | 0.0587676 | 0.2522288 | 0.2477042 | 0.01423118 | 0.04929827 |
# break down position performance - just show subset to get idea
# - roii is the return on initial investment
port.position_summary()[['cnt', 'winpct', 'roii_avg', 'duration_avg']]
cnt | winpct | roii_avg | duration_avg | ||
---|---|---|---|---|---|
side | winloss | ||||
LongShort | Wins | 2 | NaN | 0.263517 | 340.500000 |
Losses | 4 | NaN | -0.088556 | 98.500000 | |
Total | 6 | 0.333333 | 0.028802 | 179.166667 |
# Only look at the long side
port.long_only.position_frame
pid | side | open_dt | close_dt | open_qty | open_px | close_px | open_premium | pl_min | pl_max | pl | duration | ntxns | roii | state | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2 | Long | 2010-12-27 | 2011-04-19 | 1 | 28.07 | 25.15 | -28.07 | -3.29 | 0.80 | -2.92 | 80 | 2 | -0.104026 | Closed |
1 | 4 | Long | 2011-10-26 | 2012-10-16 | 1 | 26.59 | 29.49 | -26.59 | -2.29 | 6.26 | 2.90 | 246 | 2 | 0.109064 | Closed |
2 | 6 | Long | 2013-04-29 | 2015-01-16 | 1 | 32.61 | NaN | -32.61 | -1.46 | 17.00 | 13.63 | 435 | 1 | 0.417970 | Open |
# long only return analysis
dly_rets = port.long_only.dly_pl.pl / 100.
import tia.analysis.perf as perf
perf.summarize_returns(dly_rets)
daily_maxdd | daily_maxdd_dt | monthly_ret_avg | monthly_ret_cum | monthly_sharpe_ann | monthly_sortino | monthly_stdev | monthly_stdev_ann | |
---|---|---|---|---|---|---|---|---|
period | ||||||||
2010 | -0.00219856 | 2010-12-30 | -0.0001333233 | -0.001599879 | -1 | -0.2886751 | 0.0004618454 | 0.001599879 |
2011 | -0.05874481 | 2011-11-25 | -0.002861607 | -0.03395659 | -1.857723 | -1.111919 | 0.005336048 | 0.01848461 |
2012 | -0.04344703 | 2012-06-01 | 0.002950147 | 0.03437177 | 0.6053625 | 0.7077782 | 0.0168818 | 0.05848027 |
2013 | -0.05136092 | 2013-09-06 | 0.003865622 | 0.04612166 | 0.9014342 | 0.9282524 | 0.01485511 | 0.05145962 |
2014 | -0.04710624 | 2014-10-16 | 0.007348549 | 0.0911143 | 2.306281 | 2.355815 | 0.01103774 | 0.03823584 |
2015 | -0.02092591 | 2015-01-15 | -0.002319695 | -0.002319695 | NaN | -3.464102 | NaN | NaN |
LTD | -0.05874481 | 2011-11-25 | 0.002159229 | 0.1361136 | 0.6490151 | 0.6329471 | 0.01152483 | 0.03992317 |