Completed
Pull Request — master (#858)
by Eddie
01:35
created

zipline.BatchTransformAlgorithmMinute   A

Complexity

Total Complexity 2

Size/Duplication

Total Lines 19
Duplicated Lines 0 %
Metric Value
dl 0
loc 19
rs 10
wmc 2
1
#
2
# Copyright 2014 Quantopian, Inc.
3
#
4
# Licensed under the Apache License, Version 2.0 (the "License");
5
# you may not use this file except in compliance with the License.
6
# You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
16
17
"""
18
Algorithm Protocol
19
===================
20
21
For a class to be passed as a trading algorithm to the
22
:py:class:`zipline.lines.SimulatedTrading` zipline it must follow an
23
implementation protocol. Examples of this algorithm protocol are provided
24
below.
25
26
The algorithm must expose methods:
27
28
  - initialize: method that takes no args, no returns. Simply called to
29
    enable the algorithm to set any internal state needed.
30
31
  - get_sid_filter: method that takes no args, and returns a list of valid
32
    sids. List must have a length between 1 and 10. If None is returned the
33
    filter will block all events.
34
35
  - handle_data: method that accepts a :py:class:`zipline.protocol.BarData`
36
    of the current state of the simulation universe. An example data object:
37
38
        ..  This outputs the table as an HTML table but for some reason there
39
            is no bounding box. Make the previous paraagraph ending colon a
40
            double-colon to turn this back into blockquoted table in ASCII art.
41
42
        +-----------------+--------------+----------------+-------------------+
43
        |                 | sid(133)     |  sid(134)      | sid(135)          |
44
        +=================+==============+================+===================+
45
        | price           | $10.10       | $22.50         | $13.37            |
46
        +-----------------+--------------+----------------+-------------------+
47
        | volume          | 10,000       | 5,000          | 50,000            |
48
        +-----------------+--------------+----------------+-------------------+
49
        | mvg_avg_30      | $9.97        | $22.61         | $13.37            |
50
        +-----------------+--------------+----------------+-------------------+
51
        | dt              | 6/30/2012    | 6/30/2011      | 6/29/2012         |
52
        +-----------------+--------------+----------------+-------------------+
53
54
  - set_order: method that accepts a callable. Will be set as the value of the
55
    order method of trading_client. An algorithm can then place orders with a
56
    valid sid and a number of shares::
57
58
        self.order(sid(133), share_count)
59
60
  - set_performance: property which can be set equal to the
61
    cumulative_trading_performance property of the trading_client. An
62
    algorithm can then check position information with the
63
    Portfolio object::
64
65
        self.Portfolio[sid(133)]['cost_basis']
66
67
  - set_transact_setter: method that accepts a callable. Will
68
    be set as the value of the set_transact_setter method of
69
    the trading_client. This allows an algorithm to change the
70
    slippage model used to predict transactions based on orders
71
    and trade events.
72
73
"""
74
import numpy as np
75
76
from nose.tools import assert_raises
77
78
from six.moves import range
79
from six import itervalues
80
81
from zipline.algorithm import TradingAlgorithm
82
from zipline.api import (
83
    FixedSlippage,
84
    order,
85
    set_slippage,
86
    record,
87
    sid,
88
)
89
from zipline.errors import UnsupportedOrderParameters
90
from zipline.assets import Future, Equity
91
from zipline.finance.commission import PerShare
92
from zipline.finance.execution import (
93
    LimitOrder,
94
    MarketOrder,
95
    StopLimitOrder,
96
    StopOrder,
97
)
98
from zipline.finance.controls import AssetDateBounds
99
from zipline.utils.math_utils import round_if_near_integer
100
101
102
class TestAlgorithm(TradingAlgorithm):
103
    """
104
    This algorithm will send a specified number of orders, to allow unit tests
105
    to verify the orders sent/received, transactions created, and positions
106
    at the close of a simulation.
107
    """
108
109
    def initialize(self,
110
                   sid,
111
                   amount,
112
                   order_count,
113
                   sid_filter=None,
114
                   slippage=None,
115
                   commission=None):
116
        self.count = order_count
117
        self.asset = self.sid(sid)
118
        self.amount = amount
119
        self.incr = 0
120
121
        if sid_filter:
122
            self.sid_filter = sid_filter
123
        else:
124
            self.sid_filter = [self.asset.sid]
125
126
        if slippage is not None:
127
            self.set_slippage(slippage)
128
129
        if commission is not None:
130
            self.set_commission(commission)
131
132
    def handle_data(self, data):
133
        # place an order for amount shares of sid
134
        if self.incr < self.count:
135
            self.order(self.asset, self.amount)
136
            self.incr += 1
137
138
139
class HeavyBuyAlgorithm(TradingAlgorithm):
140
    """
141
    This algorithm will send a specified number of orders, to allow unit tests
142
    to verify the orders sent/received, transactions created, and positions
143
    at the close of a simulation.
144
    """
145
146
    def initialize(self, sid, amount):
147
        self.asset = self.sid(sid)
148
        self.amount = amount
149
        self.incr = 0
150
151
    def handle_data(self, data):
152
        # place an order for 100 shares of sid
153
        self.order(self.asset, self.amount)
154
        self.incr += 1
155
156
157
class NoopAlgorithm(TradingAlgorithm):
158
    """
159
    Dolce fa niente.
160
    """
161
    def initialize(self):
162
        pass
163
164
    def handle_data(self, data):
165
        pass
166
167
168
class ExceptionAlgorithm(TradingAlgorithm):
169
    """
170
    Throw an exception from the method name specified in the
171
    constructor.
172
    """
173
174
    def initialize(self, throw_from, sid):
175
176
        self.throw_from = throw_from
177
        self.asset = self.sid(sid)
178
179
        if self.throw_from == "initialize":
180
            raise Exception("Algo exception in initialize")
181
        else:
182
            pass
183
184
    def set_portfolio(self, portfolio):
185
        if self.throw_from == "set_portfolio":
186
            raise Exception("Algo exception in set_portfolio")
187
        else:
188
            pass
189
190
    def handle_data(self, data):
191
        if self.throw_from == "handle_data":
192
            raise Exception("Algo exception in handle_data")
193
        else:
194
            pass
195
196
    def get_sid_filter(self):
197
        if self.throw_from == "get_sid_filter":
198
            raise Exception("Algo exception in get_sid_filter")
199
        else:
200
            return [self.asset]
201
202
    def set_transact_setter(self, txn_sim_callable):
203
        pass
204
205
206
class DivByZeroAlgorithm(TradingAlgorithm):
207
208
    def initialize(self, sid):
209
        self.asset = self.sid(sid)
210
        self.incr = 0
211
212
    def handle_data(self, data):
213
        self.incr += 1
214
        if self.incr > 1:
215
            5 / 0
216
        pass
217
218
219
class TooMuchProcessingAlgorithm(TradingAlgorithm):
220
221
    def initialize(self, sid):
222
        self.asset = self.sid(sid)
223
224
    def handle_data(self, data):
225
        # Unless we're running on some sort of
226
        # supercomputer this will hit timeout.
227
        for i in range(1000000000):
228
            self.foo = i
229
230
231
class TimeoutAlgorithm(TradingAlgorithm):
232
233
    def initialize(self, sid):
234
        self.asset = self.sid(sid)
235
        self.incr = 0
236
237
    def handle_data(self, data):
238
        if self.incr > 4:
239
            import time
240
            time.sleep(100)
241
        pass
242
243
244
class RecordAlgorithm(TradingAlgorithm):
245
    def initialize(self):
246
        self.incr = 0
247
248
    def handle_data(self, data):
249
        self.incr += 1
250
        self.record(incr=self.incr)
251
        name = 'name'
252
        self.record(name, self.incr)
253
        record(name, self.incr, 'name2', 2, name3=self.incr)
254
255
256
class TestOrderAlgorithm(TradingAlgorithm):
257
    def initialize(self):
258
        self.incr = 0
259
260
    def handle_data(self, data):
261
        if self.incr == 0:
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...
262
            assert 0 not in self.portfolio.positions
263
        else:
264
            assert self.portfolio.positions[0]['amount'] == \
265
                self.incr, "Orders not filled immediately."
266
            assert self.portfolio.positions[0]['last_sale_price'] == \
267
                data[0].price, "Orders not filled at current price."
268
        self.incr += 1
269
        self.order(self.sid(0), 1)
270
271
272
class TestOrderInstantAlgorithm(TradingAlgorithm):
273
    def initialize(self):
274
        self.incr = 0
275
        self.last_price = None
276
277
    def handle_data(self, data):
278
        if self.incr == 0:
279
            assert 0 not in self.portfolio.positions
280
        else:
281
            assert self.portfolio.positions[0]['amount'] == \
282
                self.incr, "Orders not filled immediately."
283
            assert self.portfolio.positions[0]['last_sale_price'] == \
284
                self.last_price, "Orders was not filled at last price."
285
        self.incr += 1
286
        self.order_value(self.sid(0), data[0].price)
287
        self.last_price = data[0].price
288
289
290
class TestOrderStyleForwardingAlgorithm(TradingAlgorithm):
291
    """
292
    Test Algorithm for verifying that ExecutionStyles are properly forwarded by
293
    order API helper methods.  Pass the name of the method to be tested as a
294
    string parameter to this algorithm's constructor.
295
    """
296
297
    def __init__(self, *args, **kwargs):
298
        self.method_name = kwargs.pop('method_name')
299
        super(TestOrderStyleForwardingAlgorithm, self)\
300
            .__init__(*args, **kwargs)
301
302
    def initialize(self):
303
        self.incr = 0
304
        self.last_price = None
305
306
    def handle_data(self, data):
307
        if self.incr == 0:
308
            assert len(self.portfolio.positions.keys()) == 0
309
310
            method_to_check = getattr(self, self.method_name)
311
            method_to_check(self.sid(133),
312
                            data[0].price,
313
                            style=StopLimitOrder(10, 10))
314
315
            assert len(self.blotter.open_orders[self.sid(133)]) == 1
316
            result = self.blotter.open_orders[self.sid(133)][0]
317
            assert result.limit == 10
318
            assert result.stop == 10
319
320
            self.incr += 1
321
322
323
class TestOrderValueAlgorithm(TradingAlgorithm):
324
    def initialize(self):
325
        self.incr = 0
326
        self.sale_price = None
327
328
    def handle_data(self, data):
329
        if self.incr == 0:
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...
330
            assert 0 not in self.portfolio.positions
331
        else:
332
            assert self.portfolio.positions[0]['amount'] == \
333
                self.incr, "Orders not filled immediately."
334
            assert self.portfolio.positions[0]['last_sale_price'] == \
335
                data[0].price, "Orders not filled at current price."
336
        self.incr += 2
337
338
        multiplier = 2.
339
        if isinstance(self.sid(0), Future):
340
            multiplier *= self.sid(0).contract_multiplier
341
342
        self.order_value(self.sid(0), data[0].price * multiplier)
343
344
345
class TestTargetAlgorithm(TradingAlgorithm):
346
    def initialize(self):
347
        self.target_shares = 0
348
        self.sale_price = None
349
350
    def handle_data(self, data):
351
        if self.target_shares == 0:
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...
352
            assert 0 not in self.portfolio.positions
353
        else:
354
            assert self.portfolio.positions[0]['amount'] == \
355
                self.target_shares, "Orders not filled immediately."
356
            assert self.portfolio.positions[0]['last_sale_price'] == \
357
                data[0].price, "Orders not filled at current price."
358
        self.target_shares = 10
359
        self.order_target(self.sid(0), self.target_shares)
360
361
362
class TestOrderPercentAlgorithm(TradingAlgorithm):
363
    def initialize(self):
364
        self.target_shares = 0
365
        self.sale_price = None
366
367
    def handle_data(self, data):
368
        if self.target_shares == 0:
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...
369
            assert 0 not in self.portfolio.positions
370
            self.order(self.sid(0), 10)
371
            self.target_shares = 10
372
            return
373
        else:
374
375
            assert self.portfolio.positions[0]['amount'] == \
376
                self.target_shares, "Orders not filled immediately."
377
            assert self.portfolio.positions[0]['last_sale_price'] == \
378
                data[0].price, "Orders not filled at current price."
379
380
        self.order_percent(self.sid(0), .001)
381
382
        if isinstance(self.sid(0), Equity):
383
            price = data[0].price
384
            new_shares = (.001 * self.portfolio.portfolio_value) / price
385
        elif isinstance(self.sid(0), Future):
386
            new_shares = (.001 * self.portfolio.portfolio_value) / \
387
                (data[0].price * self.sid(0).contract_multiplier)
388
389
        new_shares = int(round_if_near_integer(new_shares))
390
        self.target_shares += new_shares
391
392
393
class TestTargetPercentAlgorithm(TradingAlgorithm):
394
    def initialize(self):
395
        self.ordered = False
396
        self.sale_price = None
397
398
        # this makes the math easier to check
399
        self.commission = PerShare(0)
400
        self.slippage = FixedSlippage(spread=0.0)
401
402
    def handle_data(self, data):
403
        if not self.ordered:
404
            assert 0 not in self.portfolio.positions
405
        else:
406
            # Since you can't own fractional shares (at least in this
407
            # example), we want to make sure that our target amount is
408
            # no more than a share's value away from our current
409
            # holdings.
410
            target_value = self.portfolio.portfolio_value * 0.002
411
            position_value = self.portfolio.positions[0]['amount'] * \
412
                self.sale_price
413
414
            assert abs(target_value - position_value) <= self.sale_price, \
415
                "Orders not filled correctly"
416
417
            assert self.portfolio.positions[0]['last_sale_price'] == \
418
                data[0].price, "Orders not filled at current price."
419
420
        self.sale_price = data[0].price
421
        self.order_target_percent(self.sid(0), .002)
422
        self.ordered = True
423
424
425
class TestTargetValueAlgorithm(TradingAlgorithm):
426
    def initialize(self):
427
        self.target_shares = 0
428
        self.sale_price = None
429
430
    def handle_data(self, data):
431
        if self.target_shares == 0:
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...
432
            assert 0 not in self.portfolio.positions
433
            self.order(self.sid(0), 10)
434
            self.target_shares = 10
435
            return
436
        else:
437
            assert self.portfolio.positions[0]['amount'] == \
438
                self.target_shares, "Orders not filled immediately."
439
            assert self.portfolio.positions[0]['last_sale_price'] == \
440
                data[0].price, "Orders not filled at current price."
441
442
        self.order_target_value(self.sid(0), 20)
443
        self.target_shares = np.round(20 / data[0].price)
444
445
        if isinstance(self.sid(0), Equity):
446
            self.target_shares = np.round(20 / data[0].price)
447
        if isinstance(self.sid(0), Future):
448
            self.target_shares = np.round(
449
                20 / (data[0].price * self.sid(0).contract_multiplier))
450
451
452
class FutureFlipAlgo(TestAlgorithm):
453
    def handle_data(self, data):
454
        if len(self.portfolio.positions) > 0:
455
            if self.portfolio.positions[self.asset.sid]["amount"] > 0:
456
                self.order_target(self.asset, -self.amount)
457
            else:
458
                self.order_target(self.asset, 0)
459
        else:
460
            self.order_target(self.asset, self.amount)
461
462
############################
463
# AccountControl Test Algos#
464
############################
465
466
467
class SetMaxLeverageAlgorithm(TradingAlgorithm):
468
    def initialize(self, max_leverage=None):
469
        self.set_max_leverage(max_leverage=max_leverage)
470
471
472
############################
473
# TradingControl Test Algos#
474
############################
475
476
477
class SetMaxPositionSizeAlgorithm(TradingAlgorithm):
478
    def initialize(self, sid=None, max_shares=None, max_notional=None):
479
        self.order_count = 0
480
        self.set_max_position_size(sid=sid,
481
                                   max_shares=max_shares,
482
                                   max_notional=max_notional)
483
484
485
class SetMaxOrderSizeAlgorithm(TradingAlgorithm):
486
    def initialize(self, sid=None, max_shares=None, max_notional=None):
487
        self.order_count = 0
488
        self.set_max_order_size(sid=sid,
489
                                max_shares=max_shares,
490
                                max_notional=max_notional)
491
492
493
class SetDoNotOrderListAlgorithm(TradingAlgorithm):
494
    def initialize(self, sid=None, restricted_list=None):
495
        self.order_count = 0
496
        self.set_do_not_order_list(restricted_list)
497
498
499
class SetMaxOrderCountAlgorithm(TradingAlgorithm):
500
    def initialize(self, count):
501
        self.order_count = 0
502
        self.set_max_order_count(count)
503
        self.minute_count = 0
504
505
506
class SetLongOnlyAlgorithm(TradingAlgorithm):
507
    def initialize(self):
508
        self.order_count = 0
509
        self.set_long_only()
510
511
512
class SetAssetDateBoundsAlgorithm(TradingAlgorithm):
513
    """
514
    Algorithm that tries to order 1 share of sid 0 on every bar and has an
515
    AssetDateBounds() trading control in place.
516
    """
517
    def initialize(self):
518
        self.register_trading_control(AssetDateBounds())
519
520
    def handle_data(algo, data):
521
        algo.order(algo.sid(0), 1)
522
523
524
class TestRegisterTransformAlgorithm(TradingAlgorithm):
525
    def initialize(self, *args, **kwargs):
526
        self.set_slippage(FixedSlippage())
527
528
    def handle_data(self, data):
529
        pass
530
531
532
class AmbitiousStopLimitAlgorithm(TradingAlgorithm):
533
    """
534
    Algorithm that tries to buy with extremely low stops/limits and tries to
535
    sell with extremely high versions of same. Should not end up with any
536
    positions for reasonable data.
537
    """
538
539
    def initialize(self, *args, **kwargs):
540
        self.asset = self.sid(kwargs.pop('sid'))
541
542
    def handle_data(self, data):
543
544
        ########
545
        # Buys #
546
        ########
547
548
        # Buy with low limit, shouldn't trigger.
549
        self.order(self.asset, 100, limit_price=1)
550
551
        # But with high stop, shouldn't trigger
552
        self.order(self.asset, 100, stop_price=10000000)
553
554
        # Buy with high limit (should trigger) but also high stop (should
555
        # prevent trigger).
556
        self.order(self.asset, 100, limit_price=10000000, stop_price=10000000)
557
558
        # Buy with low stop (should trigger), but also low limit (should
559
        # prevent trigger).
560
        self.order(self.asset, 100, limit_price=1, stop_price=1)
561
562
        #########
563
        # Sells #
564
        #########
565
566
        # Sell with high limit, shouldn't trigger.
567
        self.order(self.asset, -100, limit_price=1000000)
568
569
        # Sell with low stop, shouldn't trigger.
570
        self.order(self.asset, -100, stop_price=1)
571
572
        # Sell with low limit (should trigger), but also high stop (should
573
        # prevent trigger).
574
        self.order(self.asset, -100, limit_price=1000000, stop_price=1000000)
575
576
        # Sell with low limit (should trigger), but also low stop (should
577
        # prevent trigger).
578
        self.order(self.asset, -100, limit_price=1, stop_price=1)
579
580
        ###################
581
        # Rounding Checks #
582
        ###################
583
        self.order(self.asset, 100, limit_price=.00000001)
584
        self.order(self.asset, -100, stop_price=.00000001)
585
586
587
class SetPortfolioAlgorithm(TradingAlgorithm):
588
    """
589
    An algorithm that tries to set the portfolio directly.
590
591
    The portfolio should be treated as a read-only object
592
    within the algorithm.
593
    """
594
595
    def initialize(self, *args, **kwargs):
596
        pass
597
598
    def handle_data(self, data):
599
        self.portfolio = 3
600
601
602
class TALIBAlgorithm(TradingAlgorithm):
603
    """
604
    An algorithm that applies a TA-Lib transform. The transform object can be
605
    passed at initialization with the 'talib' keyword argument. The results are
606
    stored in the talib_results array.
607
    """
608
    def initialize(self, *args, **kwargs):
609
610
        if 'talib' not in kwargs:
611
            raise KeyError('No TA-LIB transform specified '
612
                           '(use keyword \'talib\').')
613
        elif not isinstance(kwargs['talib'], (list, tuple)):
614
            self.talib_transforms = (kwargs['talib'],)
615
        else:
616
            self.talib_transforms = kwargs['talib']
617
618
        self.talib_results = dict((t, []) for t in self.talib_transforms)
619
620
    def handle_data(self, data):
621
        for t in self.talib_transforms:
622
            result = t.handle_data(data)
623
            if result is None:
624
                if len(t.talib_fn.output_names) == 1:
625
                    result = np.nan
626
                else:
627
                    result = (np.nan,) * len(t.talib_fn.output_names)
628
            self.talib_results[t].append(result)
629
630
631
class EmptyPositionsAlgorithm(TradingAlgorithm):
632
    """
633
    An algorithm that ensures that 'phantom' positions do not appear in
634
    portfolio.positions in the case that a position has been entered
635
    and fully exited.
636
    """
637
    def initialize(self, sids, *args, **kwargs):
638
        self.ordered = False
639
        self.exited = False
640
        self.sids = sids
641
642
    def handle_data(self, data):
643
        if not self.ordered:
644
            for s in self.sids:
645
                self.order(self.sid(s), 1)
646
            self.ordered = True
647
648
        if not self.exited:
649
            amounts = [pos.amount for pos
650
                       in itervalues(self.portfolio.positions)]
651
652
            if (
653
                len(amounts) > 0 and
654
                all([(amount == 1) for amount in amounts])
655
            ):
656
                for stock in self.portfolio.positions:
657
                    self.order(self.sid(stock), -1)
658
                self.exited = True
659
660
        # Should be 0 when all positions are exited.
661
        self.record(num_positions=len(self.portfolio.positions))
662
663
664
class InvalidOrderAlgorithm(TradingAlgorithm):
665
    """
666
    An algorithm that tries to make various invalid order calls, verifying that
667
    appropriate exceptions are raised.
668
    """
669
    def initialize(self, *args, **kwargs):
670
        self.asset = self.sid(kwargs.pop('sids')[0])
671
672
    def handle_data(self, data):
673
        from zipline.api import (
674
            order_percent,
675
            order_target,
676
            order_target_percent,
677
            order_target_value,
678
            order_value,
679
        )
680
681
        for style in [MarketOrder(), LimitOrder(10),
682
                      StopOrder(10), StopLimitOrder(10, 10)]:
683
684
            with assert_raises(UnsupportedOrderParameters):
685
                order(self.asset, 10, limit_price=10, style=style)
686
687
            with assert_raises(UnsupportedOrderParameters):
688
                order(self.asset, 10, stop_price=10, style=style)
689
690
            with assert_raises(UnsupportedOrderParameters):
691
                order_value(self.asset, 300, limit_price=10, style=style)
692
693
            with assert_raises(UnsupportedOrderParameters):
694
                order_value(self.asset, 300, stop_price=10, style=style)
695
696
            with assert_raises(UnsupportedOrderParameters):
697
                order_percent(self.asset, .1, limit_price=10, style=style)
698
699
            with assert_raises(UnsupportedOrderParameters):
700
                order_percent(self.asset, .1, stop_price=10, style=style)
701
702
            with assert_raises(UnsupportedOrderParameters):
703
                order_target(self.asset, 100, limit_price=10, style=style)
704
705
            with assert_raises(UnsupportedOrderParameters):
706
                order_target(self.asset, 100, stop_price=10, style=style)
707
708
            with assert_raises(UnsupportedOrderParameters):
709
                order_target_value(self.asset, 100,
710
                                   limit_price=10,
711
                                   style=style)
712
713
            with assert_raises(UnsupportedOrderParameters):
714
                order_target_value(self.asset, 100,
715
                                   stop_price=10,
716
                                   style=style)
717
718
            with assert_raises(UnsupportedOrderParameters):
719
                order_target_percent(self.asset, .2,
720
                                     limit_price=10,
721
                                     style=style)
722
723
            with assert_raises(UnsupportedOrderParameters):
724
                order_target_percent(self.asset, .2,
725
                                     stop_price=10,
726
                                     style=style)
727
728
729
##############################
730
# Quantopian style algorithms
731
732
# Noop algo
733
def initialize_noop(context):
734
    pass
735
736
737
def handle_data_noop(context, data):
738
    pass
739
740
741
# API functions
742
def initialize_api(context):
743
    context.incr = 0
744
    context.sale_price = None
745
    set_slippage(FixedSlippage())
746
747
748
def handle_data_api(context, data):
749
    if context.incr == 0:
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...
750
        assert 0 not in context.portfolio.positions
751
    else:
752
        assert context.portfolio.positions[0]['amount'] == \
753
            context.incr, "Orders not filled immediately."
754
        assert context.portfolio.positions[0]['last_sale_price'] == \
755
            data[0].price, "Orders not filled at current price."
756
    context.incr += 1
757
    order(sid(0), 1)
758
759
    record(incr=context.incr)
760
761
###########################
762
# AlgoScripts as strings
763
noop_algo = """
764
# Noop algo
765
def initialize(context):
766
    pass
767
768
def handle_data(context, data):
769
    pass
770
"""
771
772
api_algo = """
773
from zipline.api import (order,
774
                         set_slippage,
775
                         FixedSlippage,
776
                         record,
777
                         sid)
778
779
def initialize(context):
780
    context.incr = 0
781
    context.sale_price = None
782
    set_slippage(FixedSlippage())
783
784
def handle_data(context, data):
785
    if context.incr == 0:
786
        assert 0 not in context.portfolio.positions
787
    else:
788
        assert context.portfolio.positions[0]['amount'] == \
789
                context.incr, "Orders not filled immediately."
790
        assert context.portfolio.positions[0]['last_sale_price'] == \
791
                data[0].price, "Orders not filled at current price."
792
    context.incr += 1
793
    order(sid(0), 1)
794
795
    record(incr=context.incr)
796
"""
797
798
api_get_environment_algo = """
799
from zipline.api import get_environment, order, symbol
800
801
802
def initialize(context):
803
    context.environment = get_environment()
804
805
def handle_data(context, data):
806
    pass
807
"""
808
809
api_symbol_algo = """
810
from zipline.api import (order,
811
                         symbol)
812
813
def initialize(context):
814
    pass
815
816
def handle_data(context, data):
817
    order(symbol('TEST'), 1)
818
"""
819
820
call_order_in_init = """
821
from zipline.api import (order)
822
823
def initialize(context):
824
    order(0, 10)
825
    pass
826
827
def handle_data(context, data):
828
    pass
829
"""
830
831
access_portfolio_in_init = """
832
def initialize(context):
833
    var = context.portfolio.cash
834
    pass
835
836
def handle_data(context, data):
837
    pass
838
"""
839
840
access_account_in_init = """
841
def initialize(context):
842
    var = context.account.settled_cash
843
    pass
844
845
def handle_data(context, data):
846
    pass
847
"""
848
849
call_all_order_methods = """
850
from zipline.api import (order,
851
                         order_value,
852
                         order_percent,
853
                         order_target,
854
                         order_target_value,
855
                         order_target_percent,
856
                         sid)
857
858
def initialize(context):
859
    pass
860
861
def handle_data(context, data):
862
    order(sid(0), 10)
863
    order_value(sid(0), 300)
864
    order_percent(sid(0), .1)
865
    order_target(sid(0), 100)
866
    order_target_value(sid(0), 100)
867
    order_target_percent(sid(0), .2)
868
"""
869
870
record_variables = """
871
from zipline.api import record
872
873
def initialize(context):
874
    context.stocks = [0, 1]
875
    context.incr = 0
876
877
def handle_data(context, data):
878
    context.incr += 1
879
    record(incr=context.incr)
880
"""
881
882
record_float_magic = """
883
from zipline.api import record
884
885
def initialize(context):
886
    context.stocks = [0, 1]
887
    context.incr = 0
888
889
def handle_data(context, data):
890
    context.incr += 1
891
    record(data=float('%s'))
892
"""
893