Skip to content

Instantly share code, notes, and snippets.

@vfilimonov
Created March 15, 2015 22:24
Show Gist options
  • Save vfilimonov/59d0a6f274aa4ea956be to your computer and use it in GitHub Desktop.
Save vfilimonov/59d0a6f274aa4ea956be to your computer and use it in GitHub Desktop.
Line_profile of bt.core
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