Completed
Pull Request — master (#858)
by Eddie
02:03
created

zipline.TestTargetValueAlgorithm   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 26
Duplicated Lines 0 %
Metric Value
dl 0
loc 26
rs 10
wmc 8

2 Methods

Rating   Name   Duplication   Size   Complexity  
B handle_data() 0 20 7
A initialize() 0 4 1
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.set_slippage(FixedSlippage())
348
        self.target_shares = 0
349
        self.sale_price = None
350
351
    def handle_data(self, data):
352
        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...
353
            assert 0 not in self.portfolio.positions
354
        else:
355
            assert self.portfolio.positions[0]['amount'] == \
356
                self.target_shares, "Orders not filled immediately."
357
            assert self.portfolio.positions[0]['last_sale_price'] == \
358
                data[0].price, "Orders not filled at current price."
359
        self.target_shares = 10
360
        self.order_target(self.sid(0), self.target_shares)
361
362
363
class TestOrderPercentAlgorithm(TradingAlgorithm):
364
    def initialize(self):
365
        self.set_slippage(FixedSlippage())
366
        self.target_shares = 0
367
        self.sale_price = None
368
369
    def handle_data(self, data):
370
        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...
371
            assert 0 not in self.portfolio.positions
372
            self.order(self.sid(0), 10)
373
            self.target_shares = 10
374
            return
375
        else:
376
377
            assert self.portfolio.positions[0]['amount'] == \
378
                self.target_shares, "Orders not filled immediately."
379
            assert self.portfolio.positions[0]['last_sale_price'] == \
380
                data[0].price, "Orders not filled at current price."
381
382
        self.order_percent(self.sid(0), .001)
383
384
        if isinstance(self.sid(0), Equity):
385
            price = data[0].price
386
            new_shares = (.001 * self.portfolio.portfolio_value) / price
387
        elif isinstance(self.sid(0), Future):
388
            new_shares = (.001 * self.portfolio.portfolio_value) / \
389
                (data[0].price * self.sid(0).contract_multiplier)
390
391
        new_shares = int(round_if_near_integer(new_shares))
392
        self.target_shares += new_shares
393
394
395
class TestTargetPercentAlgorithm(TradingAlgorithm):
396
    def initialize(self):
397
        self.ordered = False
398
        self.sale_price = None
399
400
        # this makes the math easier to check
401
        self.set_slippage(FixedSlippage())
402
        self.set_commission(PerShare(0))
403
404
    def handle_data(self, data):
405
        if not self.ordered:
406
            assert 0 not in self.portfolio.positions
407
        else:
408
            # Since you can't own fractional shares (at least in this
409
            # example), we want to make sure that our target amount is
410
            # no more than a share's value away from our current
411
            # holdings.
412
            target_value = self.portfolio.portfolio_value * 0.002
413
            position_value = self.portfolio.positions[0]['amount'] * \
414
                self.sale_price
415
416
            assert abs(target_value - position_value) <= self.sale_price, \
417
                "Orders not filled correctly"
418
419
            assert self.portfolio.positions[0]['last_sale_price'] == \
420
                data[0].price, "Orders not filled at current price."
421
422
        self.sale_price = data[0].price
423
        self.order_target_percent(self.sid(0), .002)
424
        self.ordered = True
425
426
427
class TestTargetValueAlgorithm(TradingAlgorithm):
428
    def initialize(self):
429
        self.set_slippage(FixedSlippage())
430
        self.target_shares = 0
431
        self.sale_price = None
432
433
    def handle_data(self, data):
434
        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...
435
            assert 0 not in self.portfolio.positions
436
            self.order(self.sid(0), 10)
437
            self.target_shares = 10
438
            return
439
        else:
440
            assert self.portfolio.positions[0]['amount'] == \
441
                self.target_shares, "Orders not filled immediately."
442
            assert self.portfolio.positions[0]['last_sale_price'] == \
443
                data[0].price, "Orders not filled at current price."
444
445
        self.order_target_value(self.sid(0), 20)
446
        self.target_shares = np.round(20 / data[0].price)
447
448
        if isinstance(self.sid(0), Equity):
449
            self.target_shares = np.round(20 / data[0].price)
450
        if isinstance(self.sid(0), Future):
451
            self.target_shares = np.round(
452
                20 / (data[0].price * self.sid(0).contract_multiplier))
453
454
455
class FutureFlipAlgo(TestAlgorithm):
456
    def handle_data(self, data):
457
        if len(self.portfolio.positions) > 0:
458
            if self.portfolio.positions[self.asset.sid]["amount"] > 0:
459
                self.order_target(self.asset, -self.amount)
460
            else:
461
                self.order_target(self.asset, 0)
462
        else:
463
            self.order_target(self.asset, self.amount)
464
465
############################
466
# AccountControl Test Algos#
467
############################
468
469
470
class SetMaxLeverageAlgorithm(TradingAlgorithm):
471
    def initialize(self, max_leverage=None):
472
        self.set_max_leverage(max_leverage=max_leverage)
473
474
475
############################
476
# TradingControl Test Algos#
477
############################
478
479
480
class SetMaxPositionSizeAlgorithm(TradingAlgorithm):
481
    def initialize(self, sid=None, max_shares=None, max_notional=None):
482
        self.set_slippage(FixedSlippage())
483
        self.order_count = 0
484
        self.set_max_position_size(sid=sid,
485
                                   max_shares=max_shares,
486
                                   max_notional=max_notional)
487
488
489
class SetMaxOrderSizeAlgorithm(TradingAlgorithm):
490
    def initialize(self, sid=None, max_shares=None, max_notional=None):
491
        self.order_count = 0
492
        self.set_max_order_size(sid=sid,
493
                                max_shares=max_shares,
494
                                max_notional=max_notional)
495
496
497
class SetDoNotOrderListAlgorithm(TradingAlgorithm):
498
    def initialize(self, sid=None, restricted_list=None):
499
        self.order_count = 0
500
        self.set_do_not_order_list(restricted_list)
501
502
503
class SetMaxOrderCountAlgorithm(TradingAlgorithm):
504
    def initialize(self, count):
505
        self.order_count = 0
506
        self.set_max_order_count(count)
507
        self.minute_count = 0
508
509
510
class SetLongOnlyAlgorithm(TradingAlgorithm):
511
    def initialize(self):
512
        self.order_count = 0
513
        self.set_long_only()
514
515
516
class SetAssetDateBoundsAlgorithm(TradingAlgorithm):
517
    """
518
    Algorithm that tries to order 1 share of sid 0 on every bar and has an
519
    AssetDateBounds() trading control in place.
520
    """
521
    def initialize(self):
522
        self.register_trading_control(AssetDateBounds())
523
524
    def handle_data(algo, data):
525
        algo.order(algo.sid(0), 1)
526
527
528
class TestRegisterTransformAlgorithm(TradingAlgorithm):
529
    def initialize(self, *args, **kwargs):
530
        self.set_slippage(FixedSlippage())
531
532
    def handle_data(self, data):
533
        pass
534
535
536
class AmbitiousStopLimitAlgorithm(TradingAlgorithm):
537
    """
538
    Algorithm that tries to buy with extremely low stops/limits and tries to
539
    sell with extremely high versions of same. Should not end up with any
540
    positions for reasonable data.
541
    """
542
543
    def initialize(self, *args, **kwargs):
544
        self.asset = self.sid(kwargs.pop('sid'))
545
546
    def handle_data(self, data):
547
548
        ########
549
        # Buys #
550
        ########
551
552
        # Buy with low limit, shouldn't trigger.
553
        self.order(self.asset, 100, limit_price=1)
554
555
        # But with high stop, shouldn't trigger
556
        self.order(self.asset, 100, stop_price=10000000)
557
558
        # Buy with high limit (should trigger) but also high stop (should
559
        # prevent trigger).
560
        self.order(self.asset, 100, limit_price=10000000, stop_price=10000000)
561
562
        # Buy with low stop (should trigger), but also low limit (should
563
        # prevent trigger).
564
        self.order(self.asset, 100, limit_price=1, stop_price=1)
565
566
        #########
567
        # Sells #
568
        #########
569
570
        # Sell with high limit, shouldn't trigger.
571
        self.order(self.asset, -100, limit_price=1000000)
572
573
        # Sell with low stop, shouldn't trigger.
574
        self.order(self.asset, -100, stop_price=1)
575
576
        # Sell with low limit (should trigger), but also high stop (should
577
        # prevent trigger).
578
        self.order(self.asset, -100, limit_price=1000000, stop_price=1000000)
579
580
        # Sell with low limit (should trigger), but also low stop (should
581
        # prevent trigger).
582
        self.order(self.asset, -100, limit_price=1, stop_price=1)
583
584
        ###################
585
        # Rounding Checks #
586
        ###################
587
        self.order(self.asset, 100, limit_price=.00000001)
588
        self.order(self.asset, -100, stop_price=.00000001)
589
590
591
class SetPortfolioAlgorithm(TradingAlgorithm):
592
    """
593
    An algorithm that tries to set the portfolio directly.
594
595
    The portfolio should be treated as a read-only object
596
    within the algorithm.
597
    """
598
599
    def initialize(self, *args, **kwargs):
600
        pass
601
602
    def handle_data(self, data):
603
        self.portfolio = 3
604
605
606
class TALIBAlgorithm(TradingAlgorithm):
607
    """
608
    An algorithm that applies a TA-Lib transform. The transform object can be
609
    passed at initialization with the 'talib' keyword argument. The results are
610
    stored in the talib_results array.
611
    """
612
    def initialize(self, *args, **kwargs):
613
614
        if 'talib' not in kwargs:
615
            raise KeyError('No TA-LIB transform specified '
616
                           '(use keyword \'talib\').')
617
        elif not isinstance(kwargs['talib'], (list, tuple)):
618
            self.talib_transforms = (kwargs['talib'],)
619
        else:
620
            self.talib_transforms = kwargs['talib']
621
622
        self.talib_results = dict((t, []) for t in self.talib_transforms)
623
624
    def handle_data(self, data):
625
        for t in self.talib_transforms:
626
            result = t.handle_data(data)
627
            if result is None:
628
                if len(t.talib_fn.output_names) == 1:
629
                    result = np.nan
630
                else:
631
                    result = (np.nan,) * len(t.talib_fn.output_names)
632
            self.talib_results[t].append(result)
633
634
635
class EmptyPositionsAlgorithm(TradingAlgorithm):
636
    """
637
    An algorithm that ensures that 'phantom' positions do not appear in
638
    portfolio.positions in the case that a position has been entered
639
    and fully exited.
640
    """
641
    def initialize(self, sids, *args, **kwargs):
642
        self.ordered = False
643
        self.exited = False
644
        self.sids = sids
645
646
    def handle_data(self, data):
647
        if not self.ordered:
648
            for s in self.sids:
649
                self.order(self.sid(s), 1)
650
            self.ordered = True
651
652
        if not self.exited:
653
            amounts = [pos.amount for pos
654
                       in itervalues(self.portfolio.positions)]
655
656
            if (
657
                len(amounts) > 0 and
658
                all([(amount == 1) for amount in amounts])
659
            ):
660
                for stock in self.portfolio.positions:
661
                    self.order(self.sid(stock), -1)
662
                self.exited = True
663
664
        # Should be 0 when all positions are exited.
665
        self.record(num_positions=len(self.portfolio.positions))
666
667
668
class InvalidOrderAlgorithm(TradingAlgorithm):
669
    """
670
    An algorithm that tries to make various invalid order calls, verifying that
671
    appropriate exceptions are raised.
672
    """
673
    def initialize(self, *args, **kwargs):
674
        self.asset = self.sid(kwargs.pop('sids')[0])
675
676
    def handle_data(self, data):
677
        from zipline.api import (
678
            order_percent,
679
            order_target,
680
            order_target_percent,
681
            order_target_value,
682
            order_value,
683
        )
684
685
        for style in [MarketOrder(), LimitOrder(10),
686
                      StopOrder(10), StopLimitOrder(10, 10)]:
687
688
            with assert_raises(UnsupportedOrderParameters):
689
                order(self.asset, 10, limit_price=10, style=style)
690
691
            with assert_raises(UnsupportedOrderParameters):
692
                order(self.asset, 10, stop_price=10, style=style)
693
694
            with assert_raises(UnsupportedOrderParameters):
695
                order_value(self.asset, 300, limit_price=10, style=style)
696
697
            with assert_raises(UnsupportedOrderParameters):
698
                order_value(self.asset, 300, stop_price=10, style=style)
699
700
            with assert_raises(UnsupportedOrderParameters):
701
                order_percent(self.asset, .1, limit_price=10, style=style)
702
703
            with assert_raises(UnsupportedOrderParameters):
704
                order_percent(self.asset, .1, stop_price=10, style=style)
705
706
            with assert_raises(UnsupportedOrderParameters):
707
                order_target(self.asset, 100, limit_price=10, style=style)
708
709
            with assert_raises(UnsupportedOrderParameters):
710
                order_target(self.asset, 100, stop_price=10, style=style)
711
712
            with assert_raises(UnsupportedOrderParameters):
713
                order_target_value(self.asset, 100,
714
                                   limit_price=10,
715
                                   style=style)
716
717
            with assert_raises(UnsupportedOrderParameters):
718
                order_target_value(self.asset, 100,
719
                                   stop_price=10,
720
                                   style=style)
721
722
            with assert_raises(UnsupportedOrderParameters):
723
                order_target_percent(self.asset, .2,
724
                                     limit_price=10,
725
                                     style=style)
726
727
            with assert_raises(UnsupportedOrderParameters):
728
                order_target_percent(self.asset, .2,
729
                                     stop_price=10,
730
                                     style=style)
731
732
733
##############################
734
# Quantopian style algorithms
735
736
# Noop algo
737
def initialize_noop(context):
738
    pass
739
740
741
def handle_data_noop(context, data):
742
    pass
743
744
745
# API functions
746
def initialize_api(context):
747
    context.incr = 0
748
    context.sale_price = None
749
    set_slippage(FixedSlippage())
750
751
752
def handle_data_api(context, data):
753
    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...
754
        assert 0 not in context.portfolio.positions
755
    else:
756
        assert context.portfolio.positions[0]['amount'] == \
757
            context.incr, "Orders not filled immediately."
758
        assert context.portfolio.positions[0]['last_sale_price'] == \
759
            data[0].price, "Orders not filled at current price."
760
    context.incr += 1
761
    order(sid(0), 1)
762
763
    record(incr=context.incr)
764
765
###########################
766
# AlgoScripts as strings
767
noop_algo = """
768
# Noop algo
769
def initialize(context):
770
    pass
771
772
def handle_data(context, data):
773
    pass
774
"""
775
776
api_algo = """
777
from zipline.api import (order,
778
                         set_slippage,
779
                         FixedSlippage,
780
                         record,
781
                         sid)
782
783
def initialize(context):
784
    context.incr = 0
785
    context.sale_price = None
786
    set_slippage(FixedSlippage())
787
788
def handle_data(context, data):
789
    if context.incr == 0:
790
        assert 0 not in context.portfolio.positions
791
    else:
792
        assert context.portfolio.positions[0]['amount'] == \
793
                context.incr, "Orders not filled immediately."
794
        assert context.portfolio.positions[0]['last_sale_price'] == \
795
                data[0].price, "Orders not filled at current price."
796
    context.incr += 1
797
    order(sid(0), 1)
798
799
    record(incr=context.incr)
800
"""
801
802
api_get_environment_algo = """
803
from zipline.api import get_environment, order, symbol
804
805
806
def initialize(context):
807
    context.environment = get_environment()
808
809
def handle_data(context, data):
810
    pass
811
"""
812
813
api_symbol_algo = """
814
from zipline.api import (order,
815
                         symbol)
816
817
def initialize(context):
818
    pass
819
820
def handle_data(context, data):
821
    order(symbol('TEST'), 1)
822
"""
823
824
call_order_in_init = """
825
from zipline.api import (order)
826
827
def initialize(context):
828
    order(0, 10)
829
    pass
830
831
def handle_data(context, data):
832
    pass
833
"""
834
835
access_portfolio_in_init = """
836
def initialize(context):
837
    var = context.portfolio.cash
838
    pass
839
840
def handle_data(context, data):
841
    pass
842
"""
843
844
access_account_in_init = """
845
def initialize(context):
846
    var = context.account.settled_cash
847
    pass
848
849
def handle_data(context, data):
850
    pass
851
"""
852
853
call_all_order_methods = """
854
from zipline.api import (order,
855
                         order_value,
856
                         order_percent,
857
                         order_target,
858
                         order_target_value,
859
                         order_target_percent,
860
                         sid)
861
862
def initialize(context):
863
    pass
864
865
def handle_data(context, data):
866
    order(sid(0), 10)
867
    order_value(sid(0), 300)
868
    order_percent(sid(0), .1)
869
    order_target(sid(0), 100)
870
    order_target_value(sid(0), 100)
871
    order_target_percent(sid(0), .2)
872
"""
873
874
record_variables = """
875
from zipline.api import record
876
877
def initialize(context):
878
    context.stocks = [0, 1]
879
    context.incr = 0
880
881
def handle_data(context, data):
882
    context.incr += 1
883
    record(incr=context.incr)
884
"""
885
886
record_float_magic = """
887
from zipline.api import record
888
889
def initialize(context):
890
    context.stocks = [0, 1]
891
    context.incr = 0
892
893
def handle_data(context, data):
894
    context.incr += 1
895
    record(data=float('%s'))
896
"""
897