Moving average xover on 1 minute data. How to get intraday performance report?

148 views
Skip to first unread message

Kaveh Vakili

unread,
Dec 4, 2017, 5:32:14 PM12/4/17
to Zipline Python Opensource Backtester
Hi all,

So I started by following on the footsteps of Richard's code for running one minute simulations in zipline.

That part works out of the box.


So now, I'm getting hungry for more and wanted to try to adapt the moving average cross-over code

to 1m data. Here is my stab:



from zipline.api import symbol, get_datetime, record, order_target
from pytz import timezone

def initialize(context):
    context
.contract  = symbol("Q0017")
    context
.i         = 0
   
def handle_data(context, data):
    context
.i += 1
   
if context.i < 30:
       
return

   
# Compute averages
   
# history() has to be called with the same params
   
# from above and returns a pandas dataframe.
    short_mavg
= data.history(context.contract, 'close', 10, '1m').mean()
    long_mavg  
= data.history(context.contract, 'close', 30, '1m').mean()

   
# Trading logic
   
if short_mavg > long_mavg:
       
# order_target orders as many shares as needed to
       
# achieve the desired number of shares.
        order_target
(context.contract, 100)
   
elif short_mavg < long_mavg:
        order_target
(context.contract, 0)

   
# Save values for later inspection
    record
(Q0017      = data.current(context.contract, "close"),
           short_mavg
= short_mavg,
           long_mavg  
= long_mavg)


# Note: this function can be removed if running
# this algorithm on quantopian.com
def analyze(context=None, results=None):
   
import matplotlib.pyplot as plt
   
import logbook
    logbook
.StderrHandler().push_application()
    log
= logbook.Logger('Algorithm')

    fig
= plt.figure()
    ax1
= fig.add_subplot(211)
    results
.portfolio_value.plot(ax=ax1)
    ax1
.set_ylabel('Portfolio value (USD)')

    ax2
= fig.add_subplot(212)
    ax2
.set_ylabel('Price (USD)')

   
# If data has been record()ed, then plot it.
   
# Otherwise, log the fact that no data has been recorded.
   
if ('Q0017' in results and 'short_mavg' in results and
           
'long_mavg' in results):
        results
['Q0017'].plot(ax=ax2)
        results
[['short_mavg', 'long_mavg']].plot(ax=ax2)

        trans
= results.ix[[t != [] for t in results.transactions]]
        buys
= trans.ix[[t[0]['amount'] > 0 for t in
                         trans
.transactions]]
        sells
= trans.ix[
           
[t[0]['amount'] < 0 for t in trans.transactions]]
        ax2
.plot(buys.index, results.short_mavg.ix[buys.index],
                 
'^', markersize=10, color='m')
        ax2
.plot(sells.index, results.short_mavg.ix[sells.index],
                 
'v', markersize=10, color='k')
        plt
.legend(loc=0)
   
else:
        msg
= 'Q0017, short_mavg & long_mavg data not captured using record().'
        ax2
.annotate(msg, xy=(0.1, 0.5))
        log
.info(msg)

    plt
.show()





And running this:

zipline run -f my_first_strategy.py --bundle ingester --data-frequency minute -s 2017-06-15 -e 2017-06-23

And this runs:

entering machina.  tuSymbols= ('Q0017',)
about to
return ingest function
[2017-12-04 22:18:01.652875] WARNING: Loader: Refusing to download new benchmark data because a download succeeded at 2017-12-04 22:02:41.574726+00:00.
[2017-12-04 22:18:05.175588] INFO: Performance: Simulated 7 trading days out of 7.
[2017-12-04 22:18:05.175732] INFO: Performance: first open: 2017-06-15 13:31:00+00:00
[2017-12-04 22:18:05.175812] INFO: Performance: last close: 2017-06-23 20:00:00+00:00

But why is the performance report only 7 rows long (one for each day)? 

Why is the performance report not 7717 rows long (one for each ingested bar)?

The ingester function successfully imported intra-day data:

$ zipline ingest -b ingester entering machina.  tuSymbols= ('Q0017',)
about to
return ingest function
entering ingest
and creating blank dfMetadata
dfMetadata
<class 'pandas.core.frame.DataFrame'>
<bound method NDFrame.describe of   start_date   end_date auto_close_date symbol
0 1970-01-01 1970-01-01      1970-01-01   None>
S
= Q0017 IFIL= /merged_data/Q0017.csv
read_csv dfData
<class 'pandas.core.frame.DataFrame'> length 7717 2017-06-15 22:00:00
start_date
<class 'pandas.tslib.Timestamp'> 2017-06-15 22:00:00 None
end_date
<class 'pandas.tslib.Timestamp'> 2017-06-23 20:00:00 None
ac_date
<class 'pandas.tslib.Timestamp'> 2017-06-24 20:00:00 None
liData
<class 'list'> length 1
Now calling minute_bar_writer
returned
from minute_bar_writer
calling asset_db_writer
dfMetadata
<class 'pandas.core.frame.DataFrame'>
           start_date            end_date     auto_close_date symbol exchange
0 2017-06-15 22:00:00 2017-06-23 20:00:00 2017-06-24 20:00:00  Q0017      ICE
symbol_map
<class 'pandas.core.series.Series'>
returned
from asset_db_writer
calling adjustment_writer
returned
from adjustment_writer
now leaving ingest
function

Thanks for any hint,

Kind regards,

Noved

unread,
May 28, 2020, 11:36:17 AM5/28/20
to Zipline Python Opensource Backtester
Hi Kaveh, Did you ever get anywhere on this (making sure the performance report is showing per-minute not per-day data when running a minute-level simulation)? If yes, do you mind sharing the fix? Thanks
Reply all
Reply to author
Forward
0 new messages