Completed
Pull Request — master (#858)
by Eddie
02:13 queued 19s
created

zipline.examples.analyze()   C

Complexity

Conditions 7

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 7
dl 0
loc 37
rs 5.5
1
#!/usr/bin/env python
2
#
3
# Copyright 2014 Quantopian, Inc.
4
#
5
# Licensed under the Apache License, Version 2.0 (the "License");
6
# you may not use this file except in compliance with the License.
7
# You may obtain a copy of the License at
8
#
9
#     http://www.apache.org/licenses/LICENSE-2.0
10
#
11
# Unless required by applicable law or agreed to in writing, software
12
# distributed under the License is distributed on an "AS IS" BASIS,
13
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
# See the License for the specific language governing permissions and
15
# limitations under the License.
16
17
"""Dual Moving Average Crossover algorithm.
18
19
This algorithm buys apple once its short moving average crosses
20
its long moving average (indicating upwards momentum) and sells
21
its shares once the averages cross again (indicating downwards
22
momentum).
23
"""
24
25
from zipline.api import order_target, record, symbol, history, add_history
26
27
28
def initialize(context):
29
    # Register 2 histories that track daily prices,
30
    # one with a 100 window and one with a 300 day window
31
    add_history(100, '1d', 'price')
32
    add_history(300, '1d', 'price')
33
34
    context.sym = symbol('AAPL')
35
36
    context.i = 0
37
38
39
def handle_data(context, data):
40
    # Skip first 300 days to get full windows
41
    context.i += 1
42
    if context.i < 300:
43
        return
44
45
    # Compute averages
46
    # history() has to be called with the same params
47
    # from above and returns a pandas dataframe.
48
    short_mavg = history(100, '1d', 'price').mean()
49
    long_mavg = history(300, '1d', 'price').mean()
50
51
    # Trading logic
52
    if short_mavg[context.sym] > long_mavg[context.sym]:
53
        # order_target orders as many shares as needed to
54
        # achieve the desired number of shares.
55
        order_target(context.sym, 100)
56
    elif short_mavg[context.sym] < long_mavg[context.sym]:
57
        order_target(context.sym, 0)
58
59
    # Save values for later inspection
60
    record(AAPL=data[context.sym].price,
61
           short_mavg=short_mavg[context.sym],
62
           long_mavg=long_mavg[context.sym])
63
64
65
# Note: this function can be removed if running
66
# this algorithm on quantopian.com
67
def analyze(context=None, results=None):
68
    import matplotlib.pyplot as plt
69
    import logbook
70
    logbook.StderrHandler().push_application()
71
    log = logbook.Logger('Algorithm')
72
73
    fig = plt.figure()
74
    ax1 = fig.add_subplot(211)
75
    results.portfolio_value.plot(ax=ax1)
76
    ax1.set_ylabel('Portfolio value (USD)')
77
78
    ax2 = fig.add_subplot(212)
79
    ax2.set_ylabel('Price (USD)')
80
81
    # If data has been record()ed, then plot it.
82
    # Otherwise, log the fact that no data has been recorded.
83
    if ('AAPL' in results and 'short_mavg' in results and
84
            'long_mavg' in results):
85
        results['AAPL'].plot(ax=ax2)
86
        results[['short_mavg', 'long_mavg']].plot(ax=ax2)
87
88
        trans = results.ix[[t != [] for t in results.transactions]]
89
        buys = trans.ix[[t[0]['amount'] > 0 for t in
90
                         trans.transactions]]
91
        sells = trans.ix[
92
            [t[0]['amount'] < 0 for t in trans.transactions]]
93
        ax2.plot(buys.index, results.short_mavg.ix[buys.index],
94
                 '^', markersize=10, color='m')
95
        ax2.plot(sells.index, results.short_mavg.ix[sells.index],
96
                 'v', markersize=10, color='k')
97
        plt.legend(loc=0)
98
    else:
99
        msg = 'AAPL, short_mavg & long_mavg data not captured using record().'
100
        ax2.annotate(msg, xy=(0.1, 0.5))
101
        log.info(msg)
102
103
    plt.show()
104
105
106
# Note: this if-block should be removed if running
107
# this algorithm on quantopian.com
108
if __name__ == '__main__':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
109
    from datetime import datetime
110
    import pytz
111
    from zipline.algorithm import TradingAlgorithm
112
    from zipline.utils.factory import load_from_yahoo
113
114
    # Set the simulation start and end dates.
115
    start = datetime(2011, 1, 1, 0, 0, 0, 0, pytz.utc)
116
    end = datetime(2013, 1, 1, 0, 0, 0, 0, pytz.utc)
117
118
    # Load price data from yahoo.
119
    data = load_from_yahoo(stocks=['AAPL'], indexes={}, start=start,
120
                           end=end)
121
122
    # Create and run the algorithm.
123
    algo = TradingAlgorithm(initialize=initialize, handle_data=handle_data,
124
                            identifiers=['AAPL'])
125
    results = algo.run(data)
126
127
    # Plot the portfolio and asset data.
128
    analyze(results=results)
129