Created
March 15, 2015 22:24
-
-
Save vfilimonov/59d0a6f274aa4ea956be to your computer and use it in GitHub Desktop.
Line_profile of bt.core
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Timer unit: 1e-06 s | |
Total time: 42.1393 s | |
Function: run at line 138 | |
Line # Hits Time Per Hit % Time Line Contents | |
============================================================== | |
138 @profile | |
139 def run(self): | |
140 """ | |
141 Runs the Backtest. | |
142 """ | |
143 # set run flag | |
144 1 4 4.0 0.0 self.has_run = True | |
145 | |
146 # setup strategy | |
147 1 1823 1823.0 0.0 self.strategy.setup(self.data) | |
148 | |
149 # adjust strategy with initial capital | |
150 1 72 72.0 0.0 self.strategy.adjust(self.initial_capital) | |
151 | |
152 # loop through dates | |
153 15382 243227 15.8 0.6 for dt in self.dates: | |
154 15381 30341164 1972.6 72.0 self.strategy.update(dt) | |
155 15381 16845 1.1 0.0 if not self.strategy.bankrupt: | |
156 15381 3982239 258.9 9.5 self.strategy.run() | |
157 # need update after to save weights, values and such | |
158 15381 7133247 463.8 16.9 self.strategy.update(dt) | |
159 | |
160 1 420509 420509.0 1.0 self.stats = self.strategy.prices.calc_perf_stats() | |
161 1 193 193.0 0.0 self._original_prices = self.strategy.prices | |
------------------------------------------------------------------------------------------ | |
------------------------------------------------------------------------------------------ | |
Total time: 36.8753 s | |
Function: update at line 445 | |
Line # Hits Time Per Hit % Time Line Contents | |
============================================================== | |
445 @profile | |
446 @cy.locals(newpt=cy.bint, val=cy.double, ret=cy.double) | |
447 def update(self, date, data=None): | |
448 """ | |
449 Update strategy. Updates prices, values, weight, etc. | |
450 """ | |
451 # resolve stale state | |
452 32258 39960 1.2 0.1 self.root.stale = False | |
453 | |
454 # update helpers on date change | |
455 # also set newpt flag | |
456 32258 28941 0.9 0.1 newpt = False | |
457 32258 92447 2.9 0.3 if self.now == 0: | |
458 1 1 1.0 0.0 newpt = True | |
459 32257 50709 1.6 0.1 elif date != self.now: | |
460 15380 15775 1.0 0.0 self._net_flows = 0 | |
461 15380 17686 1.1 0.0 self._last_price = self._price | |
462 15380 16197 1.1 0.0 self._last_value = self._value | |
463 15380 15333 1.0 0.0 self._last_fee = 0.0 | |
464 15380 14146 0.9 0.0 newpt = True | |
465 | |
466 # update now | |
467 32258 30873 1.0 0.1 self.now = date | |
468 | |
469 # update children if any and calculate value | |
470 32258 30804 1.0 0.1 val = self._capital # default if no children | |
471 | |
472 32258 30687 1.0 0.1 if self.children is not None: | |
473 186896 180790 1.0 0.5 for c in self._childrenv: | |
474 # avoid useless update call | |
475 154638 170296 1.1 0.5 if c._issec and not c._needupdate: | |
476 32912 28111 0.9 0.1 continue | |
477 121726 19818749 162.8 53.7 c.update(date, data) | |
478 121726 313466 2.6 0.9 val += c.value | |
479 | |
480 32258 38404 1.2 0.1 if self.root == self: | |
481 32258 49318 1.5 0.1 if (val < 0) and not self.bankrupt: | |
482 # Declare a bankruptcy | |
483 self.bankrupt = True | |
484 self.flatten() | |
485 | |
486 # update data if this value is different or | |
487 # if now has changed - avoid all this if not since it | |
488 # won't change | |
489 32258 32105 1.0 0.1 if newpt or self._value != val: | |
490 17379 19456 1.1 0.1 self._value = val | |
491 17379 2691677 154.9 7.3 self._values[date] = val | |
492 | |
493 17379 22402 1.3 0.1 try: | |
494 17379 19939 1.1 0.1 ret = self._value / (self._last_value | |
495 17379 51663 3.0 0.1 + self._net_flows) - 1 | |
496 except ZeroDivisionError: | |
497 if self._value == 0: | |
498 ret = 0 | |
499 else: | |
500 raise ZeroDivisionError( | |
501 'Could not update %s. Last value ' | |
502 'was %s and net flows were %s. Current' | |
503 'value is %s. Therefore, ' | |
504 'we are dividing by zero to obtain the return ' | |
505 'for the period.' % (self.name, | |
506 self._last_value, | |
507 self._net_flows, | |
508 self._value)) | |
509 | |
510 17379 33130 1.9 0.1 self._price = self._last_price * (1 + ret) | |
511 17379 2580966 148.5 7.0 self._prices[date] = self._price | |
512 | |
513 # update children weights | |
514 32258 41999 1.3 0.1 if self.children is not None: | |
515 186896 186224 1.0 0.5 for c in self._childrenv: | |
516 # avoid useless update call | |
517 154638 170179 1.1 0.5 if c._issec and not c._needupdate: | |
518 33049 29423 0.9 0.1 continue | |
519 121589 109302 0.9 0.3 try: | |
520 121589 279699 2.3 0.8 c._weight = c.value / val | |
521 except ZeroDivisionError: | |
522 c._weight = 0.0 | |
523 | |
524 # if we have strategy children, we will need to update them in universe | |
525 32258 32696 1.0 0.1 if self._has_strat_children: | |
526 for c in self._strat_children: | |
527 self._universe.loc[date, c] = self.children[c].price | |
528 | |
529 # Cash should track the unallocated capital at the end of the day, so | |
530 # we should update it every time we call "update". | |
531 # Same for fees | |
532 32258 4785452 148.3 13.0 self._cash[self.now] = self._capital | |
533 32258 4758236 147.5 12.9 self._fees[self.now] = self._last_fee | |
534 | |
535 # update paper trade if necessary | |
536 32258 48054 1.5 0.1 if newpt and self._paper_trade: | |
537 self._paper.update(date) | |
538 self._paper.run() | |
539 self._paper.update(date) | |
540 # update price | |
541 self._price = self._paper.price | |
542 self._prices[date] = self._price | |
------------------------------------------------------------------------------------------ | |
------------------------------------------------------------------------------------------ | |
Total time: 18.9958 s | |
Function: update at line 864 | |
Line # Hits Time Per Hit % Time Line Contents | |
============================================================== | |
864 @profile | |
865 @cy.locals(prc=cy.double) | |
866 def update(self, date, data=None): | |
867 """ | |
868 Update security with a given date and optionally, some data. | |
869 This will update price, value, weight, etc. | |
870 """ | |
871 # filter for internal calls when position has not changed - nothing to | |
872 # do. Internal calls (stale root calls) have None data. Also want to | |
873 # make sure date has not changed, because then we do indeed want to | |
874 # update. | |
875 124114 153790 1.2 0.8 if date == self.now and self._last_pos == self._position: | |
876 64827 33961 0.5 0.2 return | |
877 | |
878 # date change - update price | |
879 59287 46605 0.8 0.2 if date != self.now: | |
880 # update now | |
881 57289 39168 0.7 0.2 self.now = date | |
882 | |
883 57289 33409 0.6 0.2 if self._prices_set: | |
884 57289 1202737 21.0 6.3 self._price = self._prices[self.now] | |
885 # traditional data update | |
886 elif data is not None: | |
887 prc = data[self.name] | |
888 self._price = prc | |
889 self._prices[date] = prc | |
890 | |
891 59287 8796913 148.4 46.3 self._positions[date] = self._position | |
892 59287 77070 1.3 0.4 self._last_pos = self._position | |
893 | |
894 59287 135195 2.3 0.7 self._value = self._position * self._price * self.multiplier | |
895 59287 8351837 140.9 44.0 self._values[date] = self._value | |
896 | |
897 59287 124522 2.1 0.7 if self._weight == 0 and self._position == 0: | |
898 664 600 0.9 0.0 self._needupdate = False |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment