Full Code of mementum/backtrader for AI

master b853d7c90b67 cached
378 files
6.7 MB
1.8M tokens
2596 symbols
1 requests
Download .txt
Showing preview only (7,064K chars total). Download the full file or copy to clipboard to get everything.
Repository: mementum/backtrader
Branch: master
Commit: b853d7c90b67
Files: 378
Total size: 6.7 MB

Directory structure:
gitextract_g33g5s6j/

├── .github/
│   └── FUNDING.yml
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.rst
├── backtrader/
│   ├── __init__.py
│   ├── analyzer.py
│   ├── analyzers/
│   │   ├── __init__.py
│   │   ├── annualreturn.py
│   │   ├── calmar.py
│   │   ├── drawdown.py
│   │   ├── leverage.py
│   │   ├── logreturnsrolling.py
│   │   ├── periodstats.py
│   │   ├── positions.py
│   │   ├── pyfolio.py
│   │   ├── returns.py
│   │   ├── sharpe.py
│   │   ├── sqn.py
│   │   ├── timereturn.py
│   │   ├── tradeanalyzer.py
│   │   ├── transactions.py
│   │   └── vwr.py
│   ├── broker.py
│   ├── brokers/
│   │   ├── __init__.py
│   │   ├── bbroker.py
│   │   ├── ibbroker.py
│   │   ├── oandabroker.py
│   │   └── vcbroker.py
│   ├── btrun/
│   │   ├── __init__.py
│   │   └── btrun.py
│   ├── cerebro.py
│   ├── comminfo.py
│   ├── commissions/
│   │   └── __init__.py
│   ├── dataseries.py
│   ├── errors.py
│   ├── feed.py
│   ├── feeds/
│   │   ├── __init__.py
│   │   ├── blaze.py
│   │   ├── btcsv.py
│   │   ├── chainer.py
│   │   ├── csvgeneric.py
│   │   ├── ibdata.py
│   │   ├── influxfeed.py
│   │   ├── mt4csv.py
│   │   ├── oanda.py
│   │   ├── pandafeed.py
│   │   ├── quandl.py
│   │   ├── rollover.py
│   │   ├── sierrachart.py
│   │   ├── vcdata.py
│   │   ├── vchart.py
│   │   ├── vchartcsv.py
│   │   ├── vchartfile.py
│   │   └── yahoo.py
│   ├── fillers.py
│   ├── filters/
│   │   ├── __init__.py
│   │   ├── bsplitter.py
│   │   ├── calendardays.py
│   │   ├── datafiller.py
│   │   ├── datafilter.py
│   │   ├── daysteps.py
│   │   ├── heikinashi.py
│   │   ├── renko.py
│   │   └── session.py
│   ├── flt.py
│   ├── functions.py
│   ├── indicator.py
│   ├── indicators/
│   │   ├── __init__.py
│   │   ├── accdecoscillator.py
│   │   ├── aroon.py
│   │   ├── atr.py
│   │   ├── awesomeoscillator.py
│   │   ├── basicops.py
│   │   ├── bollinger.py
│   │   ├── cci.py
│   │   ├── contrib/
│   │   │   ├── __init__.py
│   │   │   └── vortex.py
│   │   ├── crossover.py
│   │   ├── dema.py
│   │   ├── deviation.py
│   │   ├── directionalmove.py
│   │   ├── dma.py
│   │   ├── dpo.py
│   │   ├── dv2.py
│   │   ├── ema.py
│   │   ├── envelope.py
│   │   ├── hadelta.py
│   │   ├── heikinashi.py
│   │   ├── hma.py
│   │   ├── hurst.py
│   │   ├── ichimoku.py
│   │   ├── kama.py
│   │   ├── kst.py
│   │   ├── lrsi.py
│   │   ├── mabase.py
│   │   ├── macd.py
│   │   ├── momentum.py
│   │   ├── ols.py
│   │   ├── oscillator.py
│   │   ├── percentchange.py
│   │   ├── percentrank.py
│   │   ├── pivotpoint.py
│   │   ├── prettygoodoscillator.py
│   │   ├── priceoscillator.py
│   │   ├── psar.py
│   │   ├── rmi.py
│   │   ├── rsi.py
│   │   ├── sma.py
│   │   ├── smma.py
│   │   ├── stochastic.py
│   │   ├── trix.py
│   │   ├── tsi.py
│   │   ├── ultimateoscillator.py
│   │   ├── vortex.py
│   │   ├── williams.py
│   │   ├── wma.py
│   │   ├── zlema.py
│   │   └── zlind.py
│   ├── linebuffer.py
│   ├── lineiterator.py
│   ├── lineroot.py
│   ├── lineseries.py
│   ├── mathsupport.py
│   ├── metabase.py
│   ├── observer.py
│   ├── observers/
│   │   ├── __init__.py
│   │   ├── benchmark.py
│   │   ├── broker.py
│   │   ├── buysell.py
│   │   ├── drawdown.py
│   │   ├── logreturns.py
│   │   ├── timereturn.py
│   │   └── trades.py
│   ├── order.py
│   ├── plot/
│   │   ├── __init__.py
│   │   ├── finance.py
│   │   ├── formatters.py
│   │   ├── locator.py
│   │   ├── multicursor.py
│   │   ├── plot.py
│   │   ├── scheme.py
│   │   └── utils.py
│   ├── position.py
│   ├── resamplerfilter.py
│   ├── signal.py
│   ├── signals/
│   │   └── __init__.py
│   ├── sizer.py
│   ├── sizers/
│   │   ├── __init__.py
│   │   ├── fixedsize.py
│   │   └── percents_sizer.py
│   ├── store.py
│   ├── stores/
│   │   ├── __init__.py
│   │   ├── ibstore.py
│   │   ├── oandastore.py
│   │   ├── vchartfile.py
│   │   └── vcstore.py
│   ├── strategies/
│   │   ├── __init__.py
│   │   └── sma_crossover.py
│   ├── strategy.py
│   ├── studies/
│   │   ├── __init__.py
│   │   └── contrib/
│   │       ├── __init__.py
│   │       └── fractal.py
│   ├── talib.py
│   ├── timer.py
│   ├── trade.py
│   ├── tradingcal.py
│   ├── utils/
│   │   ├── __init__.py
│   │   ├── autodict.py
│   │   ├── date.py
│   │   ├── dateintern.py
│   │   ├── flushfile.py
│   │   ├── ordereddefaultdict.py
│   │   └── py3.py
│   ├── version.py
│   └── writer.py
├── changelog.txt
├── contrib/
│   ├── datas/
│   │   ├── daily-KO.csv
│   │   └── daily-PEP.csv
│   ├── samples/
│   │   └── pair-trading/
│   │       └── pair-trading.py
│   └── utils/
│       ├── influxdb-import.py
│       └── iqfeed-to-influxdb.py
├── datas/
│   ├── 2005-2006-day-001.txt
│   ├── 2006-01-02-volume-min-001.txt
│   ├── 2006-day-001-optix.txt
│   ├── 2006-day-001.txt
│   ├── 2006-day-002.txt
│   ├── 2006-min-005.txt
│   ├── 2006-month-001.txt
│   ├── 2006-volume-day-001.txt
│   ├── 2006-week-001.txt
│   ├── 2006-week-002.txt
│   ├── bidask.csv
│   ├── bidask2.csv
│   ├── nvda-1999-2014.txt
│   ├── nvda-2014.txt
│   ├── orcl-1995-2014.txt
│   ├── orcl-2003-2005.txt
│   ├── orcl-2014.txt
│   ├── ticksample.csv
│   ├── yhoo-1996-2014.txt
│   ├── yhoo-1996-2015.txt
│   ├── yhoo-2003-2005.txt
│   └── yhoo-2014.txt
├── pypi.sh
├── samples/
│   ├── analyzer-annualreturn/
│   │   └── analyzer-annualreturn.py
│   ├── bidask-to-ohlc/
│   │   └── bidask-to-ohlc.py
│   ├── bracket/
│   │   └── bracket.py
│   ├── btfd/
│   │   └── btfd.py
│   ├── calendar-days/
│   │   └── calendar-days.py
│   ├── calmar/
│   │   └── calmar-test.py
│   ├── cheat-on-open/
│   │   └── cheat-on-open.py
│   ├── commission-schemes/
│   │   └── commission-schemes.py
│   ├── credit-interest/
│   │   └── credit-interest.py
│   ├── data-bid-ask/
│   │   └── bidask.py
│   ├── data-filler/
│   │   ├── data-filler.py
│   │   └── relativevolume.py
│   ├── data-multitimeframe/
│   │   └── data-multitimeframe.py
│   ├── data-pandas/
│   │   ├── data-pandas-optix.py
│   │   └── data-pandas.py
│   ├── data-replay/
│   │   └── data-replay.py
│   ├── data-resample/
│   │   └── data-resample.py
│   ├── daysteps/
│   │   └── daysteps.py
│   ├── future-spot/
│   │   └── future-spot.py
│   ├── gold-vs-sp500/
│   │   └── gold-vs-sp500.py
│   ├── ib-cash-bid-ask/
│   │   └── ib-cash-bid-ask.py
│   ├── ibtest/
│   │   └── ibtest.py
│   ├── kselrsi/
│   │   └── ksignal.py
│   ├── lineplotter/
│   │   └── lineplotter.py
│   ├── lrsi/
│   │   └── lrsi-test.py
│   ├── macd-settings/
│   │   └── macd-settings.py
│   ├── memory-savings/
│   │   └── memory-savings.py
│   ├── mixing-timeframes/
│   │   └── mixing-timeframes.py
│   ├── multi-copy/
│   │   └── multi-copy.py
│   ├── multi-example/
│   │   └── mult-values.py
│   ├── multidata-strategy/
│   │   ├── multidata-strategy-unaligned.py
│   │   └── multidata-strategy.py
│   ├── multitrades/
│   │   ├── mtradeobserver.py
│   │   └── multitrades.py
│   ├── oandatest/
│   │   └── oandatest.py
│   ├── observer-benchmark/
│   │   └── observer-benchmark.py
│   ├── observers/
│   │   ├── observers-default-drawdown.py
│   │   ├── observers-default.py
│   │   ├── observers-orderobserver.py
│   │   └── orderobserver.py
│   ├── oco/
│   │   └── oco.py
│   ├── optimization/
│   │   └── optimization.py
│   ├── order-close/
│   │   ├── close-daily.py
│   │   └── close-minute.py
│   ├── order-execution/
│   │   └── order-execution.py
│   ├── order-history/
│   │   └── order-history.py
│   ├── order_target/
│   │   └── order_target.py
│   ├── partial-plot/
│   │   └── partial-plot.py
│   ├── pinkfish-challenge/
│   │   └── pinkfish-challenge.py
│   ├── pivot-point/
│   │   ├── pivotpoint.py
│   │   └── ppsample.py
│   ├── plot-same-axis/
│   │   └── plot-same-axis.py
│   ├── psar/
│   │   ├── psar-intraday.py
│   │   └── psar.py
│   ├── pyfolio2/
│   │   ├── backtrader-pyfolio.ipynb
│   │   └── pyfoliotest.py
│   ├── pyfoliotest/
│   │   ├── backtrader-pyfolio.ipynb
│   │   └── pyfoliotest.py
│   ├── relative-volume/
│   │   ├── relative-volume.py
│   │   └── relvolbybar.py
│   ├── renko/
│   │   └── renko.py
│   ├── resample-tickdata/
│   │   └── resample-tickdata.py
│   ├── rollover/
│   │   └── rollover.py
│   ├── sharpe-timereturn/
│   │   └── sharpe-timereturn.py
│   ├── signals-strategy/
│   │   └── signals-strategy.py
│   ├── sigsmacross/
│   │   ├── sigsmacross.py
│   │   └── sigsmacross2.py
│   ├── sizertest/
│   │   └── sizertest.py
│   ├── slippage/
│   │   └── slippage.py
│   ├── sratio/
│   │   └── sratio.py
│   ├── stop-trading/
│   │   └── stop-loss-approaches.py
│   ├── stoptrail/
│   │   └── trail.py
│   ├── strategy-selection/
│   │   └── strategy-selection.py
│   ├── talib/
│   │   ├── tablibsartest.py
│   │   └── talibtest.py
│   ├── timers/
│   │   ├── scheduled-min.py
│   │   └── scheduled.py
│   ├── tradingcalendar/
│   │   ├── tcal-intra.py
│   │   └── tcal.py
│   ├── vctest/
│   │   └── vctest.py
│   ├── volumefilling/
│   │   └── volumefilling.py
│   ├── vwr/
│   │   └── vwr.py
│   ├── weekdays-filler/
│   │   ├── weekdaysaligner.py
│   │   └── weekdaysfiller.py
│   ├── writer-test/
│   │   └── writer-test.py
│   └── yahoo-test/
│       └── yahoo-test.py
├── setup.py
├── tests/
│   ├── test_analyzer-sqn.py
│   ├── test_analyzer-timereturn.py
│   ├── test_comminfo.py
│   ├── test_data_multiframe.py
│   ├── test_data_replay.py
│   ├── test_data_resample.py
│   ├── test_ind_accdecosc.py
│   ├── test_ind_aroonoscillator.py
│   ├── test_ind_aroonupdown.py
│   ├── test_ind_atr.py
│   ├── test_ind_awesomeoscillator.py
│   ├── test_ind_bbands.py
│   ├── test_ind_cci.py
│   ├── test_ind_dema.py
│   ├── test_ind_demaenvelope.py
│   ├── test_ind_demaosc.py
│   ├── test_ind_dm.py
│   ├── test_ind_dma.py
│   ├── test_ind_downmove.py
│   ├── test_ind_dpo.py
│   ├── test_ind_dv2.py
│   ├── test_ind_ema.py
│   ├── test_ind_emaenvelope.py
│   ├── test_ind_emaosc.py
│   ├── test_ind_envelope.py
│   ├── test_ind_heikinashi.py
│   ├── test_ind_highest.py
│   ├── test_ind_hma.py
│   ├── test_ind_ichimoku.py
│   ├── test_ind_kama.py
│   ├── test_ind_kamaenvelope.py
│   ├── test_ind_kamaosc.py
│   ├── test_ind_kst.py
│   ├── test_ind_lowest.py
│   ├── test_ind_lrsi.py
│   ├── test_ind_macdhisto.py
│   ├── test_ind_minperiod.py
│   ├── test_ind_momentum.py
│   ├── test_ind_momentumoscillator.py
│   ├── test_ind_oscillator.py
│   ├── test_ind_pctchange.py
│   ├── test_ind_pctrank.py
│   ├── test_ind_pgo.py
│   ├── test_ind_ppo.py
│   ├── test_ind_pposhort.py
│   ├── test_ind_priceosc.py
│   ├── test_ind_rmi.py
│   ├── test_ind_roc.py
│   ├── test_ind_rsi.py
│   ├── test_ind_rsi_safe.py
│   ├── test_ind_sma.py
│   ├── test_ind_smaenvelope.py
│   ├── test_ind_smaosc.py
│   ├── test_ind_smma.py
│   ├── test_ind_smmaenvelope.py
│   ├── test_ind_smmaosc.py
│   ├── test_ind_stochastic.py
│   ├── test_ind_stochasticfull.py
│   ├── test_ind_sumn.py
│   ├── test_ind_tema.py
│   ├── test_ind_temaenvelope.py
│   ├── test_ind_temaosc.py
│   ├── test_ind_trix.py
│   ├── test_ind_tsi.py
│   ├── test_ind_ultosc.py
│   ├── test_ind_upmove.py
│   ├── test_ind_vortex.py
│   ├── test_ind_williamsad.py
│   ├── test_ind_williamsr.py
│   ├── test_ind_wma.py
│   ├── test_ind_wmaenvelope.py
│   ├── test_ind_wmaosc.py
│   ├── test_ind_zlema.py
│   ├── test_ind_zlind.py
│   ├── test_metaclass.py
│   ├── test_order.py
│   ├── test_position.py
│   ├── test_strategy_optimized.py
│   ├── test_strategy_unoptimized.py
│   ├── test_study_fractal.py
│   ├── test_trade.py
│   ├── test_writer.py
│   └── testcommon.py
└── tools/
    ├── bt-run.py
    ├── rewrite-data.py
    └── yahoodownload.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: mementum # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']


================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml

# Translations
*.mo
*.pot

# Django stuff:
*.log

# Sphinx documentation
docs/_build/
docs2/_build/

# PyBuilder
target/

# Backups
*.bak
*~
.#*
*#
*.swp
*.swo

.ipynb*
samples2/

# Ignore test files in Datas
datas/*.py

.idea/


================================================
FILE: .travis.yml
================================================
dist: xenial
language: python
python:
  - "3.6"
  - "3.7"
  - "3.8"
  - "nightly"
  - "pypy"
  - "pypy3"

matrix:
  allow_failures:
    python: "3.8-dev"
    python: "nightly"

# command to install dependencies
# install:
#  - pip install your_package
#    pip install git+https://github.com/blampe/IbPy.git

# command to run tests
script: cd tests && nosetests -v -v


================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU General Public License is a free, copyleft license for
software and other kinds of works.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.  We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors.  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received.  You must make sure that they, too, receive
or can get the source code.  And you must show them these terms so they
know their rights.

  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.

  For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software.  For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.

  Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so.  This is fundamentally incompatible with the aim of
protecting users' freedom to change the software.  The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable.  Therefore, we
have designed this version of the GPL to prohibit the practice for those
products.  If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.

  Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary.  To prevent this, the GPL assures that
patents cannot be used to render the program non-free.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Use with the GNU Affero General Public License.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    {one line to give the program's name and a brief idea of what it does.}
    Copyright (C) {year}  {name of author}

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

    {project}  Copyright (C) {year}  {fullname}
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.

  The GNU General Public License does not permit incorporating your program
into proprietary programs.  If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.  But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.


================================================
FILE: README.rst
================================================
backtrader
==========

.. image:: https://img.shields.io/pypi/v/backtrader.svg
   :alt: PyPi Version
   :scale: 100%
   :target: https://pypi.python.org/pypi/backtrader/

..  .. image:: https://img.shields.io/pypi/dm/backtrader.svg
       :alt: PyPi Monthly Donwloads
       :scale: 100%
       :target: https://pypi.python.org/pypi/backtrader/

.. image:: https://img.shields.io/pypi/l/backtrader.svg
   :alt: License
   :scale: 100%
   :target: https://github.com/backtrader/backtrader/blob/master/LICENSE
.. image:: https://travis-ci.org/backtrader/backtrader.png?branch=master
   :alt: Travis-ci Build Status
   :scale: 100%
   :target: https://travis-ci.org/backtrader/backtrader
.. image:: https://img.shields.io/pypi/pyversions/backtrader.svg
   :alt: Python versions
   :scale: 100%
   :target: https://pypi.python.org/pypi/backtrader/

**Yahoo API Note**:

  [2018-11-16] After some testing it would seem that data downloads can be
  again relied upon over the web interface (or API ``v7``)

**Tickets**

  The ticket system is (was, actually) more often than not abused to ask for
  advice about samples.

For **feedback/questions/...** use the `Community <https://community.backtrader.com>`_

Here a snippet of a Simple Moving Average CrossOver. It can be done in several
different ways. Use the docs (and examples) Luke!
::

  from datetime import datetime
  import backtrader as bt

  class SmaCross(bt.SignalStrategy):
      def __init__(self):
          sma1, sma2 = bt.ind.SMA(period=10), bt.ind.SMA(period=30)
          crossover = bt.ind.CrossOver(sma1, sma2)
          self.signal_add(bt.SIGNAL_LONG, crossover)

  cerebro = bt.Cerebro()
  cerebro.addstrategy(SmaCross)

  data0 = bt.feeds.YahooFinanceData(dataname='MSFT', fromdate=datetime(2011, 1, 1),
                                    todate=datetime(2012, 12, 31))
  cerebro.adddata(data0)

  cerebro.run()
  cerebro.plot()

Including a full featured chart. Give it a try! This is included in the samples
as ``sigsmacross/sigsmacross2.py``. Along it is ``sigsmacross.py`` which can be
parametrized from the command line.

Features:
=========

Live Trading and backtesting platform written in Python.

  - Live Data Feed and Trading with

    - Interactive Brokers (needs ``IbPy`` and benefits greatly from an
      installed ``pytz``)
    - *Visual Chart* (needs a fork of ``comtypes`` until a pull request is
      integrated in the release and benefits from ``pytz``)
    - *Oanda* (needs ``oandapy``) (REST API Only - v20 did not support
      streaming when implemented)

  - Data feeds from csv/files, online sources or from *pandas* and *blaze*
  - Filters for datas, like breaking a daily bar into chunks to simulate
    intraday or working with Renko bricks
  - Multiple data feeds and multiple strategies supported
  - Multiple timeframes at once
  - Integrated Resampling and Replaying
  - Step by Step backtesting or at once (except in the evaluation of the Strategy)
  - Integrated battery of indicators
  - *TA-Lib* indicator support (needs python *ta-lib* / check the docs)
  - Easy development of custom indicators
  - Analyzers (for example: TimeReturn, Sharpe Ratio, SQN) and ``pyfolio``
    integration (**deprecated**)
  - Flexible definition of commission schemes
  - Integrated broker simulation with *Market*, *Close*, *Limit*, *Stop*,
    *StopLimit*, *StopTrail*, *StopTrailLimit*and *OCO* orders, bracket order,
    slippage, volume filling strategies and continuous cash adjustmet for
    future-like instruments
  - Sizers for automated staking
  - Cheat-on-Close and Cheat-on-Open modes
  - Schedulers
  - Trading Calendars
  - Plotting (requires matplotlib)

Documentation
=============

The blog:

  - `Blog <http://www.backtrader.com/blog>`_

Read the full documentation at:

  - `Documentation <http://www.backtrader.com/docu>`_

List of built-in Indicators (122)

  - `Indicators Reference <http://www.backtrader.com/docu/indautoref.html>`_

Python 2/3 Support
==================

  - Python >= ``3.2``

  - It also works with ``pypy`` and ``pypy3`` (no plotting - ``matplotlib`` is
    not supported under *pypy*)

Installation
============

``backtrader`` is self-contained with no external dependencies (except if you
want to plot)

From *pypi*:

  - ``pip install backtrader``

  - ``pip install backtrader[plotting]``

    If ``matplotlib`` is not installed and you wish to do some plotting

.. note:: The minimum matplotlib version is ``1.4.1``

An example for *IB* Data Feeds/Trading:

  - ``IbPy`` doesn't seem to be in PyPi. Do either::

      pip install git+https://github.com/blampe/IbPy.git

    or (if ``git`` is not available in your system)::

      pip install https://github.com/blampe/IbPy/archive/master.zip

For other functionalities like: ``Visual Chart``, ``Oanda``, ``TA-Lib``, check
the dependencies in the documentation.

From source:

  - Place the *backtrader* directory found in the sources inside your project

Version numbering
=================

X.Y.Z.I

  - X: Major version number. Should stay stable unless something big is changed
    like an overhaul to use ``numpy``
  - Y: Minor version number. To be changed upon adding a complete new feature or
    (god forbids) an incompatible API change.
  - Z: Revision version number. To be changed for documentation updates, small
    changes, small bug fixes
  - I: Number of Indicators already built into the platform


================================================
FILE: backtrader/__init__.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

from .version import __version__, __btversion__

from .errors import *
from . import errors as errors

from .utils import num2date, date2num, time2num, num2time

from .linebuffer import *
from .functions import *

from .order import *
from .comminfo import *
from .trade import *
from .position import *

from .store import Store

from . import broker as broker
from .broker import *

from .lineseries import *

from .dataseries import *
from .feed import *
from .resamplerfilter import *

from .lineiterator import *
from .indicator import *
from .analyzer import *
from .observer import *
from .sizer import *
from .sizers import SizerFix  # old sizer for compatibility
from .strategy import *

from .writer import *

from .signal import *

from .cerebro import *
from .timer import *
from .flt import *

from . import utils as utils

from . import feeds as feeds
from . import indicators as indicators
from . import indicators as ind
from . import studies as studies
from . import strategies as strategies
from . import strategies as strats
from . import observers as observers
from . import observers as obs
from . import analyzers as analyzers
from . import commissions as commissions
from . import commissions as comms
from . import filters as filters
from . import signals as signals
from . import sizers as sizers
from . import stores as stores
from . import brokers as brokers
from . import timer as timer

from . import talib as talib

# Load contributed indicators and studies
import backtrader.indicators.contrib
import backtrader.studies.contrib


================================================
FILE: backtrader/analyzer.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import calendar
from collections import OrderedDict
import datetime
import pprint as pp

import backtrader as bt
from backtrader import TimeFrame
from backtrader.utils.py3 import MAXINT, with_metaclass


class MetaAnalyzer(bt.MetaParams):
    def donew(cls, *args, **kwargs):
        '''
        Intercept the strategy parameter
        '''
        # Create the object and set the params in place
        _obj, args, kwargs = super(MetaAnalyzer, cls).donew(*args, **kwargs)

        _obj._children = list()

        _obj.strategy = strategy = bt.metabase.findowner(_obj, bt.Strategy)
        _obj._parent = bt.metabase.findowner(_obj, Analyzer)

        # Register with a master observer if created inside one
        masterobs = bt.metabase.findowner(_obj, bt.Observer)
        if masterobs is not None:
            masterobs._register_analyzer(_obj)

        _obj.datas = strategy.datas

        # For each data add aliases: for first data: data and data0
        if _obj.datas:
            _obj.data = data = _obj.datas[0]

            for l, line in enumerate(data.lines):
                linealias = data._getlinealias(l)
                if linealias:
                    setattr(_obj, 'data_%s' % linealias, line)
                setattr(_obj, 'data_%d' % l, line)

            for d, data in enumerate(_obj.datas):
                setattr(_obj, 'data%d' % d, data)

                for l, line in enumerate(data.lines):
                    linealias = data._getlinealias(l)
                    if linealias:
                        setattr(_obj, 'data%d_%s' % (d, linealias), line)
                    setattr(_obj, 'data%d_%d' % (d, l), line)

        _obj.create_analysis()

        # Return to the normal chain
        return _obj, args, kwargs

    def dopostinit(cls, _obj, *args, **kwargs):
        _obj, args, kwargs = \
            super(MetaAnalyzer, cls).dopostinit(_obj, *args, **kwargs)

        if _obj._parent is not None:
            _obj._parent._register(_obj)

        # Return to the normal chain
        return _obj, args, kwargs


class Analyzer(with_metaclass(MetaAnalyzer, object)):
    '''Analyzer base class. All analyzers are subclass of this one

    An Analyzer instance operates in the frame of a strategy and provides an
    analysis for that strategy.

    Automagically set member attributes:

      - ``self.strategy`` (giving access to the *strategy* and anything
        accessible from it)

      - ``self.datas[x]`` giving access to the array of data feeds present in
        the the system, which could also be accessed via the strategy reference

      - ``self.data``, giving access to ``self.datas[0]``

      - ``self.dataX`` -> ``self.datas[X]``

      - ``self.dataX_Y`` -> ``self.datas[X].lines[Y]``

      - ``self.dataX_name`` -> ``self.datas[X].name``

      - ``self.data_name`` -> ``self.datas[0].name``

      - ``self.data_Y`` -> ``self.datas[0].lines[Y]``

    This is not a *Lines* object, but the methods and operation follow the same
    design

      - ``__init__`` during instantiation and initial setup

      - ``start`` / ``stop`` to signal the begin and end of operations

      - ``prenext`` / ``nextstart`` / ``next`` family of methods that follow
        the calls made to the same methods in the strategy

      - ``notify_trade`` / ``notify_order`` / ``notify_cashvalue`` /
        ``notify_fund`` which receive the same notifications as the equivalent
        methods of the strategy

    The mode of operation is open and no pattern is preferred. As such the
    analysis can be generated with the ``next`` calls, at the end of operations
    during ``stop`` and even with a single method like ``notify_trade``

    The important thing is to override ``get_analysis`` to return a *dict-like*
    object containing the results of the analysis (the actual format is
    implementation dependent)

    '''
    csv = True

    def __len__(self):
        '''Support for invoking ``len`` on analyzers by actually returning the
        current length of the strategy the analyzer operates on'''
        return len(self.strategy)

    def _register(self, child):
        self._children.append(child)

    def _prenext(self):
        for child in self._children:
            child._prenext()

        self.prenext()

    def _notify_cashvalue(self, cash, value):
        for child in self._children:
            child._notify_cashvalue(cash, value)

        self.notify_cashvalue(cash, value)

    def _notify_fund(self, cash, value, fundvalue, shares):
        for child in self._children:
            child._notify_fund(cash, value, fundvalue, shares)

        self.notify_fund(cash, value, fundvalue, shares)

    def _notify_trade(self, trade):
        for child in self._children:
            child._notify_trade(trade)

        self.notify_trade(trade)

    def _notify_order(self, order):
        for child in self._children:
            child._notify_order(order)

        self.notify_order(order)

    def _nextstart(self):
        for child in self._children:
            child._nextstart()

        self.nextstart()

    def _next(self):
        for child in self._children:
            child._next()

        self.next()

    def _start(self):
        for child in self._children:
            child._start()

        self.start()

    def _stop(self):
        for child in self._children:
            child._stop()

        self.stop()

    def notify_cashvalue(self, cash, value):
        '''Receives the cash/value notification before each next cycle'''
        pass

    def notify_fund(self, cash, value, fundvalue, shares):
        '''Receives the current cash, value, fundvalue and fund shares'''
        pass

    def notify_order(self, order):
        '''Receives order notifications before each next cycle'''
        pass

    def notify_trade(self, trade):
        '''Receives trade notifications before each next cycle'''
        pass

    def next(self):
        '''Invoked for each next invocation of the strategy, once the minum
        preiod of the strategy has been reached'''
        pass

    def prenext(self):
        '''Invoked for each prenext invocation of the strategy, until the minimum
        period of the strategy has been reached

        The default behavior for an analyzer is to invoke ``next``
        '''
        self.next()

    def nextstart(self):
        '''Invoked exactly once for the nextstart invocation of the strategy,
        when the minimum period has been first reached
        '''
        self.next()

    def start(self):
        '''Invoked to indicate the start of operations, giving the analyzer
        time to setup up needed things'''
        pass

    def stop(self):
        '''Invoked to indicate the end of operations, giving the analyzer
        time to shut down needed things'''
        pass

    def create_analysis(self):
        '''Meant to be overriden by subclasses. Gives a chance to create the
        structures that hold the analysis.

        The default behaviour is to create a ``OrderedDict`` named ``rets``
        '''
        self.rets = OrderedDict()

    def get_analysis(self):
        '''Returns a *dict-like* object with the results of the analysis

        The keys and format of analysis results in the dictionary is
        implementation dependent.

        It is not even enforced that the result is a *dict-like object*, just
        the convention

        The default implementation returns the default OrderedDict ``rets``
        created by the default ``create_analysis`` method

        '''
        return self.rets

    def print(self, *args, **kwargs):
        '''Prints the results returned by ``get_analysis`` via a standard
        ``Writerfile`` object, which defaults to writing things to standard
        output
        '''
        writer = bt.WriterFile(*args, **kwargs)
        writer.start()
        pdct = dict()
        pdct[self.__class__.__name__] = self.get_analysis()
        writer.writedict(pdct)
        writer.stop()

    def pprint(self, *args, **kwargs):
        '''Prints the results returned by ``get_analysis`` using the pretty
        print Python module (*pprint*)
        '''
        pp.pprint(self.get_analysis(), *args, **kwargs)


class MetaTimeFrameAnalyzerBase(Analyzer.__class__):
    def __new__(meta, name, bases, dct):
        # Hack to support original method name
        if '_on_dt_over' in dct:
            dct['on_dt_over'] = dct.pop('_on_dt_over')  # rename method

        return super(MetaTimeFrameAnalyzerBase, meta).__new__(meta, name,
                                                              bases, dct)


class TimeFrameAnalyzerBase(with_metaclass(MetaTimeFrameAnalyzerBase,
                                           Analyzer)):
    params = (
        ('timeframe', None),
        ('compression', None),
        ('_doprenext', True),
    )

    def _start(self):
        # Override to add specific attributes
        self.timeframe = self.p.timeframe or self.data._timeframe
        self.compression = self.p.compression or self.data._compression

        self.dtcmp, self.dtkey = self._get_dt_cmpkey(datetime.datetime.min)
        super(TimeFrameAnalyzerBase, self)._start()

    def _prenext(self):
        for child in self._children:
            child._prenext()

        if self._dt_over():
            self.on_dt_over()

        if self.p._doprenext:
            self.prenext()

    def _nextstart(self):
        for child in self._children:
            child._nextstart()

        if self._dt_over() or not self.p._doprenext:  # exec if no prenext
            self.on_dt_over()

        self.nextstart()

    def _next(self):
        for child in self._children:
            child._next()

        if self._dt_over():
            self.on_dt_over()

        self.next()

    def on_dt_over(self):
        pass

    def _dt_over(self):
        if self.timeframe == TimeFrame.NoTimeFrame:
            dtcmp, dtkey = MAXINT, datetime.datetime.max
        else:
            # With >= 1.9.x the system datetime is in the strategy
            dt = self.strategy.datetime.datetime()
            dtcmp, dtkey = self._get_dt_cmpkey(dt)

        if self.dtcmp is None or dtcmp > self.dtcmp:
            self.dtkey, self.dtkey1 = dtkey, self.dtkey
            self.dtcmp, self.dtcmp1 = dtcmp, self.dtcmp
            return True

        return False

    def _get_dt_cmpkey(self, dt):
        if self.timeframe == TimeFrame.NoTimeFrame:
            return None, None

        if self.timeframe == TimeFrame.Years:
            dtcmp = dt.year
            dtkey = datetime.date(dt.year, 12, 31)

        elif self.timeframe == TimeFrame.Months:
            dtcmp = dt.year * 100 + dt.month
            _, lastday = calendar.monthrange(dt.year, dt.month)
            dtkey = datetime.datetime(dt.year, dt.month, lastday)

        elif self.timeframe == TimeFrame.Weeks:
            isoyear, isoweek, isoweekday = dt.isocalendar()
            dtcmp = isoyear * 100 + isoweek
            sunday = dt + datetime.timedelta(days=7 - isoweekday)
            dtkey = datetime.datetime(sunday.year, sunday.month, sunday.day)

        elif self.timeframe == TimeFrame.Days:
            dtcmp = dt.year * 10000 + dt.month * 100 + dt.day
            dtkey = datetime.datetime(dt.year, dt.month, dt.day)

        else:
            dtcmp, dtkey = self._get_subday_cmpkey(dt)

        return dtcmp, dtkey

    def _get_subday_cmpkey(self, dt):
        # Calculate intraday position
        point = dt.hour * 60 + dt.minute

        if self.timeframe < TimeFrame.Minutes:
            point = point * 60 + dt.second

        if self.timeframe < TimeFrame.Seconds:
            point = point * 1e6 + dt.microsecond

        # Apply compression to update point position (comp 5 -> 200 // 5)
        point = point // self.compression

        # Move to next boundary
        point += 1

        # Restore point to the timeframe units by de-applying compression
        point *= self.compression

        # Get hours, minutes, seconds and microseconds
        if self.timeframe == TimeFrame.Minutes:
            ph, pm = divmod(point, 60)
            ps = 0
            pus = 0
        elif self.timeframe == TimeFrame.Seconds:
            ph, pm = divmod(point, 60 * 60)
            pm, ps = divmod(pm, 60)
            pus = 0
        elif self.timeframe == TimeFrame.MicroSeconds:
            ph, pm = divmod(point, 60 * 60 * 1e6)
            pm, psec = divmod(pm, 60 * 1e6)
            ps, pus = divmod(psec, 1e6)

        extradays = 0
        if ph > 23:  # went over midnight:
            extradays = ph // 24
            ph %= 24

        # moving 1 minor unit to the left to be in the boundary
        # pm -= self.timeframe == TimeFrame.Minutes
        # ps -= self.timeframe == TimeFrame.Seconds
        # pus -= self.timeframe == TimeFrame.MicroSeconds

        tadjust = datetime.timedelta(
            minutes=self.timeframe == TimeFrame.Minutes,
            seconds=self.timeframe == TimeFrame.Seconds,
            microseconds=self.timeframe == TimeFrame.MicroSeconds)

        # Add extra day if present
        if extradays:
            dt += datetime.timedelta(days=extradays)

        # Replace intraday parts with the calculated ones and update it
        dtcmp = dt.replace(hour=ph, minute=pm, second=ps, microsecond=pus)
        dtcmp -= tadjust
        dtkey = dtcmp

        return dtcmp, dtkey


================================================
FILE: backtrader/analyzers/__init__.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

# The modules below should/must define __all__ with the objects wishes
# or prepend an "_" (underscore) to private classes/variables

from .annualreturn import *
from .drawdown import *
from .timereturn import *
from .sharpe import *
from .tradeanalyzer import *
from .sqn import *
from .leverage import *
from .positions import *
from .transactions import *
from .pyfolio import *
from .returns import *
from .vwr import *

from .logreturnsrolling import *

from .calmar import *
from .periodstats import *


================================================
FILE: backtrader/analyzers/annualreturn.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

from collections import OrderedDict

from backtrader.utils.py3 import range
from backtrader import Analyzer


class AnnualReturn(Analyzer):
    '''
    This analyzer calculates the AnnualReturns by looking at the beginning
    and end of the year

    Params:

      - (None)

    Member Attributes:

      - ``rets``: list of calculated annual returns

      - ``ret``: dictionary (key: year) of annual returns

    **get_analysis**:

      - Returns a dictionary of annual returns (key: year)
    '''

    def stop(self):
        # Must have stats.broker
        cur_year = -1

        value_start = 0.0
        value_cur = 0.0
        value_end = 0.0

        self.rets = list()
        self.ret = OrderedDict()

        for i in range(len(self.data) - 1, -1, -1):
            dt = self.data.datetime.date(-i)
            value_cur = self.strategy.stats.broker.value[-i]

            if dt.year > cur_year:
                if cur_year >= 0:
                    annualret = (value_end / value_start) - 1.0
                    self.rets.append(annualret)
                    self.ret[cur_year] = annualret

                    # changing between real years, use last value as new start
                    value_start = value_end
                else:
                    # No value set whatsoever, use the currently loaded value
                    value_start = value_cur

                cur_year = dt.year

            # No matter what, the last value is always the last loaded value
            value_end = value_cur

        if cur_year not in self.ret:
            # finish calculating pending data
            annualret = (value_end / value_start) - 1.0
            self.rets.append(annualret)
            self.ret[cur_year] = annualret

    def get_analysis(self):
        return self.ret


================================================
FILE: backtrader/analyzers/calmar.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import backtrader as bt
from . import TimeDrawDown


__all__ = ['Calmar']


class Calmar(bt.TimeFrameAnalyzerBase):
    '''This analyzer calculates the CalmarRatio
    timeframe which can be different from the one used in the underlying data
    Params:

      - ``timeframe`` (default: ``None``)
        If ``None`` the ``timeframe`` of the 1st data in the system will be
        used

        Pass ``TimeFrame.NoTimeFrame`` to consider the entire dataset with no
        time constraints

      - ``compression`` (default: ``None``)

        Only used for sub-day timeframes to for example work on an hourly
        timeframe by specifying "TimeFrame.Minutes" and 60 as compression

        If ``None`` then the compression of the 1st data of the system will be
        used
      - *None*

      - ``fund`` (default: ``None``)

        If ``None`` the actual mode of the broker (fundmode - True/False) will
        be autodetected to decide if the returns are based on the total net
        asset value or on the fund value. See ``set_fundmode`` in the broker
        documentation

        Set it to ``True`` or ``False`` for a specific behavior

    See also:

      - https://en.wikipedia.org/wiki/Calmar_ratio

    Methods:
      - ``get_analysis``

        Returns a OrderedDict with a key for the time period and the
        corresponding rolling Calmar ratio

    Attributes:
      - ``calmar`` the latest calculated calmar ratio
    '''

    packages = ('collections', 'math',)

    params = (
        ('timeframe', bt.TimeFrame.Months),  # default in calmar
        ('period', 36),
        ('fund', None),
    )

    def __init__(self):
        self._maxdd = TimeDrawDown(timeframe=self.p.timeframe,
                                   compression=self.p.compression)

    def start(self):
        self._mdd = float('-inf')
        self._values = collections.deque([float('Nan')] * self.p.period,
                                         maxlen=self.p.period)
        if self.p.fund is None:
            self._fundmode = self.strategy.broker.fundmode
        else:
            self._fundmode = self.p.fund

        if not self._fundmode:
            self._values.append(self.strategy.broker.getvalue())
        else:
            self._values.append(self.strategy.broker.fundvalue)

    def on_dt_over(self):
        self._mdd = max(self._mdd, self._maxdd.maxdd)
        if not self._fundmode:
            self._values.append(self.strategy.broker.getvalue())
        else:
            self._values.append(self.strategy.broker.fundvalue)
        rann = math.log(self._values[-1] / self._values[0]) / len(self._values)
        self.calmar = calmar = rann / (self._mdd or float('Inf'))

        self.rets[self.dtkey] = calmar

    def stop(self):
        self.on_dt_over()  # update last values


================================================
FILE: backtrader/analyzers/drawdown.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import backtrader as bt
from backtrader.utils import AutoOrderedDict


__all__ = ['DrawDown', 'TimeDrawDown']


class DrawDown(bt.Analyzer):
    '''This analyzer calculates trading system drawdowns stats such as drawdown
    values in %s and in dollars, max drawdown in %s and in dollars, drawdown
    length and drawdown max length

    Params:

      - ``fund`` (default: ``None``)

        If ``None`` the actual mode of the broker (fundmode - True/False) will
        be autodetected to decide if the returns are based on the total net
        asset value or on the fund value. See ``set_fundmode`` in the broker
        documentation

        Set it to ``True`` or ``False`` for a specific behavior

    Methods:

      - ``get_analysis``

        Returns a dictionary (with . notation support and subdctionaries) with
        drawdown stats as values, the following keys/attributes are available:

        - ``drawdown`` - drawdown value in 0.xx %
        - ``moneydown`` - drawdown value in monetary units
        - ``len`` - drawdown length

        - ``max.drawdown`` - max drawdown value in 0.xx %
        - ``max.moneydown`` - max drawdown value in monetary units
        - ``max.len`` - max drawdown length
    '''

    params = (
        ('fund', None),
    )

    def start(self):
        super(DrawDown, self).start()
        if self.p.fund is None:
            self._fundmode = self.strategy.broker.fundmode
        else:
            self._fundmode = self.p.fund

    def create_analysis(self):
        self.rets = AutoOrderedDict()  # dict with . notation

        self.rets.len = 0
        self.rets.drawdown = 0.0
        self.rets.moneydown = 0.0

        self.rets.max.len = 0.0
        self.rets.max.drawdown = 0.0
        self.rets.max.moneydown = 0.0

        self._maxvalue = float('-inf')  # any value will outdo it

    def stop(self):
        self.rets._close()  # . notation cannot create more keys

    def notify_fund(self, cash, value, fundvalue, shares):
        if not self._fundmode:
            self._value = value  # record current value
            self._maxvalue = max(self._maxvalue, value)  # update peak value
        else:
            self._value = fundvalue  # record current value
            self._maxvalue = max(self._maxvalue, fundvalue)  # update peak

    def next(self):
        r = self.rets

        # calculate current drawdown values
        r.moneydown = moneydown = self._maxvalue - self._value
        r.drawdown = drawdown = 100.0 * moneydown / self._maxvalue

        # maxximum drawdown values
        r.max.moneydown = max(r.max.moneydown, moneydown)
        r.max.drawdown = maxdrawdown = max(r.max.drawdown, drawdown)

        r.len = r.len + 1 if drawdown else 0
        r.max.len = max(r.max.len, r.len)


class TimeDrawDown(bt.TimeFrameAnalyzerBase):
    '''This analyzer calculates trading system drawdowns on the chosen
    timeframe which can be different from the one used in the underlying data
    Params:

      - ``timeframe`` (default: ``None``)
        If ``None`` the ``timeframe`` of the 1st data in the system will be
        used

        Pass ``TimeFrame.NoTimeFrame`` to consider the entire dataset with no
        time constraints

      - ``compression`` (default: ``None``)

        Only used for sub-day timeframes to for example work on an hourly
        timeframe by specifying "TimeFrame.Minutes" and 60 as compression

        If ``None`` then the compression of the 1st data of the system will be
        used
      - *None*

      - ``fund`` (default: ``None``)

        If ``None`` the actual mode of the broker (fundmode - True/False) will
        be autodetected to decide if the returns are based on the total net
        asset value or on the fund value. See ``set_fundmode`` in the broker
        documentation

        Set it to ``True`` or ``False`` for a specific behavior

    Methods:

      - ``get_analysis``

        Returns a dictionary (with . notation support and subdctionaries) with
        drawdown stats as values, the following keys/attributes are available:

        - ``drawdown`` - drawdown value in 0.xx %
        - ``maxdrawdown`` - drawdown value in monetary units
        - ``maxdrawdownperiod`` - drawdown length

      - Those are available during runs as attributes
        - ``dd``
        - ``maxdd``
        - ``maxddlen``
    '''

    params = (
        ('fund', None),
    )

    def start(self):
        super(TimeDrawDown, self).start()
        if self.p.fund is None:
            self._fundmode = self.strategy.broker.fundmode
        else:
            self._fundmode = self.p.fund
        self.dd = 0.0
        self.maxdd = 0.0
        self.maxddlen = 0
        self.peak = float('-inf')
        self.ddlen = 0

    def on_dt_over(self):
        if not self._fundmode:
            value = self.strategy.broker.getvalue()
        else:
            value = self.strategy.broker.fundvalue

        # update the maximum seen peak
        if value > self.peak:
            self.peak = value
            self.ddlen = 0  # start of streak

        # calculate the current drawdown
        self.dd = dd = 100.0 * (self.peak - value) / self.peak
        self.ddlen += bool(dd)  # if peak == value -> dd = 0

        # update the maxdrawdown if needed
        self.maxdd = max(self.maxdd, dd)
        self.maxddlen = max(self.maxddlen, self.ddlen)

    def stop(self):
        self.rets['maxdrawdown'] = self.maxdd
        self.rets['maxdrawdownperiod'] = self.maxddlen


================================================
FILE: backtrader/analyzers/leverage.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import backtrader as bt


class GrossLeverage(bt.Analyzer):
    '''This analyzer calculates the Gross Leverage of the current strategy
    on a timeframe basis

    Params:

      - ``fund`` (default: ``None``)

        If ``None`` the actual mode of the broker (fundmode - True/False) will
        be autodetected to decide if the returns are based on the total net
        asset value or on the fund value. See ``set_fundmode`` in the broker
        documentation

        Set it to ``True`` or ``False`` for a specific behavior

    Methods:

      - get_analysis

        Returns a dictionary with returns as values and the datetime points for
        each return as keys
    '''

    params = (
        ('fund', None),
    )

    def start(self):
        if self.p.fund is None:
            self._fundmode = self.strategy.broker.fundmode
        else:
            self._fundmode = self.p.fund

    def notify_fund(self, cash, value, fundvalue, shares):
        self._cash = cash
        if not self._fundmode:
            self._value = value
        else:
            self._value = fundvalue

    def next(self):
        # Updates the leverage for "dtkey" (see base class) for each cycle
        # 0.0 if 100% in cash, 1.0 if no short selling and fully invested
        lev = (self._value - self._cash) / self._value
        self.rets[self.data0.datetime.datetime()] = lev


================================================
FILE: backtrader/analyzers/logreturnsrolling.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import collections
import math

import backtrader as bt


__all__ = ['LogReturnsRolling']


class LogReturnsRolling(bt.TimeFrameAnalyzerBase):
    '''This analyzer calculates rolling returns for a given timeframe and
    compression

    Params:

      - ``timeframe`` (default: ``None``)
        If ``None`` the ``timeframe`` of the 1st data in the system will be
        used

        Pass ``TimeFrame.NoTimeFrame`` to consider the entire dataset with no
        time constraints

      - ``compression`` (default: ``None``)

        Only used for sub-day timeframes to for example work on an hourly
        timeframe by specifying "TimeFrame.Minutes" and 60 as compression

        If ``None`` then the compression of the 1st data of the system will be
        used

      - ``data`` (default: ``None``)

        Reference asset to track instead of the portfolio value.

        .. note:: this data must have been added to a ``cerebro`` instance with
                  ``addata``, ``resampledata`` or ``replaydata``

      - ``firstopen`` (default: ``True``)

        When tracking the returns of a ``data`` the following is done when
        crossing a timeframe boundary, for example ``Years``:

          - Last ``close`` of previous year is used as the reference price to
            see the return in the current year

        The problem is the 1st calculation, because the data has** no
        previous** closing price. As such and when this parameter is ``True``
        the *opening* price will be used for the 1st calculation.

        This requires the data feed to have an ``open`` price (for ``close``
        the standard [0] notation will be used without reference to a field
        price)

        Else the initial close will be used.

      - ``fund`` (default: ``None``)

        If ``None`` the actual mode of the broker (fundmode - True/False) will
        be autodetected to decide if the returns are based on the total net
        asset value or on the fund value. See ``set_fundmode`` in the broker
        documentation

        Set it to ``True`` or ``False`` for a specific behavior

    Methods:

      - get_analysis

        Returns a dictionary with returns as values and the datetime points for
        each return as keys
    '''

    params = (
        ('data', None),
        ('firstopen', True),
        ('fund', None),
    )

    def start(self):
        super(LogReturnsRolling, self).start()
        if self.p.fund is None:
            self._fundmode = self.strategy.broker.fundmode
        else:
            self._fundmode = self.p.fund

        self._values = collections.deque([float('Nan')] * self.compression,
                                         maxlen=self.compression)

        if self.p.data is None:
            # keep the initial portfolio value if not tracing a data
            if not self._fundmode:
                self._lastvalue = self.strategy.broker.getvalue()
            else:
                self._lastvalue = self.strategy.broker.fundvalue

    def notify_fund(self, cash, value, fundvalue, shares):
        if not self._fundmode:
            self._value = value if self.p.data is None else self.p.data[0]
        else:
            self._value = fundvalue if self.p.data is None else self.p.data[0]

    def _on_dt_over(self):
        # next is called in a new timeframe period
        if self.p.data is None or len(self.p.data) > 1:
            # Not tracking a data feed or data feed has data already
            vst = self._lastvalue  # update value_start to last
        else:
            # The 1st tick has no previous reference, use the opening price
            vst = self.p.data.open[0] if self.p.firstopen else self.p.data[0]

        self._values.append(vst)  # push values backwards (and out)

    def next(self):
        # Calculate the return
        super(LogReturnsRolling, self).next()
        self.rets[self.dtkey] = math.log(self._value / self._values[0])
        self._lastvalue = self._value  # keep last value


================================================
FILE: backtrader/analyzers/periodstats.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)


import backtrader as bt
from backtrader.utils.py3 import itervalues
from backtrader.mathsupport import average, standarddev
from . import TimeReturn


__all__ = ['PeriodStats']


class PeriodStats(bt.Analyzer):
    '''Calculates basic statistics for given timeframe

    Params:

      - ``timeframe`` (default: ``Years``)
        If ``None`` the ``timeframe`` of the 1st data in the system will be
        used

        Pass ``TimeFrame.NoTimeFrame`` to consider the entire dataset with no
        time constraints

      - ``compression`` (default: ``1``)

        Only used for sub-day timeframes to for example work on an hourly
        timeframe by specifying "TimeFrame.Minutes" and 60 as compression

        If ``None`` then the compression of the 1st data of the system will be
        used

      - ``fund`` (default: ``None``)

        If ``None`` the actual mode of the broker (fundmode - True/False) will
        be autodetected to decide if the returns are based on the total net
        asset value or on the fund value. See ``set_fundmode`` in the broker
        documentation

        Set it to ``True`` or ``False`` for a specific behavior


    ``get_analysis`` returns a dictionary containing the keys:

      - ``average``
      - ``stddev``
      - ``positive``
      - ``negative``
      - ``nochange``
      - ``best``
      - ``worst``

    If the parameter ``zeroispos`` is set to ``True``, periods with no change
    will be counted as positive
    '''

    params = (
        ('timeframe', bt.TimeFrame.Years),
        ('compression', 1),
        ('zeroispos', False),
        ('fund', None),
    )

    def __init__(self):
        self._tr = TimeReturn(timeframe=self.p.timeframe,
                              compression=self.p.compression, fund=self.p.fund)

    def stop(self):
        trets = self._tr.get_analysis()  # dict key = date, value = ret
        pos = nul = neg = 0
        trets = list(itervalues(trets))
        for tret in trets:
            if tret > 0.0:
                pos += 1
            elif tret < 0.0:
                neg += 1
            else:
                if self.p.zeroispos:
                    pos += tret == 0.0
                else:
                    nul += tret == 0.0

        self.rets['average'] = avg = average(trets)
        self.rets['stddev'] = standarddev(trets, avg)

        self.rets['positive'] = pos
        self.rets['negative'] = neg
        self.rets['nochange'] = nul

        self.rets['best'] = max(trets)
        self.rets['worst'] = min(trets)


================================================
FILE: backtrader/analyzers/positions.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)


import backtrader as bt


class PositionsValue(bt.Analyzer):
    '''This analyzer reports the value of the positions of the current set of
    datas

    Params:

      - timeframe (default: ``None``)
        If ``None`` then the timeframe of the 1st data of the system will be
        used

      - compression (default: ``None``)

        Only used for sub-day timeframes to for example work on an hourly
        timeframe by specifying "TimeFrame.Minutes" and 60 as compression

        If ``None`` then the compression of the 1st data of the system will be
        used

      - headers (default: ``False``)

        Add an initial key to the dictionary holding the results with the names
        of the datas ('Datetime' as key

      - cash (default: ``False``)

        Include the actual cash as an extra position (for the header 'cash'
        will be used as name)

    Methods:

      - get_analysis

        Returns a dictionary with returns as values and the datetime points for
        each return as keys
    '''
    params = (
        ('headers',  False),
        ('cash', False),
    )

    def start(self):
        if self.p.headers:
            headers = [d._name or 'Data%d' % i
                       for i, d in enumerate(self.datas)]
            self.rets['Datetime'] = headers + ['cash'] * self.p.cash

        tf = min(d._timeframe for d in self.datas)
        self._usedate = tf >= bt.TimeFrame.Days

    def next(self):
        pvals = [self.strategy.broker.get_value([d]) for d in self.datas]
        if self.p.cash:
            pvals.append(self.strategy.broker.get_cash())

        if self._usedate:
            self.rets[self.strategy.datetime.date()] = pvals
        else:
            self.rets[self.strategy.datetime.datetime()] = pvals


================================================
FILE: backtrader/analyzers/pyfolio.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)


import collections

import backtrader as bt
from backtrader.utils.py3 import items, iteritems

from . import TimeReturn, PositionsValue, Transactions, GrossLeverage


class PyFolio(bt.Analyzer):
    '''This analyzer uses 4 children analyzers to collect data and transforms it
    in to a data set compatible with ``pyfolio``

    Children Analyzer

      - ``TimeReturn``

        Used to calculate the returns of the global portfolio value

      - ``PositionsValue``

        Used to calculate the value of the positions per data. It sets the
        ``headers`` and ``cash`` parameters to ``True``

      - ``Transactions``

        Used to record each transaction on a data (size, price, value). Sets
        the ``headers`` parameter to ``True``

      - ``GrossLeverage``

        Keeps track of the gross leverage (how much the strategy is invested)

    Params:
      These are passed transparently to the children

      - timeframe (default: ``bt.TimeFrame.Days``)

        If ``None`` then the timeframe of the 1st data of the system will be
        used

      - compression (default: `1``)

        If ``None`` then the compression of the 1st data of the system will be
        used

    Both ``timeframe`` and ``compression`` are set following the default
    behavior of ``pyfolio`` which is working with *daily* data and upsample it
    to obtaine values like yearly returns.

    Methods:

      - get_analysis

        Returns a dictionary with returns as values and the datetime points for
        each return as keys
    '''
    params = (
        ('timeframe', bt.TimeFrame.Days),
        ('compression', 1)
    )

    def __init__(self):
        dtfcomp = dict(timeframe=self.p.timeframe,
                       compression=self.p.compression)

        self._returns = TimeReturn(**dtfcomp)
        self._positions = PositionsValue(headers=True, cash=True)
        self._transactions = Transactions(headers=True)
        self._gross_lev = GrossLeverage()

    def stop(self):
        super(PyFolio, self).stop()
        self.rets['returns'] = self._returns.get_analysis()
        self.rets['positions'] = self._positions.get_analysis()
        self.rets['transactions'] = self._transactions.get_analysis()
        self.rets['gross_lev'] = self._gross_lev.get_analysis()

    def get_pf_items(self):
        '''Returns a tuple of 4 elements which can be used for further processing with
          ``pyfolio``

          returns, positions, transactions, gross_leverage

        Because the objects are meant to be used as direct input to ``pyfolio``
        this method makes a local import of ``pandas`` to convert the internal
        *backtrader* results to *pandas DataFrames* which is the expected input
        by, for example, ``pyfolio.create_full_tear_sheet``

        The method will break if ``pandas`` is not installed
        '''
        # keep import local to avoid disturbing installations with no pandas
        import pandas
        from pandas import DataFrame as DF

        #
        # Returns
        cols = ['index', 'return']
        returns = DF.from_records(iteritems(self.rets['returns']),
                                  index=cols[0], columns=cols)
        returns.index = pandas.to_datetime(returns.index)
        returns.index = returns.index.tz_localize('UTC')
        rets = returns['return']
        #
        # Positions
        pss = self.rets['positions']
        ps = [[k] + v[-2:] for k, v in iteritems(pss)]
        cols = ps.pop(0)  # headers are in the first entry
        positions = DF.from_records(ps, index=cols[0], columns=cols)
        positions.index = pandas.to_datetime(positions.index)
        positions.index = positions.index.tz_localize('UTC')

        #
        # Transactions
        txss = self.rets['transactions']
        txs = list()
        # The transactions have a common key (date) and can potentially happend
        # for several assets. The dictionary has a single key and a list of
        # lists. Each sublist contains the fields of a transaction
        # Hence the double loop to undo the list indirection
        for k, v in iteritems(txss):
            for v2 in v:
                txs.append([k] + v2)

        cols = txs.pop(0)  # headers are in the first entry
        transactions = DF.from_records(txs, index=cols[0], columns=cols)
        transactions.index = pandas.to_datetime(transactions.index)
        transactions.index = transactions.index.tz_localize('UTC')

        # Gross Leverage
        cols = ['index', 'gross_lev']
        gross_lev = DF.from_records(iteritems(self.rets['gross_lev']),
                                    index=cols[0], columns=cols)

        gross_lev.index = pandas.to_datetime(gross_lev.index)
        gross_lev.index = gross_lev.index.tz_localize('UTC')
        glev = gross_lev['gross_lev']

        # Return all together
        return rets, positions, transactions, glev


================================================
FILE: backtrader/analyzers/returns.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import math

import backtrader as bt
from backtrader import TimeFrameAnalyzerBase


class Returns(TimeFrameAnalyzerBase):
    '''Total, Average, Compound and Annualized Returns calculated using a
    logarithmic approach

    See:

      - https://www.crystalbull.com/sharpe-ratio-better-with-log-returns/

    Params:

      - ``timeframe`` (default: ``None``)

        If ``None`` the ``timeframe`` of the 1st data in the system will be
        used

        Pass ``TimeFrame.NoTimeFrame`` to consider the entire dataset with no
        time constraints

      - ``compression`` (default: ``None``)

        Only used for sub-day timeframes to for example work on an hourly
        timeframe by specifying "TimeFrame.Minutes" and 60 as compression

        If ``None`` then the compression of the 1st data of the system will be
        used

      - ``tann`` (default: ``None``)

        Number of periods to use for the annualization (normalization) of the

        namely:

          - ``days: 252``
          - ``weeks: 52``
          - ``months: 12``
          - ``years: 1``

      - ``fund`` (default: ``None``)

        If ``None`` the actual mode of the broker (fundmode - True/False) will
        be autodetected to decide if the returns are based on the total net
        asset value or on the fund value. See ``set_fundmode`` in the broker
        documentation

        Set it to ``True`` or ``False`` for a specific behavior

    Methods:

      - get_analysis

        Returns a dictionary with returns as values and the datetime points for
        each return as keys

        The returned dict the following keys:

          - ``rtot``: Total compound return
          - ``ravg``: Average return for the entire period (timeframe specific)
          - ``rnorm``: Annualized/Normalized return
          - ``rnorm100``: Annualized/Normalized return expressed in 100%

    '''

    params = (
        ('tann', None),
        ('fund', None),
    )

    _TANN = {
        bt.TimeFrame.Days: 252.0,
        bt.TimeFrame.Weeks: 52.0,
        bt.TimeFrame.Months: 12.0,
        bt.TimeFrame.Years: 1.0,
    }

    def start(self):
        super(Returns, self).start()
        if self.p.fund is None:
            self._fundmode = self.strategy.broker.fundmode
        else:
            self._fundmode = self.p.fund

        if not self._fundmode:
            self._value_start = self.strategy.broker.getvalue()
        else:
            self._value_start = self.strategy.broker.fundvalue

        self._tcount = 0

    def stop(self):
        super(Returns, self).stop()

        if not self._fundmode:
            self._value_end = self.strategy.broker.getvalue()
        else:
            self._value_end = self.strategy.broker.fundvalue

        # Compound return
        try:
            nlrtot = self._value_end / self._value_start
        except ZeroDivisionError:
            rtot = float('-inf')
        else:
            if nlrtot < 0.0:
                rtot = float('-inf')
            else:
                rtot = math.log(nlrtot)

        self.rets['rtot'] = rtot

        # Average return
        self.rets['ravg'] = ravg = rtot / self._tcount

        # Annualized normalized return
        tann = self.p.tann or self._TANN.get(self.timeframe, None)
        if tann is None:
            tann = self._TANN.get(self.data._timeframe, 1.0)  # assign default

        if ravg > float('-inf'):
            self.rets['rnorm'] = rnorm = math.expm1(ravg * tann)
        else:
            self.rets['rnorm'] = rnorm = ravg

        self.rets['rnorm100'] = rnorm * 100.0  # human readable %

    def _on_dt_over(self):
        self._tcount += 1  # count the subperiod


================================================
FILE: backtrader/analyzers/sharpe.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import math

from backtrader.utils.py3 import itervalues

from backtrader import Analyzer, TimeFrame
from backtrader.mathsupport import average, standarddev
from backtrader.analyzers import TimeReturn, AnnualReturn


class SharpeRatio(Analyzer):
    '''This analyzer calculates the SharpeRatio of a strategy using a risk free
    asset which is simply an interest rate

    See also:

      - https://en.wikipedia.org/wiki/Sharpe_ratio

    Params:

      - ``timeframe``: (default: ``TimeFrame.Years``)

      - ``compression`` (default: ``1``)

        Only used for sub-day timeframes to for example work on an hourly
        timeframe by specifying "TimeFrame.Minutes" and 60 as compression

      - ``riskfreerate`` (default: 0.01 -> 1%)

        Expressed in annual terms (see ``convertrate`` below)

      - ``convertrate`` (default: ``True``)

        Convert the ``riskfreerate`` from annual to monthly, weekly or daily
        rate. Sub-day conversions are not supported

      - ``factor`` (default: ``None``)

        If ``None``, the conversion factor for the riskfree rate from *annual*
        to the chosen timeframe will be chosen from a predefined table

          Days: 252, Weeks: 52, Months: 12, Years: 1

        Else the specified value will be used

      - ``annualize`` (default: ``False``)

        If ``convertrate`` is ``True``, the *SharpeRatio* will be delivered in
        the ``timeframe`` of choice.

        In most occasions the SharpeRatio is delivered in annualized form.
        Convert the ``riskfreerate`` from annual to monthly, weekly or daily
        rate. Sub-day conversions are not supported

      - ``stddev_sample`` (default: ``False``)

        If this is set to ``True`` the *standard deviation* will be calculated
        decreasing the denominator in the mean by ``1``. This is used when
        calculating the *standard deviation* if it's considered that not all
        samples are used for the calculation. This is known as the *Bessels'
        correction*

      - ``daysfactor`` (default: ``None``)

        Old naming for ``factor``. If set to anything else than ``None`` and
        the ``timeframe`` is ``TimeFrame.Days`` it will be assumed this is old
        code and the value will be used

      - ``legacyannual`` (default: ``False``)

        Use the ``AnnualReturn`` return analyzer, which as the name implies
        only works on years

      - ``fund`` (default: ``None``)

        If ``None`` the actual mode of the broker (fundmode - True/False) will
        be autodetected to decide if the returns are based on the total net
        asset value or on the fund value. See ``set_fundmode`` in the broker
        documentation

        Set it to ``True`` or ``False`` for a specific behavior

    Methods:

      - get_analysis

        Returns a dictionary with key "sharperatio" holding the ratio

    '''
    params = (
        ('timeframe', TimeFrame.Years),
        ('compression', 1),
        ('riskfreerate', 0.01),
        ('factor', None),
        ('convertrate', True),
        ('annualize', False),
        ('stddev_sample', False),

        # old behavior
        ('daysfactor', None),
        ('legacyannual', False),
        ('fund', None),
    )

    RATEFACTORS = {
        TimeFrame.Days: 252,
        TimeFrame.Weeks: 52,
        TimeFrame.Months: 12,
        TimeFrame.Years: 1,
    }

    def __init__(self):
        if self.p.legacyannual:
            self.anret = AnnualReturn()
        else:
            self.timereturn = TimeReturn(
                timeframe=self.p.timeframe,
                compression=self.p.compression,
                fund=self.p.fund)

    def stop(self):
        super(SharpeRatio, self).stop()
        if self.p.legacyannual:
            rate = self.p.riskfreerate
            retavg = average([r - rate for r in self.anret.rets])
            retdev = standarddev(self.anret.rets)

            self.ratio = retavg / retdev
        else:
            # Get the returns from the subanalyzer
            returns = list(itervalues(self.timereturn.get_analysis()))

            rate = self.p.riskfreerate  #

            factor = None

            # Hack to identify old code
            if self.p.timeframe == TimeFrame.Days and \
               self.p.daysfactor is not None:

                factor = self.p.daysfactor

            else:
                if self.p.factor is not None:
                    factor = self.p.factor  # user specified factor
                elif self.p.timeframe in self.RATEFACTORS:
                    # Get the conversion factor from the default table
                    factor = self.RATEFACTORS[self.p.timeframe]

            if factor is not None:
                # A factor was found

                if self.p.convertrate:
                    # Standard: downgrade annual returns to timeframe factor
                    rate = pow(1.0 + rate, 1.0 / factor) - 1.0
                else:
                    # Else upgrade returns to yearly returns
                    returns = [pow(1.0 + x, factor) - 1.0 for x in returns]

            lrets = len(returns) - self.p.stddev_sample
            # Check if the ratio can be calculated
            if lrets:
                # Get the excess returns - arithmetic mean - original sharpe
                ret_free = [r - rate for r in returns]
                ret_free_avg = average(ret_free)
                retdev = standarddev(ret_free, avgx=ret_free_avg,
                                     bessel=self.p.stddev_sample)

                try:
                    ratio = ret_free_avg / retdev

                    if factor is not None and \
                       self.p.convertrate and self.p.annualize:

                        ratio = math.sqrt(factor) * ratio
                except (ValueError, TypeError, ZeroDivisionError):
                    ratio = None
            else:
                # no returns or stddev_sample was active and 1 return
                ratio = None

            self.ratio = ratio

        self.rets['sharperatio'] = self.ratio


class SharpeRatio_A(SharpeRatio):
    '''Extension of the SharpeRatio which returns the Sharpe Ratio directly in
    annualized form

    The following param has been changed from ``SharpeRatio``

      - ``annualize`` (default: ``True``)

    '''

    params = (
        ('annualize', True),
    )


================================================
FILE: backtrader/analyzers/sqn.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import math

from backtrader import Analyzer
from backtrader.mathsupport import average, standarddev
from backtrader.utils import AutoOrderedDict


class SQN(Analyzer):
    '''SQN or SystemQualityNumber. Defined by Van K. Tharp to categorize trading
    systems.

      - 1.6 - 1.9 Below average
      - 2.0 - 2.4 Average
      - 2.5 - 2.9 Good
      - 3.0 - 5.0 Excellent
      - 5.1 - 6.9 Superb
      - 7.0 -     Holy Grail?

    The formula:

      - SquareRoot(NumberTrades) * Average(TradesProfit) / StdDev(TradesProfit)

    The sqn value should be deemed reliable when the number of trades >= 30

    Methods:

      - get_analysis

        Returns a dictionary with keys "sqn" and "trades" (number of
        considered trades)

    '''
    alias = ('SystemQualityNumber',)

    def create_analysis(self):
        '''Replace default implementation to instantiate an AutoOrdereDict
        rather than an OrderedDict'''
        self.rets = AutoOrderedDict()

    def start(self):
        super(SQN, self).start()
        self.pnl = list()
        self.count = 0

    def notify_trade(self, trade):
        if trade.status == trade.Closed:
            self.pnl.append(trade.pnlcomm)
            self.count += 1

    def stop(self):
        if self.count > 1:
            pnl_av = average(self.pnl)
            pnl_stddev = standarddev(self.pnl)
            try:
                sqn = math.sqrt(len(self.pnl)) * pnl_av / pnl_stddev
            except ZeroDivisionError:
                sqn = None
        else:
            sqn = 0

        self.rets.sqn = sqn
        self.rets.trades = self.count


================================================
FILE: backtrader/analyzers/timereturn.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

from backtrader import TimeFrameAnalyzerBase


class TimeReturn(TimeFrameAnalyzerBase):
    '''This analyzer calculates the Returns by looking at the beginning
    and end of the timeframe

    Params:

      - ``timeframe`` (default: ``None``)
        If ``None`` the ``timeframe`` of the 1st data in the system will be
        used

        Pass ``TimeFrame.NoTimeFrame`` to consider the entire dataset with no
        time constraints

      - ``compression`` (default: ``None``)

        Only used for sub-day timeframes to for example work on an hourly
        timeframe by specifying "TimeFrame.Minutes" and 60 as compression

        If ``None`` then the compression of the 1st data of the system will be
        used

      - ``data`` (default: ``None``)

        Reference asset to track instead of the portfolio value.

        .. note:: this data must have been added to a ``cerebro`` instance with
                  ``addata``, ``resampledata`` or ``replaydata``

      - ``firstopen`` (default: ``True``)

        When tracking the returns of a ``data`` the following is done when
        crossing a timeframe boundary, for example ``Years``:

          - Last ``close`` of previous year is used as the reference price to
            see the return in the current year

        The problem is the 1st calculation, because the data has** no
        previous** closing price. As such and when this parameter is ``True``
        the *opening* price will be used for the 1st calculation.

        This requires the data feed to have an ``open`` price (for ``close``
        the standard [0] notation will be used without reference to a field
        price)

        Else the initial close will be used.

      - ``fund`` (default: ``None``)

        If ``None`` the actual mode of the broker (fundmode - True/False) will
        be autodetected to decide if the returns are based on the total net
        asset value or on the fund value. See ``set_fundmode`` in the broker
        documentation

        Set it to ``True`` or ``False`` for a specific behavior

    Methods:

      - get_analysis

        Returns a dictionary with returns as values and the datetime points for
        each return as keys
    '''

    params = (
        ('data', None),
        ('firstopen', True),
        ('fund', None),
    )

    def start(self):
        super(TimeReturn, self).start()
        if self.p.fund is None:
            self._fundmode = self.strategy.broker.fundmode
        else:
            self._fundmode = self.p.fund

        self._value_start = 0.0
        self._lastvalue = None
        if self.p.data is None:
            # keep the initial portfolio value if not tracing a data
            if not self._fundmode:
                self._lastvalue = self.strategy.broker.getvalue()
            else:
                self._lastvalue = self.strategy.broker.fundvalue

    def notify_fund(self, cash, value, fundvalue, shares):
        if not self._fundmode:
            # Record current value
            if self.p.data is None:
                self._value = value  # the portofolio value if tracking no data
            else:
                self._value = self.p.data[0]  # the data value if tracking data
        else:
            if self.p.data is None:
                self._value = fundvalue  # the fund value if tracking no data
            else:
                self._value = self.p.data[0]  # the data value if tracking data

    def on_dt_over(self):
        # next is called in a new timeframe period
        # if self.p.data is None or len(self.p.data) > 1:
        if self.p.data is None or self._lastvalue is not None:
            self._value_start = self._lastvalue  # update value_start to last

        else:
            # The 1st tick has no previous reference, use the opening price
            if self.p.firstopen:
                self._value_start = self.p.data.open[0]
            else:
                self._value_start = self.p.data[0]

    def next(self):
        # Calculate the return
        super(TimeReturn, self).next()
        self.rets[self.dtkey] = (self._value / self._value_start) - 1.0
        self._lastvalue = self._value  # keep last value


================================================
FILE: backtrader/analyzers/tradeanalyzer.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import sys

from backtrader import Analyzer
from backtrader.utils import AutoOrderedDict, AutoDict
from backtrader.utils.py3 import MAXINT


class TradeAnalyzer(Analyzer):
    '''
    Provides statistics on closed trades (keeps also the count of open ones)

      - Total Open/Closed Trades

      - Streak Won/Lost Current/Longest

      - ProfitAndLoss Total/Average

      - Won/Lost Count/ Total PNL/ Average PNL / Max PNL

      - Long/Short Count/ Total PNL / Average PNL / Max PNL

          - Won/Lost Count/ Total PNL/ Average PNL / Max PNL

      - Length (bars in the market)

        - Total/Average/Max/Min

        - Won/Lost Total/Average/Max/Min

        - Long/Short Total/Average/Max/Min

          - Won/Lost Total/Average/Max/Min

    Note:

      The analyzer uses an "auto"dict for the fields, which means that if no
      trades are executed, no statistics will be generated.

      In that case there will be a single field/subfield in the dictionary
      returned by ``get_analysis``, namely:

        - dictname['total']['total'] which will have a value of 0 (the field is
          also reachable with dot notation dictname.total.total
    '''
    def create_analysis(self):
        self.rets = AutoOrderedDict()
        self.rets.total.total = 0

    def stop(self):
        super(TradeAnalyzer, self).stop()
        self.rets._close()

    def notify_trade(self, trade):
        if trade.justopened:
            # Trade just opened
            self.rets.total.total += 1
            self.rets.total.open += 1

        elif trade.status == trade.Closed:
            trades = self.rets

            res = AutoDict()
            # Trade just closed

            won = res.won = int(trade.pnlcomm >= 0.0)
            lost = res.lost = int(not won)
            tlong = res.tlong = trade.long
            tshort = res.tshort = not trade.long

            trades.total.open -= 1
            trades.total.closed += 1

            # Streak
            for wlname in ['won', 'lost']:
                wl = res[wlname]

                trades.streak[wlname].current *= wl
                trades.streak[wlname].current += wl

                ls = trades.streak[wlname].longest or 0
                trades.streak[wlname].longest = \
                    max(ls, trades.streak[wlname].current)

            trpnl = trades.pnl
            trpnl.gross.total += trade.pnl
            trpnl.gross.average = trades.pnl.gross.total / trades.total.closed
            trpnl.net.total += trade.pnlcomm
            trpnl.net.average = trades.pnl.net.total / trades.total.closed

            # Won/Lost statistics
            for wlname in ['won', 'lost']:
                wl = res[wlname]
                trwl = trades[wlname]

                trwl.total += wl  # won.total / lost.total

                trwlpnl = trwl.pnl
                pnlcomm = trade.pnlcomm * wl

                trwlpnl.total += pnlcomm
                trwlpnl.average = trwlpnl.total / (trwl.total or 1.0)

                wm = trwlpnl.max or 0.0
                func = max if wlname == 'won' else min
                trwlpnl.max = func(wm, pnlcomm)

            # Long/Short statistics
            for tname in ['long', 'short']:
                trls = trades[tname]
                ls = res['t' + tname]

                trls.total += ls  # long.total / short.total
                trls.pnl.total += trade.pnlcomm * ls
                trls.pnl.average = trls.pnl.total / (trls.total or 1.0)

                for wlname in ['won', 'lost']:
                    wl = res[wlname]
                    pnlcomm = trade.pnlcomm * wl * ls

                    trls[wlname] += wl * ls  # long.won / short.won

                    trls.pnl[wlname].total += pnlcomm
                    trls.pnl[wlname].average = \
                        trls.pnl[wlname].total / (trls[wlname] or 1.0)

                    wm = trls.pnl[wlname].max or 0.0
                    func = max if wlname == 'won' else min
                    trls.pnl[wlname].max = func(wm, pnlcomm)

            # Length
            trades.len.total += trade.barlen
            trades.len.average = trades.len.total / trades.total.closed
            ml = trades.len.max or 0
            trades.len.max = max(ml, trade.barlen)

            ml = trades.len.min or MAXINT
            trades.len.min = min(ml, trade.barlen)

            # Length Won/Lost
            for wlname in ['won', 'lost']:
                trwl = trades.len[wlname]
                wl = res[wlname]

                trwl.total += trade.barlen * wl
                trwl.average = trwl.total / (trades[wlname].total or 1.0)

                m = trwl.max or 0
                trwl.max = max(m, trade.barlen * wl)
                if trade.barlen * wl:
                    m = trwl.min or MAXINT
                    trwl.min = min(m, trade.barlen * wl)

            # Length Long/Short
            for lsname in ['long', 'short']:
                trls = trades.len[lsname]  # trades.len.long
                ls = res['t' + lsname]  # tlong/tshort

                barlen = trade.barlen * ls

                trls.total += barlen  # trades.len.long.total
                total_ls = trades[lsname].total   # trades.long.total
                trls.average = trls.total / (total_ls or 1.0)

                # max/min
                m = trls.max or 0
                trls.max = max(m, barlen)
                m = trls.min or MAXINT
                trls.min = min(m, barlen or m)

                for wlname in ['won', 'lost']:
                    wl = res[wlname]  # won/lost

                    barlen2 = trade.barlen * ls * wl

                    trls_wl = trls[wlname]  # trades.len.long.won
                    trls_wl.total += barlen2  # trades.len.long.won.total

                    trls_wl.average = \
                        trls_wl.total / (trades[lsname][wlname] or 1.0)

                    # max/min
                    m = trls_wl.max or 0
                    trls_wl.max = max(m, barlen2)
                    m = trls_wl.min or MAXINT
                    trls_wl.min = min(m, barlen2 or m)


================================================
FILE: backtrader/analyzers/transactions.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)


import collections

import backtrader as bt
from backtrader import Order, Position


class Transactions(bt.Analyzer):
    '''This analyzer reports the transactions occurred with each an every data in
    the system

    It looks at the order execution bits to create a ``Position`` starting from
    0 during each ``next`` cycle.

    The result is used during next to record the transactions

    Params:

      - headers (default: ``True``)

        Add an initial key to the dictionary holding the results with the names
        of the datas

        This analyzer was modeled to facilitate the integration with
        ``pyfolio`` and the header names are taken from the samples used for
        it::

          'date', 'amount', 'price', 'sid', 'symbol', 'value'

    Methods:

      - get_analysis

        Returns a dictionary with returns as values and the datetime points for
        each return as keys
    '''
    params = (
        ('headers', False),
        ('_pfheaders', ('date', 'amount', 'price', 'sid', 'symbol', 'value')),
    )

    def start(self):
        super(Transactions, self).start()
        if self.p.headers:
            self.rets[self.p._pfheaders[0]] = [list(self.p._pfheaders[1:])]

        self._positions = collections.defaultdict(Position)
        self._idnames = list(enumerate(self.strategy.getdatanames()))

    def notify_order(self, order):
        # An order could have several partial executions per cycle (unlikely
        # but possible) and therefore: collect each new execution notification
        # and let the work for next

        # We use a fresh Position object for each round to get summary of what
        # the execution bits have done in that round
        if order.status not in [Order.Partial, Order.Completed]:
            return  # It's not an execution

        pos = self._positions[order.data._name]
        for exbit in order.executed.iterpending():
            if exbit is None:
                break  # end of pending reached

            pos.update(exbit.size, exbit.price)

    def next(self):
        # super(Transactions, self).next()  # let dtkey update
        entries = []
        for i, dname in self._idnames:
            pos = self._positions.get(dname, None)
            if pos is not None:
                size, price = pos.size, pos.price
                if size:
                    entries.append([size, price, i, dname, -size * price])

        if entries:
            self.rets[self.strategy.datetime.datetime()] = entries

        self._positions.clear()


================================================
FILE: backtrader/analyzers/vwr.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import math

import backtrader as bt
from backtrader import TimeFrameAnalyzerBase
from . import Returns
from ..mathsupport import standarddev


class VWR(TimeFrameAnalyzerBase):
    '''Variability-Weighted Return: Better SharpeRatio with Log Returns

    Alias:

      - VariabilityWeightedReturn

    See:

      - https://www.crystalbull.com/sharpe-ratio-better-with-log-returns/

    Params:

      - ``timeframe`` (default: ``None``)
        If ``None`` then the complete return over the entire backtested period
        will be reported

        Pass ``TimeFrame.NoTimeFrame`` to consider the entire dataset with no
        time constraints

      - ``compression`` (default: ``None``)

        Only used for sub-day timeframes to for example work on an hourly
        timeframe by specifying "TimeFrame.Minutes" and 60 as compression

        If ``None`` then the compression of the 1st data of the system will be
        used

      - ``tann`` (default: ``None``)

        Number of periods to use for the annualization (normalization) of the
        average returns. If ``None``, then standard ``t`` values will be used,
        namely:

          - ``days: 252``
          - ``weeks: 52``
          - ``months: 12``
          - ``years: 1``

      - ``tau`` (default: ``2.0``)

        factor for the calculation (see the literature)

      - ``sdev_max`` (default: ``0.20``)

        max standard deviation (see the literature)

      - ``fund`` (default: ``None``)

        If ``None`` the actual mode of the broker (fundmode - True/False) will
        be autodetected to decide if the returns are based on the total net
        asset value or on the fund value. See ``set_fundmode`` in the broker
        documentation

        Set it to ``True`` or ``False`` for a specific behavior

    Methods:

      - get_analysis

        Returns a dictionary with returns as values and the datetime points for
        each return as keys

        The returned dict contains the following keys:

          - ``vwr``: Variability-Weighted Return
    '''

    params = (
        ('tann', None),
        ('tau', 0.20),
        ('sdev_max', 2.0),
        ('fund', None),
    )

    _TANN = {
        bt.TimeFrame.Days: 252.0,
        bt.TimeFrame.Weeks: 52.0,
        bt.TimeFrame.Months: 12.0,
        bt.TimeFrame.Years: 1.0,
    }

    def __init__(self):
        # Children log return analyzer
        self._returns = Returns(timeframe=self.p.timeframe,
                                compression=self.p.compression,
                                tann=self.p.tann)

    def start(self):
        super(VWR, self).start()
        # Add an initial placeholder for [-1] operation
        if self.p.fund is None:
            self._fundmode = self.strategy.broker.fundmode
        else:
            self._fundmode = self.p.fund

        if not self._fundmode:
            self._pis = [self.strategy.broker.getvalue()]  # keep initial value
        else:
            self._pis = [self.strategy.broker.fundvalue]  # keep initial value

        self._pns = [None]  # keep final prices (value)

    def stop(self):
        super(VWR, self).stop()
        # Check if no value has been seen after the last 'dt_over'
        # If so, there is one 'pi' out of place and a None 'pn'. Purge
        if self._pns[-1] is None:
            self._pis.pop()
            self._pns.pop()

        # Get results from children
        rs = self._returns.get_analysis()
        ravg = rs['ravg']
        rnorm100 = rs['rnorm100']

        # make n 1 based in enumerate (number of periods and not index)
        # skip initial placeholders for synchronization
        dts = []
        for n, pipn in enumerate(zip(self._pis, self._pns), 1):
            pi, pn = pipn

            dt = pn / (pi * math.exp(ravg * n)) - 1.0
            dts.append(dt)

        sdev_p = standarddev(dts, bessel=True)

        vwr = rnorm100 * (1.0 - pow(sdev_p / self.p.sdev_max, self.p.tau))
        self.rets['vwr'] = vwr

    def notify_fund(self, cash, value, fundvalue, shares):
        if not self._fundmode:
            self._pns[-1] = value  # annotate last seen pn for current period
        else:
            self._pns[-1] = fundvalue  # annotate last pn for current period

    def _on_dt_over(self):
        self._pis.append(self._pns[-1])  # last pn is pi in next period
        self._pns.append(None)  # placeholder for [-1] operation


VariabilityWeightedReturn = VWR


================================================
FILE: backtrader/broker.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

from backtrader.comminfo import CommInfoBase
from backtrader.metabase import MetaParams
from backtrader.utils.py3 import with_metaclass

from . import fillers as fillers
from . import fillers as filler


class MetaBroker(MetaParams):
    def __init__(cls, name, bases, dct):
        '''
        Class has already been created ... fill missing methods if needed be
        '''
        # Initialize the class
        super(MetaBroker, cls).__init__(name, bases, dct)
        translations = {
            'get_cash': 'getcash',
            'get_value': 'getvalue',
        }

        for attr, trans in translations.items():
            if not hasattr(cls, attr):
                setattr(cls, name, getattr(cls, trans))


class BrokerBase(with_metaclass(MetaBroker, object)):
    params = (
        ('commission', CommInfoBase(percabs=True)),
    )

    def __init__(self):
        self.comminfo = dict()
        self.init()

    def init(self):
        # called from init and from start
        if None not in self.comminfo:
            self.comminfo = dict({None: self.p.commission})

    def start(self):
        self.init()

    def stop(self):
        pass

    def add_order_history(self, orders, notify=False):
        '''Add order history. See cerebro for details'''
        raise NotImplementedError

    def set_fund_history(self, fund):
        '''Add fund history. See cerebro for details'''
        raise NotImplementedError

    def getcommissioninfo(self, data):
        '''Retrieves the ``CommissionInfo`` scheme associated with the given
        ``data``'''
        if data._name in self.comminfo:
            return self.comminfo[data._name]

        return self.comminfo[None]

    def setcommission(self,
                      commission=0.0, margin=None, mult=1.0,
                      commtype=None, percabs=True, stocklike=False,
                      interest=0.0, interest_long=False, leverage=1.0,
                      automargin=False,
                      name=None):

        '''This method sets a `` CommissionInfo`` object for assets managed in
        the broker with the parameters. Consult the reference for
        ``CommInfoBase``

        If name is ``None``, this will be the default for assets for which no
        other ``CommissionInfo`` scheme can be found
        '''

        comm = CommInfoBase(commission=commission, margin=margin, mult=mult,
                            commtype=commtype, stocklike=stocklike,
                            percabs=percabs,
                            interest=interest, interest_long=interest_long,
                            leverage=leverage, automargin=automargin)
        self.comminfo[name] = comm

    def addcommissioninfo(self, comminfo, name=None):
        '''Adds a ``CommissionInfo`` object that will be the default for all assets if
        ``name`` is ``None``'''
        self.comminfo[name] = comminfo

    def getcash(self):
        raise NotImplementedError

    def getvalue(self, datas=None):
        raise NotImplementedError

    def get_fundshares(self):
        '''Returns the current number of shares in the fund-like mode'''
        return 1.0  # the abstract mode has only 1 share

    fundshares = property(get_fundshares)

    def get_fundvalue(self):
        return self.getvalue()

    fundvalue = property(get_fundvalue)

    def set_fundmode(self, fundmode, fundstartval=None):
        '''Set the actual fundmode (True or False)

        If the argument fundstartval is not ``None``, it will used
        '''
        pass  # do nothing, not all brokers can support this

    def get_fundmode(self):
        '''Returns the actual fundmode (True or False)'''
        return False

    fundmode = property(get_fundmode, set_fundmode)

    def getposition(self, data):
        raise NotImplementedError

    def submit(self, order):
        raise NotImplementedError

    def cancel(self, order):
        raise NotImplementedError

    def buy(self, owner, data, size, price=None, plimit=None,
            exectype=None, valid=None, tradeid=0, oco=None,
            trailamount=None, trailpercent=None,
            **kwargs):

        raise NotImplementedError

    def sell(self, owner, data, size, price=None, plimit=None,
             exectype=None, valid=None, tradeid=0, oco=None,
             trailamount=None, trailpercent=None,
             **kwargs):

        raise NotImplementedError

    def next(self):
        pass

# __all__ = ['BrokerBase', 'fillers', 'filler']


================================================
FILE: backtrader/brokers/__init__.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

# The modules below should/must define __all__ with the objects wishes
# or prepend an "_" (underscore) to private classes/variables

from .bbroker import BackBroker, BrokerBack

try:
    from .ibbroker import IBBroker
except ImportError:
    pass  # The user may not have ibpy installed

try:
    from .vcbroker import VCBroker
except ImportError:
    pass  # The user may not have something installed

try:
    from .oandabroker import OandaBroker
except ImportError as e:
    pass  # The user may not have something installed


================================================
FILE: backtrader/brokers/bbroker.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import collections
import datetime

import backtrader as bt
from backtrader.comminfo import CommInfoBase
from backtrader.order import Order, BuyOrder, SellOrder
from backtrader.position import Position
from backtrader.utils.py3 import string_types, integer_types

__all__ = ['BackBroker', 'BrokerBack']


class BackBroker(bt.BrokerBase):
    '''Broker Simulator

      The simulation supports different order types, checking a submitted order
      cash requirements against current cash, keeping track of cash and value
      for each iteration of ``cerebro`` and keeping the current position on
      different datas.

      *cash* is adjusted on each iteration for instruments like ``futures`` for
       which a price change implies in real brokers the addition/substracion of
       cash.

      Supported order types:

        - ``Market``: to be executed with the 1st tick of the next bar (namely
          the ``open`` price)

        - ``Close``: meant for intraday in which the order is executed with the
          closing price of the last bar of the session

        - ``Limit``: executes if the given limit price is seen during the
          session

        - ``Stop``: executes a ``Market`` order if the given stop price is seen

        - ``StopLimit``: sets a ``Limit`` order in motion if the given stop
          price is seen

      Because the broker is instantiated by ``Cerebro`` and there should be
      (mostly) no reason to replace the broker, the params are not controlled
      by the user for the instance.  To change this there are two options:

        1. Manually create an instance of this class with the desired params
           and use ``cerebro.broker = instance`` to set the instance as the
           broker for the ``run`` execution

        2. Use the ``set_xxx`` to set the value using
           ``cerebro.broker.set_xxx`` where ```xxx`` stands for the name of the
           parameter to set

        .. note::

           ``cerebro.broker`` is a *property* supported by the ``getbroker``
           and ``setbroker`` methods of ``Cerebro``

      Params:

        - ``cash`` (default: ``10000``): starting cash

        - ``commission`` (default: ``CommInfoBase(percabs=True)``)
          base commission scheme which applies to all assets

        - ``checksubmit`` (default: ``True``)
          check margin/cash before accepting an order into the system

        - ``eosbar`` (default: ``False``):
          With intraday bars consider a bar with the same ``time`` as the end
          of session to be the end of the session. This is not usually the
          case, because some bars (final auction) are produced by many
          exchanges for many products for a couple of minutes after the end of
          the session

        - ``filler`` (default: ``None``)

          A callable with signature: ``callable(order, price, ago)``

            - ``order``: obviously the order in execution. This provides access
              to the *data* (and with it the *ohlc* and *volume* values), the
              *execution type*, remaining size (``order.executed.remsize``) and
              others.

              Please check the ``Order`` documentation and reference for things
              available inside an ``Order`` instance

            - ``price`` the price at which the order is going to be executed in
              the ``ago`` bar

            - ``ago``: index meant to be used with ``order.data`` for the
              extraction of the *ohlc* and *volume* prices. In most cases this
              will be ``0`` but on a corner case for ``Close`` orders, this
              will be ``-1``.

              In order to get the bar volume (for example) do: ``volume =
              order.data.voluume[ago]``

          The callable must return the *executed size* (a value >= 0)

          The callable may of course be an object with ``__call__`` matching
          the aforementioned signature

          With the default ``None`` orders will be completely executed in a
          single shot

        - ``slip_perc`` (default: ``0.0``) Percentage in absolute termns (and
          positive) that should be used to slip prices up/down for buy/sell
          orders

          Note:

            - ``0.01`` is ``1%``

            - ``0.001`` is ``0.1%``

        - ``slip_fixed`` (default: ``0.0``) Percentage in units (and positive)
          that should be used to slip prices up/down for buy/sell orders

          Note: if ``slip_perc`` is non zero, it takes precendence over this.

        - ``slip_open`` (default: ``False``) whether to slip prices for order
          execution which would specifically used the *opening* price of the
          next bar. An example would be ``Market`` order which is executed with
          the next available tick, i.e: the opening price of the bar.

          This also applies to some of the other executions, because the logic
          tries to detect if the *opening* price would match the requested
          price/execution type when moving to a new bar.

        - ``slip_match`` (default: ``True``)

          If ``True`` the broker will offer a match by capping slippage at
          ``high/low`` prices in case they would be exceeded.

          If ``False`` the broker will not match the order with the current
          prices and will try execution during the next iteration

        - ``slip_limit`` (default: ``True``)

          ``Limit`` orders, given the exact match price requested, will be
          matched even if ``slip_match`` is ``False``.

          This option controls that behavior.

          If ``True``, then ``Limit`` orders will be matched by capping prices
          to the ``limit`` / ``high/low`` prices

          If ``False`` and slippage exceeds the cap, then there will be no
          match

        - ``slip_out`` (default: ``False``)

          Provide *slippage* even if the price falls outside the ``high`` -
          ``low`` range.

        - ``coc`` (default: ``False``)

          *Cheat-On-Close* Setting this to ``True`` with ``set_coc`` enables
           matching a ``Market`` order to the closing price of the bar in which
           the order was issued. This is actually *cheating*, because the bar
           is *closed* and any order should first be matched against the prices
           in the next bar

        - ``coo`` (default: ``False``)

          *Cheat-On-Open* Setting this to ``True`` with ``set_coo`` enables
           matching a ``Market`` order to the opening price, by for example
           using a timer with ``cheat`` set to ``True``, because such a timer
           gets executed before the broker has evaluated

        - ``int2pnl`` (default: ``True``)

          Assign generated interest (if any) to the profit and loss of
          operation that reduces a position (be it long or short). There may be
          cases in which this is undesired, because different strategies are
          competing and the interest would be assigned on a non-deterministic
          basis to any of them.

        - ``shortcash`` (default: ``True``)

          If True then cash will be increased when a stocklike asset is shorted
          and the calculated value for the asset will be negative.

          If ``False`` then the cash will be deducted as operation cost and the
          calculated value will be positive to end up with the same amount

        - ``fundstartval`` (default: ``100.0``)

          This parameter controls the start value for measuring the performance
          in a fund-like way, i.e.: cash can be added and deducted increasing
          the amount of shares. Performance is not measured using the net
          asset value of the porftoflio but using the value of the fund

        - ``fundmode`` (default: ``False``)

          If this is set to ``True`` analyzers like ``TimeReturn`` can
          automatically calculate returns based on the fund value and not on
          the total net asset value

    '''
    params = (
        ('cash', 10000.0),
        ('checksubmit', True),
        ('eosbar', False),
        ('filler', None),
        # slippage options
        ('slip_perc', 0.0),
        ('slip_fixed', 0.0),
        ('slip_open', False),
        ('slip_match', True),
        ('slip_limit', True),
        ('slip_out', False),
        ('coc', False),
        ('coo', False),
        ('int2pnl', True),
        ('shortcash', True),
        ('fundstartval', 100.0),
        ('fundmode', False),
    )

    def __init__(self):
        super(BackBroker, self).__init__()
        self._userhist = []
        self._fundhist = []
        # share_value, net asset value
        self._fhistlast = [float('NaN'), float('NaN')]

    def init(self):
        super(BackBroker, self).init()
        self.startingcash = self.cash = self.p.cash
        self._value = self.cash
        self._valuemkt = 0.0  # no open position

        self._valuelever = 0.0  # no open position
        self._valuemktlever = 0.0  # no open position

        self._leverage = 1.0  # initially nothing is open
        self._unrealized = 0.0  # no open position

        self.orders = list()  # will only be appending
        self.pending = collections.deque()  # popleft and append(right)
        self._toactivate = collections.deque()  # to activate in next cycle

        self.positions = collections.defaultdict(Position)
        self.d_credit = collections.defaultdict(float)  # credit per data
        self.notifs = collections.deque()

        self.submitted = collections.deque()

        # to keep dependent orders if needed
        self._pchildren = collections.defaultdict(collections.deque)

        self._ocos = dict()
        self._ocol = collections.defaultdict(list)

        self._fundval = self.p.fundstartval
        self._fundshares = self.p.cash / self._fundval
        self._cash_addition = collections.deque()

    def get_notification(self):
        try:
            return self.notifs.popleft()
        except IndexError:
            pass

        return None

    def set_fundmode(self, fundmode, fundstartval=None):
        '''Set the actual fundmode (True or False)

        If the argument fundstartval is not ``None``, it will used
        '''
        self.p.fundmode = fundmode
        if fundstartval is not None:
            self.set_fundstartval(fundstartval)

    def get_fundmode(self):
        '''Returns the actual fundmode (True or False)'''
        return self.p.fundmode

    fundmode = property(get_fundmode, set_fundmode)

    def set_fundstartval(self, fundstartval):
        '''Set the starting value of the fund-like performance tracker'''
        self.p.fundstartval = fundstartval

    def set_int2pnl(self, int2pnl):
        '''Configure assignment of interest to profit and loss'''
        self.p.int2pnl = int2pnl

    def set_coc(self, coc):
        '''Configure the Cheat-On-Close method to buy the close on order bar'''
        self.p.coc = coc

    def set_coo(self, coo):
        '''Configure the Cheat-On-Open method to buy the close on order bar'''
        self.p.coo = coo

    def set_shortcash(self, shortcash):
        '''Configure the shortcash parameters'''
        self.p.shortcash = shortcash

    def set_slippage_perc(self, perc,
                          slip_open=True, slip_limit=True,
                          slip_match=True, slip_out=False):
        '''Configure slippage to be percentage based'''
        self.p.slip_perc = perc
        self.p.slip_fixed = 0.0
        self.p.slip_open = slip_open
        self.p.slip_limit = slip_limit
        self.p.slip_match = slip_match
        self.p.slip_out = slip_out

    def set_slippage_fixed(self, fixed,
                           slip_open=True, slip_limit=True,
                           slip_match=True, slip_out=False):
        '''Configure slippage to be fixed points based'''
        self.p.slip_perc = 0.0
        self.p.slip_fixed = fixed
        self.p.slip_open = slip_open
        self.p.slip_limit = slip_limit
        self.p.slip_match = slip_match
        self.p.slip_out = slip_out

    def set_filler(self, filler):
        '''Sets a volume filler for volume filling execution'''
        self.p.filler = filler

    def set_checksubmit(self, checksubmit):
        '''Sets the checksubmit parameter'''
        self.p.checksubmit = checksubmit

    def set_eosbar(self, eosbar):
        '''Sets the eosbar parameter (alias: ``seteosbar``'''
        self.p.eosbar = eosbar

    seteosbar = set_eosbar

    def get_cash(self):
        '''Returns the current cash (alias: ``getcash``)'''
        return self.cash

    getcash = get_cash

    def set_cash(self, cash):
        '''Sets the cash parameter (alias: ``setcash``)'''
        self.startingcash = self.cash = self.p.cash = cash
        self._value = cash

    setcash = set_cash

    def add_cash(self, cash):
        '''Add/Remove cash to the system (use a negative value to remove)'''
        self._cash_addition.append(cash)

    def get_fundshares(self):
        '''Returns the current number of shares in the fund-like mode'''
        return self._fundshares

    fundshares = property(get_fundshares)

    def get_fundvalue(self):
        '''Returns the Fund-like share value'''
        return self._fundval

    fundvalue = property(get_fundvalue)

    def cancel(self, order, bracket=False):
        try:
            self.pending.remove(order)
        except ValueError:
            # If the list didn't have the element we didn't cancel anything
            return False

        order.cancel()
        self.notify(order)
        self._ococheck(order)
        if not bracket:
            self._bracketize(order, cancel=True)
        return True

    def get_value(self, datas=None, mkt=False, lever=False):
        '''Returns the portfolio value of the given datas (if datas is ``None``, then
        the total portfolio value will be returned (alias: ``getvalue``)
        '''
        if datas is None:
            if mkt:
                return self._valuemkt if not lever else self._valuemktlever

            return self._value if not lever else self._valuelever

        return self._get_value(datas=datas, lever=lever)

    getvalue = get_value

    def get_value_lever(self, datas=None, mkt=False):
        return self.get_value(datas=datas, mkt=mkt)

    def _get_value(self, datas=None, lever=False):
        pos_value = 0.0
        pos_value_unlever = 0.0
        unrealized = 0.0

        while self._cash_addition:
            c = self._cash_addition.popleft()
            self._fundshares += c / self._fundval
            self.cash += c

        for data in datas or self.positions:
            comminfo = self.getcommissioninfo(data)
            position = self.positions[data]
            # use valuesize:  returns raw value, rather than negative adj val
            if not self.p.shortcash:
                dvalue = comminfo.getvalue(position, data.close[0])
            else:
                dvalue = comminfo.getvaluesize(position.size, data.close[0])

            dunrealized = comminfo.profitandloss(position.size, position.price,
                                                 data.close[0])
            if datas and len(datas) == 1:
                if lever and dvalue > 0:
                    dvalue -= dunrealized
                    return (dvalue / comminfo.get_leverage()) + dunrealized
                return dvalue  # raw data value requested, short selling is neg

            if not self.p.shortcash:
                dvalue = abs(dvalue)  # short selling adds value in this case

            pos_value += dvalue
            unrealized += dunrealized

            if dvalue > 0:  # long position - unlever
                dvalue -= dunrealized
                pos_value_unlever += (dvalue / comminfo.get_leverage())
                pos_value_unlever += dunrealized
            else:
                pos_value_unlever += dvalue

        if not self._fundhist:
            self._value = v = self.cash + pos_value_unlever
            self._fundval = self._value / self._fundshares  # update fundvalue
        else:
            # Try to fetch a value
            fval, fvalue = self._process_fund_history()

            self._value = fvalue
            self.cash = fvalue - pos_value_unlever
            self._fundval = fval
            self._fundshares = fvalue / fval
            lev = pos_value / (pos_value_unlever or 1.0)

            # update the calculated values above to the historical values
            pos_value_unlever = fvalue
            pos_value = fvalue * lev

        self._valuemkt = pos_value_unlever

        self._valuelever = self.cash + pos_value
        self._valuemktlever = pos_value

        self._leverage = pos_value / (pos_value_unlever or 1.0)
        self._unrealized = unrealized

        return self._value if not lever else self._valuelever

    def get_leverage(self):
        return self._leverage

    def get_orders_open(self, safe=False):
        '''Returns an iterable with the orders which are still open (either not
        executed or partially executed

        The orders returned must not be touched.

        If order manipulation is needed, set the parameter ``safe`` to True
        '''
        if safe:
            os = [x.clone() for x in self.pending]
        else:
            os = [x for x in self.pending]

        return os

    def getposition(self, data):
        '''Returns the current position status (a ``Position`` instance) for
        the given ``data``'''
        return self.positions[data]

    def orderstatus(self, order):
        try:
            o = self.orders.index(order)
        except ValueError:
            o = order

        return o.status

    def _take_children(self, order):
        oref = order.ref
        pref = getattr(order.parent, 'ref', oref)  # parent ref or self

        if oref != pref:
            if pref not in self._pchildren:
                order.reject()  # parent not there - may have been rejected
                self.notify(order)  # reject child, notify
                return None

        return pref

    def submit(self, order, check=True):
        pref = self._take_children(order)
        if pref is None:  # order has not been taken
            return order

        pc = self._pchildren[pref]
        pc.append(order)  # store in parent/children queue

        if order.transmit:  # if single order, sent and queue cleared
            # if parent-child, the parent will be sent, the other kept
            rets = [self.transmit(x, check=check) for x in pc]
            return rets[-1]  # last one is the one triggering transmission

        return order

    def transmit(self, order, check=True):
        if check and self.p.checksubmit:
            order.submit()
            self.submitted.append(order)
            self.orders.append(order)
            self.notify(order)
        else:
            self.submit_accept(order)

        return order

    def check_submitted(self):
        cash = self.cash
        positions = dict()

        while self.submitted:
            order = self.submitted.popleft()

            if self._take_children(order) is None:  # children not taken
                continue

            comminfo = self.getcommissioninfo(order.data)

            position = positions.setdefault(
                order.data, self.positions[order.data].clone())

            # pseudo-execute the order to get the remaining cash after exec
            cash = self._execute(order, cash=cash, position=position)

            if cash >= 0.0:
                self.submit_accept(order)
                continue

            order.margin()
            self.notify(order)
            self._ococheck(order)
            self._bracketize(order, cancel=True)

    def submit_accept(self, order):
        order.pannotated = None
        order.submit()
        order.accept()
        self.pending.append(order)
        self.notify(order)

    def _bracketize(self, order, cancel=False):
        oref = order.ref
        pref = getattr(order.parent, 'ref', oref)
        parent = oref == pref

        pc = self._pchildren[pref]  # defdict - guaranteed
        if cancel or not parent:  # cancel left or child exec -> cancel other
            while pc:
                self.cancel(pc.popleft(), bracket=True)  # idempotent

            del self._pchildren[pref]  # defdict guaranteed

        else:  # not cancel -> parent exec'd
            pc.popleft()  # remove parent
            for o in pc:  # activate childnre
                self._toactivate.append(o)

    def _ococheck(self, order):
        # ocoref = self._ocos[order.ref] or order.ref  # a parent or self
        parentref = self._ocos[order.ref]
        ocoref = self._ocos.get(parentref, None)
        ocol = self._ocol.pop(ocoref, None)
        if ocol:
            for i in range(len(self.pending) - 1, -1, -1):
                o = self.pending[i]
                if o is not None and o.ref in ocol:
                    del self.pending[i]
                    o.cancel()
                    self.notify(o)

    def _ocoize(self, order, oco):
        oref = order.ref
        if oco is None:
            self._ocos[oref] = oref  # current order is parent
            self._ocol[oref].append(oref)  # create ocogroup
        else:
            ocoref = self._ocos[oco.ref]  # ref to group leader
            self._ocos[oref] = ocoref  # ref to group leader
            self._ocol[ocoref].append(oref)  # add to group

    def add_order_history(self, orders, notify=True):
        oiter = iter(orders)
        o = next(oiter, None)
        self._userhist.append([o, oiter, notify])

    def set_fund_history(self, fund):
        # iterable with the following pro item
        # [datetime, share_value, net asset value]
        fiter = iter(fund)
        f = list(next(fiter))  # must not be empty
        self._fundhist = [f, fiter]
        # self._fhistlast = f[1:]

        self.set_cash(float(f[2]))

    def buy(self, owner, data,
            size, price=None, plimit=None,
            exectype=None, valid=None, tradeid=0, oco=None,
            trailamount=None, trailpercent=None,
            parent=None, transmit=True,
            histnotify=False, _checksubmit=True,
            **kwargs):

        order = BuyOrder(owner=owner, data=data,
                         size=size, price=price, pricelimit=plimit,
                         exectype=exectype, valid=valid, tradeid=tradeid,
                         trailamount=trailamount, trailpercent=trailpercent,
                         parent=parent, transmit=transmit,
                         histnotify=histnotify)

        order.addinfo(**kwargs)
        self._ocoize(order, oco)

        return self.submit(order, check=_checksubmit)

    def sell(self, owner, data,
             size, price=None, plimit=None,
             exectype=None, valid=None, tradeid=0, oco=None,
             trailamount=None, trailpercent=None,
             parent=None, transmit=True,
             histnotify=False, _checksubmit=True,
             **kwargs):

        order = SellOrder(owner=owner, data=data,
                          size=size, price=price, pricelimit=plimit,
                          exectype=exectype, valid=valid, tradeid=tradeid,
                          trailamount=trailamount, trailpercent=trailpercent,
                          parent=parent, transmit=transmit,
                          histnotify=histnotify)

        order.addinfo(**kwargs)
        self._ocoize(order, oco)

        return self.submit(order, check=_checksubmit)

    def _execute(self, order, ago=None, price=None, cash=None, position=None,
                 dtcoc=None):
        # ago = None is used a flag for pseudo execution
        if ago is not None and price is None:
            return  # no psuedo exec no price - no execution

        if self.p.filler is None or ago is None:
            # Order gets full size or pseudo-execution
            size = order.executed.remsize
        else:
            # Execution depends on volume filler
            size = self.p.filler(order, price, ago)
            if not order.isbuy():
                size = -size

        # Get comminfo object for the data
        comminfo = self.getcommissioninfo(order.data)

        # Check if something has to be compensated
        if order.data._compensate is not None:
            data = order.data._compensate
            cinfocomp = self.getcommissioninfo(data)  # for actual commission
        else:
            data = order.data
            cinfocomp = comminfo

        # Adjust position with operation size
        if ago is not None:
            # Real execution with date
            position = self.positions[data]
            pprice_orig = position.price

            psize, pprice, opened, closed = position.pseudoupdate(size, price)

            # if part/all of a position has been closed, then there has been
            # a profitandloss ... record it
            pnl = comminfo.profitandloss(-closed, pprice_orig, price)
            cash = self.cash
        else:
            pnl = 0
            if not self.p.coo:
                price = pprice_orig = order.created.price
            else:
                # When doing cheat on open, the price to be considered for a
                # market order is the opening price and not the default closing
                # price with which the order was created
                if order.exectype == Order.Market:
                    price = pprice_orig = order.data.open[0]
                else:
                    price = pprice_orig = order.created.price

            psize, pprice, opened, closed = position.update(size, price)

        # "Closing" totally or partially is possible. Cash may be re-injected
        if closed:
            # Adjust to returned value for closed items & acquired opened items
            if self.p.shortcash:
                closedvalue = comminfo.getvaluesize(-closed, pprice_orig)
            else:
                closedvalue = comminfo.getoperationcost(closed, pprice_orig)

            closecash = closedvalue
            if closedvalue > 0:  # long position closed
                closecash /= comminfo.get_leverage()  # inc cash with lever

            cash += closecash + pnl * comminfo.stocklike
            # Calculate and substract commission
            closedcomm = comminfo.getcommission(closed, price)
            cash -= closedcomm

            if ago is not None:
                # Cashadjust closed contracts: prev close vs exec price
                # The operation can inject or take cash out
                cash += comminfo.cashadjust(-closed,
                                            position.adjbase,
                                            price)

                # Update system cash
                self.cash = cash
        else:
            closedvalue = closedcomm = 0.0

        popened = opened
        if opened:
            if self.p.shortcash:
                openedvalue = comminfo.getvaluesize(opened, price)
            else:
                openedvalue = comminfo.getoperationcost(opened, price)

            opencash = openedvalue
            if openedvalue > 0:  # long position being opened
                opencash /= comminfo.get_leverage()  # dec cash with level

            cash -= opencash  # original behavior

            openedcomm = cinfocomp.getcommission(opened, price)
            cash -= openedcomm

            if cash < 0.0:
                # execution is not possible - nullify
                opened = 0
                openedvalue = openedcomm = 0.0

            elif ago is not None:  # real execution
                if abs(psize) > abs(opened):
                    # some futures were opened - adjust the cash of the
                    # previously existing futures to the operation price and
                    # use that as new adjustment base, because it already is
                    # for the new futures At the end of the cycle the
                    # adjustment to the close price will be done for all open
                    # futures from a common base price with regards to the
                    # close price
                    adjsize = psize - opened
                    cash += comminfo.cashadjust(adjsize,
                                                position.adjbase, price)

                # record adjust price base for end of bar cash adjustment
                position.adjbase = price

                # update system cash - checking if opened is still != 0
                self.cash = cash
        else:
            openedvalue = openedcomm = 0.0

        if ago is None:
            # return cash from pseudo-execution
            return cash

        execsize = closed + opened

        if execsize:
            # Confimrm the operation to the comminfo object
            comminfo.confirmexec(execsize, price)

            # do a real position update if something was executed
            position.update(execsize, price, data.datetime.datetime())

            if closed and self.p.int2pnl:  # Assign accumulated interest data
                closedcomm += self.d_credit.pop(data, 0.0)

            # Execute and notify the order
            order.execute(dtcoc or data.datetime[ago],
                          execsize, price,
                          closed, closedvalue, closedcomm,
                          opened, openedvalue, openedcomm,
                          comminfo.margin, pnl,
                          psize, pprice)

            order.addcomminfo(comminfo)

            self.notify(order)
            self._ococheck(order)

        if popened and not opened:
            # opened was not executed - not enough cash
            order.margin()
            self.notify(order)
            self._ococheck(order)
            self._bracketize(order, cancel=True)

    def notify(self, order):
        self.notifs.append(order.clone())

    def _try_exec_historical(self, order):
        self._execute(order, ago=0, price=order.created.price)

    def _try_exec_market(self, order, popen, phigh, plow):
        ago = 0
        if self.p.coc and order.info.get('coc', True):
            dtcoc = order.created.dt
            exprice = order.created.pclose
        else:
            if not self.p.coo and order.data.datetime[0] <= order.created.dt:
                return    # can only execute after creation time

            dtcoc = None
            exprice = popen

        if order.isbuy():
            p = self._slip_up(phigh, exprice, doslip=self.p.slip_open)
        else:
            p = self._slip_down(plow, exprice, doslip=self.p.slip_open)

        self._execute(order, ago=0, price=p, dtcoc=dtcoc)

    def _try_exec_close(self, order, pclose):
        # pannotated allows to keep track of the closing bar if there is no
        # information which lets us know that the current bar is the closing
        # bar (like matching end of session bar)
        # The actual matching will be done one bar afterwards but using the
        # information from the actual closing bar

        dt0 = order.data.datetime[0]
        # don't use "len" -> in replay the close can be reached with same len
        if dt0 > order.created.dt:  # can only execute after creation time
            # or (self.p.eosbar and dt0 == order.dteos):
            if dt0 >= order.dteos:
                # past the end of session or right at it and eosbar is True
                if order.pannotated and dt0 > order.dteos:
                    ago = -1
                    execprice = order.pannotated
                else:
                    ago = 0
                    execprice = pclose

                self._execute(order, ago=ago, price=execprice)
                return

        # If no exexcution has taken place ... annotate the closing price
        order.pannotated = pclose

    def _try_exec_limit(self, order, popen, phigh, plow, plimit):
        if order.isbuy():
            if plimit >= popen:
                # open smaller/equal than requested - buy cheaper
                pmax = min(phigh, plimit)
                p = self._slip_up(pmax, popen, doslip=self.p.slip_open,
                                  lim=True)
                self._execute(order, ago=0, price=p)
            elif plimit >= plow:
                # day low below req price ... match limit price
                self._execute(order, ago=0, price=plimit)

        else:  # Sell
            if plimit <= popen:
                # open greater/equal than requested - sell more expensive
                pmin = max(plow, plimit)
                p = self._slip_down(plimit, popen, doslip=self.p.slip_open,
                                    lim=True)
                self._execute(order, ago=0, price=p)
            elif plimit <= phigh:
                # day high above req price ... match limit price
                self._execute(order, ago=0, price=plimit)

    def _try_exec_stop(self, order, popen, phigh, plow, pcreated, pclose):
        if order.isbuy():
            if popen >= pcreated:
                # price penetrated with an open gap - use open
                p = self._slip_up(phigh, popen, doslip=self.p.slip_open)
                self._execute(order, ago=0, price=p)
            elif phigh >= pcreated:
                # price penetrated during the session - use trigger price
                p = self._slip_up(phigh, pcreated)
                self._execute(order, ago=0, price=p)

        else:  # Sell
            if popen <= pcreated:
                # price penetrated with an open gap - use open
                p = self._slip_down(plow, popen, doslip=self.p.slip_open)
                self._execute(order, ago=0, price=p)
            elif plow <= pcreated:
                # price penetrated during the session - use trigger price
                p = self._slip_down(plow, pcreated)
                self._execute(order, ago=0, price=p)

        # not (completely) executed and trailing stop
        if order.alive() and order.exectype == Order.StopTrail:
            order.trailadjust(pclose)

    def _try_exec_stoplimit(self, order,
                            popen, phigh, plow, pclose,
                            pcreated, plimit):
        if order.isbuy():
            if popen >= pcreated:
                order.triggered = True
                self._try_exec_limit(order, popen, phigh, plow, plimit)

            elif phigh >= pcreated:
                # price penetrated upwards during the session
                order.triggered = True
                # can calculate execution for a few cases - datetime is fixed
                if popen > pclose:
                    if plimit >= pcreated:  # limit above stop trigger
                        p = self._slip_up(phigh, pcreated, lim=True)
                        self._execute(order, ago=0, price=p)
                    elif plimit >= pclose:
                        self._execute(order, ago=0, price=plimit)
                else:  # popen < pclose
                    if plimit >= pcreated:
                        p = self._slip_up(phigh, pcreated, lim=True)
                        self._execute(order, ago=0, price=p)
        else:  # Sell
            if popen <= pcreated:
                # price penetrated downwards with an open gap
                order.triggered = True
                self._try_exec_limit(order, popen, phigh, plow, plimit)

            elif plow <= pcreated:
                # price penetrated downwards during the session
                order.triggered = True
                # can calculate execution for a few cases - datetime is fixed
                if popen <= pclose:
                    if plimit <= pcreated:
                        p = self._slip_down(plow, pcreated, lim=True)
                        self._execute(order, ago=0, price=p)
                    elif plimit <= pclose:
                        self._execute(order, ago=0, price=plimit)
                else:
                    # popen > pclose
                    if plimit <= pcreated:
                        p = self._slip_down(plow, pcreated, lim=True)
                        self._execute(order, ago=0, price=p)

        # not (completely) executed and trailing stop
        if order.alive() and order.exectype == Order.StopTrailLimit:
            order.trailadjust(pclose)

    def _slip_up(self, pmax, price, doslip=True, lim=False):
        if not doslip:
            return price

        slip_perc = self.p.slip_perc
        slip_fixed = self.p.slip_fixed
        if slip_perc:
            pslip = price * (1 + slip_perc)
        elif slip_fixed:
            pslip = price + slip_fixed
        else:
            return price

        if pslip <= pmax:  # slipping can return price
            return pslip
        elif self.p.slip_match or (lim and self.p.slip_limit):
            if not self.p.slip_out:
                return pmax

            return pslip  # non existent price

        return None  # no price can be returned

    def _slip_down(self, pmin, price, doslip=True, lim=False):
        if not doslip:
            return price

        slip_perc = self.p.slip_perc
        slip_fixed = self.p.slip_fixed
        if slip_perc:
            pslip = price * (1 - slip_perc)
        elif slip_fixed:
            pslip = price - slip_fixed
        else:
            return price

        if pslip >= pmin:  # slipping can return price
            return pslip
        elif self.p.slip_match or (lim and self.p.slip_limit):
            if not self.p.slip_out:
                return pmin

            return pslip  # non existent price

        return None  # no price can be returned

    def _try_exec(self, order):
        data = order.data

        popen = getattr(data, 'tick_open', None)
        if popen is None:
            popen = data.open[0]
        phigh = getattr(data, 'tick_high', None)
        if phigh is None:
            phigh = data.high[0]
        plow = getattr(data, 'tick_low', None)
        if plow is None:
            plow = data.low[0]
        pclose = getattr(data, 'tick_close', None)
        if pclose is None:
            pclose = data.close[0]

        pcreated = order.created.price
        plimit = order.created.pricelimit

        if order.exectype == Order.Market:
            self._try_exec_market(order, popen, phigh, plow)

        elif order.exectype == Order.Close:
            self._try_exec_close(order, pclose)

        elif order.exectype == Order.Limit:
            self._try_exec_limit(order, popen, phigh, plow, pcreated)

        elif (order.triggered and
              order.exectype in [Order.StopLimit, Order.StopTrailLimit]):
            self._try_exec_limit(order, popen, phigh, plow, plimit)

        elif order.exectype in [Order.Stop, Order.StopTrail]:
            self._try_exec_stop(order, popen, phigh, plow, pcreated, pclose)

        elif order.exectype in [Order.StopLimit, Order.StopTrailLimit]:
            self._try_exec_stoplimit(order,
                                     popen, phigh, plow, pclose,
                                     pcreated, plimit)

        elif order.exectype == Order.Historical:
            self._try_exec_historical(order)

    def _process_fund_history(self):
        fhist = self._fundhist  # [last element, iterator]
        f, funds = fhist
        if not f:
            return self._fhistlast

        dt = f[0]  # date/datetime instance
        if isinstance(dt, string_types):
            dtfmt = '%Y-%m-%d'
            if 'T' in dt:
                dtfmt += 'T%H:%M:%S'
                if '.' in dt:
                    dtfmt += '.%f'
            dt = datetime.datetime.strptime(dt, dtfmt)
            f[0] = dt  # update value

        elif isinstance(dt, datetime.datetime):
            pass
        elif isinstance(dt, datetime.date):
            dt = datetime.datetime(year=dt.year, month=dt.month, day=dt.day)
            f[0] = dt  # Update the value

        # Synchronization with the strategy is not possible because the broker
        # is called before the strategy advances. The 2 lines below would do it
        # if possible
        # st0 = self.cerebro.runningstrats[0]
        # if dt <= st0.datetime.datetime():
        if dt <= self.cerebro._dtmaster:
            self._fhistlast = f[1:]
            fhist[0] = list(next(funds, []))

        return self._fhistlast

    def _process_order_history(self):
        for uhist in self._userhist:
            uhorder, uhorders, uhnotify = uhist
            while uhorder is not None:
                uhorder = list(uhorder)  # to support assignment (if tuple)
                try:
                    dataidx = uhorder[3]  # 2nd field
                except IndexError:
                    dataidx = None  # Field not present, use default

                if dataidx is None:
                    d = self.cerebro.datas[0]
                elif isinstance(dataidx, integer_types):
                    d = self.cerebro.datas[dataidx]
                else:  # assume string
                    d = self.cerebro.datasbyname[dataidx]

                if not len(d):
                    break  # may start later as oter data feeds

                dt = uhorder[0]  # date/datetime instance
                if isinstance(dt, string_types):
                    dtfmt = '%Y-%m-%d'
                    if 'T' in dt:
                        dtfmt += 'T%H:%M:%S'
                        if '.' in dt:
                            dtfmt += '.%f'
                    dt = datetime.datetime.strptime(dt, dtfmt)
                    uhorder[0] = dt
                elif isinstance(dt, datetime.datetime):
                    pass
                elif isinstance(dt, datetime.date):
                    dt = datetime.datetime(year=dt.year,
                                           month=dt.month,
                                           day=dt.day)
                    uhorder[0] = dt

                if dt > d.datetime.datetime():
                    break  # cannot execute yet 1st in queue, stop processing

                size = uhorder[1]
                price = uhorder[2]
                owner = self.cerebro.runningstrats[0]
                if size > 0:
                    o = self.buy(owner=owner, data=d,
                                 size=size, price=price,
                                 exectype=Order.Historical,
                                 histnotify=uhnotify,
                                 _checksubmit=False)

                elif size < 0:
                    o = self.sell(owner=owner, data=d,
                                  size=abs(size), price=price,
                                  exectype=Order.Historical,
                                  histnotify=uhnotify,
                                  _checksubmit=False)

                # update to next potential order
                uhist[0] = uhorder = next(uhorders, None)

    def next(self):
        while self._toactivate:
            self._toactivate.popleft().activate()

        if self.p.checksubmit:
            self.check_submitted()

        # Discount any cash for positions hold
        credit = 0.0
        for data, pos in self.positions.items():
            if pos:
                comminfo = self.getcommissioninfo(data)
                dt0 = data.datetime.datetime()
                dcredit = comminfo.get_credit_interest(data, pos, dt0)
                self.d_credit[data] += dcredit
                credit += dcredit
                pos.datetime = dt0  # mark last credit operation

        self.cash -= credit

        self._process_order_history()

        # Iterate once over all elements of the pending queue
        self.pending.append(None)
        while True:
            order = self.pending.popleft()
            if order is None:
                break

            if order.expire():
                self.notify(order)
                self._ococheck(order)
                self._bracketize(order, cancel=True)

            elif not order.active():
                self.pending.append(order)  # cannot yet be processed

            else:
                self._try_exec(order)
                if order.alive():
                    self.pending.append(order)

                elif order.status == Order.Completed:
                    # a bracket parent order may have been executed
                    self._bracketize(order)

        # Operations have been executed ... adjust cash end of bar
        for data, pos in self.positions.items():
            # futures change cash every bar
            if pos:
                comminfo = self.getcommissioninfo(data)
                self.cash += comminfo.cashadjust(pos.size,
                                                 pos.adjbase,
                                                 data.close[0])
                # record the last adjustment price
                pos.adjbase = data.close[0]

        self._get_value()  # update value


# Alias
BrokerBack = BackBroker


================================================
FILE: backtrader/brokers/ibbroker.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import collections
from copy import copy
from datetime import date, datetime, timedelta
import threading
import uuid

import ib.ext.Order
import ib.opt as ibopt

from backtrader.feed import DataBase
from backtrader import (TimeFrame, num2date, date2num, BrokerBase,
                        Order, OrderBase, OrderData)
from backtrader.utils.py3 import bytes, bstr, with_metaclass, queue, MAXFLOAT
from backtrader.metabase import MetaParams
from backtrader.comminfo import CommInfoBase
from backtrader.position import Position
from backtrader.stores import ibstore
from backtrader.utils import AutoDict, AutoOrderedDict
from backtrader.comminfo import CommInfoBase

bytes = bstr  # py2/3 need for ibpy


class IBOrderState(object):
    # wraps OrderState object and can print it
    _fields = ['status', 'initMargin', 'maintMargin', 'equityWithLoan',
               'commission', 'minCommission', 'maxCommission',
               'commissionCurrency', 'warningText']

    def __init__(self, orderstate):
        for f in self._fields:
            fname = 'm_' + f
            setattr(self, fname, getattr(orderstate, fname))

    def __str__(self):
        txt = list()
        txt.append('--- ORDERSTATE BEGIN')
        for f in self._fields:
            fname = 'm_' + f
            txt.append('{}: {}'.format(f.capitalize(), getattr(self, fname)))
        txt.append('--- ORDERSTATE END')
        return '\n'.join(txt)


class IBOrder(OrderBase, ib.ext.Order.Order):
    '''Subclasses the IBPy order to provide the minimum extra functionality
    needed to be compatible with the internally defined orders

    Once ``OrderBase`` has processed the parameters, the __init__ method takes
    over to use the parameter values and set the appropriate values in the
    ib.ext.Order.Order object

    Any extra parameters supplied with kwargs are applied directly to the
    ib.ext.Order.Order object, which could be used as follows::

      Example: if the 4 order execution types directly supported by
      ``backtrader`` are not enough, in the case of for example
      *Interactive Brokers* the following could be passed as *kwargs*::

        orderType='LIT', lmtPrice=10.0, auxPrice=9.8

      This would override the settings created by ``backtrader`` and
      generate a ``LIMIT IF TOUCHED`` order with a *touched* price of 9.8
      and a *limit* price of 10.0.

    This would be done almost always from the ``Buy`` and ``Sell`` methods of
    the ``Strategy`` subclass being used in ``Cerebro``
    '''

    def __str__(self):
        '''Get the printout from the base class and add some ib.Order specific
        fields'''
        basetxt = super(IBOrder, self).__str__()
        tojoin = [basetxt]
        tojoin.append('Ref: {}'.format(self.ref))
        tojoin.append('orderId: {}'.format(self.m_orderId))
        tojoin.append('Action: {}'.format(self.m_action))
        tojoin.append('Size (ib): {}'.format(self.m_totalQuantity))
        tojoin.append('Lmt Price: {}'.format(self.m_lmtPrice))
        tojoin.append('Aux Price: {}'.format(self.m_auxPrice))
        tojoin.append('OrderType: {}'.format(self.m_orderType))
        tojoin.append('Tif (Time in Force): {}'.format(self.m_tif))
        tojoin.append('GoodTillDate: {}'.format(self.m_goodTillDate))
        return '\n'.join(tojoin)

    # Map backtrader order types to the ib specifics
    _IBOrdTypes = {
        None: bytes('MKT'),  # default
        Order.Market: bytes('MKT'),
        Order.Limit: bytes('LMT'),
        Order.Close: bytes('MOC'),
        Order.Stop: bytes('STP'),
        Order.StopLimit: bytes('STPLMT'),
        Order.StopTrail: bytes('TRAIL'),
        Order.StopTrailLimit: bytes('TRAIL LIMIT'),
    }

    def __init__(self, action, **kwargs):

        # Marker to indicate an openOrder has been seen with
        # PendinCancel/Cancelled which is indication of an upcoming
        # cancellation
        self._willexpire = False

        self.ordtype = self.Buy if action == 'BUY' else self.Sell

        super(IBOrder, self).__init__()
        ib.ext.Order.Order.__init__(self)  # Invoke 2nd base class

        # Now fill in the specific IB parameters
        self.m_orderType = self._IBOrdTypes[self.exectype]
        self.m_permid = 0

        # 'B' or 'S' should be enough
        self.m_action = bytes(action)

        # Set the prices
        self.m_lmtPrice = 0.0
        self.m_auxPrice = 0.0

        if self.exectype == self.Market:  # is it really needed for Market?
            pass
        elif self.exectype == self.Close:  # is it ireally needed for Close?
            pass
        elif self.exectype == self.Limit:
            self.m_lmtPrice = self.price
        elif self.exectype == self.Stop:
            self.m_auxPrice = self.price  # stop price / exec is market
        elif self.exectype == self.StopLimit:
            self.m_lmtPrice = self.pricelimit  # req limit execution
            self.m_auxPrice = self.price  # trigger price
        elif self.exectype == self.StopTrail:
            if self.trailamount is not None:
                self.m_auxPrice = self.trailamount
            elif self.trailpercent is not None:
                # value expected in % format ... multiply 100.0
                self.m_trailingPercent = self.trailpercent * 100.0
        elif self.exectype == self.StopTrailLimit:
            self.m_trailStopPrice = self.m_lmtPrice = self.price
            # The limit offset is set relative to the price difference in TWS
            self.m_lmtPrice = self.pricelimit
            if self.trailamount is not None:
                self.m_auxPrice = self.trailamount
            elif self.trailpercent is not None:
                # value expected in % format ... multiply 100.0
                self.m_trailingPercent = self.trailpercent * 100.0

        self.m_totalQuantity = abs(self.size)  # ib takes only positives

        self.m_transmit = self.transmit
        if self.parent is not None:
            self.m_parentId = self.parent.m_orderId

        # Time In Force: DAY, GTC, IOC, GTD
        if self.valid is None:
            tif = 'GTC'  # Good til cancelled
        elif isinstance(self.valid, (datetime, date)):
            tif = 'GTD'  # Good til date
            self.m_goodTillDate = bytes(self.valid.strftime('%Y%m%d %H:%M:%S'))
        elif isinstance(self.valid, (timedelta,)):
            if self.valid == self.DAY:
                tif = 'DAY'
            else:
                tif = 'GTD'  # Good til date
                valid = datetime.now() + self.valid  # .now, using localtime
                self.m_goodTillDate = bytes(valid.strftime('%Y%m%d %H:%M:%S'))

        elif self.valid == 0:
            tif = 'DAY'
        else:
            tif = 'GTD'  # Good til date
            valid = num2date(self.valid)
            self.m_goodTillDate = bytes(valid.strftime('%Y%m%d %H:%M:%S'))

        self.m_tif = bytes(tif)

        # OCA
        self.m_ocaType = 1  # Cancel all remaining orders with block

        # pass any custom arguments to the order
        for k in kwargs:
            setattr(self, (not hasattr(self, k)) * 'm_' + k, kwargs[k])


class IBCommInfo(CommInfoBase):
    '''
    Commissions are calculated by ib, but the trades calculations in the
    ```Strategy`` rely on the order carrying a CommInfo object attached for the
    calculation of the operation cost and value.

    These are non-critical informations, but removing them from the trade could
    break existing usage and it is better to provide a CommInfo objet which
    enables those calculations even if with approvimate values.

    The margin calculation is not a known in advance information with IB
    (margin impact can be gotten from OrderState objects) and therefore it is
    left as future exercise to get it'''

    def getvaluesize(self, size, price):
        # In real life the margin approaches the price
        return abs(size) * price

    def getoperationcost(self, size, price):
        '''Returns the needed amount of cash an operation would cost'''
        # Same reasoning as above
        return abs(size) * price


class MetaIBBroker(BrokerBase.__class__):
    def __init__(cls, name, bases, dct):
        '''Class has already been created ... register'''
        # Initialize the class
        super(MetaIBBroker, cls).__init__(name, bases, dct)
        ibstore.IBStore.BrokerCls = cls


class IBBroker(with_metaclass(MetaIBBroker, BrokerBase)):
    '''Broker implementation for Interactive Brokers.

    This class maps the orders/positions from Interactive Brokers to the
    internal API of ``backtrader``.

    Notes:

      - ``tradeid`` is not really supported, because the profit and loss are
        taken directly from IB. Because (as expected) calculates it in FIFO
        manner, the pnl is not accurate for the tradeid.

      - Position

        If there is an open position for an asset at the beginning of
        operaitons or orders given by other means change a position, the trades
        calculated in the ``Strategy`` in cerebro will not reflect the reality.

        To avoid this, this broker would have to do its own position
        management which would also allow tradeid with multiple ids (profit and
        loss would also be calculated locally), but could be considered to be
        defeating the purpose of working with a live broker
    '''
    params = ()

    def __init__(self, **kwargs):
        super(IBBroker, self).__init__()

        self.ib = ibstore.IBStore(**kwargs)

        self.startingcash = self.cash = 0.0
        self.startingvalue = self.value = 0.0

        self._lock_orders = threading.Lock()  # control access
        self.orderbyid = dict()  # orders by order id
        self.executions = dict()  # notified executions
        self.ordstatus = collections.defaultdict(dict)
        self.notifs = queue.Queue()  # holds orders which are notified
        self.tonotify = collections.deque()  # hold oids to be notified

    def start(self):
        super(IBBroker, self).start()
        self.ib.start(broker=self)

        if self.ib.connected():
            self.ib.reqAccountUpdates()
            self.startingcash = self.cash = self.ib.get_acc_cash()
            self.startingvalue = self.value = self.ib.get_acc_value()
        else:
            self.startingcash = self.cash = 0.0
            self.startingvalue = self.value = 0.0

    def stop(self):
        super(IBBroker, self).stop()
        self.ib.stop()

    def getcash(self):
        # This call cannot block if no answer is available from ib
        self.cash = self.ib.get_acc_cash()
        return self.cash

    def getvalue(self, datas=None):
        self.value = self.ib.get_acc_value()
        return self.value

    def getposition(self, data, clone=True):
        return self.ib.getposition(data.tradecontract, clone=clone)

    def cancel(self, order):
        try:
            o = self.orderbyid[order.m_orderId]
        except (ValueError, KeyError):
            return  # not found ... not cancellable

        if order.status == Order.Cancelled:  # already cancelled
            return

        self.ib.cancelOrder(order.m_orderId)

    def orderstatus(self, order):
        try:
            o = self.orderbyid[order.m_orderId]
        except (ValueError, KeyError):
            o = order

        return o.status

    def submit(self, order):
        order.submit(self)

        # ocoize if needed
        if order.oco is None:  # Generate a UniqueId
            order.m_ocaGroup = bytes(uuid.uuid4())
        else:
            order.m_ocaGroup = self.orderbyid[order.oco.m_orderId].m_ocaGroup

        self.orderbyid[order.m_orderId] = order
        self.ib.placeOrder(order.m_orderId, order.data.tradecontract, order)
        self.notify(order)

        return order

    def getcommissioninfo(self, data):
        contract = data.tradecontract
        try:
            mult = float(contract.m_multiplier)
        except (ValueError, TypeError):
            mult = 1.0

        stocklike = contract.m_secType not in ('FUT', 'OPT', 'FOP',)

        return IBCommInfo(mult=mult, stocklike=stocklike)

    def _makeorder(self, action, owner, data,
                   size, price=None, plimit=None,
                   exectype=None, valid=None,
                   tradeid=0, **kwargs):

        order = IBOrder(action, owner=owner, data=data,
                        size=size, price=price, pricelimit=plimit,
   
Download .txt
gitextract_g33g5s6j/

├── .github/
│   └── FUNDING.yml
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.rst
├── backtrader/
│   ├── __init__.py
│   ├── analyzer.py
│   ├── analyzers/
│   │   ├── __init__.py
│   │   ├── annualreturn.py
│   │   ├── calmar.py
│   │   ├── drawdown.py
│   │   ├── leverage.py
│   │   ├── logreturnsrolling.py
│   │   ├── periodstats.py
│   │   ├── positions.py
│   │   ├── pyfolio.py
│   │   ├── returns.py
│   │   ├── sharpe.py
│   │   ├── sqn.py
│   │   ├── timereturn.py
│   │   ├── tradeanalyzer.py
│   │   ├── transactions.py
│   │   └── vwr.py
│   ├── broker.py
│   ├── brokers/
│   │   ├── __init__.py
│   │   ├── bbroker.py
│   │   ├── ibbroker.py
│   │   ├── oandabroker.py
│   │   └── vcbroker.py
│   ├── btrun/
│   │   ├── __init__.py
│   │   └── btrun.py
│   ├── cerebro.py
│   ├── comminfo.py
│   ├── commissions/
│   │   └── __init__.py
│   ├── dataseries.py
│   ├── errors.py
│   ├── feed.py
│   ├── feeds/
│   │   ├── __init__.py
│   │   ├── blaze.py
│   │   ├── btcsv.py
│   │   ├── chainer.py
│   │   ├── csvgeneric.py
│   │   ├── ibdata.py
│   │   ├── influxfeed.py
│   │   ├── mt4csv.py
│   │   ├── oanda.py
│   │   ├── pandafeed.py
│   │   ├── quandl.py
│   │   ├── rollover.py
│   │   ├── sierrachart.py
│   │   ├── vcdata.py
│   │   ├── vchart.py
│   │   ├── vchartcsv.py
│   │   ├── vchartfile.py
│   │   └── yahoo.py
│   ├── fillers.py
│   ├── filters/
│   │   ├── __init__.py
│   │   ├── bsplitter.py
│   │   ├── calendardays.py
│   │   ├── datafiller.py
│   │   ├── datafilter.py
│   │   ├── daysteps.py
│   │   ├── heikinashi.py
│   │   ├── renko.py
│   │   └── session.py
│   ├── flt.py
│   ├── functions.py
│   ├── indicator.py
│   ├── indicators/
│   │   ├── __init__.py
│   │   ├── accdecoscillator.py
│   │   ├── aroon.py
│   │   ├── atr.py
│   │   ├── awesomeoscillator.py
│   │   ├── basicops.py
│   │   ├── bollinger.py
│   │   ├── cci.py
│   │   ├── contrib/
│   │   │   ├── __init__.py
│   │   │   └── vortex.py
│   │   ├── crossover.py
│   │   ├── dema.py
│   │   ├── deviation.py
│   │   ├── directionalmove.py
│   │   ├── dma.py
│   │   ├── dpo.py
│   │   ├── dv2.py
│   │   ├── ema.py
│   │   ├── envelope.py
│   │   ├── hadelta.py
│   │   ├── heikinashi.py
│   │   ├── hma.py
│   │   ├── hurst.py
│   │   ├── ichimoku.py
│   │   ├── kama.py
│   │   ├── kst.py
│   │   ├── lrsi.py
│   │   ├── mabase.py
│   │   ├── macd.py
│   │   ├── momentum.py
│   │   ├── ols.py
│   │   ├── oscillator.py
│   │   ├── percentchange.py
│   │   ├── percentrank.py
│   │   ├── pivotpoint.py
│   │   ├── prettygoodoscillator.py
│   │   ├── priceoscillator.py
│   │   ├── psar.py
│   │   ├── rmi.py
│   │   ├── rsi.py
│   │   ├── sma.py
│   │   ├── smma.py
│   │   ├── stochastic.py
│   │   ├── trix.py
│   │   ├── tsi.py
│   │   ├── ultimateoscillator.py
│   │   ├── vortex.py
│   │   ├── williams.py
│   │   ├── wma.py
│   │   ├── zlema.py
│   │   └── zlind.py
│   ├── linebuffer.py
│   ├── lineiterator.py
│   ├── lineroot.py
│   ├── lineseries.py
│   ├── mathsupport.py
│   ├── metabase.py
│   ├── observer.py
│   ├── observers/
│   │   ├── __init__.py
│   │   ├── benchmark.py
│   │   ├── broker.py
│   │   ├── buysell.py
│   │   ├── drawdown.py
│   │   ├── logreturns.py
│   │   ├── timereturn.py
│   │   └── trades.py
│   ├── order.py
│   ├── plot/
│   │   ├── __init__.py
│   │   ├── finance.py
│   │   ├── formatters.py
│   │   ├── locator.py
│   │   ├── multicursor.py
│   │   ├── plot.py
│   │   ├── scheme.py
│   │   └── utils.py
│   ├── position.py
│   ├── resamplerfilter.py
│   ├── signal.py
│   ├── signals/
│   │   └── __init__.py
│   ├── sizer.py
│   ├── sizers/
│   │   ├── __init__.py
│   │   ├── fixedsize.py
│   │   └── percents_sizer.py
│   ├── store.py
│   ├── stores/
│   │   ├── __init__.py
│   │   ├── ibstore.py
│   │   ├── oandastore.py
│   │   ├── vchartfile.py
│   │   └── vcstore.py
│   ├── strategies/
│   │   ├── __init__.py
│   │   └── sma_crossover.py
│   ├── strategy.py
│   ├── studies/
│   │   ├── __init__.py
│   │   └── contrib/
│   │       ├── __init__.py
│   │       └── fractal.py
│   ├── talib.py
│   ├── timer.py
│   ├── trade.py
│   ├── tradingcal.py
│   ├── utils/
│   │   ├── __init__.py
│   │   ├── autodict.py
│   │   ├── date.py
│   │   ├── dateintern.py
│   │   ├── flushfile.py
│   │   ├── ordereddefaultdict.py
│   │   └── py3.py
│   ├── version.py
│   └── writer.py
├── changelog.txt
├── contrib/
│   ├── datas/
│   │   ├── daily-KO.csv
│   │   └── daily-PEP.csv
│   ├── samples/
│   │   └── pair-trading/
│   │       └── pair-trading.py
│   └── utils/
│       ├── influxdb-import.py
│       └── iqfeed-to-influxdb.py
├── datas/
│   ├── 2005-2006-day-001.txt
│   ├── 2006-01-02-volume-min-001.txt
│   ├── 2006-day-001-optix.txt
│   ├── 2006-day-001.txt
│   ├── 2006-day-002.txt
│   ├── 2006-min-005.txt
│   ├── 2006-month-001.txt
│   ├── 2006-volume-day-001.txt
│   ├── 2006-week-001.txt
│   ├── 2006-week-002.txt
│   ├── bidask.csv
│   ├── bidask2.csv
│   ├── nvda-1999-2014.txt
│   ├── nvda-2014.txt
│   ├── orcl-1995-2014.txt
│   ├── orcl-2003-2005.txt
│   ├── orcl-2014.txt
│   ├── ticksample.csv
│   ├── yhoo-1996-2014.txt
│   ├── yhoo-1996-2015.txt
│   ├── yhoo-2003-2005.txt
│   └── yhoo-2014.txt
├── pypi.sh
├── samples/
│   ├── analyzer-annualreturn/
│   │   └── analyzer-annualreturn.py
│   ├── bidask-to-ohlc/
│   │   └── bidask-to-ohlc.py
│   ├── bracket/
│   │   └── bracket.py
│   ├── btfd/
│   │   └── btfd.py
│   ├── calendar-days/
│   │   └── calendar-days.py
│   ├── calmar/
│   │   └── calmar-test.py
│   ├── cheat-on-open/
│   │   └── cheat-on-open.py
│   ├── commission-schemes/
│   │   └── commission-schemes.py
│   ├── credit-interest/
│   │   └── credit-interest.py
│   ├── data-bid-ask/
│   │   └── bidask.py
│   ├── data-filler/
│   │   ├── data-filler.py
│   │   └── relativevolume.py
│   ├── data-multitimeframe/
│   │   └── data-multitimeframe.py
│   ├── data-pandas/
│   │   ├── data-pandas-optix.py
│   │   └── data-pandas.py
│   ├── data-replay/
│   │   └── data-replay.py
│   ├── data-resample/
│   │   └── data-resample.py
│   ├── daysteps/
│   │   └── daysteps.py
│   ├── future-spot/
│   │   └── future-spot.py
│   ├── gold-vs-sp500/
│   │   └── gold-vs-sp500.py
│   ├── ib-cash-bid-ask/
│   │   └── ib-cash-bid-ask.py
│   ├── ibtest/
│   │   └── ibtest.py
│   ├── kselrsi/
│   │   └── ksignal.py
│   ├── lineplotter/
│   │   └── lineplotter.py
│   ├── lrsi/
│   │   └── lrsi-test.py
│   ├── macd-settings/
│   │   └── macd-settings.py
│   ├── memory-savings/
│   │   └── memory-savings.py
│   ├── mixing-timeframes/
│   │   └── mixing-timeframes.py
│   ├── multi-copy/
│   │   └── multi-copy.py
│   ├── multi-example/
│   │   └── mult-values.py
│   ├── multidata-strategy/
│   │   ├── multidata-strategy-unaligned.py
│   │   └── multidata-strategy.py
│   ├── multitrades/
│   │   ├── mtradeobserver.py
│   │   └── multitrades.py
│   ├── oandatest/
│   │   └── oandatest.py
│   ├── observer-benchmark/
│   │   └── observer-benchmark.py
│   ├── observers/
│   │   ├── observers-default-drawdown.py
│   │   ├── observers-default.py
│   │   ├── observers-orderobserver.py
│   │   └── orderobserver.py
│   ├── oco/
│   │   └── oco.py
│   ├── optimization/
│   │   └── optimization.py
│   ├── order-close/
│   │   ├── close-daily.py
│   │   └── close-minute.py
│   ├── order-execution/
│   │   └── order-execution.py
│   ├── order-history/
│   │   └── order-history.py
│   ├── order_target/
│   │   └── order_target.py
│   ├── partial-plot/
│   │   └── partial-plot.py
│   ├── pinkfish-challenge/
│   │   └── pinkfish-challenge.py
│   ├── pivot-point/
│   │   ├── pivotpoint.py
│   │   └── ppsample.py
│   ├── plot-same-axis/
│   │   └── plot-same-axis.py
│   ├── psar/
│   │   ├── psar-intraday.py
│   │   └── psar.py
│   ├── pyfolio2/
│   │   ├── backtrader-pyfolio.ipynb
│   │   └── pyfoliotest.py
│   ├── pyfoliotest/
│   │   ├── backtrader-pyfolio.ipynb
│   │   └── pyfoliotest.py
│   ├── relative-volume/
│   │   ├── relative-volume.py
│   │   └── relvolbybar.py
│   ├── renko/
│   │   └── renko.py
│   ├── resample-tickdata/
│   │   └── resample-tickdata.py
│   ├── rollover/
│   │   └── rollover.py
│   ├── sharpe-timereturn/
│   │   └── sharpe-timereturn.py
│   ├── signals-strategy/
│   │   └── signals-strategy.py
│   ├── sigsmacross/
│   │   ├── sigsmacross.py
│   │   └── sigsmacross2.py
│   ├── sizertest/
│   │   └── sizertest.py
│   ├── slippage/
│   │   └── slippage.py
│   ├── sratio/
│   │   └── sratio.py
│   ├── stop-trading/
│   │   └── stop-loss-approaches.py
│   ├── stoptrail/
│   │   └── trail.py
│   ├── strategy-selection/
│   │   └── strategy-selection.py
│   ├── talib/
│   │   ├── tablibsartest.py
│   │   └── talibtest.py
│   ├── timers/
│   │   ├── scheduled-min.py
│   │   └── scheduled.py
│   ├── tradingcalendar/
│   │   ├── tcal-intra.py
│   │   └── tcal.py
│   ├── vctest/
│   │   └── vctest.py
│   ├── volumefilling/
│   │   └── volumefilling.py
│   ├── vwr/
│   │   └── vwr.py
│   ├── weekdays-filler/
│   │   ├── weekdaysaligner.py
│   │   └── weekdaysfiller.py
│   ├── writer-test/
│   │   └── writer-test.py
│   └── yahoo-test/
│       └── yahoo-test.py
├── setup.py
├── tests/
│   ├── test_analyzer-sqn.py
│   ├── test_analyzer-timereturn.py
│   ├── test_comminfo.py
│   ├── test_data_multiframe.py
│   ├── test_data_replay.py
│   ├── test_data_resample.py
│   ├── test_ind_accdecosc.py
│   ├── test_ind_aroonoscillator.py
│   ├── test_ind_aroonupdown.py
│   ├── test_ind_atr.py
│   ├── test_ind_awesomeoscillator.py
│   ├── test_ind_bbands.py
│   ├── test_ind_cci.py
│   ├── test_ind_dema.py
│   ├── test_ind_demaenvelope.py
│   ├── test_ind_demaosc.py
│   ├── test_ind_dm.py
│   ├── test_ind_dma.py
│   ├── test_ind_downmove.py
│   ├── test_ind_dpo.py
│   ├── test_ind_dv2.py
│   ├── test_ind_ema.py
│   ├── test_ind_emaenvelope.py
│   ├── test_ind_emaosc.py
│   ├── test_ind_envelope.py
│   ├── test_ind_heikinashi.py
│   ├── test_ind_highest.py
│   ├── test_ind_hma.py
│   ├── test_ind_ichimoku.py
│   ├── test_ind_kama.py
│   ├── test_ind_kamaenvelope.py
│   ├── test_ind_kamaosc.py
│   ├── test_ind_kst.py
│   ├── test_ind_lowest.py
│   ├── test_ind_lrsi.py
│   ├── test_ind_macdhisto.py
│   ├── test_ind_minperiod.py
│   ├── test_ind_momentum.py
│   ├── test_ind_momentumoscillator.py
│   ├── test_ind_oscillator.py
│   ├── test_ind_pctchange.py
│   ├── test_ind_pctrank.py
│   ├── test_ind_pgo.py
│   ├── test_ind_ppo.py
│   ├── test_ind_pposhort.py
│   ├── test_ind_priceosc.py
│   ├── test_ind_rmi.py
│   ├── test_ind_roc.py
│   ├── test_ind_rsi.py
│   ├── test_ind_rsi_safe.py
│   ├── test_ind_sma.py
│   ├── test_ind_smaenvelope.py
│   ├── test_ind_smaosc.py
│   ├── test_ind_smma.py
│   ├── test_ind_smmaenvelope.py
│   ├── test_ind_smmaosc.py
│   ├── test_ind_stochastic.py
│   ├── test_ind_stochasticfull.py
│   ├── test_ind_sumn.py
│   ├── test_ind_tema.py
│   ├── test_ind_temaenvelope.py
│   ├── test_ind_temaosc.py
│   ├── test_ind_trix.py
│   ├── test_ind_tsi.py
│   ├── test_ind_ultosc.py
│   ├── test_ind_upmove.py
│   ├── test_ind_vortex.py
│   ├── test_ind_williamsad.py
│   ├── test_ind_williamsr.py
│   ├── test_ind_wma.py
│   ├── test_ind_wmaenvelope.py
│   ├── test_ind_wmaosc.py
│   ├── test_ind_zlema.py
│   ├── test_ind_zlind.py
│   ├── test_metaclass.py
│   ├── test_order.py
│   ├── test_position.py
│   ├── test_strategy_optimized.py
│   ├── test_strategy_unoptimized.py
│   ├── test_study_fractal.py
│   ├── test_trade.py
│   ├── test_writer.py
│   └── testcommon.py
└── tools/
    ├── bt-run.py
    ├── rewrite-data.py
    └── yahoodownload.py
Download .txt
SYMBOL INDEX (2596 symbols across 323 files)

FILE: backtrader/analyzer.py
  class MetaAnalyzer (line 34) | class MetaAnalyzer(bt.MetaParams):
    method donew (line 35) | def donew(cls, *args, **kwargs):
    method dopostinit (line 78) | def dopostinit(cls, _obj, *args, **kwargs):
  class Analyzer (line 89) | class Analyzer(with_metaclass(MetaAnalyzer, object)):
    method __len__ (line 140) | def __len__(self):
    method _register (line 145) | def _register(self, child):
    method _prenext (line 148) | def _prenext(self):
    method _notify_cashvalue (line 154) | def _notify_cashvalue(self, cash, value):
    method _notify_fund (line 160) | def _notify_fund(self, cash, value, fundvalue, shares):
    method _notify_trade (line 166) | def _notify_trade(self, trade):
    method _notify_order (line 172) | def _notify_order(self, order):
    method _nextstart (line 178) | def _nextstart(self):
    method _next (line 184) | def _next(self):
    method _start (line 190) | def _start(self):
    method _stop (line 196) | def _stop(self):
    method notify_cashvalue (line 202) | def notify_cashvalue(self, cash, value):
    method notify_fund (line 206) | def notify_fund(self, cash, value, fundvalue, shares):
    method notify_order (line 210) | def notify_order(self, order):
    method notify_trade (line 214) | def notify_trade(self, trade):
    method next (line 218) | def next(self):
    method prenext (line 223) | def prenext(self):
    method nextstart (line 231) | def nextstart(self):
    method start (line 237) | def start(self):
    method stop (line 242) | def stop(self):
    method create_analysis (line 247) | def create_analysis(self):
    method get_analysis (line 255) | def get_analysis(self):
    method print (line 270) | def print(self, *args, **kwargs):
    method pprint (line 282) | def pprint(self, *args, **kwargs):
  class MetaTimeFrameAnalyzerBase (line 289) | class MetaTimeFrameAnalyzerBase(Analyzer.__class__):
    method __new__ (line 290) | def __new__(meta, name, bases, dct):
  class TimeFrameAnalyzerBase (line 299) | class TimeFrameAnalyzerBase(with_metaclass(MetaTimeFrameAnalyzerBase,
    method _start (line 307) | def _start(self):
    method _prenext (line 315) | def _prenext(self):
    method _nextstart (line 325) | def _nextstart(self):
    method _next (line 334) | def _next(self):
    method on_dt_over (line 343) | def on_dt_over(self):
    method _dt_over (line 346) | def _dt_over(self):
    method _get_dt_cmpkey (line 361) | def _get_dt_cmpkey(self, dt):
    method _get_subday_cmpkey (line 389) | def _get_subday_cmpkey(self, dt):

FILE: backtrader/analyzers/annualreturn.py
  class AnnualReturn (line 30) | class AnnualReturn(Analyzer):
    method stop (line 50) | def stop(self):
    method get_analysis (line 88) | def get_analysis(self):

FILE: backtrader/analyzers/calmar.py
  class Calmar (line 31) | class Calmar(bt.TimeFrameAnalyzerBase):
    method __init__ (line 83) | def __init__(self):
    method start (line 87) | def start(self):
    method on_dt_over (line 101) | def on_dt_over(self):
    method stop (line 112) | def stop(self):

FILE: backtrader/analyzers/drawdown.py
  class DrawDown (line 31) | class DrawDown(bt.Analyzer):
    method start (line 67) | def start(self):
    method create_analysis (line 74) | def create_analysis(self):
    method stop (line 87) | def stop(self):
    method notify_fund (line 90) | def notify_fund(self, cash, value, fundvalue, shares):
    method next (line 98) | def next(self):
  class TimeDrawDown (line 113) | class TimeDrawDown(bt.TimeFrameAnalyzerBase):
    method start (line 164) | def start(self):
    method on_dt_over (line 176) | def on_dt_over(self):
    method stop (line 195) | def stop(self):

FILE: backtrader/analyzers/leverage.py
  class GrossLeverage (line 27) | class GrossLeverage(bt.Analyzer):
    method start (line 54) | def start(self):
    method notify_fund (line 60) | def notify_fund(self, cash, value, fundvalue, shares):
    method next (line 67) | def next(self):

FILE: backtrader/analyzers/logreturnsrolling.py
  class LogReturnsRolling (line 33) | class LogReturnsRolling(bt.TimeFrameAnalyzerBase):
    method start (line 102) | def start(self):
    method notify_fund (line 119) | def notify_fund(self, cash, value, fundvalue, shares):
    method _on_dt_over (line 125) | def _on_dt_over(self):
    method next (line 136) | def next(self):

FILE: backtrader/analyzers/periodstats.py
  class PeriodStats (line 34) | class PeriodStats(bt.Analyzer):
    method __init__ (line 85) | def __init__(self):
    method stop (line 89) | def stop(self):

FILE: backtrader/analyzers/positions.py
  class PositionsValue (line 28) | class PositionsValue(bt.Analyzer):
    method start (line 68) | def start(self):
    method next (line 77) | def next(self):

FILE: backtrader/analyzers/pyfolio.py
  class PyFolio (line 33) | class PyFolio(bt.Analyzer):
    method __init__ (line 86) | def __init__(self):
    method stop (line 95) | def stop(self):
    method get_pf_items (line 102) | def get_pf_items(self):

FILE: backtrader/analyzers/returns.py
  class Returns (line 30) | class Returns(TimeFrameAnalyzerBase):
    method start (line 104) | def start(self):
    method stop (line 118) | def stop(self):
    method _on_dt_over (line 154) | def _on_dt_over(self):

FILE: backtrader/analyzers/sharpe.py
  class SharpeRatio (line 33) | class SharpeRatio(Analyzer):
    method __init__ (line 134) | def __init__(self):
    method stop (line 143) | def stop(self):
  class SharpeRatio_A (line 209) | class SharpeRatio_A(SharpeRatio):

FILE: backtrader/analyzers/sqn.py
  class SQN (line 31) | class SQN(Analyzer):
    method create_analysis (line 58) | def create_analysis(self):
    method start (line 63) | def start(self):
    method notify_trade (line 68) | def notify_trade(self, trade):
    method stop (line 73) | def stop(self):

FILE: backtrader/analyzers/timereturn.py
  class TimeReturn (line 27) | class TimeReturn(TimeFrameAnalyzerBase):
    method start (line 96) | def start(self):
    method notify_fund (line 112) | def notify_fund(self, cash, value, fundvalue, shares):
    method on_dt_over (line 125) | def on_dt_over(self):
    method next (line 138) | def next(self):

FILE: backtrader/analyzers/tradeanalyzer.py
  class TradeAnalyzer (line 31) | class TradeAnalyzer(Analyzer):
    method create_analysis (line 68) | def create_analysis(self):
    method stop (line 72) | def stop(self):
    method notify_trade (line 76) | def notify_trade(self, trade):

FILE: backtrader/analyzers/transactions.py
  class Transactions (line 31) | class Transactions(bt.Analyzer):
    method start (line 65) | def start(self):
    method notify_order (line 73) | def notify_order(self, order):
    method next (line 90) | def next(self):

FILE: backtrader/analyzers/vwr.py
  class VWR (line 32) | class VWR(TimeFrameAnalyzerBase):
    method __init__ (line 114) | def __init__(self):
    method start (line 120) | def start(self):
    method stop (line 135) | def stop(self):
    method notify_fund (line 162) | def notify_fund(self, cash, value, fundvalue, shares):
    method _on_dt_over (line 168) | def _on_dt_over(self):

FILE: backtrader/broker.py
  class MetaBroker (line 32) | class MetaBroker(MetaParams):
    method __init__ (line 33) | def __init__(cls, name, bases, dct):
  class BrokerBase (line 49) | class BrokerBase(with_metaclass(MetaBroker, object)):
    method __init__ (line 54) | def __init__(self):
    method init (line 58) | def init(self):
    method start (line 63) | def start(self):
    method stop (line 66) | def stop(self):
    method add_order_history (line 69) | def add_order_history(self, orders, notify=False):
    method set_fund_history (line 73) | def set_fund_history(self, fund):
    method getcommissioninfo (line 77) | def getcommissioninfo(self, data):
    method setcommission (line 85) | def setcommission(self,
    method addcommissioninfo (line 107) | def addcommissioninfo(self, comminfo, name=None):
    method getcash (line 112) | def getcash(self):
    method getvalue (line 115) | def getvalue(self, datas=None):
    method get_fundshares (line 118) | def get_fundshares(self):
    method get_fundvalue (line 124) | def get_fundvalue(self):
    method set_fundmode (line 129) | def set_fundmode(self, fundmode, fundstartval=None):
    method get_fundmode (line 136) | def get_fundmode(self):
    method getposition (line 142) | def getposition(self, data):
    method submit (line 145) | def submit(self, order):
    method cancel (line 148) | def cancel(self, order):
    method buy (line 151) | def buy(self, owner, data, size, price=None, plimit=None,
    method sell (line 158) | def sell(self, owner, data, size, price=None, plimit=None,
    method next (line 165) | def next(self):

FILE: backtrader/brokers/bbroker.py
  class BackBroker (line 36) | class BackBroker(bt.BrokerBase):
    method __init__ (line 244) | def __init__(self):
    method init (line 251) | def init(self):
    method get_notification (line 283) | def get_notification(self):
    method set_fundmode (line 291) | def set_fundmode(self, fundmode, fundstartval=None):
    method get_fundmode (line 300) | def get_fundmode(self):
    method set_fundstartval (line 306) | def set_fundstartval(self, fundstartval):
    method set_int2pnl (line 310) | def set_int2pnl(self, int2pnl):
    method set_coc (line 314) | def set_coc(self, coc):
    method set_coo (line 318) | def set_coo(self, coo):
    method set_shortcash (line 322) | def set_shortcash(self, shortcash):
    method set_slippage_perc (line 326) | def set_slippage_perc(self, perc,
    method set_slippage_fixed (line 337) | def set_slippage_fixed(self, fixed,
    method set_filler (line 348) | def set_filler(self, filler):
    method set_checksubmit (line 352) | def set_checksubmit(self, checksubmit):
    method set_eosbar (line 356) | def set_eosbar(self, eosbar):
    method get_cash (line 362) | def get_cash(self):
    method set_cash (line 368) | def set_cash(self, cash):
    method add_cash (line 375) | def add_cash(self, cash):
    method get_fundshares (line 379) | def get_fundshares(self):
    method get_fundvalue (line 385) | def get_fundvalue(self):
    method cancel (line 391) | def cancel(self, order, bracket=False):
    method get_value (line 405) | def get_value(self, datas=None, mkt=False, lever=False):
    method get_value_lever (line 419) | def get_value_lever(self, datas=None, mkt=False):
    method _get_value (line 422) | def _get_value(self, datas=None, lever=False):
    method get_leverage (line 489) | def get_leverage(self):
    method get_orders_open (line 492) | def get_orders_open(self, safe=False):
    method getposition (line 507) | def getposition(self, data):
    method orderstatus (line 512) | def orderstatus(self, order):
    method _take_children (line 520) | def _take_children(self, order):
    method submit (line 532) | def submit(self, order, check=True):
    method transmit (line 547) | def transmit(self, order, check=True):
    method check_submitted (line 558) | def check_submitted(self):
    method submit_accept (line 585) | def submit_accept(self, order):
    method _bracketize (line 592) | def _bracketize(self, order, cancel=False):
    method _ococheck (line 609) | def _ococheck(self, order):
    method _ocoize (line 622) | def _ocoize(self, order, oco):
    method add_order_history (line 632) | def add_order_history(self, orders, notify=True):
    method set_fund_history (line 637) | def set_fund_history(self, fund):
    method buy (line 647) | def buy(self, owner, data,
    method sell (line 667) | def sell(self, owner, data,
    method _execute (line 687) | def _execute(self, order, ago=None, price=None, cash=None, position=None,
    method notify (line 847) | def notify(self, order):
    method _try_exec_historical (line 850) | def _try_exec_historical(self, order):
    method _try_exec_market (line 853) | def _try_exec_market(self, order, popen, phigh, plow):
    method _try_exec_close (line 872) | def _try_exec_close(self, order, pclose):
    method _try_exec_limit (line 898) | def _try_exec_limit(self, order, popen, phigh, plow, plimit):
    method _try_exec_stop (line 921) | def _try_exec_stop(self, order, popen, phigh, plow, pcreated, pclose):
    method _try_exec_stoplimit (line 946) | def _try_exec_stoplimit(self, order,
    method _slip_up (line 994) | def _slip_up(self, pmax, price, doslip=True, lim=False):
    method _slip_down (line 1017) | def _slip_down(self, pmin, price, doslip=True, lim=False):
    method _try_exec (line 1040) | def _try_exec(self, order):
    method _process_fund_history (line 1083) | def _process_fund_history(self):
    method _process_order_history (line 1116) | def _process_order_history(self):
    method next (line 1176) | def next(self):

FILE: backtrader/brokers/ibbroker.py
  class IBOrderState (line 47) | class IBOrderState(object):
    method __init__ (line 53) | def __init__(self, orderstate):
    method __str__ (line 58) | def __str__(self):
  class IBOrder (line 68) | class IBOrder(OrderBase, ib.ext.Order.Order):
    method __str__ (line 93) | def __str__(self):
    method __init__ (line 121) | def __init__(self, action, **kwargs):
  class IBCommInfo (line 208) | class IBCommInfo(CommInfoBase):
    method getvaluesize (line 222) | def getvaluesize(self, size, price):
    method getoperationcost (line 226) | def getoperationcost(self, size, price):
  class MetaIBBroker (line 232) | class MetaIBBroker(BrokerBase.__class__):
    method __init__ (line 233) | def __init__(cls, name, bases, dct):
  class IBBroker (line 240) | class IBBroker(with_metaclass(MetaIBBroker, BrokerBase)):
    method __init__ (line 265) | def __init__(self, **kwargs):
    method start (line 280) | def start(self):
    method stop (line 292) | def stop(self):
    method getcash (line 296) | def getcash(self):
    method getvalue (line 301) | def getvalue(self, datas=None):
    method getposition (line 305) | def getposition(self, data, clone=True):
    method cancel (line 308) | def cancel(self, order):
    method orderstatus (line 319) | def orderstatus(self, order):
    method submit (line 327) | def submit(self, order):
    method getcommissioninfo (line 342) | def getcommissioninfo(self, data):
    method _makeorder (line 353) | def _makeorder(self, action, owner, data,
    method buy (line 369) | def buy(self, owner, data,
    method sell (line 381) | def sell(self, owner, data,
    method notify (line 393) | def notify(self, order):
    method get_notification (line 396) | def get_notification(self):
    method next (line 404) | def next(self):
    method push_orderstatus (line 413) | def push_orderstatus(self, msg):
    method push_execution (line 477) | def push_execution(self, ex):
    method push_commissionreport (line 480) | def push_commissionreport(self, cr):
    method push_portupdate (line 532) | def push_portupdate(self):
    method push_ordererror (line 543) | def push_ordererror(self, msg):
    method push_orderstate (line 565) | def push_orderstate(self, msg):

FILE: backtrader/brokers/oandabroker.py
  class OandaCommInfo (line 41) | class OandaCommInfo(CommInfoBase):
    method getvaluesize (line 42) | def getvaluesize(self, size, price):
    method getoperationcost (line 46) | def getoperationcost(self, size, price):
  class MetaOandaBroker (line 52) | class MetaOandaBroker(BrokerBase.__class__):
    method __init__ (line 53) | def __init__(cls, name, bases, dct):
  class OandaBroker (line 60) | class OandaBroker(with_metaclass(MetaOandaBroker, BrokerBase)):
    method __init__ (line 79) | def __init__(self, **kwargs):
    method start (line 94) | def start(self):
    method data_started (line 110) | def data_started(self, data):
    method stop (line 145) | def stop(self):
    method getcash (line 149) | def getcash(self):
    method getvalue (line 154) | def getvalue(self, datas=None):
    method getposition (line 158) | def getposition(self, data, clone=True):
    method orderstatus (line 166) | def orderstatus(self, order):
    method _submit (line 170) | def _submit(self, oref):
    method _reject (line 178) | def _reject(self, oref):
    method _accept (line 184) | def _accept(self, oref):
    method _cancel (line 192) | def _cancel(self, oref):
    method _expire (line 198) | def _expire(self, oref):
    method _bracketnotif (line 204) | def _bracketnotif(self, order):
    method _bracketize (line 209) | def _bracketize(self, order, cancel=False):
    method _fill (line 231) | def _fill(self, oref, size, price, ttype, **kwargs):
    method _transmit (line 281) | def _transmit(self, order):
    method buy (line 306) | def buy(self, owner, data,
    method sell (line 323) | def sell(self, owner, data,
    method cancel (line 340) | def cancel(self, order):
    method notify (line 347) | def notify(self, order):
    method get_notification (line 350) | def get_notification(self):
    method next (line 356) | def next(self):

FILE: backtrader/brokers/vcbroker.py
  class VCCommInfo (line 38) | class VCCommInfo(CommInfoBase):
    method getvaluesize (line 52) | def getvaluesize(self, size, price):
    method getoperationcost (line 56) | def getoperationcost(self, size, price):
  class MetaVCBroker (line 62) | class MetaVCBroker(BrokerBase.__class__):
    method __init__ (line 63) | def __init__(cls, name, bases, dct):
  class VCBroker (line 70) | class VCBroker(with_metaclass(MetaVCBroker, BrokerBase)):
    method __init__ (line 131) | def __init__(self, **kwargs):
    method start (line 182) | def start(self):
    method stop (line 186) | def stop(self):
    method getcash (line 190) | def getcash(self):
    method getvalue (line 194) | def getvalue(self, datas=None):
    method get_notification (line 197) | def get_notification(self):
    method notify (line 200) | def notify(self, order):
    method next (line 203) | def next(self):
    method getposition (line 206) | def getposition(self, data, clone=True):
    method getcommissioninfo (line 214) | def getcommissioninfo(self, data):
    method _makeorder (line 226) | def _makeorder(self, ordtype, owner, data,
    method submit (line 291) | def submit(self, order, vcorder):
    method buy (line 310) | def buy(self, owner, data,
    method sell (line 327) | def sell(self, owner, data,
    method __call__ (line 347) | def __call__(self, trader):
    method OnChangedBalance (line 361) | def OnChangedBalance(self, Account):
    method OnModifiedOrder (line 372) | def OnModifiedOrder(self, Order):
    method OnCancelledOrder (line 377) | def OnCancelledOrder(self, Order):
    method OnTotalExecutedOrder (line 387) | def OnTotalExecutedOrder(self, Order):
    method OnPartialExecutedOrder (line 390) | def OnPartialExecutedOrder(self, Order):
    method OnExecutedOrder (line 393) | def OnExecutedOrder(self, Order, partial):
    method OnOrderInMarket (line 436) | def OnOrderInMarket(self, Order):
    method OnNewOrderLocation (line 447) | def OnNewOrderLocation(self, Order):
    method OnChangedOpenPositions (line 451) | def OnChangedOpenPositions(self, Account):
    method OnNewClosedOperations (line 458) | def OnNewClosedOperations(self, Account):
    method OnServerShutDown (line 462) | def OnServerShutDown(self):
    method OnInternalEvent (line 465) | def OnInternalEvent(self, p1, p2, p3):

FILE: backtrader/btrun/btrun.py
  function btrun (line 73) | def btrun(pargs=''):
  function setbroker (line 171) | def setbroker(args, cerebro):
  function getdatas (line 204) | def getdatas(args):
  function getmodclasses (line 245) | def getmodclasses(mod, clstype, clsname=None):
  function getmodfunctions (line 263) | def getmodfunctions(mod, funcname=None):
  function loadmodule (line 279) | def loadmodule(modpath, modname=''):
  function loadmodule2 (line 299) | def loadmodule2(modpath, modname):
  function loadmodule3 (line 310) | def loadmodule3(modpath, modname):
  function getobjects (line 322) | def getobjects(iterable, clsbase, modbase, issignal=False):
  function getfunctions (line 373) | def getfunctions(iterable, modbase):
  function parse_args (line 415) | def parse_args(pargs=''):

FILE: backtrader/cerebro.py
  class OptReturn (line 53) | class OptReturn(object):
    method __init__ (line 54) | def __init__(self, params, **kwargs):
  class Cerebro (line 60) | class Cerebro(with_metaclass(MetaParams, object)):
    method __init__ (line 296) | def __init__(self):
    method iterize (line 330) | def iterize(iterable):
    method set_fund_history (line 345) | def set_fund_history(self, fund):
    method add_order_history (line 369) | def add_order_history(self, orders, notify=True):
    method notify_timer (line 410) | def notify_timer(self, timer, when, *args, **kwargs):
    method _add_timer (line 421) | def _add_timer(self, owner, when,
    method add_timer (line 446) | def add_timer(self, when,
    method addtz (line 545) | def addtz(self, tz):
    method addcalendar (line 566) | def addcalendar(self, cal):
    method add_signal (line 592) | def add_signal(self, sigtype, sigcls, *sigargs, **sigkwargs):
    method signal_strategy (line 597) | def signal_strategy(self, stratcls, *args, **kwargs):
    method signal_concurrent (line 601) | def signal_concurrent(self, onoff):
    method signal_accumulate (line 606) | def signal_accumulate(self, onoff):
    method addstore (line 612) | def addstore(self, store):
    method addwriter (line 617) | def addwriter(self, wrtcls, *args, **kwargs):
    method addsizer (line 623) | def addsizer(self, sizercls, *args, **kwargs):
    method addsizer_byidx (line 629) | def addsizer_byidx(self, idx, sizercls, *args, **kwargs):
    method addindicator (line 636) | def addindicator(self, indcls, *args, **kwargs):
    method addanalyzer (line 643) | def addanalyzer(self, ancls, *args, **kwargs):
    method addobserver (line 650) | def addobserver(self, obscls, *args, **kwargs):
    method addobservermulti (line 657) | def addobservermulti(self, obscls, *args, **kwargs):
    method addstorecb (line 669) | def addstorecb(self, callback):
    method _notify_store (line 684) | def _notify_store(self, msg, *args, **kwargs):
    method notify_store (line 690) | def notify_store(self, msg, *args, **kwargs):
    method _storenotify (line 702) | def _storenotify(self):
    method adddatacb (line 711) | def adddatacb(self, callback):
    method _datanotify (line 726) | def _datanotify(self):
    method _notify_data (line 734) | def _notify_data(self, data, status, *args, **kwargs):
    method notify_data (line 740) | def notify_data(self, data, status, *args, **kwargs):
    method adddata (line 752) | def adddata(self, data, name=None):
    method chaindata (line 776) | def chaindata(self, *args, **kwargs):
    method rolloverdata (line 793) | def rolloverdata(self, *args, **kwargs):
    method replaydata (line 812) | def replaydata(self, dataname, name=None, **kwargs):
    method resampledata (line 831) | def resampledata(self, dataname, name=None, **kwargs):
    method optcallback (line 850) | def optcallback(self, cb):
    method optstrategy (line 859) | def optstrategy(self, strategy, *args, **kwargs):
    method addstrategy (line 908) | def addstrategy(self, strategy, *args, **kwargs):
    method setbroker (line 922) | def setbroker(self, broker):
    method getbroker (line 931) | def getbroker(self):
    method plot (line 941) | def plot(self, plotter=None, numfigs=1, iplot=True, start=None, end=None,
    method __call__ (line 1005) | def __call__(self, iterstrat):
    method __getstate__ (line 1014) | def __getstate__(self):
    method runstop (line 1025) | def runstop(self):
    method run (line 1030) | def run(self, **kwargs):
    method _init_stcount (line 1165) | def _init_stcount(self):
    method _next_stid (line 1168) | def _next_stid(self):
    method runstrategies (line 1171) | def runstrategies(self, iterstrat, predata=False):
    method stop_writers (line 1340) | def stop_writers(self, runstrats):
    method _brokernotify (line 1360) | def _brokernotify(self):
    method _runnext_old (line 1377) | def _runnext_old(self, runstrats):
    method _runonce_old (line 1443) | def _runonce_old(self, runstrats):
    method _next_writers (line 1475) | def _next_writers(self, runstrats):
    method _disable_runonce (line 1494) | def _disable_runonce(self):
    method _runnext (line 1498) | def _runnext(self, runstrats):
    method _runonce (line 1649) | def _runonce(self, runstrats):
    method _check_timers (line 1706) | def _check_timers(self, runstrats, dt0, cheat=False):

FILE: backtrader/comminfo.py
  class CommInfoBase (line 30) | class CommInfoBase(with_metaclass(MetaParams)):
    method __init__ (line 133) | def __init__(self):
    method margin (line 162) | def margin(self):
    method stocklike (line 166) | def stocklike(self):
    method get_margin (line 169) | def get_margin(self, price):
    method get_leverage (line 187) | def get_leverage(self):
    method getsize (line 192) | def getsize(self, price, cash):
    method getoperationcost (line 199) | def getoperationcost(self, size, price):
    method getvaluesize (line 206) | def getvaluesize(self, size, price):
    method getvalue (line 214) | def getvalue(self, position, price):
    method _getcommission (line 229) | def _getcommission(self, size, price, pseudoexec):
    method getcommission (line 239) | def getcommission(self, size, price):
    method confirmexec (line 244) | def confirmexec(self, size, price):
    method profitandloss (line 247) | def profitandloss(self, size, price, newprice):
    method cashadjust (line 251) | def cashadjust(self, size, price, newprice):
    method get_credit_interest (line 258) | def get_credit_interest(self, data, pos, dt):
    method _get_credit_interest (line 274) | def _get_credit_interest(self, data, size, price, days, dt0, dt1):
  class CommissionInfo (line 308) | class CommissionInfo(CommInfoBase):

FILE: backtrader/commissions/__init__.py
  class CommInfo (line 27) | class CommInfo(CommInfoBase):
  class CommInfo_Futures (line 31) | class CommInfo_Futures(CommInfoBase):
  class CommInfo_Futures_Perc (line 37) | class CommInfo_Futures_Perc(CommInfo_Futures):
  class CommInfo_Futures_Fixed (line 43) | class CommInfo_Futures_Fixed(CommInfo_Futures):
  class CommInfo_Stocks (line 49) | class CommInfo_Stocks(CommInfoBase):
  class CommInfo_Stocks_Perc (line 55) | class CommInfo_Stocks_Perc(CommInfo_Stocks):
  class CommInfo_Stocks_Fixed (line 61) | class CommInfo_Stocks_Fixed(CommInfo_Stocks):

FILE: backtrader/dataseries.py
  class TimeFrame (line 33) | class TimeFrame(object):
    method getname (line 43) | def getname(cls, tframe, compression=None):
    method TFrame (line 52) | def TFrame(cls, name):
    method TName (line 56) | def TName(cls, tframe):
  class DataSeries (line 60) | class DataSeries(LineSeries):
    method getwriterheaders (line 71) | def getwriterheaders(self):
    method getwritervalues (line 82) | def getwritervalues(self):
    method getwriterinfo (line 97) | def getwriterinfo(self):
  class OHLC (line 107) | class OHLC(DataSeries):
  class OHLCDateTime (line 111) | class OHLCDateTime(OHLC):
  class SimpleFilterWrapper (line 115) | class SimpleFilterWrapper(object):
    method __init__ (line 128) | def __init__(self, data, ffilter, *args, **kwargs):
    method __call__ (line 138) | def __call__(self, data):
  class _Bar (line 146) | class _Bar(AutoOrderedDict):
    method __init__ (line 163) | def __init__(self, maxdate=False):
    method bstart (line 167) | def bstart(self, maxdate=False):
    method isopen (line 178) | def isopen(self):
    method bupdate (line 187) | def bupdate(self, data, reopen=False):

FILE: backtrader/errors.py
  class BacktraderError (line 28) | class BacktraderError(Exception):
  class StrategySkipError (line 33) | class StrategySkipError(BacktraderError):
  class ModuleImportError (line 39) | class ModuleImportError(BacktraderError):
    method __init__ (line 42) | def __init__(self, message, *args):
  class FromModuleImportError (line 47) | class FromModuleImportError(ModuleImportError):
    method __init__ (line 50) | def __init__(self, message, *args):

FILE: backtrader/feed.py
  class MetaAbstractDataBase (line 41) | class MetaAbstractDataBase(dataseries.OHLCDateTime.__class__):
    method __init__ (line 44) | def __init__(cls, name, bases, dct):
    method dopreinit (line 55) | def dopreinit(cls, _obj, *args, **kwargs):
    method dopostinit (line 68) | def dopostinit(cls, _obj, *args, **kwargs):
  class AbstractDataBase (line 122) | class AbstractDataBase(with_metaclass(MetaAbstractDataBase,
    method _getstatusname (line 149) | def _getstatusname(cls, status):
    method _start_finish (line 167) | def _start_finish(self):
    method _start (line 202) | def _start(self):
    method _timeoffset (line 208) | def _timeoffset(self):
    method _getnexteos (line 211) | def _getnexteos(self):
    method _gettzinput (line 237) | def _gettzinput(self):
    method _gettz (line 241) | def _gettz(self):
    method date2num (line 246) | def date2num(self, dt):
    method num2date (line 252) | def num2date(self, dt=None, tz=None, naive=True):
    method haslivedata (line 258) | def haslivedata(self):
    method do_qcheck (line 261) | def do_qcheck(self, onoff, qlapse):
    method islive (line 268) | def islive(self):
    method put_notification (line 274) | def put_notification(self, status, *args, **kwargs):
    method get_notifications (line 280) | def get_notifications(self):
    method getfeed (line 294) | def getfeed(self):
    method qbuffer (line 297) | def qbuffer(self, savemem=0, replaying=False):
    method start (line 302) | def start(self):
    method stop (line 307) | def stop(self):
    method clone (line 310) | def clone(self, **kwargs):
    method copyas (line 313) | def copyas(self, _dataname, **kwargs):
    method setenvironment (line 319) | def setenvironment(self, env):
    method getenvironment (line 323) | def getenvironment(self):
    method addfilter_simple (line 326) | def addfilter_simple(self, f, *args, **kwargs):
    method addfilter (line 330) | def addfilter(self, p, *args, **kwargs):
    method compensate (line 341) | def compensate(self, other):
    method _tick_nullify (line 347) | def _tick_nullify(self):
    method _tick_fill (line 358) | def _tick_fill(self, force=False):
    method advance_peek (line 369) | def advance_peek(self):
    method advance (line 375) | def advance(self, size=1, datamaster=None, ticks=True):
    method next (line 400) | def next(self, datamaster=None, ticks=True):
    method preload (line 438) | def preload(self):
    method _last (line 445) | def _last(self, datamaster=None):
    method _check (line 464) | def _check(self, forcedata=None):
    method load (line 471) | def load(self):
    method _load (line 538) | def _load(self):
    method _add2stack (line 541) | def _add2stack(self, bar, stash=False):
    method _save2stack (line 548) | def _save2stack(self, erase=False, force=False, stash=False):
    method _updatebar (line 562) | def _updatebar(self, bar, forward=False, ago=0):
    method _fromstack (line 573) | def _fromstack(self, forward=False, stash=False):
    method resample (line 592) | def resample(self, **kwargs):
    method replay (line 595) | def replay(self, **kwargs):
  class DataBase (line 599) | class DataBase(AbstractDataBase):
  class FeedBase (line 603) | class FeedBase(with_metaclass(metabase.MetaParams, object)):
    method __init__ (line 606) | def __init__(self):
    method start (line 609) | def start(self):
    method stop (line 613) | def stop(self):
    method getdata (line 617) | def getdata(self, dataname, name=None, **kwargs):
    method _getdata (line 629) | def _getdata(self, dataname, **kwargs):
  class MetaCSVDataBase (line 637) | class MetaCSVDataBase(DataBase.__class__):
    method dopostinit (line 638) | def dopostinit(cls, _obj, *args, **kwargs):
  class CSVDataBase (line 649) | class CSVDataBase(with_metaclass(MetaCSVDataBase, DataBase)):
    method start (line 667) | def start(self):
    method stop (line 682) | def stop(self):
    method preload (line 688) | def preload(self):
    method _load (line 699) | def _load(self):
    method _getnextline (line 713) | def _getnextline(self):
  class CSVFeedBase (line 728) | class CSVFeedBase(FeedBase):
    method _getdata (line 731) | def _getdata(self, dataname, **kwargs):
  class DataClone (line 736) | class DataClone(AbstractDataBase):
    method __init__ (line 739) | def __init__(self):
    method _start (line 752) | def _start(self):
    method start (line 773) | def start(self):
    method preload (line 778) | def preload(self):
    method _load (line 784) | def _load(self):
    method advance (line 811) | def advance(self, size=1, datamaster=None, ticks=True):

FILE: backtrader/feeds/blaze.py
  class BlazeData (line 28) | class BlazeData(feed.DataBase):
    method start (line 59) | def start(self):
    method _load (line 65) | def _load(self):

FILE: backtrader/feeds/btcsv.py
  class BacktraderCSVData (line 30) | class BacktraderCSVData(feed.CSVDataBase):
    method _loadline (line 39) | def _loadline(self, linetokens):
  class BacktraderCSV (line 62) | class BacktraderCSV(feed.CSVFeedBase):

FILE: backtrader/feeds/chainer.py
  class MetaChainer (line 31) | class MetaChainer(bt.DataBase.__class__):
    method __init__ (line 32) | def __init__(cls, name, bases, dct):
    method donew (line 37) | def donew(cls, *args, **kwargs):
  class Chainer (line 49) | class Chainer(bt.with_metaclass(MetaChainer, bt.DataBase)):
    method islive (line 52) | def islive(self):
    method __init__ (line 57) | def __init__(self, *args):
    method start (line 60) | def start(self):
    method stop (line 71) | def stop(self):
    method get_notifications (line 76) | def get_notifications(self):
    method _gettz (line 79) | def _gettz(self):
    method _load (line 86) | def _load(self):

FILE: backtrader/feeds/csvgeneric.py
  class GenericCSVData (line 32) | class GenericCSVData(feed.CSVDataBase):
    method start (line 87) | def start(self):
    method _loadline (line 103) | def _loadline(self, linetokens):
  class GenericCSV (line 161) | class GenericCSV(feed.CSVFeedBase):

FILE: backtrader/feeds/ibdata.py
  class MetaIBData (line 35) | class MetaIBData(DataBase.__class__):
    method __init__ (line 36) | def __init__(cls, name, bases, dct):
  class IBData (line 45) | class IBData(with_metaclass(MetaIBData, DataBase)):
    method _timeoffset (line 219) | def _timeoffset(self):
    method _gettz (line 222) | def _gettz(self):
    method islive (line 255) | def islive(self):
    method __init__ (line 260) | def __init__(self, **kwargs):
    method setenvironment (line 265) | def setenvironment(self, env):
    method parsecontract (line 271) | def parsecontract(self, dataname):
    method start (line 342) | def start(self):
    method stop (line 407) | def stop(self):
    method reqdata (line 412) | def reqdata(self):
    method canceldata (line 425) | def canceldata(self):
    method haslivedata (line 435) | def haslivedata(self):
    method _load (line 438) | def _load(self):
    method _st_start (line 631) | def _st_start(self):
    method _load_rtbar (line 664) | def _load_rtbar(self, rtbar, hist=False):
    method _load_rtvolume (line 684) | def _load_rtvolume(self, rtvol):

FILE: backtrader/feeds/influxfeed.py
  class InfluxDB (line 41) | class InfluxDB(feed.DataBase):
    method start (line 63) | def start(self):
    method _load (line 100) | def _load(self):

FILE: backtrader/feeds/mt4csv.py
  class MT4CSVData (line 29) | class MT4CSVData(GenericCSVData):

FILE: backtrader/feeds/oanda.py
  class MetaOandaData (line 34) | class MetaOandaData(DataBase.__class__):
    method __init__ (line 35) | def __init__(cls, name, bases, dct):
  class OandaData (line 44) | class OandaData(with_metaclass(MetaOandaData, DataBase)):
    method _timeoffset (line 161) | def _timeoffset(self):
    method islive (line 165) | def islive(self):
    method __init__ (line 170) | def __init__(self, **kwargs):
    method setenvironment (line 174) | def setenvironment(self, env):
    method start (line 180) | def start(self):
    method _st_start (line 217) | def _st_start(self, instart=True, tmout=None):
    method stop (line 252) | def stop(self):
    method haslivedata (line 257) | def haslivedata(self):
    method _load (line 260) | def _load(self):
    method _load_tick (line 398) | def _load_tick(self, msg):
    method _load_history (line 420) | def _load_history(self, msg):

FILE: backtrader/feeds/pandafeed.py
  class PandasDirectData (line 30) | class PandasDirectData(feed.DataBase):
    method start (line 61) | def start(self):
    method _load (line 67) | def _load(self):
  class PandasData (line 107) | class PandasData(feed.DataBase):
    method __init__ (line 163) | def __init__(self):
    method start (line 204) | def start(self):
    method _load (line 234) | def _load(self):

FILE: backtrader/feeds/quandl.py
  class QuandlCSV (line 39) | class QuandlCSV(feed.CSVDataBase):
    method start (line 76) | def start(self):
    method _loadline (line 95) | def _loadline(self, linetokens):
  class Quandl (line 131) | class Quandl(QuandlCSV):
    method start (line 189) | def start(self):

FILE: backtrader/feeds/rollover.py
  class MetaRollOver (line 30) | class MetaRollOver(bt.DataBase.__class__):
    method __init__ (line 31) | def __init__(cls, name, bases, dct):
    method donew (line 36) | def donew(cls, *args, **kwargs):
  class RollOver (line 48) | class RollOver(bt.with_metaclass(MetaRollOver, bt.DataBase)):
    method islive (line 109) | def islive(self):
    method __init__ (line 114) | def __init__(self, *args):
    method start (line 117) | def start(self):
    method stop (line 129) | def stop(self):
    method _gettz (line 134) | def _gettz(self):
    method _checkdate (line 141) | def _checkdate(self, dt, d):
    method _checkcondition (line 147) | def _checkcondition(self, d0, d1):
    method _load (line 153) | def _load(self):

FILE: backtrader/feeds/sierrachart.py
  class SierraChartCSVData (line 28) | class SierraChartCSVData(GenericCSVData):

FILE: backtrader/feeds/vcdata.py
  class MetaVCData (line 37) | class MetaVCData(DataBase.__class__):
    method __init__ (line 38) | def __init__(cls, name, bases, dct):
  class VCData (line 47) | class VCData(with_metaclass(MetaVCData, DataBase)):
    method _timeoffset (line 172) | def _timeoffset(self):
    method _gettzinput (line 176) | def _gettzinput(self):
    method _gettz (line 180) | def _gettz(self, tzin=False):
    method islive (line 241) | def islive(self):
    method __init__ (line 246) | def __init__(self, **kwargs):
    method setenvironment (line 264) | def setenvironment(self, env):
    method start (line 270) | def start(self):
    method stop (line 362) | def stop(self):
    method _setserie (line 368) | def _setserie(self, serie):
    method haslivedata (line 372) | def haslivedata(self):
    method _load (line 375) | def _load(self):
    method _getpingtmout (line 437) | def _getpingtmout(self):
    method OnNewDataSerieBar (line 448) | def OnNewDataSerieBar(self, DataSerie, forcepush=False):
    method ping (line 486) | def ping(self):
    method OnInternalEvent (line 517) | def OnInternalEvent(self, p1, p2, p3):
    method OnNewTicks (line 529) | def OnNewTicks(self, ArrayTicks):
    method debug_ticks (line 580) | def debug_ticks(self, ticks):

FILE: backtrader/feeds/vchart.py
  class VChartData (line 33) | class VChartData(feed.DataBase):
    method start (line 49) | def start(self):
    method stop (line 87) | def stop(self):
    method _load (line 92) | def _load(self):
  class VChartFeed (line 128) | class VChartFeed(feed.FeedBase):
    method _getdata (line 133) | def _getdata(self, dataname, **kwargs):

FILE: backtrader/feeds/vchartcsv.py
  class VChartCSVData (line 31) | class VChartCSVData(feed.CSVDataBase):
    method _loadline (line 46) | def _loadline(self, linetokens):
  class VChartCSV (line 85) | class VChartCSV(feed.CSVFeedBase):

FILE: backtrader/feeds/vchartfile.py
  class MetaVChartFile (line 32) | class MetaVChartFile(bt.DataBase.__class__):
    method __init__ (line 33) | def __init__(cls, name, bases, dct):
  class VChartFile (line 42) | class VChartFile(bt.with_metaclass(MetaVChartFile, bt.DataBase)):
    method start (line 53) | def start(self):
    method stop (line 91) | def stop(self):
    method _load (line 96) | def _load(self):

FILE: backtrader/feeds/yahoo.py
  class YahooFinanceCSVData (line 37) | class YahooFinanceCSVData(feed.CSVDataBase):
    method start (line 93) | def start(self):
    method _loadline (line 110) | def _loadline(self, linetokens):
  class YahooLegacyCSV (line 181) | class YahooLegacyCSV(YahooFinanceCSVData):
  class YahooFinanceCSV (line 192) | class YahooFinanceCSV(feed.CSVFeedBase):
  class YahooFinanceData (line 196) | class YahooFinanceData(YahooFinanceCSVData):
    method start_v7 (line 253) | def start_v7(self):
    method start (line 352) | def start(self):
  class YahooFinance (line 359) | class YahooFinance(feed.CSVFeedBase):

FILE: backtrader/fillers.py
  class FixedSize (line 30) | class FixedSize(with_metaclass(MetaParams, object)):
    method __call__ (line 47) | def __call__(self, order, price, ago):
  class FixedBarPerc (line 52) | class FixedBarPerc(with_metaclass(MetaParams, object)):
    method __call__ (line 66) | def __call__(self, order, price, ago):
  class BarPointPerc (line 73) | class BarPointPerc(with_metaclass(MetaParams, object)):
    method __call__ (line 99) | def __call__(self, order, price, ago):

FILE: backtrader/filters/bsplitter.py
  class DaySplitter_Close (line 29) | class DaySplitter_Close(bt.with_metaclass(bt.MetaParams, object)):
    method __init__ (line 64) | def __init__(self, data):
    method __call__ (line 67) | def __call__(self, data):

FILE: backtrader/filters/calendardays.py
  class CalendarDays (line 31) | class CalendarDays(with_metaclass(metabase.MetaParams, object)):
    method __init__ (line 58) | def __init__(self, data):
    method __call__ (line 61) | def __call__(self, data):
    method _fillbars (line 80) | def _fillbars(self, data, dt, lastdt):

FILE: backtrader/filters/datafiller.py
  class DataFiller (line 30) | class DataFiller(AbstractDataBase):
    method start (line 61) | def start(self):
    method preload (line 66) | def preload(self):
    method _copyfromdata (line 79) | def _copyfromdata(self):
    method _frombars (line 88) | def _frombars(self):
    method _load (line 110) | def _load(self):

FILE: backtrader/filters/datafilter.py
  class DataFilter (line 27) | class DataFilter(bt.AbstractDataBase):
    method preload (line 44) | def preload(self):
    method _load (line 57) | def _load(self):

FILE: backtrader/filters/daysteps.py
  class BarReplayer_Open (line 25) | class BarReplayer_Open(object):
    method __init__ (line 39) | def __init__(self, data):
    method __call__ (line 44) | def __call__(self, data):
    method last (line 70) | def last(self, data):

FILE: backtrader/filters/heikinashi.py
  class HeikinAshi (line 28) | class HeikinAshi(object):
    method __init__ (line 38) | def __init__(self, data):
    method __call__ (line 41) | def __call__(self, data):

FILE: backtrader/filters/renko.py
  class Renko (line 31) | class Renko(Filter):
    method nextstart (line 75) | def nextstart(self, data):
    method next (line 85) | def next(self, data):

FILE: backtrader/filters/session.py
  class SessionFiller (line 31) | class SessionFiller(with_metaclass(metabase.MetaParams, object)):
    method __init__ (line 73) | def __init__(self, data):
    method __call__ (line 81) | def __call__(self, data):
    method _fillbars (line 142) | def _fillbars(self, data, time_start, time_end, tostack=True):
    method _fillbar (line 161) | def _fillbar(self, data, dtime):
  class SessionFilterSimple (line 187) | class SessionFilterSimple(with_metaclass(metabase.MetaParams, object)):
    method __init__ (line 201) | def __init__(self, data):
    method __call__ (line 204) | def __call__(self, data):
  class SessionFilter (line 216) | class SessionFilter(with_metaclass(metabase.MetaParams, object)):
    method __init__ (line 227) | def __init__(self, data):
    method __call__ (line 230) | def __call__(self, data):

FILE: backtrader/flt.py
  class MetaFilter (line 32) | class MetaFilter(MetaParams):
  class Filter (line 36) | class Filter(with_metaclass(MetaParams, object)):
    method __init__ (line 40) | def __init__(self, data):
    method __call__ (line 43) | def __call__(self, data):
    method nextstart (line 50) | def nextstart(self, data):
    method next (line 53) | def next(self, data):

FILE: backtrader/functions.py
  class List (line 32) | class List(list):
    method __contains__ (line 33) | def __contains__(self, other):
  class Logic (line 37) | class Logic(LineActions):
    method __init__ (line 38) | def __init__(self, *args):
  class DivByZero (line 43) | class DivByZero(Logic):
    method __init__ (line 54) | def __init__(self, a, b, zero=0.0):
    method next (line 60) | def next(self):
    method once (line 64) | def once(self, start, end):
  class DivZeroByZero (line 76) | class DivZeroByZero(Logic):
    method __init__ (line 88) | def __init__(self, a, b, single=float('inf'), dual=0.0):
    method next (line 95) | def next(self):
    method once (line 103) | def once(self, start, end):
  class Cmp (line 120) | class Cmp(Logic):
    method __init__ (line 121) | def __init__(self, a, b):
    method next (line 126) | def next(self):
    method once (line 129) | def once(self, start, end):
  class CmpEx (line 139) | class CmpEx(Logic):
    method __init__ (line 140) | def __init__(self, a, b, r1, r2, r3):
    method next (line 148) | def next(self):
    method once (line 151) | def once(self, start, end):
  class If (line 172) | class If(Logic):
    method __init__ (line 173) | def __init__(self, cond, a, b):
    method next (line 179) | def next(self):
    method once (line 182) | def once(self, start, end):
  class MultiLogic (line 193) | class MultiLogic(Logic):
    method next (line 194) | def next(self):
    method once (line 197) | def once(self, start, end):
  class MultiLogicReduce (line 207) | class MultiLogicReduce(MultiLogic):
    method __init__ (line 208) | def __init__(self, *args, **kwargs):
  class Reduce (line 217) | class Reduce(MultiLogicReduce):
    method __init__ (line 218) | def __init__(self, flogic, *args, **kwargs):
  function _andlogic (line 225) | def _andlogic(x, y):
  class And (line 229) | class And(MultiLogicReduce):
  function _orlogic (line 233) | def _orlogic(x, y):
  class Or (line 237) | class Or(MultiLogicReduce):
  class Max (line 241) | class Max(MultiLogic):
  class Min (line 245) | class Min(MultiLogic):
  class Sum (line 249) | class Sum(MultiLogic):
  class Any (line 253) | class Any(MultiLogic):
  class All (line 257) | class All(MultiLogic):

FILE: backtrader/indicator.py
  class MetaIndicator (line 32) | class MetaIndicator(IndicatorBase.__class__):
    method cleancache (line 40) | def cleancache(cls):
    method usecache (line 44) | def usecache(cls, onoff):
    method __call__ (line 51) | def __call__(cls, *args, **kwargs):
    method __init__ (line 67) | def __init__(cls, name, bases, dct):
  class Indicator (line 90) | class Indicator(with_metaclass(MetaIndicator, IndicatorBase)):
    method advance (line 95) | def advance(self, size=1):
    method preonce_via_prenext (line 101) | def preonce_via_prenext(self, start, end):
    method oncestart_via_nextstart (line 113) | def oncestart_via_nextstart(self, start, end):
    method once_via_next (line 126) | def once_via_next(self, start, end):
  class MtLinePlotterIndicator (line 139) | class MtLinePlotterIndicator(Indicator.__class__):
    method donew (line 140) | def donew(cls, *args, **kwargs):
  class LinePlotterIndicator (line 163) | class LinePlotterIndicator(with_metaclass(MtLinePlotterIndicator, Indica...

FILE: backtrader/indicators/accdecoscillator.py
  class AccelerationDecelerationOscillator (line 31) | class AccelerationDecelerationOscillator(bt.Indicator):
    method __init__ (line 56) | def __init__(self):

FILE: backtrader/indicators/aroon.py
  class _AroonBase (line 27) | class _AroonBase(Indicator):
    method _plotlabel (line 45) | def _plotlabel(self):
    method _plotinit (line 49) | def _plotinit(self):
    method __init__ (line 52) | def __init__(self):
  class AroonUp (line 69) | class AroonUp(_AroonBase):
    method __init__ (line 93) | def __init__(self):
  class AroonDown (line 99) | class AroonDown(_AroonBase):
    method __init__ (line 123) | def __init__(self):
  class AroonUpDown (line 129) | class AroonUpDown(AroonUp, AroonDown):
  class AroonOscillator (line 155) | class AroonOscillator(_AroonBase):
    method _plotinit (line 175) | def _plotinit(self):
    method __init__ (line 181) | def __init__(self):
  class AroonUpDownOscillator (line 187) | class AroonUpDownOscillator(AroonUpDown, AroonOscillator):

FILE: backtrader/indicators/atr.py
  class TrueHigh (line 27) | class TrueHigh(Indicator):
    method __init__ (line 43) | def __init__(self):
  class TrueLow (line 48) | class TrueLow(Indicator):
    method __init__ (line 64) | def __init__(self):
  class TrueRange (line 69) | class TrueRange(Indicator):
    method __init__ (line 91) | def __init__(self):
  class AverageTrueRange (line 96) | class AverageTrueRange(Indicator):
    method _plotlabel (line 115) | def _plotlabel(self):
    method __init__ (line 120) | def __init__(self):

FILE: backtrader/indicators/awesomeoscillator.py
  class AwesomeOscillator (line 31) | class AwesomeOscillator(bt.Indicator):
    method __init__ (line 58) | def __init__(self):

FILE: backtrader/indicators/basicops.py
  class PeriodN (line 33) | class PeriodN(Indicator):
    method __init__ (line 42) | def __init__(self):
  class OperationN (line 47) | class OperationN(PeriodN):
    method next (line 60) | def next(self):
    method once (line 63) | def once(self, start, end):
  class BaseApplyN (line 73) | class BaseApplyN(OperationN):
    method __init__ (line 88) | def __init__(self):
  class ApplyN (line 93) | class ApplyN(BaseApplyN):
  class Highest (line 103) | class Highest(OperationN):
  class Lowest (line 117) | class Lowest(OperationN):
  class ReduceN (line 131) | class ReduceN(OperationN):
    method __init__ (line 151) | def __init__(self, function, **kwargs):
  class SumN (line 161) | class SumN(OperationN):
  class AnyN (line 175) | class AnyN(OperationN):
  class AllN (line 189) | class AllN(OperationN):
  class FindFirstIndex (line 203) | class FindFirstIndex(OperationN):
    method func (line 218) | def func(self, iterable):
  class FindFirstIndexHighest (line 223) | class FindFirstIndexHighest(FindFirstIndex):
  class FindFirstIndexLowest (line 237) | class FindFirstIndexLowest(FindFirstIndex):
  class FindLastIndex (line 251) | class FindLastIndex(OperationN):
    method func (line 266) | def func(self, iterable):
  class FindLastIndexHighest (line 275) | class FindLastIndexHighest(FindLastIndex):
  class FindLastIndexLowest (line 289) | class FindLastIndexLowest(FindLastIndex):
  class Accum (line 303) | class Accum(Indicator):
    method nextstart (line 318) | def nextstart(self):
    method next (line 321) | def next(self):
    method oncestart (line 324) | def oncestart(self, start, end):
    method once (line 332) | def once(self, start, end):
  class Average (line 341) | class Average(PeriodN):
    method next (line 354) | def next(self):
    method once (line 358) | def once(self, start, end):
  class ExponentialSmoothing (line 367) | class ExponentialSmoothing(Average):
    method __init__ (line 383) | def __init__(self):
    method nextstart (line 392) | def nextstart(self):
    method next (line 396) | def next(self):
    method oncestart (line 399) | def oncestart(self, start, end):
    method once (line 403) | def once(self, start, end):
  class ExponentialSmoothingDynamic (line 415) | class ExponentialSmoothingDynamic(ExponentialSmoothing):
    method __init__ (line 433) | def __init__(self):
    method next (line 442) | def next(self):
    method once (line 446) | def once(self, start, end):
  class WeightedAverage (line 458) | class WeightedAverage(PeriodN):
    method __init__ (line 477) | def __init__(self):
    method next (line 480) | def next(self):
    method once (line 485) | def once(self, start, end):

FILE: backtrader/indicators/bollinger.py
  class BollingerBands (line 27) | class BollingerBands(Indicator):
    method _plotlabel (line 52) | def _plotlabel(self):
    method __init__ (line 57) | def __init__(self):
  class BollingerBandsPct (line 67) | class BollingerBandsPct(BollingerBands):
    method __init__ (line 74) | def __init__(self):

FILE: backtrader/indicators/cci.py
  class CommodityChannelIndex (line 27) | class CommodityChannelIndex(Indicator):
    method _plotlabel (line 53) | def _plotlabel(self):
    method _plotinit (line 58) | def _plotinit(self):
    method __init__ (line 61) | def __init__(self):

FILE: backtrader/indicators/contrib/vortex.py
  class Vortex (line 30) | class Vortex(bt.Indicator):
    method __init__ (line 42) | def __init__(self):

FILE: backtrader/indicators/crossover.py
  class NonZeroDifference (line 27) | class NonZeroDifference(Indicator):
    method nextstart (line 40) | def nextstart(self):
    method next (line 43) | def next(self):
    method oncestart (line 47) | def oncestart(self, start, end):
    method once (line 51) | def once(self, start, end):
  class _CrossBase (line 62) | class _CrossBase(Indicator):
    method __init__ (line 69) | def __init__(self):
  class CrossUp (line 82) | class CrossUp(_CrossBase):
  class CrossDown (line 97) | class CrossDown(_CrossBase):
  class CrossOver (line 112) | class CrossOver(Indicator):
    method __init__ (line 134) | def __init__(self):

FILE: backtrader/indicators/dema.py
  class DoubleExponentialMovingAverage (line 28) | class DoubleExponentialMovingAverage(MovingAverageBase):
    method __init__ (line 47) | def __init__(self):
  class TripleExponentialMovingAverage (line 55) | class TripleExponentialMovingAverage(MovingAverageBase):
    method __init__ (line 77) | def __init__(self):

FILE: backtrader/indicators/deviation.py
  class StandardDeviation (line 27) | class StandardDeviation(Indicator):
    method _plotlabel (line 53) | def _plotlabel(self):
    method __init__ (line 58) | def __init__(self):
  class MeanDeviation (line 73) | class MeanDeviation(Indicator):
    method _plotlabel (line 95) | def _plotlabel(self):
    method __init__ (line 100) | def __init__(self):

FILE: backtrader/indicators/directionalmove.py
  class UpMove (line 27) | class UpMove(Indicator):
    method __init__ (line 43) | def __init__(self):
  class DownMove (line 48) | class DownMove(Indicator):
    method __init__ (line 64) | def __init__(self):
  class _DirectionalIndicator (line 69) | class _DirectionalIndicator(Indicator):
    method _plotlabel (line 83) | def _plotlabel(self):
    method __init__ (line 88) | def __init__(self, _plus=True, _minus=True):
  class DirectionalIndicator (line 111) | class DirectionalIndicator(_DirectionalIndicator):
    method __init__ (line 143) | def __init__(self):
  class PlusDirectionalIndicator (line 150) | class PlusDirectionalIndicator(_DirectionalIndicator):
    method __init__ (line 182) | def __init__(self):
  class MinusDirectionalIndicator (line 188) | class MinusDirectionalIndicator(_DirectionalIndicator):
    method __init__ (line 220) | def __init__(self):
  class AverageDirectionalMovementIndex (line 226) | class AverageDirectionalMovementIndex(_DirectionalIndicator):
    method __init__ (line 263) | def __init__(self):
  class AverageDirectionalMovementIndexRating (line 270) | class AverageDirectionalMovementIndexRating(AverageDirectionalMovementIn...
    method __init__ (line 309) | def __init__(self):
  class DirectionalMovementIndex (line 315) | class DirectionalMovementIndex(AverageDirectionalMovementIndex,
  class DirectionalMovement (line 350) | class DirectionalMovement(AverageDirectionalMovementIndexRating,

FILE: backtrader/indicators/dma.py
  class DicksonMovingAverage (line 28) | class DicksonMovingAverage(MovingAverageBase):
    method _plotlabel (line 63) | def _plotlabel(self):
    method __init__ (line 69) | def __init__(self):

FILE: backtrader/indicators/dpo.py
  class DetrendedPriceOscillator (line 28) | class DetrendedPriceOscillator(Indicator):
    method _plotlabel (line 56) | def _plotlabel(self):
    method __init__ (line 61) | def __init__(self):

FILE: backtrader/indicators/dv2.py
  class DV2 (line 31) | class DV2(Indicator):
    method __init__ (line 50) | def __init__(self):

FILE: backtrader/indicators/ema.py
  class ExponentialMovingAverage (line 27) | class ExponentialMovingAverage(MovingAverageBase):
    method __init__ (line 45) | def __init__(self):

FILE: backtrader/indicators/envelope.py
  class EnvelopeMixIn (line 29) | class EnvelopeMixIn(object):
    method __init__ (line 51) | def __init__(self):
  class _EnvelopeBase (line 62) | class _EnvelopeBase(Indicator):
    method __init__ (line 71) | def __init__(self):
  class Envelope (line 76) | class Envelope(_EnvelopeBase, EnvelopeMixIn):

FILE: backtrader/indicators/hadelta.py
  class haDelta (line 32) | class haDelta(bt.Indicator):
    method __init__ (line 66) | def __init__(self):

FILE: backtrader/indicators/heikinashi.py
  class HeikinAshi (line 32) | class HeikinAshi(bt.Indicator):
    method __init__ (line 59) | def __init__(self):
    method prenext (line 72) | def prenext(self):

FILE: backtrader/indicators/hma.py
  class HullMovingAverage (line 29) | class HullMovingAverage(MovingAverageBase):
    method __init__ (line 58) | def __init__(self):

FILE: backtrader/indicators/hurst.py
  class HurstExponent (line 30) | class HurstExponent(PeriodN):
    method _plotlabel (line 71) | def _plotlabel(self):
    method __init__ (line 77) | def __init__(self):
    method next (line 85) | def next(self):

FILE: backtrader/indicators/ichimoku.py
  class Ichimoku (line 28) | class Ichimoku(bt.Indicator):
    method __init__ (line 67) | def __init__(self):

FILE: backtrader/indicators/kama.py
  class AdaptiveMovingAverage (line 27) | class AdaptiveMovingAverage(MovingAverageBase):
    method __init__ (line 64) | def __init__(self):

FILE: backtrader/indicators/kst.py
  class KnowSureThing (line 28) | class KnowSureThing(bt.Indicator):
    method __init__ (line 68) | def __init__(self):

FILE: backtrader/indicators/lrsi.py
  class LaguerreRSI (line 30) | class LaguerreRSI(PeriodN):
    method next (line 56) | def next(self):
  class LaguerreFilter (line 88) | class LaguerreFilter(PeriodN):
    method next (line 103) | def next(self):

FILE: backtrader/indicators/mabase.py
  class MovingAverage (line 29) | class MovingAverage(object):
    method register (line 52) | def register(cls, regcls):
  class MovAv (line 71) | class MovAv(MovingAverage):
  class MetaMovAvBase (line 75) | class MetaMovAvBase(Indicator.__class__):
    method __new__ (line 79) | def __new__(meta, name, bases, dct):
  class MovingAverageBase (line 89) | class MovingAverageBase(with_metaclass(MetaMovAvBase, Indicator)):

FILE: backtrader/indicators/macd.py
  class MACD (line 27) | class MACD(Indicator):
    method _plotlabel (line 51) | def _plotlabel(self):
    method __init__ (line 57) | def __init__(self):
  class MACDHisto (line 66) | class MACDHisto(MACD):
    method __init__ (line 82) | def __init__(self):

FILE: backtrader/indicators/momentum.py
  class Momentum (line 27) | class Momentum(Indicator):
    method __init__ (line 43) | def __init__(self):
  class MomentumOscillator (line 48) | class MomentumOscillator(Indicator):
    method _plotlabel (line 67) | def _plotlabel(self):
    method _plotinit (line 71) | def _plotinit(self):
    method __init__ (line 74) | def __init__(self):
  class RateOfChange (line 79) | class RateOfChange(Indicator):
    method __init__ (line 97) | def __init__(self):
  class RateOfChange100 (line 103) | class RateOfChange100(Indicator):
    method __init__ (line 124) | def __init__(self):

FILE: backtrader/indicators/ols.py
  class OLS_Slope_InterceptN (line 32) | class OLS_Slope_InterceptN(PeriodN):
    method next (line 50) | def next(self):
  class OLS_TransformationN (line 60) | class OLS_TransformationN(PeriodN):
    method __init__ (line 70) | def __init__(self):
  class OLS_BetaN (line 81) | class OLS_BetaN(PeriodN):
    method next (line 96) | def next(self):
  class CointN (line 102) | class CointN(PeriodN):
    method next (line 124) | def next(self):

FILE: backtrader/indicators/oscillator.py
  class OscillatorMixIn (line 30) | class OscillatorMixIn(Indicator):
    method _plotinit (line 46) | def _plotinit(self):
    method __init__ (line 53) | def __init__(self):
  class Oscillator (line 58) | class Oscillator(Indicator):
    method _plotinit (line 83) | def _plotinit(self):
    method __init__ (line 90) | def __init__(self):

FILE: backtrader/indicators/percentchange.py
  class PercentChange (line 30) | class PercentChange(Indicator):
    method __init__ (line 44) | def __init__(self):

FILE: backtrader/indicators/percentrank.py
  class PercentRank (line 32) | class PercentRank(BaseApplyN):

FILE: backtrader/indicators/pivotpoint.py
  class PivotPoint (line 27) | class PivotPoint(Indicator):
    method _plotinit (line 74) | def _plotinit(self):
    method __init__ (line 80) | def __init__(self):
  class FibonacciPivotPoint (line 106) | class FibonacciPivotPoint(Indicator):
    method _plotinit (line 158) | def _plotinit(self):
    method __init__ (line 164) | def __init__(self):
  class DemarkPivotPoint (line 192) | class DemarkPivotPoint(Indicator):
    method _plotinit (line 245) | def _plotinit(self):
    method __init__ (line 251) | def __init__(self):

FILE: backtrader/indicators/prettygoodoscillator.py
  class PrettyGoodOscillator (line 28) | class PrettyGoodOscillator(Indicator):
    method __init__ (line 55) | def __init__(self):

FILE: backtrader/indicators/priceoscillator.py
  class _PriceOscBase (line 27) | class _PriceOscBase(Indicator):
    method __init__ (line 33) | def __init__(self):
  class PriceOscillator (line 41) | class PriceOscillator(_PriceOscBase):
  class PercentagePriceOscillator (line 56) | class PercentagePriceOscillator(_PriceOscBase):
    method __init__ (line 81) | def __init__(self):
  class PercentagePriceOscillatorShort (line 91) | class PercentagePriceOscillatorShort(PercentagePriceOscillator):

FILE: backtrader/indicators/psar.py
  class _SarStatus (line 30) | class _SarStatus(object):
    method __str__ (line 36) | def __str__(self):
  class ParabolicSAR (line 45) | class ParabolicSAR(PeriodN):
    method prenext (line 75) | def prenext(self):
    method nextstart (line 87) | def nextstart(self):
    method next (line 119) | def next(self):

FILE: backtrader/indicators/rmi.py
  class RelativeMomentumIndex (line 27) | class RelativeMomentumIndex(RSI):
    method _plotlabel (line 58) | def _plotlabel(self):

FILE: backtrader/indicators/rsi.py
  class UpDay (line 28) | class UpDay(Indicator):
    method __init__ (line 45) | def __init__(self):
  class DownDay (line 50) | class DownDay(Indicator):
    method __init__ (line 67) | def __init__(self):
  class UpDayBool (line 72) | class UpDayBool(Indicator):
    method __init__ (line 92) | def __init__(self):
  class DownDayBool (line 97) | class DownDayBool(Indicator):
    method __init__ (line 117) | def __init__(self):
  class RelativeStrengthIndex (line 122) | class RelativeStrengthIndex(Indicator):
    method _plotlabel (line 169) | def _plotlabel(self):
    method _plotinit (line 175) | def _plotinit(self):
    method __init__ (line 178) | def __init__(self):
    method _rscalc (line 193) | def _rscalc(self, rsi):
  class RSI_Safe (line 202) | class RSI_Safe(RSI):
  class RSI_SMA (line 213) | class RSI_SMA(RSI):
  class RSI_EMA (line 225) | class RSI_EMA(RSI):

FILE: backtrader/indicators/sma.py
  class MovingAverageSimple (line 27) | class MovingAverageSimple(MovingAverageBase):
    method __init__ (line 40) | def __init__(self):

FILE: backtrader/indicators/smma.py
  class SmoothedMovingAverage (line 27) | class SmoothedMovingAverage(MovingAverageBase):
    method __init__ (line 51) | def __init__(self):

FILE: backtrader/indicators/stochastic.py
  class _StochasticBase (line 27) | class _StochasticBase(Indicator):
    method _plotlabel (line 36) | def _plotlabel(self):
    method _plotinit (line 41) | def _plotinit(self):
    method __init__ (line 44) | def __init__(self):
  class StochasticFast (line 58) | class StochasticFast(_StochasticBase):
    method __init__ (line 81) | def __init__(self):
  class Stochastic (line 87) | class Stochastic(_StochasticBase):
    method _plotlabel (line 106) | def _plotlabel(self):
    method __init__ (line 111) | def __init__(self):
  class StochasticFull (line 117) | class StochasticFull(_StochasticBase):
    method _plotlabel (line 138) | def _plotlabel(self):
    method __init__ (line 143) | def __init__(self):

FILE: backtrader/indicators/trix.py
  class Trix (line 27) | class Trix(Indicator):
    method _plotlabel (line 53) | def _plotlabel(self):
    method __init__ (line 59) | def __init__(self):
  class TrixSignal (line 71) | class TrixSignal(Trix):
    method __init__ (line 85) | def __init__(self):

FILE: backtrader/indicators/tsi.py
  class TrueStrengthIndicator (line 29) | class TrueStrengthIndicator(bt.Indicator):
    method __init__ (line 65) | def __init__(self):

FILE: backtrader/indicators/ultimateoscillator.py
  class UltimateOscillator (line 29) | class UltimateOscillator(bt.Indicator):
    method _plotinit (line 59) | def _plotinit(self):
    method __init__ (line 68) | def __init__(self):

FILE: backtrader/indicators/vortex.py
  class Vortex (line 27) | class Vortex(bt.Indicator):
    method __init__ (line 39) | def __init__(self):

FILE: backtrader/indicators/williams.py
  class WilliamsR (line 28) | class WilliamsR(Indicator):
    method _plotinif (line 51) | def _plotinif(self):
    method __init__ (line 54) | def __init__(self):
  class WilliamsAD (line 64) | class WilliamsAD(Indicator):
    method __init__ (line 80) | def __init__(self):

FILE: backtrader/indicators/wma.py
  class WeightedMovingAverage (line 29) | class WeightedMovingAverage(MovingAverageBase):
    method __init__ (line 45) | def __init__(self):

FILE: backtrader/indicators/zlema.py
  class ZeroLagExponentialMovingAverage (line 28) | class ZeroLagExponentialMovingAverage(MovingAverageBase):
    method __init__ (line 46) | def __init__(self):

FILE: backtrader/indicators/zlind.py
  class ZeroLagIndicator (line 32) | class ZeroLagIndicator(MovingAverageBase):
    method _plotlabel (line 64) | def _plotlabel(self):
    method __init__ (line 69) | def __init__(self):
    method next (line 76) | def next(self):

FILE: backtrader/linebuffer.py
  class LineBuffer (line 50) | class LineBuffer(LineSingle):
    method __init__ (line 75) | def __init__(self):
    method get_idx (line 82) | def get_idx(self):
    method set_idx (line 85) | def set_idx(self, idx, force=False):
    method reset (line 102) | def reset(self):
    method qbuffer (line 121) | def qbuffer(self, savemem=0, extrasize=0):
    method getindicators (line 128) | def getindicators(self):
    method minbuffer (line 131) | def minbuffer(self, size):
    method __len__ (line 149) | def __len__(self):
    method buflen (line 152) | def buflen(self):
    method __getitem__ (line 162) | def __getitem__(self, ago):
    method get (line 165) | def get(self, ago=0, size=1):
    method getzeroval (line 186) | def getzeroval(self, idx=0):
    method getzero (line 199) | def getzero(self, idx=0, size=1):
    method __setitem__ (line 214) | def __setitem__(self, ago, value):
    method set (line 226) | def set(self, value, ago=0):
    method home (line 238) | def home(self):
    method forward (line 247) | def forward(self, value=NAN, size=1):
    method backwards (line 260) | def backwards(self, size=1, force=False):
    method rewind (line 273) | def rewind(self, size=1):
    method advance (line 277) | def advance(self, size=1):
    method extend (line 286) | def extend(self, value=NAN, size=0):
    method addbinding (line 300) | def addbinding(self, binding):
    method plot (line 312) | def plot(self, idx=0, size=None):
    method plotrange (line 328) | def plotrange(self, start, end):
    method oncebinding (line 334) | def oncebinding(self):
    method bind2lines (line 343) | def bind2lines(self, binding=0):
    method __call__ (line 358) | def __call__(self, ago=None):
    method _makeoperation (line 376) | def _makeoperation(self, other, operation, r=False, _ownerskip=None):
    method _makeoperationown (line 380) | def _makeoperationown(self, operation, _ownerskip=None):
    method _settz (line 383) | def _settz(self, tz):
    method datetime (line 386) | def datetime(self, ago=0, tz=None, naive=True):
    method date (line 390) | def date(self, ago=0, tz=None, naive=True):
    method time (line 394) | def time(self, ago=0, tz=None, naive=True):
    method dt (line 398) | def dt(self, ago=0):
    method tm_raw (line 404) | def tm_raw(self, ago=0):
    method tm (line 413) | def tm(self, ago=0):
    method tm_lt (line 422) | def tm_lt(self, other, ago=0):
    method tm_le (line 434) | def tm_le(self, other, ago=0):
    method tm_eq (line 446) | def tm_eq(self, other, ago=0):
    method tm_gt (line 458) | def tm_gt(self, other, ago=0):
    method tm_ge (line 470) | def tm_ge(self, other, ago=0):
    method tm2dtime (line 482) | def tm2dtime(self, tm, ago=0):
    method tm2datetime (line 490) | def tm2datetime(self, tm, ago=0):
  class MetaLineActions (line 499) | class MetaLineActions(LineBuffer.__class__):
    method cleancache (line 513) | def cleancache(cls):
    method usecache (line 517) | def usecache(cls, onoff):
    method __call__ (line 520) | def __call__(cls, *args, **kwargs):
    method dopreinit (line 536) | def dopreinit(cls, _obj, *args, **kwargs):
    method dopostinit (line 561) | def dopostinit(cls, _obj, *args, **kwargs):
  class PseudoArray (line 571) | class PseudoArray(object):
    method __init__ (line 572) | def __init__(self, wrapped):
    method __getitem__ (line 575) | def __getitem__(self, key):
    method array (line 579) | def array(self):
  class LineActions (line 583) | class LineActions(with_metaclass(MetaLineActions, LineBuffer)):
    method getindicators (line 594) | def getindicators(self):
    method qbuffer (line 597) | def qbuffer(self, savemem=0):
    method arrayize (line 603) | def arrayize(obj):
    method _next (line 612) | def _next(self):
    method _once (line 625) | def _once(self):
  function LineDelay (line 636) | def LineDelay(a, ago=0, **kwargs):
  function LineNum (line 643) | def LineNum(num):
  class _LineDelay (line 647) | class _LineDelay(LineActions):
    method __init__ (line 652) | def __init__(self, a, ago):
    method next (line 662) | def next(self):
    method once (line 665) | def once(self, start, end):
  class _LineForward (line 675) | class _LineForward(LineActions):
    method __init__ (line 680) | def __init__(self, a, ago):
    method next (line 692) | def next(self):
    method once (line 695) | def once(self, start, end):
  class LinesOperation (line 705) | class LinesOperation(LineActions):
    method __init__ (line 727) | def __init__(self, a, b, operation, r=False):
    method next (line 742) | def next(self):
    method once (line 753) | def once(self, start, end):
    method _once_op (line 764) | def _once_op(self, start, end):
    method _once_time_op (line 774) | def _once_time_op(self, start, end):
    method _once_val_op (line 785) | def _once_val_op(self, start, end):
    method _once_val_op_r (line 795) | def _once_val_op_r(self, start, end):
  class LineOwnOperation (line 806) | class LineOwnOperation(LineActions):
    method __init__ (line 813) | def __init__(self, a, operation):
    method next (line 819) | def next(self):
    method once (line 822) | def once(self, start, end):

FILE: backtrader/lineiterator.py
  class MetaLineIterator (line 38) | class MetaLineIterator(LineSeries.__class__):
    method donew (line 39) | def donew(cls, *args, **kwargs):
    method dopreinit (line 106) | def dopreinit(cls, _obj, *args, **kwargs):
    method dopostinit (line 130) | def dopostinit(cls, _obj, *args, **kwargs):
  class LineIterator (line 148) | class LineIterator(with_metaclass(MetaLineIterator, LineSeries)):
    method _periodrecalc (line 169) | def _periodrecalc(self):
    method _stage2 (line 178) | def _stage2(self):
    method _stage1 (line 188) | def _stage1(self):
    method getindicators (line 198) | def getindicators(self):
    method getindicators_lines (line 201) | def getindicators_lines(self):
    method getobservers (line 205) | def getobservers(self):
    method addindicator (line 208) | def addindicator(self, indicator):
    method bindlines (line 223) | def bindlines(self, owner=None, own=None):
    method _next (line 259) | def _next(self):
    method _clk_update (line 286) | def _clk_update(self):
    method _once (line 293) | def _once(self):
    method preonce (line 323) | def preonce(self, start, end):
    method oncestart (line 326) | def oncestart(self, start, end):
    method once (line 329) | def once(self, start, end):
    method prenext (line 332) | def prenext(self):
    method nextstart (line 339) | def nextstart(self):
    method next (line 349) | def next(self):
    method _addnotification (line 356) | def _addnotification(self, *args, **kwargs):
    method _notify (line 359) | def _notify(self):
    method _plotinit (line 362) | def _plotinit(self):
    method qbuffer (line 365) | def qbuffer(self, savemem=0):
  class DataAccessor (line 383) | class DataAccessor(LineIterator):
  class IndicatorBase (line 393) | class IndicatorBase(DataAccessor):
  class ObserverBase (line 397) | class ObserverBase(DataAccessor):
  class StrategyBase (line 401) | class StrategyBase(DataAccessor):
  class SingleCoupler (line 408) | class SingleCoupler(LineActions):
    method __init__ (line 409) | def __init__(self, cdata, clock=None):
    method next (line 417) | def next(self):
  class MultiCoupler (line 425) | class MultiCoupler(LineIterator):
    method __init__ (line 428) | def __init__(self):
    method next (line 434) | def next(self):
  function LinesCoupler (line 445) | def LinesCoupler(cdata, clock=None, **kwargs):

FILE: backtrader/lineroot.py
  class MetaLineRoot (line 41) | class MetaLineRoot(metabase.MetaParams):
    method donew (line 47) | def donew(cls, *args, **kwargs):
  class LineRoot (line 61) | class LineRoot(with_metaclass(MetaLineRoot, object)):
    method _stage1 (line 77) | def _stage1(self):
    method _stage2 (line 80) | def _stage2(self):
    method _operation (line 83) | def _operation(self, other, operation, r=False, intify=False):
    method _operationown (line 90) | def _operationown(self, operation):
    method qbuffer (line 96) | def qbuffer(self, savemem=0):
    method minbuffer (line 100) | def minbuffer(self, size):
    method setminperiod (line 104) | def setminperiod(self, minperiod):
    method updateminperiod (line 112) | def updateminperiod(self, minperiod):
    method addminperiod (line 120) | def addminperiod(self, minperiod):
    method incminperiod (line 126) | def incminperiod(self, minperiod):
    method prenext (line 132) | def prenext(self):
    method nextstart (line 138) | def nextstart(self):
    method next (line 146) | def next(self):
    method preonce (line 152) | def preonce(self, start, end):
    method oncestart (line 158) | def oncestart(self, start, end):
    method once (line 167) | def once(self, start, end):
    method _makeoperation (line 174) | def _makeoperation(self, other, operation, r=False, _ownerskip=None):
    method _makeoperationown (line 177) | def _makeoperationown(self, operation, _ownerskip=None):
    method _operationown_stage1 (line 180) | def _operationown_stage1(self, operation):
    method _roperation (line 186) | def _roperation(self, other, operation, intify=False):
    method _operation_stage1 (line 193) | def _operation_stage1(self, other, operation, r=False, intify=False):
    method _operation_stage2 (line 203) | def _operation_stage2(self, other, operation, r=False):
    method _operationown_stage2 (line 217) | def _operationown_stage2(self, operation):
    method __add__ (line 220) | def __add__(self, other):
    method __radd__ (line 223) | def __radd__(self, other):
    method __sub__ (line 226) | def __sub__(self, other):
    method __rsub__ (line 229) | def __rsub__(self, other):
    method __mul__ (line 232) | def __mul__(self, other):
    method __rmul__ (line 235) | def __rmul__(self, other):
    method __div__ (line 238) | def __div__(self, other):
    method __rdiv__ (line 241) | def __rdiv__(self, other):
    method __floordiv__ (line 244) | def __floordiv__(self, other):
    method __rfloordiv__ (line 247) | def __rfloordiv__(self, other):
    method __truediv__ (line 250) | def __truediv__(self, other):
    method __rtruediv__ (line 253) | def __rtruediv__(self, other):
    method __pow__ (line 256) | def __pow__(self, other):
    method __rpow__ (line 259) | def __rpow__(self, other):
    method __abs__ (line 262) | def __abs__(self):
    method __neg__ (line 265) | def __neg__(self):
    method __lt__ (line 268) | def __lt__(self, other):
    method __gt__ (line 271) | def __gt__(self, other):
    method __le__ (line 274) | def __le__(self, other):
    method __ge__ (line 277) | def __ge__(self, other):
    method __eq__ (line 280) | def __eq__(self, other):
    method __ne__ (line 283) | def __ne__(self, other):
    method __nonzero__ (line 286) | def __nonzero__(self):
  class LineMultiple (line 296) | class LineMultiple(LineRoot):
    method reset (line 300) | def reset(self):
    method _stage1 (line 304) | def _stage1(self):
    method _stage2 (line 309) | def _stage2(self):
    method addminperiod (line 314) | def addminperiod(self, minperiod):
    method incminperiod (line 322) | def incminperiod(self, minperiod):
    method _makeoperation (line 330) | def _makeoperation(self, other, operation, r=False, _ownerskip=None):
    method _makeoperationown (line 333) | def _makeoperationown(self, operation, _ownerskip=None):
    method qbuffer (line 336) | def qbuffer(self, savemem=0):
    method minbuffer (line 340) | def minbuffer(self, size):
  class LineSingle (line 345) | class LineSingle(LineRoot):
    method addminperiod (line 349) | def addminperiod(self, minperiod):
    method incminperiod (line 355) | def incminperiod(self, minperiod):

FILE: backtrader/lineseries.py
  class LineAlias (line 44) | class LineAlias(object):
    method __init__ (line 58) | def __init__(self, line):
    method __get__ (line 61) | def __get__(self, obj, cls=None):
    method __set__ (line 64) | def __set__(self, obj, value):
  class Lines (line 84) | class Lines(object):
    method _derive (line 100) | def _derive(cls, name, lines, extralines, otherbases, linesoverride=Fa...
    method _getlinealias (line 182) | def _getlinealias(cls, i):
    method getlinealiases (line 193) | def getlinealiases(cls):
    method itersize (line 196) | def itersize(self):
    method __init__ (line 199) | def __init__(self, initlines=None):
    method __len__ (line 216) | def __len__(self):
    method size (line 222) | def size(self):
    method fullsize (line 225) | def fullsize(self):
    method extrasize (line 228) | def extrasize(self):
    method __getitem__ (line 231) | def __getitem__(self, line):
    method get (line 237) | def get(self, ago=0, size=1, line=0):
    method __setitem__ (line 243) | def __setitem__(self, line, value):
    method forward (line 249) | def forward(self, value=NAN, size=1):
    method backwards (line 256) | def backwards(self, size=1, force=False):
    method rewind (line 263) | def rewind(self, size=1):
    method extend (line 270) | def extend(self, value=NAN, size=0):
    method reset (line 277) | def reset(self):
    method home (line 284) | def home(self):
    method advance (line 291) | def advance(self, size=1):
    method buflen (line 298) | def buflen(self, line=0):
  class MetaLineSeries (line 305) | class MetaLineSeries(LineMultiple.__class__):
    method __new__ (line 326) | def __new__(meta, name, bases, dct):
    method donew (line 406) | def donew(cls, *args, **kwargs):
  class LineSeries (line 444) | class LineSeries(with_metaclass(MetaLineSeries, LineMultiple)):
    method array (line 454) | def array(self):
    method __getattr__ (line 457) | def __getattr__(self, name):
    method __len__ (line 463) | def __len__(self):
    method __getitem__ (line 466) | def __getitem__(self, key):
    method __setitem__ (line 469) | def __setitem__(self, key, value):
    method __init__ (line 472) | def __init__(self, *args, **kwargs):
    method plotlabel (line 480) | def plotlabel(self):
    method _plotlabel (line 497) | def _plotlabel(self):
    method _getline (line 500) | def _getline(self, line, minusall=False):
    method __call__ (line 512) | def __call__(self, ago=None, line=-1):
    method forward (line 553) | def forward(self, value=NAN, size=1):
    method backwards (line 556) | def backwards(self, size=1, force=False):
    method rewind (line 559) | def rewind(self, size=1):
    method extend (line 562) | def extend(self, value=NAN, size=0):
    method reset (line 565) | def reset(self):
    method home (line 568) | def home(self):
    method advance (line 571) | def advance(self, size=1):
  class LineSeriesStub (line 575) | class LineSeriesStub(LineSeries):
    method __init__ (line 595) | def __init__(self, line, slave=False):
    method forward (line 603) | def forward(self, value=NAN, size=1):
    method backwards (line 607) | def backwards(self, size=1, force=False):
    method rewind (line 611) | def rewind(self, size=1):
    method extend (line 615) | def extend(self, value=NAN, size=0):
    method reset (line 619) | def reset(self):
    method home (line 623) | def home(self):
    method advance (line 627) | def advance(self, size=1):
    method qbuffer (line 631) | def qbuffer(self):
    method minbuffer (line 635) | def minbuffer(self, size):
  function LineSeriesMaker (line 640) | def LineSeriesMaker(arg, slave=False):

FILE: backtrader/mathsupport.py
  function average (line 27) | def average(x, bessel=False):
  function variance (line 41) | def variance(x, avgx=None):
  function standarddev (line 54) | def standarddev(x, avgx=None, bessel=False):

FILE: backtrader/metabase.py
  function findbases (line 32) | def findbases(kls, topclass):
  function findowner (line 42) | def findowner(owned, cls, startlevel=2, skip=None):
  class MetaBase (line 66) | class MetaBase(type):
    method doprenew (line 67) | def doprenew(cls, *args, **kwargs):
    method donew (line 70) | def donew(cls, *args, **kwargs):
    method dopreinit (line 74) | def dopreinit(cls, _obj, *args, **kwargs):
    method doinit (line 77) | def doinit(cls, _obj, *args, **kwargs):
    method dopostinit (line 81) | def dopostinit(cls, _obj, *args, **kwargs):
    method __call__ (line 84) | def __call__(cls, *args, **kwargs):
  class AutoInfoClass (line 93) | class AutoInfoClass(object):
    method _derive (line 99) | def _derive(cls, name, info, otherbases, recurse=False):
    method isdefault (line 154) | def isdefault(self, pname):
    method notdefault (line 157) | def notdefault(self, pname):
    method _get (line 160) | def _get(self, name, default=None):
    method _getkwargsdefault (line 164) | def _getkwargsdefault(cls):
    method _getkeys (line 168) | def _getkeys(cls):
    method _getdefaults (line 172) | def _getdefaults(cls):
    method _getitems (line 176) | def _getitems(cls):
    method _gettuple (line 180) | def _gettuple(cls):
    method _getkwargs (line 183) | def _getkwargs(self, skip_=False):
    method _getvalues (line 189) | def _getvalues(self):
    method __new__ (line 192) | def __new__(cls, *args, **kwargs):
  class MetaParams (line 203) | class MetaParams(MetaBase):
    method __new__ (line 204) | def __new__(meta, name, bases, dct):
    method donew (line 243) | def donew(cls, *args, **kwargs):
  class ParamsBase (line 296) | class ParamsBase(with_metaclass(MetaParams, object)):
  class ItemCollection (line 300) | class ItemCollection(object):
    method __init__ (line 307) | def __init__(self):
    method __len__ (line 311) | def __len__(self):
    method append (line 314) | def append(self, item, name=None):
    method __getitem__ (line 320) | def __getitem__(self, key):
    method getnames (line 323) | def getnames(self):
    method getitems (line 326) | def getitems(self):
    method getbyname (line 329) | def getbyname(self, name):

FILE: backtrader/observer.py
  class MetaObserver (line 29) | class MetaObserver(ObserverBase.__class__):
    method donew (line 30) | def donew(cls, *args, **kwargs):
    method dopreinit (line 36) | def dopreinit(cls, _obj, *args, **kwargs):
  class Observer (line 46) | class Observer(with_metaclass(MetaObserver, ObserverBase)):
    method prenext (line 58) | def prenext(self):
    method _register_analyzer (line 61) | def _register_analyzer(self, analyzer):
    method _start (line 64) | def _start(self):
    method start (line 67) | def start(self):

FILE: backtrader/observers/benchmark.py
  class Benchmark (line 28) | class Benchmark(TimeReturn):
    method _plotlabel (line 94) | def _plotlabel(self):
    method __init__ (line 99) | def __init__(self):
    method next (line 112) | def next(self):
    method prenext (line 117) | def prenext(self):

FILE: backtrader/observers/broker.py
  class Cash (line 27) | class Cash(Observer):
    method next (line 38) | def next(self):
  class Value (line 42) | class Value(Observer):
    method start (line 68) | def start(self):
    method next (line 74) | def next(self):
  class Broker (line 81) | class Broker(Observer):
    method start (line 98) | def start(self):
    method next (line 108) | def next(self):
  class FundValue (line 116) | class FundValue(Observer):
    method next (line 128) | def next(self):
  class FundShares (line 132) | class FundShares(Observer):
    method next (line 143) | def next(self):

FILE: backtrader/observers/buysell.py
  class BuySell (line 29) | class BuySell(Observer):
    method next (line 60) | def next(self):

FILE: backtrader/observers/drawdown.py
  class DrawDown (line 28) | class DrawDown(Observer):
    method __init__ (line 56) | def __init__(self):
    method next (line 61) | def next(self):
  class DrawDownLength (line 66) | class DrawDownLength(Observer):
    method __init__ (line 80) | def __init__(self):
    method next (line 83) | def next(self):
  class DrawDown_Old (line 88) | class DrawDown_Old(Observer):
    method __init__ (line 102) | def __init__(self):
    method next (line 108) | def next(self):

FILE: backtrader/observers/logreturns.py
  class LogReturns (line 31) | class LogReturns(bt.Observer):
    method _plotlabel (line 72) | def _plotlabel(self):
    method __init__ (line 76) | def __init__(self):
    method next (line 81) | def next(self):
  class LogReturns2 (line 85) | class LogReturns2(LogReturns):
    method __init__ (line 89) | def __init__(self):
    method next (line 96) | def next(self):

FILE: backtrader/observers/timereturn.py
  class TimeReturn (line 33) | class TimeReturn(Observer):
    method _plotlabel (line 75) | def _plotlabel(self):
    method __init__ (line 83) | def __init__(self):
    method next (line 87) | def next(self):

FILE: backtrader/observers/trades.py
  class Trades (line 32) | class Trades(Observer):
    method __init__ (line 66) | def __init__(self):
    method next (line 91) | def next(self):
  class MetaDataTrades (line 107) | class MetaDataTrades(Observer.__class__):
    method donew (line 108) | def donew(cls, *args, **kwargs):
  class DataTrades (line 144) | class DataTrades(with_metaclass(MetaDataTrades, Observer)):
    method next (line 154) | def next(self):

FILE: backtrader/order.py
  class OrderExecutionBit (line 35) | class OrderExecutionBit(object):
    method __init__ (line 62) | def __init__(self,
  class OrderData (line 88) | class OrderData(object):
    method __init__ (line 130) | def __init__(self, dt=None, size=0, price=0.0, pricelimit=0.0, remsize=0,
    method _getplimit (line 163) | def _getplimit(self):
    method _setplimit (line 166) | def _setplimit(self, val):
    method __len__ (line 171) | def __len__(self):
    method __getitem__ (line 174) | def __getitem__(self, key):
    method add (line 177) | def add(self, dt, size, price,
    method addbit (line 189) | def addbit(self, exbit):
    method getpending (line 206) | def getpending(self):
    method iterpending (line 209) | def iterpending(self):
    method markpending (line 212) | def markpending(self):
    method clone (line 216) | def clone(self):
  class OrderBase (line 222) | class OrderBase(with_metaclass(MetaParams, object)):
    method _getplimit (line 262) | def _getplimit(self):
    method _setplimit (line 265) | def _setplimit(self, val):
    method __getattr__ (line 270) | def __getattr__(self, name):
    method __setattribute__ (line 274) | def __setattribute__(self, name, value):
    method __str__ (line 280) | def __str__(self):
    method __init__ (line 302) | def __init__(self):
    method clone (line 384) | def clone(self):
    method getstatusname (line 392) | def getstatusname(self, status=None):
    method getordername (line 396) | def getordername(self, exectype=None):
    method ExecType (line 401) | def ExecType(cls, exectype):
    method ordtypename (line 404) | def ordtypename(self, ordtype=None):
    method active (line 408) | def active(self):
    method activate (line 411) | def activate(self):
    method alive (line 414) | def alive(self):
    method addcomminfo (line 421) | def addcomminfo(self, comminfo):
    method addinfo (line 425) | def addinfo(self, **kwargs):
    method __eq__ (line 432) | def __eq__(self, other):
    method __ne__ (line 435) | def __ne__(self, other):
    method isbuy (line 438) | def isbuy(self):
    method issell (line 442) | def issell(self):
    method setposition (line 446) | def setposition(self, position):
    method submit (line 450) | def submit(self, broker=None):
    method accept (line 457) | def accept(self, broker=None):
    method brokerstatus (line 462) | def brokerstatus(self):
    method reject (line 471) | def reject(self, broker=None):
    method cancel (line 482) | def cancel(self):
    method margin (line 488) | def margin(self):
    method completed (line 494) | def completed(self):
    method partial (line 498) | def partial(self):
    method execute (line 502) | def execute(self, dt, size, price,
    method expire (line 519) | def expire(self):
    method trailadjust (line 524) | def trailadjust(self, price):
  class Order (line 528) | class Order(OrderBase):
    method execute (line 566) | def execute(self, dt, size, price,
    method expire (line 584) | def expire(self):
    method trailadjust (line 595) | def trailadjust(self, price):
  class BuyOrder (line 620) | class BuyOrder(Order):
  class StopBuyOrder (line 624) | class StopBuyOrder(BuyOrder):
  class StopLimitBuyOrder (line 628) | class StopLimitBuyOrder(BuyOrder):
  class SellOrder (line 632) | class SellOrder(Order):
  class StopSellOrder (line 636) | class StopSellOrder(SellOrder):
  class StopLimitSellOrder (line 640) | class StopLimitSellOrder(SellOrder):

FILE: backtrader/plot/finance.py
  class CandlestickPlotHandler (line 34) | class CandlestickPlotHandler(object):
    method __init__ (line 40) | def __init__(self,
    method legend_artist (line 102) | def legend_artist(self, legend, orig_handle, fontsize, handlebox):
    method barcollection (line 125) | def barcollection(self,
  function plot_candlestick (line 211) | def plot_candlestick(ax,
  class VolumePlotHandler (line 242) | class VolumePlotHandler(object):
    method __init__ (line 247) | def __init__(self,
    method legend_artist (line 289) | def legend_artist(self, legend, orig_handle, fontsize, handlebox):
    method barcollection (line 307) | def barcollection(self,
  function plot_volume (line 343) | def plot_volume(
  class OHLCPlotHandler (line 362) | class OHLCPlotHandler(object):
    method __init__ (line 368) | def __init__(self,
    method legend_artist (line 404) | def legend_artist(self, legend, orig_handle, fontsize, handlebox):
    method barcollection (line 429) | def barcollection(self,
  function plot_ohlc (line 495) | def plot_ohlc(ax, x, opens, highs, lows, closes,
  class LineOnClosePlotHandler (line 513) | class LineOnClosePlotHandler(object):
    method __init__ (line 516) | def __init__(self,
    method legend_artist (line 541) | def legend_artist(self, legend, orig_handle, fontsize, handlebox):
    method barcollection (line 560) | def barcollection(self,
  function plot_lineonclose (line 581) | def plot_lineonclose(ax, x, closes,

FILE: backtrader/plot/formatters.py
  class MyVolFormatter (line 30) | class MyVolFormatter(mplticker.Formatter):
    method __init__ (line 33) | def __init__(self, volmax):
    method __call__ (line 43) | def __call__(self, y, pos=0):
  class MyDateFormatter (line 53) | class MyDateFormatter(mplticker.Formatter):
    method __init__ (line 54) | def __init__(self, dates, fmt='%Y-%m-%d'):
    method __call__ (line 59) | def __call__(self, x, pos=0):
  function patch_locator (line 71) | def patch_locator(locator, xdates):
  function patch_formatter (line 98) | def patch_formatter(formatter, xdates):
  function getlocator (line 114) | def getlocator(xdates, numticks=5, tz=None):

FILE: backtrader/plot/locator.py
  function _idx2dt (line 46) | def _idx2dt(idx, dates, tz):
  class RRuleLocator (line 61) | class RRuleLocator(RRLocator):
    method __init__ (line 63) | def __init__(self, dates, o, tz=None):
    method datalim_to_dt (line 67) | def datalim_to_dt(self):
    method viewlim_to_dt (line 78) | def viewlim_to_dt(self):
    method tick_values (line 89) | def tick_values(self, vmin, vmax):
  class AutoDateLocator (line 95) | class AutoDateLocator(ADLocator):
    method __init__ (line 97) | def __init__(self, dates, *args, **kwargs):
    method datalim_to_dt (line 101) | def datalim_to_dt(self):
    method viewlim_to_dt (line 112) | def viewlim_to_dt(self):
    method tick_values (line 123) | def tick_values(self, vmin, vmax):
    method get_locator (line 128) | def get_locator(self, dmin, dmax):
  class AutoDateFormatter (line 242) | class AutoDateFormatter(ADFormatter):
    method __init__ (line 243) | def __init__(self, dates, locator, tz=None, defaultfmt='%Y-%m-%d'):
    method __call__ (line 247) | def __call__(self, x, pos=None):

FILE: backtrader/plot/multicursor.py
  class Widget (line 65) | class Widget(object):
    method set_active (line 73) | def set_active(self, active):
    method get_active (line 78) | def get_active(self):
    method ignore (line 87) | def ignore(self, event):
  class MultiCursor (line 95) | class MultiCursor(Widget):
    method __init__ (line 124) | def __init__(self, canvas, axes, useblit=True,
    method connect (line 173) | def connect(self):
    method disconnect (line 179) | def disconnect(self):
    method clear (line 184) | def clear(self, event):
    method onmove (line 194) | def onmove(self, event):
    method _update (line 223) | def _update(self, event):
  class MultiCursor2 (line 240) | class MultiCursor2(Widget):
    method __init__ (line 261) | def __init__(self, canvas, axes, useblit=True, horizOn=False, vertOn=T...
    method connect (line 298) | def connect(self):
    method disconnect (line 304) | def disconnect(self):
    method clear (line 309) | def clear(self, event):
    method onmove (line 319) | def onmove(self, event):
    method _update (line 342) | def _update(self, event):

FILE: backtrader/plot/plot.py
  class PInfo (line 50) | class PInfo(object):
    method __init__ (line 51) | def __init__(self, sch):
    method newfig (line 71) | def newfig(self, figid, numfig, mpyplot):
    method nextcolor (line 80) | def nextcolor(self, ax):
    method color (line 84) | def color(self, ax):
    method zordernext (line 87) | def zordernext(self, ax):
    method zordercur (line 93) | def zordercur(self, ax):
  class Plot_OldSync (line 97) | class Plot_OldSync(with_metaclass(MetaParams, object)):
    method __init__ (line 100) | def __init__(self, **kwargs):
    method drawtag (line 107) | def drawtag(self, ax, x, y, facecolor, edgecolor, alpha=0.9, **kwargs):
    method plot (line 119) | def plot(self, strategy, figid=0, numfigs=1, iplot=True,
    method setlocators (line 276) | def setlocators(self, ax):
    method calcrows (line 317) | def calcrows(self, strategy):
    method newaxis (line 361) | def newaxis(self, obj, rowspan):
    method plotind (line 382) | def plotind(self, iref, ind,
    method plotvolume (line 578) | def plotvolume(self, data, opens, highs, lows, closes, volumes, label):
    method plotdata (line 642) | def plotdata(self, data, indicators):
    method show (line 820) | def show(self):
    method savefig (line 823) | def savefig(self, fig, filename, width=16, height=9, dpi=300, tight=Tr...
    method sortdataindicators (line 828) | def sortdataindicators(self, strategy):

FILE: backtrader/plot/scheme.py
  class PlotScheme (line 77) | class PlotScheme(object):
    method __init__ (line 78) | def __init__(self):
    method color (line 187) | def color(self, idx):

FILE: backtrader/plot/utils.py
  function tag_box_style (line 30) | def tag_box_style(x0, y0, width, height, mutation_size, mutation_aspect=1):
  function shade_color (line 66) | def shade_color(color, percent):

FILE: backtrader/position.py
  class Position (line 28) | class Position(object):
    method __str__ (line 41) | def __str__(self):
    method __init__ (line 53) | def __init__(self, size=0, price=0.0):
    method fix (line 68) | def fix(self, size, price):
    method set (line 74) | def set(self, size, price):
    method __len__ (line 110) | def __len__(self):
    method __bool__ (line 113) | def __bool__(self):
    method clone (line 118) | def clone(self):
    method pseudoupdate (line 121) | def pseudoupdate(self, size, price):
    method update (line 124) | def update(self, size, price, dt=None):

FILE: backtrader/resamplerfilter.py
  class DTFaker (line 33) | class DTFaker(object):
    method __init__ (line 47) | def __init__(self, data, forcedata=None):
    method __len__ (line 64) | def __len__(self):
    method __call__ (line 67) | def __call__(self, idx=0):
    method datetime (line 70) | def datetime(self, idx=0):
    method date (line 73) | def date(self, idx=0):
    method time (line 76) | def time(self, idx=0):
    method _calendar (line 80) | def _calendar(self):
    method __getitem__ (line 83) | def __getitem__(self, idx):
    method num2date (line 86) | def num2date(self, *args, **kwargs):
    method date2num (line 89) | def date2num(self, *args, **kwargs):
    method _getnexteos (line 92) | def _getnexteos(self):
  class _BaseResampler (line 96) | class _BaseResampler(with_metaclass(metabase.MetaParams, object)):
    method __init__ (line 111) | def __init__(self, data):
    method _latedata (line 134) | def _latedata(self, data):
    method _checkbarover (line 142) | def _checkbarover(self, data, fromcheck=False, forcedata=None):
    method _barover (line 159) | def _barover(self, data):
    method _eosset (line 181) | def _eosset(self):
    method _eoscheck (line 186) | def _eoscheck(self, data, seteos=True, exact=False):
    method _barover_days (line 214) | def _barover_days(self, data):
    method _barover_weeks (line 217) | def _barover_weeks(self, data):
    method _barover_months (line 229) | def _barover_months(self, data):
    method _barover_years (line 238) | def _barover_years(self, data):
    method _gettmpoint (line 242) | def _gettmpoint(self, tm):
    method _barover_subdays (line 266) | def _barover_subdays(self, data):
    method check (line 299) | def check(self, data, _forcedata=None):
    method _dataonedge (line 312) | def _dataonedge(self, data):
    method _calcadjtime (line 362) | def _calcadjtime(self, greater=False):
    method _adjusttime (line 418) | def _adjusttime(self, greater=False, forcedata=None):
  class Resampler (line 435) | class Resampler(_BaseResampler):
    method last (line 478) | def last(self, data):
    method __call__ (line 495) | def __call__(self, data, fromcheck=False, forcedata=None):
  class Replayer (line 563) | class Replayer(_BaseResampler):
    method __call__ (line 615) | def __call__(self, data, fromcheck=False, forcedata=None):
  class ResamplerTicks (line 703) | class ResamplerTicks(Resampler):
  class ResamplerSeconds (line 707) | class ResamplerSeconds(Resampler):
  class ResamplerMinutes (line 711) | class ResamplerMinutes(Resampler):
  class ResamplerDaily (line 715) | class ResamplerDaily(Resampler):
  class ResamplerWeekly (line 719) | class ResamplerWeekly(Resampler):
  class ResamplerMonthly (line 723) | class ResamplerMonthly(Resampler):
  class ResamplerYearly (line 727) | class ResamplerYearly(Resampler):
  class ReplayerTicks (line 731) | class ReplayerTicks(Replayer):
  class ReplayerSeconds (line 735) | class ReplayerSeconds(Replayer):
  class ReplayerMinutes (line 739) | class ReplayerMinutes(Replayer):
  class ReplayerDaily (line 743) | class ReplayerDaily(Replayer):
  class ReplayerWeekly (line 747) | class ReplayerWeekly(Replayer):
  class ReplayerMonthly (line 751) | class ReplayerMonthly(Replayer):

FILE: backtrader/signal.py
  class Signal (line 56) | class Signal(bt.Indicator):
    method __init__ (line 61) | def __init__(self):

FILE: backtrader/sizer.py
  class Sizer (line 29) | class Sizer(with_metaclass(MetaParams, object)):
    method getsizing (line 50) | def getsizing(self, data, isbuy):
    method _getsizing (line 54) | def _getsizing(self, comminfo, cash, data, isbuy):
    method set (line 79) | def set(self, strategy, broker):

FILE: backtrader/sizers/fixedsize.py
  class FixedSize (line 27) | class FixedSize(bt.Sizer):
    method _getsizing (line 43) | def _getsizing(self, comminfo, cash, data, isbuy):
    method setsizing (line 49) | def setsizing(self, stake):
  class FixedReverser (line 59) | class FixedReverser(bt.Sizer):
    method _getsizing (line 72) | def _getsizing(self, comminfo, cash, data, isbuy):
  class FixedSizeTarget (line 78) | class FixedSizeTarget(bt.Sizer):
    method _getsizing (line 95) | def _getsizing(self, comminfo, cash, data, isbuy):
    method setsizing (line 102) | def setsizing(self, stake):

FILE: backtrader/sizers/percents_sizer.py
  class PercentSizer (line 29) | class PercentSizer(bt.Sizer):
    method __init__ (line 41) | def __init__(self):
    method _getsizing (line 44) | def _getsizing(self, comminfo, cash, data, isbuy):
  class AllInSizer (line 57) | class AllInSizer(PercentSizer):
  class PercentSizerInt (line 68) | class PercentSizerInt(PercentSizer):
  class AllInSizerInt (line 81) | class AllInSizerInt(PercentSizerInt):

FILE: backtrader/store.py
  class MetaSingleton (line 30) | class MetaSingleton(MetaParams):
    method __init__ (line 32) | def __init__(cls, name, bases, dct):
    method __call__ (line 36) | def __call__(cls, *args, **kwargs):
  class Store (line 44) | class Store(with_metaclass(MetaSingleton, object)):
    method getdata (line 51) | def getdata(self, *args, **kwargs):
    method getbroker (line 58) | def getbroker(cls, *args, **kwargs):
    method start (line 67) | def start(self, data=None, broker=None):
    method stop (line 85) | def stop(self):
    method put_notification (line 88) | def put_notification(self, msg, *args, **kwargs):
    method get_notifications (line 91) | def get_notifications(self):

FILE: backtrader/stores/ibstore.py
  function _ts2dt (line 44) | def _ts2dt(tstamp=None):
  class RTVolume (line 54) | class RTVolume(object):
    method __init__ (line 69) | def __init__(self, rtvol='', price=None, tmoffset=None):
  class MetaSingleton (line 85) | class MetaSingleton(MetaParams):
    method __init__ (line 87) | def __init__(cls, name, bases, dct):
    method __call__ (line 91) | def __call__(cls, *args, **kwargs):
  function ibregister (line 100) | def ibregister(f):
  class IBStore (line 105) | class IBStore(with_metaclass(MetaSingleton, object)):
    method getdata (line 190) | def getdata(cls, *args, **kwargs):
    method getbroker (line 195) | def getbroker(cls, *args, **kwargs):
    method __init__ (line 199) | def __init__(self):
    method start (line 300) | def start(self, data=None, broker=None):
    method stop (line 316) | def stop(self):
    method logmsg (line 326) | def logmsg(self, *args):
    method watcher (line 331) | def watcher(self, msg):
    method connected (line 337) | def connected(self):
    method reconnect (line 349) | def reconnect(self, fromstart=False, resub=False):
    method startdatas (line 400) | def startdatas(self):
    method stopdatas (line 411) | def stopdatas(self):
    method get_notifications (line 426) | def get_notifications(self):
    method error (line 441) | def error(self, msg):
    method connectionClosed (line 541) | def connectionClosed(self, msg):
    method managedAccounts (line 548) | def managedAccounts(self, msg):
    method reqCurrentTime (line 556) | def reqCurrentTime(self):
    method currentTime (line 560) | def currentTime(self, msg):
    method timeoffset (line 569) | def timeoffset(self):
    method nextTickerId (line 573) | def nextTickerId(self):
    method nextValidId (line 578) | def nextValidId(self, msg):
    method nextOrderId (line 582) | def nextOrderId(self):
    method reuseQueue (line 587) | def reuseQueue(self, tickerId):
    method getTickerQueue (line 602) | def getTickerQueue(self, start=False):
    method cancelQueue (line 617) | def cancelQueue(self, q, sendnone=False):
    method validQueue (line 628) | def validQueue(self, q):
    method getContractDetails (line 632) | def getContractDetails(self, contract, maxcount=None):
    method reqContractDetails (line 648) | def reqContractDetails(self, contract):
    method contractDetailsEnd (line 655) | def contractDetailsEnd(self, msg):
    method contractDetails (line 660) | def contractDetails(self, msg):
    method reqHistoricalDataEx (line 664) | def reqHistoricalDataEx(self, contract, enddate, begindate,
    method reqHistoricalData (line 761) | def reqHistoricalData(self, contract, enddate, duration, barsize,
    method cancelHistoricalData (line 795) | def cancelHistoricalData(self, q):
    method reqRealTimeBars (line 805) | def reqRealTimeBars(self, contract, useRTH=False, duration=5):
    method cancelRealTimeBars (line 829) | def cancelRealTimeBars(self, q):
    method reqMktData (line 842) | def reqMktData(self, contract, what=None):
    method cancelMktData (line 866) | def cancelMktData(self, q):
    method tickString (line 880) | def tickString(self, msg):
    method tickPrice (line 893) | def tickPrice(self, msg):
    method realtimeBar (line 925) | def realtimeBar(self, msg):
    method historicalData (line 936) | def historicalData(self, msg):
    method getdurations (line 1133) | def getdurations(self,  timeframe, compression):
    method getmaxduration (line 1140) | def getmaxduration(self, timeframe, compression):
    method tfcomp_to_size (line 1149) | def tfcomp_to_size(self, timeframe, compression):
    method dt_plus_duration (line 1175) | def dt_plus_duration(self, dt, duration):
    method calcdurations (line 1197) | def calcdurations(self, dtbegin, dtend):
    method calcduration (line 1214) | def calcduration(self, dtbegin, dtend):
    method histduration (line 1219) | def histduration(self, dt1, dt2):
    method makecontract (line 1275) | def makecontract(self, symbol, sectype, exch, curr,
    method cancelOrder (line 1294) | def cancelOrder(self, orderid):
    method placeOrder (line 1298) | def placeOrder(self, orderid, contract, order):
    method openOrder (line 1303) | def openOrder(self, msg):
    method execDetails (line 1308) | def execDetails(self, msg):
    method orderStatus (line 1313) | def orderStatus(self, msg):
    method commissionReport (line 1318) | def commissionReport(self, msg):
    method reqPositions (line 1322) | def reqPositions(self):
    method position (line 1327) | def position(self, msg):
    method reqAccountUpdates (line 1331) | def reqAccountUpdates(self, subscribe=True, account=None):
    method accountDownloadEnd (line 1344) | def accountDownloadEnd(self, msg):
    method updatePortfolio (line 1356) | def updatePortfolio(self, msg):
    method getposition (line 1377) | def getposition(self, contract, clone=False):
    method updateAccountValue (line 1388) | def updateAccountValue(self, msg):
    method get_acc_values (line 1405) | def get_acc_values(self, account=None):
    method get_acc_value (line 1442) | def get_acc_value(self, account=None):
    method get_acc_cash (line 1479) | def get_acc_cash(self, account=None):

FILE: backtrader/stores/oandastore.py
  class OandaRequestError (line 41) | class OandaRequestError(oandapy.OandaError):
    method __init__ (line 42) | def __init__(self):
  class OandaStreamError (line 47) | class OandaStreamError(oandapy.OandaError):
    method __init__ (line 48) | def __init__(self, content=''):
  class OandaTimeFrameError (line 53) | class OandaTimeFrameError(oandapy.OandaError):
    method __init__ (line 54) | def __init__(self, content):
  class OandaNetworkError (line 59) | class OandaNetworkError(oandapy.OandaError):
    method __init__ (line 60) | def __init__(self):
  class API (line 65) | class API(oandapy.API):
    method request (line 66) | def request(self, endpoint, method='GET', params=None):
  class Streamer (line 99) | class Streamer(oandapy.Streamer):
    method __init__ (line 100) | def __init__(self, q, headers=None, *args, **kwargs):
    method run (line 109) | def run(self, endpoint, params=None):
    method on_success (line 152) | def on_success(self, data):
    method on_error (line 158) | def on_error(self, data):
  class MetaSingleton (line 163) | class MetaSingleton(MetaParams):
    method __init__ (line 165) | def __init__(cls, name, bases, dct):
    method __call__ (line 169) | def __call__(cls, *args, **kwargs):
  class OandaStore (line 177) | class OandaStore(with_metaclass(MetaSingleton, object)):
    method getdata (line 207) | def getdata(cls, *args, **kwargs):
    method getbroker (line 212) | def getbroker(cls, *args, **kwargs):
    method __init__ (line 216) | def __init__(self):
    method start (line 238) | def start(self, data=None, broker=None):
    method stop (line 257) | def stop(self):
    method put_notification (line 264) | def put_notification(self, msg, *args, **kwargs):
    method get_notifications (line 267) | def get_notifications(self):
    method get_positions (line 297) | def get_positions(self):
    method get_granularity (line 306) | def get_granularity(self, timeframe, compression):
    method get_instrument (line 309) | def get_instrument(self, dataname):
    method streaming_events (line 319) | def streaming_events(self, tmout=None):
    method _t_streaming_listener (line 332) | def _t_streaming_listener(self, q, tmout=None):
    method _t_streaming_events (line 337) | def _t_streaming_events(self, q, tmout=None):
    method candles (line 348) | def candles(self, dataname, dtbegin, dtend, timeframe, compression,
    method _t_candles (line 359) | def _t_candles(self, dataname, dtbegin, dtend, timeframe, compression,
    method streaming_prices (line 391) | def streaming_prices(self, dataname, tmout=None):
    method _t_streaming_prices (line 399) | def _t_streaming_prices(self, dataname, q, tmout):
    method get_cash (line 409) | def get_cash(self):
    method get_value (line 412) | def get_value(self):
    method broker_threads (line 422) | def broker_threads(self):
    method _t_account (line 442) | def _t_account(self):
    method order_create (line 465) | def order_create(self, order, stopside=None, takeside=None, **kwargs):
    method _t_order_create (line 502) | def _t_order_create(self):
    method order_cancel (line 549) | def order_cancel(self, order):
    method _t_order_cancel (line 553) | def _t_order_cancel(self):
    method _transaction (line 572) | def _transaction(self, trans):
    method _process_transaction (line 631) | def _process_transaction(self, oid, trans):

FILE: backtrader/stores/vchartfile.py
  class VChartFile (line 29) | class VChartFile(bt.Store):
    method __init__ (line 44) | def __init__(self):
    method _find_vchart (line 50) | def _find_vchart():
    method get_datapath (line 86) | def get_datapath(self):

FILE: backtrader/stores/vcstore.py
  class _SymInfo (line 41) | class _SymInfo(object):
    method __init__ (line 46) | def __init__(self, syminfo):
  function PumpEvents (line 56) | def PumpEvents(timeout=-1, hevt=None, cb=None):
  class RTEventSink (line 148) | class RTEventSink(object):
    method __init__ (line 149) | def __init__(self, store):
    method OnNewTicks (line 154) | def OnNewTicks(self, ArrayTicks):
    method OnServerShutDown (line 157) | def OnServerShutDown(self):
    method OnInternalEvent (line 160) | def OnInternalEvent(self, p1, p2, p3):
  class MetaSingleton (line 173) | class MetaSingleton(MetaParams):
    method __init__ (line 175) | def __init__(cls, name, bases, dct):
    method __call__ (line 179) | def __call__(cls, *args, **kwargs):
  class VCStore (line 187) | class VCStore(with_metaclass(MetaSingleton, object)):
    method getdata (line 215) | def getdata(cls, *args, **kwargs):
    method getbroker (line 220) | def getbroker(cls, *args, **kwargs):
    method find_vchart (line 242) | def find_vchart(self):
    method _load_comtypes (line 288) | def _load_comtypes(self):
    method __init__ (line 303) | def __init__(self):
    method put_notification (line 373) | def put_notification(self, msg, *args, **kwargs):
    method get_notifications (line 376) | def get_notifications(self):
    method start (line 381) | def start(self, data=None, broker=None):
    method stop (line 396) | def stop(self):
    method connected (line 399) | def connected(self):
    method _start_vcrt (line 402) | def _start_vcrt(self):
    method _vcrt_connection (line 411) | def _vcrt_connection(self, status):
    method _tf2ct (line 428) | def _tf2ct(self, timeframe, compression):
    method _ticking (line 433) | def _ticking(self, timeframe):
    method _getq (line 438) | def _getq(self, data):
    method _delq (line 444) | def _delq(self, q):
    method _rtdata (line 448) | def _rtdata(self, data, symbol):
    method _t_rtdata (line 455) | def _t_rtdata(self, data, symbol):
    method _symboldata (line 465) | def _symboldata(self, symbol):
    method _canceldirectdata (line 479) | def _canceldirectdata(self, q):
    method _directdata (line 482) | def _directdata(self, data,
    method _t_directdata (line 499) | def _t_directdata(self, data,
    method _t_broker (line 539) | def _t_broker(self, broker):

FILE: backtrader/strategies/sma_crossover.py
  class MA_CrossOver (line 29) | class MA_CrossOver(bt.Strategy):
    method __init__ (line 62) | def __init__(self):
    method next (line 68) | def next(self):

FILE: backtrader/strategy.py
  class MetaStrategy (line 43) | class MetaStrategy(StrategyBase.__class__):
    method __new__ (line 46) | def __new__(meta, name, bases, dct):
    method __init__ (line 57) | def __init__(cls, name, bases, dct):
    method donew (line 68) | def donew(cls, *args, **kwargs):
    method dopreinit (line 77) | def dopreinit(cls, _obj, *args, **kwargs):
    method dopostinit (line 98) | def dopostinit(cls, _obj, *args, **kwargs):
  class Strategy (line 107) | class Strategy(with_metaclass(MetaStrategy, StrategyBase)):
    method qbuffer (line 120) | def qbuffer(self, savemem=0, replaying=False):
    method _periodset (line 155) | def _periodset(self):
    method _addwriter (line 217) | def _addwriter(self, writer):
    method _addindicator (line 225) | def _addindicator(self, indcls, *indargs, **indkwargs):
    method _addanalyzer_slave (line 228) | def _addanalyzer_slave(self, ancls, *anargs, **ankwargs):
    method _getanalyzer_slave (line 240) | def _getanalyzer_slave(self, idx):
    method _addanalyzer (line 243) | def _addanalyzer(self, ancls, *anargs, **ankwargs):
    method _addobserver (line 250) | def _addobserver(self, multi, obscls, *obsargs, **obskwargs):
    method _getminperstatus (line 268) | def _getminperstatus(self):
    method prenext_open (line 274) | def prenext_open(self):
    method nextstart_open (line 277) | def nextstart_open(self):
    method next_open (line 280) | def next_open(self):
    method _oncepost_open (line 283) | def _oncepost_open(self):
    method _oncepost (line 292) | def _oncepost(self, dt):
    method _clk_update (line 320) | def _clk_update(self):
    method _next_open (line 337) | def _next_open(self):
    method _next (line 346) | def _next(self):
    method _next_observers (line 355) | def _next_observers(self, minperstatus, once=False):
    method _next_analyzers (line 381) | def _next_analyzers(self, minperstatus, once=False):
    method _settz (line 390) | def _settz(self, tz):
    method _start (line 393) | def _start(self):
    method start (line 415) | def start(self):
    method getwriterheaders (line 419) | def getwriterheaders(self):
    method getwritervalues (line 437) | def getwritervalues(self):
    method getwriterinfo (line 452) | def getwriterinfo(self):
    method _stop (line 482) | def _stop(self):
    method stop (line 491) | def stop(self):
    method set_tradehistory (line 495) | def set_tradehistory(self, onoff=True):
    method clear (line 498) | def clear(self):
    method _addnotification (line 503) | def _addnotification(self, order, quicknotify=False):
    method _notify (line 577) | def _notify(self, qorders=[], qtrades=[]):
    method add_timer (line 615) | def add_timer(self, when,
    method notify_timer (line 715) | def notify_timer(self, timer, when, *args, **kwargs):
    method notify_cashvalue (line 726) | def notify_cashvalue(self, cash, value):
    method notify_fund (line 732) | def notify_fund(self, cash, value, fundvalue, shares):
    method notify_order (line 738) | def notify_order(self, order):
    method notify_trade (line 744) | def notify_trade(self, trade):
    method notify_store (line 750) | def notify_store(self, msg, *args, **kwargs):
    method notify_data (line 754) | def notify_data(self, data, status, *args, **kwargs):
    method getdatanames (line 758) | def getdatanames(self):
    method getdatabyname (line 764) | def getdatabyname(self, name):
    method cancel (line 770) | def cancel(self, order):
    method buy (line 774) | def buy(self, data=None,
    method sell (line 943) | def sell(self, data=None,
    method close (line 973) | def close(self, data=None, size=None, **kwargs):
    method buy_bracket (line 1001) | def buy_bracket(self, data=None, size=None, price=None, plimit=None,
    method sell_bracket (line 1175) | def sell_bracket(self, data=None,
    method order_target_size (line 1247) | def order_target_size(self, data=None, target=0, **kwargs):
    method order_target_value (line 1283) | def order_target_value(self, data=None, target=0.0, price=None, **kwar...
    method order_target_percent (line 1330) | def order_target_percent(self, data=None, target=0.0, **kwargs):
    method getposition (line 1378) | def getposition(self, data=None, broker=None):
    method getpositionbyname (line 1392) | def getpositionbyname(self, name=None, broker=None):
    method getpositions (line 1406) | def getpositions(self, broker=None):
    method getpositionsbyname (line 1419) | def getpositionsbyname(self, broker=None):
    method _addsizer (line 1438) | def _addsizer(self, sizer, *args, **kwargs):
    method setsizer (line 1444) | def setsizer(self, sizer):
    method getsizer (line 1452) | def getsizer(self):
    method getsizing (line 1463) | def getsizing(self, data=None, isbuy=True):
  class MetaSigStrategy (line 1472) | class MetaSigStrategy(Strategy.__class__):
    method __new__ (line 1474) | def __new__(meta, name, bases, dct):
    method dopreinit (line 1485) | def dopreinit(cls, _obj, *args, **kwargs):
    method dopostinit (line 1505) | def dopostinit(cls, _obj, *args, **kwargs):
  class SignalStrategy (line 1524) | class SignalStrategy(with_metaclass(MetaSigStrategy, Strategy)):
    method _start (line 1612) | def _start(self):
    method signal_add (line 1616) | def signal_add(self, sigtype, signal):
    method _notify (line 1619) | def _notify(self, qorders=[], qtrades=[]):
    method _next_catch (line 1630) | def _next_catch(self):
    method _next_signal (line 1635) | def _next_signal(self):

FILE: backtrader/studies/contrib/fractal.py
  class Fractal (line 30) | class Fractal(bt.ind.PeriodN):
    method next (line 52) | def next(self):

FILE: backtrader/talib.py
  class _MetaTALibIndicator (line 65) | class _MetaTALibIndicator(bt.Indicator.__class__):
    method dopostinit (line 71) | def dopostinit(cls, _obj, *args, **kwargs):
  class _TALibIndicator (line 92) | class _TALibIndicator(with_metaclass(_MetaTALibIndicator, bt.Indicator)):
    method _subclass (line 97) | def _subclass(cls, name):
    method oncestart (line 187) | def oncestart(self, start, end):
    method once (line 190) | def once(self, start, end):
    method next (line 212) | def next(self):

FILE: backtrader/timer.py
  class Timer (line 42) | class Timer(with_metaclass(MetaParams, object)):
    method __init__ (line 61) | def __init__(self, *args, **kwargs):
    method start (line 65) | def start(self, data):
    method _reset_when (line 90) | def _reset_when(self, ddate=datetime.min):
    method _check_month (line 96) | def _check_month(self, ddate):
    method _check_week (line 123) | def _check_week(self, ddate=date.min):
    method check (line 150) | def check(self, dt):

FILE: backtrader/trade.py
  class TradeHistory (line 31) | class TradeHistory(AutoOrderedDict):
    method __init__ (line 58) | def __init__(self,
    method __reduce__ (line 74) | def __reduce__(self):
    method doupdate (line 79) | def doupdate(self, order, size, price, commission):
    method datetime (line 89) | def datetime(self, tz=None, naive=True):
  class Trade (line 94) | class Trade(object):
    method __str__ (line 152) | def __str__(self):
    method __init__ (line 165) | def __init__(self, data=None, tradeid=0, historyon=False,
    method __len__ (line 194) | def __len__(self):
    method __bool__ (line 198) | def __bool__(self):
    method getdataname (line 204) | def getdataname(self):
    method open_datetime (line 208) | def open_datetime(self, tz=None, naive=True):
    method close_datetime (line 214) | def close_datetime(self, tz=None, naive=True):
    method update (line 220) | def update(self, order, size, price, value, commission, pnl,

FILE: backtrader/tradingcal.py
  class TradingCalendarBase (line 47) | class TradingCalendarBase(with_metaclass(MetaParams, object)):
    method _nextday (line 48) | def _nextday(self, day):
    method schedule (line 57) | def schedule(self, day):
    method nextday (line 64) | def nextday(self, day):
    method nextday_week (line 71) | def nextday_week(self, day):
    method last_weekday (line 78) | def last_weekday(self, day):
    method last_monthday (line 87) | def last_monthday(self, day):
    method last_yearday (line 96) | def last_yearday(self, day):
  class TradingCalendar (line 106) | class TradingCalendar(TradingCalendarBase):
    method __init__ (line 146) | def __init__(self):
    method _nextday (line 149) | def _nextday(self, day):
    method schedule (line 164) | def schedule(self, day, tz=None):
  class PandasMarketCalendar (line 197) | class PandasMarketCalendar(TradingCalendarBase):
    method __init__ (line 229) | def __init__(self):
    method _nextday (line 241) | def _nextday(self, day):
    method schedule (line 259) | def schedule(self, day, tz=None):

FILE: backtrader/utils/autodict.py
  function Tree (line 29) | def Tree():
  class AutoDictList (line 33) | class AutoDictList(dict):
    method __missing__ (line 34) | def __missing__(self, key):
  class DotDict (line 39) | class DotDict(dict):
    method __getattr__ (line 41) | def __getattr__(self, key):
  class AutoDict (line 47) | class AutoDict(dict):
    method _close (line 50) | def _close(self):
    method _open (line 56) | def _open(self):
    method __missing__ (line 59) | def __missing__(self, key):
    method __getattr__ (line 66) | def __getattr__(self, key):
    method __setattr__ (line 72) | def __setattr__(self, key, value):
  class AutoOrderedDict (line 80) | class AutoOrderedDict(OrderedDict):
    method _close (line 83) | def _close(self):
    method _open (line 89) | def _open(self):
    method __missing__ (line 92) | def __missing__(self, key):
    method __getattr__ (line 100) | def __getattr__(self, key):
    method __setattr__ (line 106) | def __setattr__(self, key, value):
    method __iadd__ (line 114) | def __iadd__(self, other):
    method __isub__ (line 120) | def __isub__(self, other):
    method __imul__ (line 126) | def __imul__(self, other):
    method __idiv__ (line 132) | def __idiv__(self, other):
    method __itruediv__ (line 138) | def __itruediv__(self, other):
    method lvalues (line 144) | def lvalues(self):

FILE: backtrader/utils/dateintern.py
  function tzparse (line 48) | def tzparse(tz):
  function Localizer (line 73) | def Localizer(tz):
  class _UTC (line 87) | class _UTC(datetime.tzinfo):
    method utcoffset (line 90) | def utcoffset(self, dt):
    method tzname (line 93) | def tzname(self, dt):
    method dst (line 96) | def dst(self, dt):
    method localize (line 99) | def localize(self, dt):
  class _LocalTimezone (line 103) | class _LocalTimezone(datetime.tzinfo):
    method utcoffset (line 105) | def utcoffset(self, dt):
    method dst (line 111) | def dst(self, dt):
    method tzname (line 117) | def tzname(self, dt):
    method _isdst (line 120) | def _isdst(self, dt):
    method localize (line 132) | def localize(self, dt):
  function num2date (line 149) | def num2date(x, tz=None, naive=True):
  function num2dt (line 194) | def num2dt(num, tz=None, naive=True):
  function num2time (line 198) | def num2time(num, tz=None, naive=True):
  function date2num (line 202) | def date2num(dt, tz=None):
  function time2num (line 230) | def time2num(tm):

FILE: backtrader/utils/flushfile.py
  class flushfile (line 27) | class flushfile(object):
    method __init__ (line 29) | def __init__(self, f):
    method write (line 32) | def write(self, x):
    method flush (line 36) | def flush(self):
  class StdOutDevNull (line 44) | class StdOutDevNull(object):
    method __init__ (line 46) | def __init__(self):
    method write (line 50) | def write(self, x):
    method flush (line 53) | def flush(self):
    method stop (line 56) | def stop(self):

FILE: backtrader/utils/ordereddefaultdict.py
  class OrderedDefaultdict (line 31) | class OrderedDefaultdict(OrderedDict):
    method __init__ (line 32) | def __init__(self, *args, **kwargs):
    method __missing__ (line 42) | def __missing__(self, key):
    method __reduce__ (line 48) | def __reduce__(self):  # optional, for pickle support

FILE: backtrader/utils/py3.py
  function iterkeys (line 61) | def iterkeys(d): return d.iterkeys()
  function itervalues (line 63) | def itervalues(d): return d.itervalues()
  function iteritems (line 65) | def iteritems(d): return d.iteritems()
  function keys (line 67) | def keys(d): return d.keys()
  function values (line 69) | def values(d): return d.values()
  function items (line 71) | def items(d): return d.items()
  function cmp (line 96) | def cmp(a, b): return (a > b) - (a < b)
  function bytes (line 98) | def bytes(x): return x.encode('utf-8')
  function bstr (line 100) | def bstr(x): return str(x)
  function iterkeys (line 108) | def iterkeys(d): return iter(d.keys())
  function itervalues (line 110) | def itervalues(d): return iter(d.values())
  function iteritems (line 112) | def iteritems(d): return iter(d.items())
  function keys (line 114) | def keys(d): return list(d.keys())
  function values (line 116) | def values(d): return list(d.values())
  function items (line 118) | def items(d): return list(d.items())
  function with_metaclass (line 124) | def with_metaclass(meta, *bases):

FILE: backtrader/writer.py
  class WriterBase (line 39) | class WriterBase(with_metaclass(bt.MetaParams, object)):
  class WriterFile (line 43) | class WriterFile(WriterBase):
    method __init__ (line 108) | def __init__(self):
    method _start_output (line 113) | def _start_output(self):
    method start (line 126) | def start(self):
    method stop (line 133) | def stop(self):
    method next (line 137) | def next(self):
    method addheaders (line 142) | def addheaders(self, headers):
    method addvalues (line 146) | def addvalues(self, values):
    method writeiterable (line 152) | def writeiterable(self, iterable, func=None, counter=''):
    method writeline (line 162) | def writeline(self, line):
    method writelines (line 165) | def writelines(self, lines):
    method writelineseparator (line 169) | def writelineseparator(self, level=0):
    method writedict (line 177) | def writedict(self, dct, level=0, recurse=False):
  class WriterStringIO (line 221) | class WriterStringIO(WriterFile):
    method __init__ (line 224) | def __init__(self):
    method _start_output (line 227) | def _start_output(self):
    method stop (line 231) | def stop(self):

FILE: contrib/samples/pair-trading/pair-trading.py
  class PairTradingStrategy (line 20) | class PairTradingStrategy(bt.Strategy):
    method log (line 35) | def log(self, txt, dt=None):
    method notify_order (line 41) | def notify_order(self, order):
    method __init__ (line 60) | def __init__(self):
    method next (line 82) | def next(self):
    method stop (line 156) | def stop(self):
  function runstrategy (line 163) | def runstrategy():
  function parse_args (line 212) | def parse_args():

FILE: contrib/utils/influxdb-import.py
  class InfluxDBTool (line 15) | class InfluxDBTool(object):
    method __init__ (line 16) | def __init__(self):
    method write_dataframe_to_idb (line 29) | def write_dataframe_to_idb(self, ticker):
    method get_tickers_from_file (line 51) | def get_tickers_from_file(self, filename):

FILE: contrib/utils/iqfeed-to-influxdb.py
  class IQFeedTool (line 17) | class IQFeedTool(object):
    method __init__ (line 18) | def __init__(self):
    method _send_cmd (line 59) | def _send_cmd(self, cmd: str):
    method iq_query (line 63) | def iq_query(self, message: str):
    method get_historical_minute_data (line 92) | def get_historical_minute_data(self, ticker: str):
    method add_data_to_df (line 120) | def add_data_to_df(self, data: np.array):
    method get_tickers_from_file (line 144) | def get_tickers_from_file(self, filename):

FILE: samples/analyzer-annualreturn/analyzer-annualreturn.py
  class LongShortStrategy (line 35) | class LongShortStrategy(bt.Strategy):
    method start (line 49) | def start(self):
    method stop (line 52) | def stop(self):
    method log (line 55) | def log(self, txt, dt=None):
    method __init__ (line 61) | def __init__(self):
    method next (line 71) | def next(self):
    method notify_order (line 92) | def notify_order(self, order):
    method notify_trade (line 111) | def notify_trade(self, trade):
  function runstrategy (line 120) | def runstrategy():
  function parse_args (line 181) | def parse_args():

FILE: samples/bidask-to-ohlc/bidask-to-ohlc.py
  class St (line 31) | class St(bt.Strategy):
    method next (line 32) | def next(self):
  function runstrat (line 40) | def runstrat():
  function parse_args (line 70) | def parse_args():

FILE: samples/bracket/bracket.py
  class St (line 31) | class St(bt.Strategy):
    method notify_order (line 44) | def notify_order(self, order):
    method __init__ (line 56) | def __init__(self):
    method next (line 65) | def next(self):
  function runstrat (line 126) | def runstrat(args=None):
  function parse_args (line 161) | def parse_args(pargs=None):

FILE: samples/btfd/btfd.py
  class ValueUnlever (line 34) | class ValueUnlever(bt.observers.Value):
    method next (line 39) | def next(self):
  class St (line 51) | class St(bt.Strategy):
    method __init__ (line 62) | def __init__(self):
    method next (line 72) | def next(self):
    method start (line 94) | def start(self):
    method notify_order (line 104) | def notify_order(self, order):
    method notify_trade (line 118) | def notify_trade(self, trade):
  function runstrat (line 142) | def runstrat(args=None):
  function parse_args (line 183) | def parse_args(pargs=None):

FILE: samples/calendar-days/calendar-days.py
  function runstrat (line 33) | def runstrat():
  function parse_args (line 79) | def parse_args():

FILE: samples/calmar/calmar-test.py
  class St (line 31) | class St(bt.SignalStrategy):
    method __init__ (line 35) | def __init__(self):
    method next2 (line 39) | def next2(self):
  function runstrat (line 43) | def runstrat(args=None):
  function parse_args (line 83) | def parse_args(pargs=None):

FILE: samples/cheat-on-open/cheat-on-open.py
  class St (line 30) | class St(bt.Strategy):
    method __init__ (line 36) | def __init__(self):
    method notify_order (line 42) | def notify_order(self, order):
    method operate (line 52) | def operate(self, fromopen):
    method next (line 65) | def next(self):
    method next_open (line 75) | def next_open(self):
  function runstrat (line 81) | def runstrat(args=None):
  function parse_args (line 116) | def parse_args(pargs=None):

FILE: samples/commission-schemes/commission-schemes.py
  class SMACrossOver (line 32) | class SMACrossOver(bt.Strategy):
    method log (line 38) | def log(self, txt, dt=None):
    method notify_order (line 43) | def notify_order(self, order):
    method notify_trade (line 63) | def notify_trade(self, trade):
    method __init__ (line 68) | def __init__(self):
    method next (line 73) | def next(self):
  function runstrategy (line 83) | def runstrategy():
  function parse_args (line 129) | def parse_args():

FILE: samples/credit-interest/credit-interest.py
  class SMACrossOver (line 32) | class SMACrossOver(bt.Signal):
    method __init__ (line 35) | def __init__(self):
  class NoExit (line 41) | class NoExit(bt.Signal):
    method next (line 42) | def next(self):
  class St (line 46) | class St(bt.SignalStrategy):
    method notify_order (line 49) | def notify_order(self, order):
    method notify_trade (line 58) | def notify_trade(self, trade):
  function runstrat (line 64) | def runstrat(args=None):
  function parse_args (line 121) | def parse_args(pargs=None):

FILE: samples/data-bid-ask/bidask.py
  class BidAskCSV (line 31) | class BidAskCSV(btfeeds.GenericCSVData):
  class St (line 43) | class St(bt.Strategy):
    method __init__ (line 46) | def __init__(self):
    method next (line 50) | def next(self):
  function parse_args (line 60) | def parse_args():
  function runstrategy (line 85) | def runstrategy():

FILE: samples/data-filler/data-filler.py
  function runstrategy (line 37) | def runstrategy():
  function parse_args (line 95) | def parse_args():

FILE: samples/data-filler/relativevolume.py
  class RelativeVolume (line 29) | class RelativeVolume(bt.Indicator):
    method __init__ (line 38) | def __init__(self):

FILE: samples/data-multitimeframe/data-multitimeframe.py
  class SMAStrategy (line 34) | class SMAStrategy(bt.Strategy):
    method __init__ (line 40) | def __init__(self):
    method prenext (line 48) | def prenext(self):
    method nextstart (line 51) | def nextstart(self):
    method next (line 58) | def next(self):
  function runstrat (line 93) | def runstrat():
  function parse_args (line 174) | def parse_args():

FILE: samples/data-pandas/data-pandas-optix.py
  class PandasDataOptix (line 32) | class PandasDataOptix(btfeeds.PandasData):
  class StrategyOptix (line 45) | class StrategyOptix(bt.Strategy):
    method next (line 47) | def next(self):
  function runstrat (line 55) | def runstrat():
  function parse_args (line 95) | def parse_args():

FILE: samples/data-pandas/data-pandas.py
  function runstrat (line 32) | def runstrat():
  function parse_args (line 77) | def parse_args():

FILE: samples/data-replay/data-replay.py
  class SMAStrategy (line 31) | class SMAStrategy(bt.Strategy):
    method __init__ (line 37) | def __init__(self):
    method start (line 40) | def start(self):
    method prenext (line 43) | def prenext(self):
    method next (line 47) | def next(self):
  function runstrat (line 52) | def runstrat():
  function parse_args (line 96) | def parse_args():

FILE: samples/data-resample/data-resample.py
  function runstrat (line 30) | def runstrat():
  function parse_args (line 74) | def parse_args():

FILE: samples/daysteps/daysteps.py
  class St (line 29) | class St(bt.Strategy):
    method __init__ (line 32) | def __init__(self):
    method start (line 35) | def start(self):
    method next (line 52) | def next(self):
  function runstrat (line 74) | def runstrat():
  function parse_args (line 91) | def parse_args(pargs=None):

FILE: samples/future-spot/future-spot.py
  function close_changer (line 30) | def close_changer(data, *args, **kwargs):
  class BuySellArrows (line 36) | class BuySellArrows(bt.observers.BuySell):
  class St (line 41) | class St(bt.Strategy):
    method __init__ (line 42) | def __init__(self):
    method next (line 46) | def next(self):
  function runstrat (line 57) | def runstrat(args=None):
  function parse_args (line 85) | def parse_args(pargs=None):

FILE: samples/gold-vs-sp500/gold-vs-sp500.py
  class PearsonR (line 35) | class PearsonR(bt.ind.PeriodN):
    method next (line 41) | def next(self):
  class MACrossOver (line 48) | class MACrossOver(bt.Strategy):
    method __init__ (line 55) | def __init__(self):
  function runstrat (line 61) | def runstrat(args=None):
  function parse_args (line 115) | def parse_args(pargs=None):

FILE: samples/ib-cash-bid-ask/ib-cash-bid-ask.py
  class St (line 34) | class St(bt.Strategy):
    method logdata (line 35) | def logdata(self):
    method notify_data (line 52) | def notify_data(self, data, status, *args, **kwargs):
    method next (line 67) | def next(self):
  function run (line 83) | def run(args=None):

FILE: samples/ibtest/ibtest.py
  class TestStrategy (line 32) | class TestStrategy(bt.Strategy):
    method __init__ (line 51) | def __init__(self):
    method notify_data (line 66) | def notify_data(self, data, status, *args, **kwargs):
    method notify_store (line 72) | def notify_store(self, msg, *args, **kwargs):
    method notify_order (line 75) | def notify_order(self, order):
    method notify_trade (line 83) | def notify_trade(self, trade):
    method prenext (line 88) | def prenext(self):
    method next (line 91) | def next(self, frompre=False):
    method start (line 199) | def start(self):
  function runstrategy (line 211) | def runstrategy():
  function parse_args (line 342) | def parse_args():

FILE: samples/kselrsi/ksignal.py
  class TheStrategy (line 30) | class TheStrategy(bt.SignalStrategy):
    method notify_order (line 34) | def notify_order(self, order):
    method __init__ (line 44) | def __init__(self):
  function runstrat (line 62) | def runstrat(pargs=None):
  function parse_args (line 87) | def parse_args(pargs=None):

FILE: samples/lineplotter/lineplotter.py
  class St (line 30) | class St(bt.Strategy):
    method __init__ (line 35) | def __init__(self):
  function runstrat (line 45) | def runstrat(pargs=None):
  function parse_args (line 75) | def parse_args(pargs=None):

FILE: samples/lrsi/lrsi-test.py
  class St (line 31) | class St(bt.Strategy):
    method __init__ (line 35) | def __init__(self):
    method next (line 42) | def next(self):
  function runstrat (line 46) | def runstrat(args=None):
  function parse_args (line 81) | def parse_args(pargs=None):

FILE: samples/macd-settings/macd-settings.py
  class FixedPerc (line 34) | class FixedPerc(bt.Sizer):
    method _getsizing (line 45) | def _getsizing(self, comminfo, cash, data, isbuy):
  class TheStrategy (line 54) | class TheStrategy(bt.Strategy):
    method notify_order (line 85) | def notify_order(self, order):
    method __init__ (line 92) | def __init__(self):
    method start (line 108) | def start(self):
    method next (line 111) | def next(self):
  function runstrat (line 140) | def runstrat(args=None):
  function parse_args (line 206) | def parse_args(pargs=None):

FILE: samples/memory-savings/memory-savings.py
  class TestInd (line 33) | class TestInd(bt.Indicator):
    method __init__ (line 36) | def __init__(self):
  class St (line 41) | class St(bt.Strategy):
    method __init__ (line 47) | def __init__(self):
    method next (line 55) | def next(self):
    method loglendetails (line 65) | def loglendetails(self, msg):
    method stop (line 69) | def stop(self):
    method rindicator (line 101) | def rindicator(self, ind, i, deep):
  function runstrat (line 123) | def runstrat():
  function parse_args (line 137) | def parse_args():

FILE: samples/mixing-timeframes/mixing-timeframes.py
  class St (line 32) | class St(bt.Strategy):
    method __init__ (line 35) | def __init__(self):
    method next (line 45) | def next(self):
  function runstrat (line 58) | def runstrat():
  function parse_args (line 73) | def parse_args():

FILE: samples/multi-copy/multi-copy.py
  class TheStrategy (line 32) | class TheStrategy(bt.Strategy):
    method notify_order (line 55) | def notify_order(self, order):
    method __init__ (line 70) | def __init__(self):
    method start (line 87) | def start(self):
    method next (line 94) | def next(self):
  class TheStrategy2 (line 124) | class TheStrategy2(TheStrategy):
  function runstrat (line 139) | def runstrat(args=None):
  function parse_args (line 193) | def parse_args(pargs=None):

FILE: samples/multi-example/mult-values.py
  class TestSizer (line 31) | class TestSizer(bt.Sizer):
    method _getsizing (line 34) | def _getsizing(self, comminfo, cash, data, isbuy):
  class St (line 43) | class St(bt.Strategy):
    method notify_order (line 54) | def notify_order(self, order):
    method __init__ (line 73) | def __init__(self):
    method next (line 77) | def next(self):
  function runstrat (line 130) | def runstrat(args=None):
  function parse_args (line 175) | def parse_args(pargs=None):

FILE: samples/multidata-strategy/multidata-strategy-unaligned.py
  class MultiDataStrategy (line 33) | class MultiDataStrategy(bt.Strategy):
    method log (line 50) | def log(self, txt, dt=None):
    method notify_order (line 56) | def notify_order(self, order):
    method __init__ (line 75) | def __init__(self):
    method next (line 84) | def next(self):
    method stop (line 108) | def stop(self):
  function runstrategy (line 115) | def runstrategy():
  function parse_args (line 164) | def parse_args():

FILE: samples/multidata-strategy/multidata-strategy.py
  class MultiDataStrategy (line 33) | class MultiDataStrategy(bt.Strategy):
    method log (line 50) | def log(self, txt, dt=None):
    method notify_order (line 56) | def notify_order(self, order):
    method __init__ (line 75) | def __init__(self):
    method next (line 84) | def next(self):
    method stop (line 110) | def stop(self):
  function runstrategy (line 117) | def runstrategy():
  function parse_args (line 166) | def parse_args():

FILE: samples/multitrades/mtradeobserver.py
  class MTradeObserver (line 29) | class MTradeObserver(bt.observer.Observer):
    method next (line 40) | def next(self):

FILE: samples/multitrades/multitrades.py
  class MultiTradeStrategy (line 36) | class MultiTradeStrategy(bt.Strategy):
    method log (line 50) | def log(self, txt, dt=None):
    method __init__ (line 56) | def __init__(self):
    method next (line 71) | def next(self):
    method notify_order (line 94) | def notify_order(self, order):
    method notify_trade (line 113) | def notify_trade(self, trade):
  function runstrategy (line 122) | def runstrategy():
  function parse_args (line 168) | def parse_args():

FILE: samples/oandatest/oandatest.py
  class TestStrategy (line 36) | class TestStrategy(bt.Strategy):
    method __init__ (line 50) | def __init__(self):
    method notify_data (line 65) | def notify_data(self, data, status, *args, **kwargs):
    method notify_store (line 71) | def notify_store(self, msg, *args, **kwargs):
    method notify_order (line 74) | def notify_order(self, order):
    method notify_trade (line 82) | def notify_trade(self, trade):
    method prenext (line 87) | def prenext(self):
    method next (line 90) | def next(self, frompre=False):
    method start (line 179) | def start(self):
  function runstrategy (line 191) | def runstrategy():
  function parse_args (line 321) | def parse_args(pargs=None):

FILE: samples/observer-benchmark/observer-benchmark.py
  class St (line 32) | class St(bt.Strategy):
    method __init__ (line 39) | def __init__(self):
    method start (line 43) | def start(self):
    method next (line 56) | def next(self):
  function runstrat (line 95) | def runstrat(args=None):
  function parse_args (line 142) | def parse_args(pargs=None):

FILE: samples/observers/observers-default-drawdown.py
  class MyStrategy (line 36) | class MyStrategy(bt.Strategy):
    method log (line 39) | def log(self, txt, dt=None):
    method __init__ (line 46) | def __init__(self):
    method next (line 57) | def next(self):
  function runstrat (line 73) | def runstrat():

FILE: samples/observers/observers-orderobserver.py
  class MyStrategy (line 33) | class MyStrategy(bt.Strategy):
    method log (line 40) | def log(self, txt, dt=None):
    method notify_order (line 47) | def notify_order(self, order):
    method __init__ (line 74) | def __init__(self):
    method next (line 85) | def next(self):
  function runstrat (line 104) | def runstrat():

FILE: samples/observers/orderobserver.py
  class OrderObserver (line 29) | class OrderObserver(bt.observer.Observer):
    method next (line 39) | def next(self):

FILE: samples/oco/oco.py
  class St (line 31) | class St(bt.Strategy):
    method notify_order (line 46) | def notify_order(self, order):
    method __init__ (line 58) | def __init__(self):
    method next (line 72) | def next(self):
  function runstrat (line 122) | def runstrat(args=None):
  function parse_args (line 157) | def parse_args(pargs=None):

FILE: samples/optimization/optimization.py
  class OptimizeStrategy (line 35) | class OptimizeStrategy(bt.Strategy):
    method __init__ (line 42) | def __init__(self):
  function runstrat (line 51) | def runstrat():
  function parse_args (line 104) | def parse_args():

FILE: samples/order-close/close-daily.py
  class St (line 34) | class St(bt.Strategy):
    method __init__ (line 35) | def __init__(self):
    method notify_order (line 38) | def notify_order(self, order):
    method next (line 49) | def next(self):
  class SessionEndFiller (line 64) | class SessionEndFiller(with_metaclass(bt.metabase.MetaParams, object)):
    method __call__ (line 76) | def __call__(self, data):
  function runstrat (line 91) | def runstrat():
  function getdata (line 103) | def getdata(args):
  function parse_args (line 141) | def parse_args():

FILE: samples/order-close/close-minute.py
  class St (line 31) | class St(bt.Strategy):
    method __init__ (line 32) | def __init__(self):
    method notify_order (line 37) | def notify_order(self, order):
    method next (line 47) | def next(self):
  function runstrat (line 64) | def runstrat():
  function getdata (line 76) | def getdata(args):
  function parse_args (line 110) | def parse_args():

FILE: samples/order-execution/order-execution.py
  class OrderExecutionStrategy (line 36) | class OrderExecutionStrategy(bt.Strategy):
    method log (line 45) | def log(self, txt, dt=None):
    method notify_order (line 52) | def notify_order(self, order):
    method __init__ (line 79) | def __init__(self):
    method next (line 90) | def next(self):
  function runstrat (line 164) | def runstrat():
  function getdata (line 186) | def getdata(args):
  function parse_args (line 215) | def parse_args():

FILE: samples/order-history/order-history.py
  class SmaCross (line 61) | class SmaCross(bt.SignalStrategy):
    method notify_order (line 64) | def notify_order(self, order):
    method notify_trade (line 71) | def notify_trade(self, trade):
    method __init__ (line 75) | def __init__(self):
  class St (line 83) | class St(bt.Strategy):
    method notify_order (line 87) | def notify_order(self, order):
    method notify_trade (line 94) | def notify_trade(self, trade):
    method __init__ (line 98) | def __init__(self):
    method next (line 102) | def next(self):
  function runstrat (line 106) | def runstrat(args=None):
  function parse_args (line 148) | def parse_args(pargs=None):

FILE: samples/order_target/order_target.py
  class TheStrategy (line 30) | class TheStrategy(bt.Strategy):
    method notify_order (line 56) | def notify_order(self, order):
    method start (line 63) | def start(self):
    method next (line 66) | def next(self):
  function runstrat (line 115) | def runstrat(args=None):
  function parse_args (line 148) | def parse_args(pargs=None):

FILE: samples/partial-plot/partial-plot.py
  class St (line 31) | class St(bt.Strategy):
    method __init__ (line 35) | def __init__(self):
    method next (line 45) | def next(self):
  function runstrat (line 49) | def runstrat(args=None):
  function parse_args (line 86) | def parse_args(pargs=None):

FILE: samples/pinkfish-challenge/pinkfish-challenge.py
  class DayStepsCloseFilter (line 31) | class DayStepsCloseFilter(bt.with_metaclass(bt.MetaParams, object)):
    method __init__ (line 52) | def __init__(self, data):
    method __call__ (line 55) | def __call__(self, data):
    method last (line 82) | def last(self, data):
  class DayStepsReplayFilter (line 95) | class DayStepsReplayFilter(bt.with_metaclass(bt.MetaParams, object)):
    method __init__ (line 118) | def __init__(self, data):
    method __call__ (line 122) | def __call__(self, data):
  class St (line 169) | class St(bt.Strategy):
    method __init__ (line 176) | def __init__(self):
    method start (line 179) | def start(self):
    method notify_order (line 202) | def notify_order(self, order):
    method next (line 208) | def next(self):
  function runstrat (line 244) | def runstrat():
  function parse_args (line 290) | def parse_args(pargs=None):

FILE: samples/pivot-point/pivotpoint.py
  class PivotPoint1 (line 27) | class PivotPoint1(bt.Indicator):
    method __init__ (line 30) | def __init__(self):
  class PivotPoint (line 46) | class PivotPoint(bt.Indicator):
    method __init__ (line 50) | def __init__(self):

FILE: samples/pivot-point/ppsample.py
  class St (line 31) | class St(bt.Strategy):
    method __init__ (line 35) | def __init__(self):
    method next (line 39) | def next(self):
  function runstrat (line 51) | def runstrat():
  function parse_args (line 67) | def parse_args():

FILE: samples/plot-same-axis/plot-same-axis.py
  class PlotStrategy (line 33) | class PlotStrategy(bt.Strategy):
    method __init__ (line 46) | def __init__(self):
  function runstrategy (line 66) | def runstrategy():
  function parse_args (line 101) | def parse_args():

FILE: samples/psar/psar-intraday.py
  class St (line 31) | class St(bt.Strategy):
    method __init__ (line 35) | def __init__(self):
    method next (line 40) | def next(self):
  function runstrat (line 58) | def runstrat(args=None):
  function parse_args (line 98) | def parse_args(pargs=None):

FILE: samples/psar/psar.py
  class St (line 31) | class St(bt.Strategy):
    method __init__ (line 35) | def __init__(self):
    method next (line 39) | def next(self):
  function runstrat (line 46) | def runstrat(args=None):
  function parse_args (line 81) | def parse_args(pargs=None):

FILE: samples/pyfolio2/pyfoliotest.py
  class St (line 33) | class St(bt.SignalStrategy):
    method __init__ (line 42) | def __init__(self):
    method start (line 51) | def start(self):
    method next (line 65) | def next(self):
  function runstrat (line 94) | def runstrat(args=None):
  function parse_args (line 185) | def parse_args(pargs=None):

FILE: samples/pyfoliotest/pyfoliotest.py
  class St (line 32) | class St(bt.Strategy):
    method __init__ (line 38) | def __init__(self):
    method start (line 41) | def start(self):
    method next (line 54) | def next(self):
  function runstrat (line 85) | def runstrat(args=None):
  function parse_args (line 142) | def parse_args(args=None):

FILE: samples/relative-volume/relative-volume.py
  function runstrategy (line 34) | def runstrategy():
  function parse_args (line 78) | def parse_args():

FILE: samples/relative-volume/relvolbybar.py
  class RelativeVolumeByBar (line 32) | class RelativeVolumeByBar(bt.Indicator):
    method _plotlabel (line 42) | def _plotlabel(self):
    method __init__ (line 49) | def __init__(self):
    method _barisvalid (line 64) | def _barisvalid(self, tm):
    method _daycount (line 67) | def _daycount(self):
    method prenext (line 73) | def prenext(self):
    method next (line 81) | def next(self):
    method _calcbuffer (line 104) | def _calcbuffer(self):

FILE: samples/renko/renko.py
  class St (line 30) | class St(bt.Strategy):
    method __init__ (line 34) | def __init__(self):
    method next (line 38) | def next(self):
  function runstrat (line 42) | def runstrat(args=None):
  function parse_args (line 91) | def parse_args(pargs=None):

FILE: samples/resample-tickdata/resample-tickdata.py
  function runstrat (line 30) | def runstrat():
  function parse_args (line 78) | def parse_args():

FILE: samples/rollover/rollover.py
  class TheStrategy (line 33) | class TheStrategy(bt.Strategy):
    method start (line 34) | def start(self):
    method next (line 39) | def next(self):
  function checkdate (line 56) | def checkdate(dt, d):
  function checkvolume (line 88) | def checkvolume(d0, d1):
  function runstrat (line 92) | def runstrat(args=None):
  function parse_args (line 129) | def parse_args(pargs=None):

FILE: samples/sharpe-timereturn/sharpe-timereturn.py
  function runstrat (line 30) | def runstrat(pargs=None):
  function parse_args (line 99) | def parse_args(pargs=None):

FILE: samples/signals-strategy/signals-strategy.py
  class SMACloseSignal (line 43) | class SMACloseSignal(bt.Indicator):
    method __init__ (line 47) | def __init__(self):
  class SMAExitSignal (line 51) | class SMAExitSignal(bt.Indicator):
    method __init__ (line 55) | def __init__(self):
  function runstrat (line 61) | def runstrat(args=None):
  function parse_args (line 99) | def parse_args(pargs=None):

FILE: samples/sigsmacross/sigsmacross.py
  class SmaCross (line 30) | class SmaCross(bt.SignalStrategy):
    method notify_order (line 33) | def notify_order(self, order):
    method notify_trade (line 42) | def notify_trade(self, trade):
    method __init__ (line 46) | def __init__(self):
  function runstrat (line 53) | def runstrat(pargs=None):
  function parse_args (line 73) | def parse_args(pargs=None):

FILE: samples/sigsmacross/sigsmacross2.py
  class SmaCross (line 25) | class SmaCross(bt.SignalStrategy):
    method __init__ (line 26) | def __init__(self):

FILE: samples/sizertest/sizertest.py
  class CloseSMA (line 31) | class CloseSMA(bt.Strategy):
    method __init__ (line 34) | def __init__(self):
    method next (line 38) | def next(self):
  class LongOnly (line 46) | class LongOnly(bt.Sizer):
    method _getsizing (line 49) | def _getsizing(self, comminfo, cash, data, isbuy):
  class FixedReverser (line 61) | class FixedReverser(bt.Sizer):
    method _getsizing (line 64) | def _getsizing(self, comminfo, cash, data, isbuy):
  function runstrat (line 70) | def runstrat(args=None):
  function parse_args (line 104) | def parse_args(pargs=None):

FILE: samples/slippage/slippage.py
  class SMACrossOver (line 32) | class SMACrossOver(bt.Indicator):
    method __init__ (line 36) | def __init__(self):
  class SlipSt (line 42) | class SlipSt(bt.SignalStrategy):
    method notify_order (line 45) | def notify_order(self, order):
  function runstrat (line 55) | def runstrat(args=None):
  function parse_args (line 104) | def parse_args(pargs=None):

FILE: samples/sratio/sratio.py
  function average (line 18) | def average(x):
  function variance (line 22) | def variance(x):
  function standarddev (line 27) | def standarddev(x):
  function run (line 31) | def run(pargs=None):
  function parse_args (line 50) | def parse_args(pargs=None):

FILE: samples/stop-trading/stop-loss-approaches.py
  class BaseStrategy (line 30) | class BaseStrategy(bt.Strategy):
    method __init__ (line 36) | def __init__(self):
  class ManualStopOrStopTrail (line 44) | class ManualStopOrStopTrail(BaseStrategy):
    method notify_order (line 50) | def notify_order(self, order):
    method next (line 67) | def next(self):
  class ManualStopOrStopTrailCheat (line 73) | class ManualStopOrStopTrailCheat(BaseStrategy):
    method __init__ (line 79) | def __init__(self):
    method notify_order (line 83) | def notify_order(self, order):
    method next (line 94) | def next(self):
  class AutoStopOrStopTrail (line 107) | class AutoStopOrStopTrail(BaseStrategy):
    method notify_order (line 116) | def notify_order(self, order):
    method next (line 132) | def next(self):
  function runstrat (line 165) | def runstrat(args=None):
  function parse_args (line 200) | def parse_args(pargs=None):

FILE: samples/stoptrail/trail.py
  class St (line 30) | class St(bt.Strategy):
    method __init__ (line 41) | def __init__(self):
    method next (line 46) | def next(self):
  function runstrat (line 89) | def runstrat(args=None):
  function parse_args (line 124) | def parse_args(pargs=None):

FILE: samples/strategy-selection/strategy-selection.py
  class St0 (line 29) | class St0(bt.SignalStrategy):
    method __init__ (line 30) | def __init__(self):
  class St1 (line 36) | class St1(bt.SignalStrategy):
    method __init__ (line 37) | def __init__(self):
  class StFetcher (line 43) | class StFetcher(object):
    method __new__ (line 46) | def __new__(cls, *args, **kwargs):
  function runstrat (line 53) | def runstrat(pargs=None):
  function parse_args (line 71) | def parse_args(pargs=None):

FILE: samples/talib/tablibsartest.py
  class TALibStrategy (line 30) | class TALibStrategy(bt.Strategy):
    method __init__ (line 31) | def __init__(self):
  function runstrat (line 36) | def runstrat(args=None):
  function parse_args (line 64) | def parse_args(pargs=None):

FILE: samples/talib/talibtest.py
  class TALibStrategy (line 30) | class TALibStrategy(bt.Strategy):
    method __init__ (line 37) | def __init__(self):
  function runstrat (line 117) | def runstrat(args=None):
  function parse_args (line 146) | def parse_args(pargs=None):

FILE: samples/timers/scheduled-min.py
  class St (line 30) | class St(bt.Strategy):
    method __init__ (line 43) | def __init__(self):
    method prenext (line 71) | def prenext(self):
    method next (line 74) | def next(self):
    method notify_timer (line 84) | def notify_timer(self, timer, when, *args, **kwargs):
    method notify_order (line 93) | def notify_order(self, order):
  function runstrat (line 99) | def runstrat(args=None):
  function parse_args (line 138) | def parse_args(pargs=None):

FILE: samples/timers/scheduled.py
  class St (line 30) | class St(bt.Strategy):
    method __init__ (line 40) | def __init__(self):
    method prenext (line 59) | def prenext(self):
    method next (line 62) | def next(self):
    method notify_timer (line 72) | def notify_timer(self, timer, when, *args, **kwargs):
    method notify_order (line 80) | def notify_order(self, order):
  function runstrat (line 86) | def runstrat(args=None):
  function parse_args (line 126) | def parse_args(pargs=None):

FILE: samples/tradingcalendar/tcal-intra.py
  class NYSE_2016 (line 30) | class NYSE_2016(bt.TradingCalendar):
  class St (line 52) | class St(bt.Strategy):
    method __init__ (line 56) | def __init__(self):
    method prenext (line 59) | def prenext(self):
    method next (line 62) | def next(self):
  function runstrat (line 76) | def runstrat(args=None):
  function parse_args (line 127) | def parse_args(pargs=None):

FILE: samples/tradingcalendar/tcal.py
  class NYSE_2016 (line 30) | class NYSE_2016(bt.TradingCalendar):
  class St (line 46) | class St(bt.Strategy):
    method __init__ (line 50) | def __init__(self):
    method start (line 53) | def start(self):
    method stop (line 56) | def stop(self):
    method prenext (line 60) | def prenext(self):
    method next (line 63) | def next(self):
  function runstrat (line 77) | def runstrat(args=None):
  function parse_args (line 126) | def parse_args(pargs=None):

FILE: samples/vctest/vctest.py
  class TestStrategy (line 33) | class TestStrategy(bt.Strategy):
    method __init__ (line 47) | def __init__(self):
    method notify_data (line 62) | def notify_data(self, data, status, *args, **kwargs):
    method notify_store (line 68) | def notify_store(self, msg, *args, **kwargs):
    method notify_order (line 71) | def notify_order(self, order):
    method notify_trade (line 79) | def notify_trade(self, trade):
    method prenext (line 84) | def prenext(self):
    method next (line 87) | def next(self, frompre=False):
    method start (line 147) | def start(self):
  function runstrategy (line 155) | def runstrategy():
  function parse_args (line 268) | def parse_args():

FILE: samples/volumefilling/volumefilling.py
  class St (line 34) | class St(bt.Strategy):
    method notify_order (line 40) | def notify_order(self, order):
    method __init__ (line 50) | def __init__(self):
    method start (line 53) | def start(self):
    method next (line 68) | def next(self):
  function runstrat (line 100) | def runstrat():
  function parse_args (line 133) | def parse_args():

FILE: samples/vwr/vwr.py
  function runstrat (line 36) | def runstrat(pargs=None):
  function parse_args (line 106) | def parse_args(pargs=None):

FILE: samples/weekdays-filler/weekdaysaligner.py
  class St (line 36) | class St(bt.Strategy):
    method __init__ (line 39) | def __init__(self):
    method next (line 44) | def next(self):
  function runstrat (line 55) | def runstrat():
  function parse_args (line 90) | def parse_args():

FILE: samples/weekdays-filler/weekdaysfiller.py
  class WeekDaysFiller (line 27) | class WeekDaysFiller(object):
    method __init__ (line 33) | def __init__(self, data, fillclose=False):
    method __call__ (line 37) | def __call__(self, data):

FILE: samples/writer-test/writer-test.py
  class LongShortStrategy (line 34) | class LongShortStrategy(bt.Strategy):
    method start (line 48) | def start(self):
    method stop (line 51) | def stop(self):
    method log (line 54) | def log(self, txt, dt=None):
    method __init__ (line 60) | def __init__(self):
    method next (line 70) | def next(self):
    method notify_order (line 91) | def notify_order(self, order):
    method notify_trade (line 110) | def notify_trade(self, trade):
  function runstrategy (line 119) | def runstrategy():
  function parse_args (line 165) | def parse_args():

FILE: samples/yahoo-test/yahoo-test.py
  function runstrat (line 33) | def runstrat():
  function parse_args (line 69) | def parse_args():

FILE: tests/test_analyzer-sqn.py
  class TestStrategy (line 37) | class TestStrategy(bt.Strategy):
    method log (line 46) | def log(self, txt, dt=None, nodate=False):
    method notify_trade (line 54) | def notify_trade(self, trade):
    method notify_order (line 58) | def notify_order(self, order):
    method __init__ (line 84) | def __init__(self):
    method start (line 91) | def start(self):
    method stop (line 108) | def stop(self):
    method next (line 118) | def next(self):
  function test_run (line 154) | def test_run(main=False):

FILE: tests/test_analyzer-timereturn.py
  class TestStrategy (line 37) | class TestStrategy(bt.Strategy):
    method log (line 45) | def log(self, txt, dt=None, nodate=False):
    method notify_order (line 53) | def notify_order(self, order):
    method __init__ (line 79) | def __init__(self):
    method start (line 86) | def start(self):
    method stop (line 102) | def stop(self):
    method next (line 112) | def next(self):
  function test_run (line 147) | def test_run(main=False):

FILE: tests/test_comminfo.py
  function check_stocks (line 30) | def check_stocks():
  function check_futures (line 56) | def check_futures():
  function test_run (line 84) | def test_run(main=False):

FILE: tests/test_data_multiframe.py
  function test_run (line 37) | def test_run(main=False):

FILE: tests/test_data_replay.py
  function test_run (line 40) | def test_run(main=False, exbar=False):

FILE: tests/test_data_resample.py
  function test_run (line 39) | def test_run(main=False):

FILE: tests/test_ind_accdecosc.py
  function test_run (line 37) | def test_run(main=False):

FILE: tests/test_ind_aroonoscillator.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_aroonupdown.py
  function test_run (line 39) | def test_run(main=False):

FILE: tests/test_ind_atr.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_awesomeoscillator.py
  function test_run (line 37) | def test_run(main=False):

FILE: tests/test_ind_bbands.py
  function test_run (line 40) | def test_run(main=False):

FILE: tests/test_ind_cci.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_dema.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_demaenvelope.py
  function test_run (line 40) | def test_run(main=False):

FILE: tests/test_ind_demaosc.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_dm.py
  function test_run (line 41) | def test_run(main=False):

FILE: tests/test_ind_dma.py
  function test_run (line 39) | def test_run(main=False):

FILE: tests/test_ind_downmove.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_dpo.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_dv2.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_ema.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_emaenvelope.py
  function test_run (line 40) | def test_run(main=False):

FILE: tests/test_ind_emaosc.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_envelope.py
  class TS2 (line 40) | class TS2(testcommon.TestStrategy):
    method __init__ (line 41) | def __init__(self):
  function test_run (line 47) | def test_run(main=False):

FILE: tests/test_ind_heikinashi.py
  function test_run (line 40) | def test_run(main=False):

FILE: tests/test_ind_highest.py
  function test_run (line 39) | def test_run(main=False):

FILE: tests/test_ind_hma.py
  function test_run (line 39) | def test_run(main=False):

FILE: tests/test_ind_ichimoku.py
  function test_run (line 42) | def test_run(main=False):

FILE: tests/test_ind_kama.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_kamaenvelope.py
  function test_run (line 40) | def test_run(main=False):

FILE: tests/test_ind_kamaosc.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_kst.py
  function test_run (line 39) | def test_run(main=False):

FILE: tests/test_ind_lowest.py
  function test_run (line 39) | def test_run(main=False):

FILE: tests/test_ind_lrsi.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_macdhisto.py
  function test_run (line 40) | def test_run(main=False):

FILE: tests/test_ind_minperiod.py
  function test_run (line 37) | def test_run(main=False):

FILE: tests/test_ind_momentum.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_momentumoscillator.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_oscillator.py
  class TS2 (line 38) | class TS2(testcommon.TestStrategy):
    method __init__ (line 39) | def __init__(self):
  function test_run (line 45) | def test_run(main=False):

FILE: tests/test_ind_pctchange.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_pctrank.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_pgo.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_ppo.py
  function test_run (line 40) | def test_run(main=False):

FILE: tests/test_ind_pposhort.py
  function test_run (line 40) | def test_run(main=False):

FILE: tests/test_ind_priceosc.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_rmi.py
  function test_run (line 37) | def test_run(main=False):

FILE: tests/test_ind_roc.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_rsi.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_rsi_safe.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_sma.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_smaenvelope.py
  function test_run (line 40) | def test_run(main=False):

FILE: tests/test_ind_smaosc.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_smma.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_smmaenvelope.py
  function test_run (line 40) | def test_run(main=False):

FILE: tests/test_ind_smmaosc.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_stochastic.py
  function test_run (line 39) | def test_run(main=False):

FILE: tests/test_ind_stochasticfull.py
  function test_run (line 40) | def test_run(main=False):

FILE: tests/test_ind_sumn.py
  function test_run (line 39) | def test_run(main=False):

FILE: tests/test_ind_tema.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_temaenvelope.py
  function test_run (line 40) | def test_run(main=False):

FILE: tests/test_ind_temaosc.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_trix.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_tsi.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_ultosc.py
  function test_run (line 37) | def test_run(main=False):

FILE: tests/test_ind_upmove.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_vortex.py
  function test_run (line 39) | def test_run(main=False):

FILE: tests/test_ind_williamsad.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_williamsr.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_wma.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_wmaenvelope.py
  function test_run (line 40) | def test_run(main=False):

FILE: tests/test_ind_wmaosc.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_zlema.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_ind_zlind.py
  function test_run (line 38) | def test_run(main=False):

FILE: tests/test_metaclass.py
  class TestFrompackages (line 23) | class TestFrompackages(testcommon.SampleParamsHolder):
    method __init__ (line 29) | def __init__(self):
  function test_run (line 33) | def test_run(main=False):

FILE: tests/test_order.py
  class FakeCommInfo (line 28) | class FakeCommInfo(object):
    method getvaluesize (line 29) | def getvaluesize(self, size, price):
    method profitandloss (line 32) | def profitandloss(self, size, price, newprice):
    method getoperationcost (line 35) | def getoperationcost(self, size, price):
    method getcommission (line 38) | def getcommission(self, size, price):
  class FakeData (line 42) | class FakeData(object):
    method __len__ (line 47) | def __len__(self):
    method datetime (line 51) | def datetime(self):
    method close (line 55) | def close(self):
  function _execute (line 59) | def _execute(position, order, size, price, partial):
  function test_run (line 87) | def test_run(main=False):

FILE: tests/test_position.py
  function test_run (line 30) | def test_run(main=False):

FILE: tests/test_strategy_optimized.py
  class TestStrategy (line 63) | class TestStrategy(bt.Strategy):
    method log (line 70) | def log(self, txt, dt=None):
    method __init__ (line 75) | def __init__(self):
    method start (line 82) | def start(self):
    method stop (line 87) | def stop(self):
    method next (line 104) | def next(self):
  function test_run (line 121) | def test_run(main=False):

FILE: tests/test_strategy_unoptimized.py
  class TestStrategy (line 56) | class TestStrategy(bt.Strategy):
    method log (line 64) | def log(self, txt, dt=None, nodate=False):
    method notify_order (line 72) | def notify_order(self, order):
    method __init__ (line 98) | def __init__(self):
    method start (line 105) | def start(self):
    method stop (line 121) | def stop(self):
    method next (line 151) | def next(self):
  function test_run (line 186) | def test_run(main=False):

FILE: tests/test_study_fractal.py
  function test_run (line 39) | def test_run(main=False):

FILE: tests/test_trade.py
  class FakeCommInfo (line 30) | class FakeCommInfo(object):
    method getvaluesize (line 31) | def getvaluesize(self, size, price):
    method profitandloss (line 34) | def profitandloss(self, size, price, newprice):
  class FakeData (line 38) | class FakeData(object):
    method __len__ (line 43) | def __len__(self):
    method datetime (line 47) | def datetime(self):
    method close (line 51) | def close(self):
  function test_run (line 55) | def test_run(main=False):

FILE: tests/test_writer.py
  class TestStrategy (line 35) | class TestStrategy(bt.Strategy):
    method __init__ (line 38) | def __init__(self):
  function test_run (line 42) | def test_run(main=False):

FILE: tests/testcommon.py
  function getdata (line 50) | def getdata(index, fromdate=FROMDATE, todate=TODATE):
  function runtest (line 61) | def runtest(datas,
  class TestStrategy (line 120) | class TestStrategy(bt.Strategy):
    method __init__ (line 129) | def __init__(self):
    method prenext (line 151) | def prenext(self):
    method nextstart (line 154) | def nextstart(self):
    method next (line 158) | def next(self):
    method start (line 169) | def start(self):
    method stop (line 172) | def stop(self):
  class SampleParamsHolder (line 226) | class SampleParamsHolder(ParamsBase):
    method __init__ (line 236) | def __init__(self):

FILE: tools/rewrite-data.py
  class RewriteStrategy (line 50) | class RewriteStrategy(bt.Strategy):
    method start (line 56) | def start(self):
    method next (line 70) | def next(self):
  function runstrat (line 96) | def runstrat(pargs=None):
  function parse_args (line 141) | def parse_args(pargs=None):

FILE: tools/yahoodownload.py
  class YahooDownload (line 47) | class YahooDownload(object):
    method __init__ (line 52) | def __init__(self, ticker, fromdate, todate, period='d', reverse=False):
    method writetofile (line 146) | def writetofile(self, filename):
  function parse_args (line 163) | def parse_args():
Condensed preview — 378 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (7,195K chars).
[
  {
    "path": ".github/FUNDING.yml",
    "chars": 720,
    "preview": "# These are supported funding model platforms\n\ngithub: mementum # Replace with up to 4 GitHub Sponsors-enabled usernames"
  },
  {
    "path": ".gitignore",
    "chars": 796,
    "preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\n"
  },
  {
    "path": ".travis.yml",
    "chars": 368,
    "preview": "dist: xenial\nlanguage: python\npython:\n  - \"3.6\"\n  - \"3.7\"\n  - \"3.8\"\n  - \"nightly\"\n  - \"pypy\"\n  - \"pypy3\"\n\nmatrix:\n  allo"
  },
  {
    "path": "LICENSE",
    "chars": 35121,
    "preview": "GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation,"
  },
  {
    "path": "README.rst",
    "chars": 5409,
    "preview": "backtrader\n==========\n\n.. image:: https://img.shields.io/pypi/v/backtrader.svg\n   :alt: PyPi Version\n   :scale: 100%\n   "
  },
  {
    "path": "backtrader/__init__.py",
    "chars": 2578,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzer.py",
    "chars": 14440,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/__init__.py",
    "chars": 1527,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/annualreturn.py",
    "chars": 2818,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/calmar.py",
    "chars": 3821,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/drawdown.py",
    "chars": 6513,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/leverage.py",
    "chars": 2397,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/logreturnsrolling.py",
    "chars": 5020,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/periodstats.py",
    "chars": 3555,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/positions.py",
    "chars": 2790,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/pyfolio.py",
    "chars": 5933,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/returns.py",
    "chars": 4698,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/sharpe.py",
    "chars": 7383,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/sqn.py",
    "chars": 2623,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/timereturn.py",
    "chars": 5210,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/tradeanalyzer.py",
    "chars": 7116,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/transactions.py",
    "chars": 3562,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/analyzers/vwr.py",
    "chars": 5460,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/broker.py",
    "chars": 5504,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/brokers/__init__.py",
    "chars": 1548,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/brokers/bbroker.py",
    "chars": 46016,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/brokers/ibbroker.py",
    "chars": 21489,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/brokers/oandabroker.py",
    "chars": 12811,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/brokers/vcbroker.py",
    "chars": 15907,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/btrun/__init__.py",
    "chars": 1044,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/btrun/btrun.py",
    "chars": 25093,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/cerebro.py",
    "chars": 63590,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/comminfo.py",
    "chars": 11691,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/commissions/__init__.py",
    "chars": 1796,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/dataseries.py",
    "chars": 6498,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/errors.py",
    "chars": 1890,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feed.py",
    "chars": 26027,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/__init__.py",
    "chars": 1674,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/blaze.py",
    "chars": 2877,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/btcsv.py",
    "chars": 2266,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/chainer.py",
    "chars": 3489,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/csvgeneric.py",
    "chars": 5624,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/ibdata.py",
    "chars": 27438,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/influxfeed.py",
    "chars": 4060,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/mt4csv.py",
    "chars": 1704,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/oanda.py",
    "chars": 16545,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/pandafeed.py",
    "chars": 8735,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/quandl.py",
    "chars": 6851,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/rollover.py",
    "chars": 6892,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/sierrachart.py",
    "chars": 1420,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/vcdata.py",
    "chars": 22443,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/vchart.py",
    "chars": 4598,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/vchartcsv.py",
    "chars": 2777,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/vchartfile.py",
    "chars": 4662,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/feeds/yahoo.py",
    "chars": 10867,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/fillers.py",
    "chars": 3754,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/filters/__init__.py",
    "chars": 1242,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/filters/bsplitter.py",
    "chars": 3932,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/filters/calendardays.py",
    "chars": 3933,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/filters/datafiller.py",
    "chars": 6343,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/filters/datafilter.py",
    "chars": 2743,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/filters/daysteps.py",
    "chars": 3135,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/filters/heikinashi.py",
    "chars": 1944,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/filters/renko.py",
    "chars": 4627,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/filters/session.py",
    "chars": 8533,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/flt.py",
    "chars": 1512,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/functions.py",
    "chars": 7219,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicator.py",
    "chars": 5584,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/__init__.py",
    "chars": 2548,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/accdecoscillator.py",
    "chars": 2166,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/aroon.py",
    "chars": 6378,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/atr.py",
    "chars": 3661,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/awesomeoscillator.py",
    "chars": 2173,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/basicops.py",
    "chars": 13527,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/bollinger.py",
    "chars": 2713,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/cci.py",
    "chars": 2416,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/contrib/__init__.py",
    "chars": 1158,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/contrib/vortex.py",
    "chars": 1953,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/crossover.py",
    "chars": 4245,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/dema.py",
    "chars": 2843,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/deviation.py",
    "chars": 3596,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/directionalmove.py",
    "chars": 13343,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/dma.py",
    "chars": 2873,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/dpo.py",
    "chars": 2401,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/dv2.py",
    "chars": 1781,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/ema.py",
    "chars": 2025,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/envelope.py",
    "chars": 3996,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/hadelta.py",
    "chars": 2282,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/heikinashi.py",
    "chars": 2419,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/hma.py",
    "chars": 2579,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/hurst.py",
    "chars": 3307,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/ichimoku.py",
    "chars": 3138,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/kama.py",
    "chars": 3378,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/kst.py",
    "chars": 3008,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/lrsi.py",
    "chars": 3556,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/mabase.py",
    "chars": 2719,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/macd.py",
    "chars": 2837,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/momentum.py",
    "chars": 3525,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/ols.py",
    "chars": 3987,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/oscillator.py",
    "chars": 4050,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/percentchange.py",
    "chars": 1605,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/percentrank.py",
    "chars": 1410,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/pivotpoint.py",
    "chars": 9353,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/prettygoodoscillator.py",
    "chars": 2262,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/priceoscillator.py",
    "chars": 3801,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/psar.py",
    "chars": 5931,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/rmi.py",
    "chars": 2474,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/rsi.py",
    "chars": 6813,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/sma.py",
    "chars": 1665,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/smma.py",
    "chars": 2190,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/stochastic.py",
    "chars": 4869,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/trix.py",
    "chars": 2947,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/tsi.py",
    "chars": 2660,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/ultimateoscillator.py",
    "chars": 2913,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/vortex.py",
    "chars": 1888,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/williams.py",
    "chars": 3038,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/wma.py",
    "chars": 2088,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/zlema.py",
    "chars": 1880,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/indicators/zlind.py",
    "chars": 3192,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/linebuffer.py",
    "chars": 26583,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/lineiterator.py",
    "chars": 15838,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/lineroot.py",
    "chars": 10689,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/lineseries.py",
    "chars": 22007,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/mathsupport.py",
    "chars": 1923,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/metabase.py",
    "chars": 11160,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/observer.py",
    "chars": 2274,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/observers/__init__.py",
    "chars": 1325,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/observers/benchmark.py",
    "chars": 4314,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/observers/broker.py",
    "chars": 3868,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/observers/buysell.py",
    "chars": 3882,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/observers/drawdown.py",
    "chars": 3643,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/observers/logreturns.py",
    "chars": 3234,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/observers/timereturn.py",
    "chars": 3088,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/observers/trades.py",
    "chars": 4983,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/order.py",
    "chars": 21937,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/plot/__init__.py",
    "chars": 1494,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/plot/finance.py",
    "chars": 19346,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/plot/formatters.py",
    "chars": 4042,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/plot/locator.py",
    "chars": 9435,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/plot/multicursor.py",
    "chars": 12231,
    "preview": "# LICENSE AGREEMENT FOR MATPLOTLIB 1.2.0\n# --------------------------------------\n#\n# 1. This LICENSE AGREEMENT is betwe"
  },
  {
    "path": "backtrader/plot/plot.py",
    "chars": 33959,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/plot/scheme.py",
    "chars": 6433,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/plot/utils.py",
    "chars": 2920,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/position.py",
    "chars": 7445,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/resamplerfilter.py",
    "chars": 26141,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/signal.py",
    "chars": 1894,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/signals/__init__.py",
    "chars": 1019,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/sizer.py",
    "chars": 2977,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/sizers/__init__.py",
    "chars": 1208,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/sizers/fixedsize.py",
    "chars": 3486,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/sizers/percents_sizer.py",
    "chars": 2482,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/store.py",
    "chars": 3135,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/stores/__init__.py",
    "chars": 1527,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/stores/ibstore.py",
    "chars": 54280,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/stores/oandastore.py",
    "chars": 22120,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/stores/vchartfile.py",
    "chars": 2700,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/stores/vcstore.py",
    "chars": 19039,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/strategies/__init__.py",
    "chars": 1048,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/strategies/sma_crossover.py",
    "chars": 2197,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/strategy.py",
    "chars": 61718,
    "preview": "#!/usr/bin389/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n###################################################"
  },
  {
    "path": "backtrader/studies/__init__.py",
    "chars": 1053,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/studies/contrib/__init__.py",
    "chars": 1159,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/studies/contrib/fractal.py",
    "chars": 2608,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n\n#####################################################"
  },
  {
    "path": "backtrader/talib.py",
    "chars": 8950,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/timer.py",
    "chars": 7585,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/trade.py",
    "chars": 11662,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/tradingcal.py",
    "chars": 9893,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/utils/__init__.py",
    "chars": 1145,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/utils/autodict.py",
    "chars": 3787,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/utils/date.py",
    "chars": 1319,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/utils/dateintern.py",
    "chars": 6972,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/utils/flushfile.py",
    "chars": 1588,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/utils/ordereddefaultdict.py",
    "chars": 2091,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/utils/py3.py",
    "chars": 3409,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/version.py",
    "chars": 1110,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "backtrader/writer.py",
    "chars": 7688,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n######################################################"
  },
  {
    "path": "changelog.txt",
    "chars": 58797,
    "preview": "1.9.78.123:\n  - PR#479 Fix errors for simulated orders\n1.9.77.123:\n  - PR#472\n    - Added posibitity for Black theme for"
  },
  {
    "path": "contrib/datas/daily-KO.csv",
    "chars": 20045,
    "preview": "Date,Open,High,Low,Close,Volume,Adj Close\n1997-01-02,52.5,52.5,51.125,51.875,7161800,16.206907\n1997-01-03,52.25,53.375,5"
  },
  {
    "path": "contrib/datas/daily-PEP.csv",
    "chars": 19914,
    "preview": "Date,Open,High,Low,Close,Volume,Adj Close\n1997-01-02,30.0,30.0,29.25,29.5,4237700,17.596354\n1997-01-03,29.75,30.0,29.625"
  },
  {
    "path": "contrib/samples/pair-trading/pair-trading.py",
    "chars": 9958,
    "preview": "# coding: utf-8\n# ##################################################################\n# Pair Trading adapted to backtrade"
  },
  {
    "path": "contrib/utils/influxdb-import.py",
    "chars": 4932,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8; py-indent-offset:4 -*-\n\nimport sys\nimport os\nimport io\nimport logging\nimport "
  },
  {
    "path": "contrib/utils/iqfeed-to-influxdb.py",
    "chars": 8744,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8; py-indent-offset:4 -*-\n\nimport sys\nimport os\nimport io\nimport socket\nimport "
  },
  {
    "path": "datas/2005-2006-day-001.txt",
    "chars": 24109,
    "preview": "Date,Open,High,Low,Close,Volume,OpenInterest\n2005-01-03,2952.29,2989.61,2946.80,2970.02,0,0\n2005-01-04,2969.78,2979.88,2"
  },
  {
    "path": "datas/2006-01-02-volume-min-001.txt",
    "chars": 1820067,
    "preview": "Date,Open,High,Low,Close,Volume,OpenInterest\r\n2006-01-02,09:01:00,3602.00,3603.00,3597.00,3599.00,5699,0\r\n2006-01-02,09:"
  },
  {
    "path": "datas/2006-day-001-optix.txt",
    "chars": 15123,
    "preview": "Date,Open,High,Low,Close,Volume,OpenInterest,Optix_Close,Optix_Pess,Optix_Opt\n2006-01-02,3578.73,3605.95,3578.73,3604.33"
  },
  {
    "path": "datas/2006-day-001.txt",
    "chars": 12030,
    "preview": "Date,Open,High,Low,Close,Volume,OpenInterest\n2006-01-02,3578.73,3605.95,3578.73,3604.33,0,0\n2006-01-03,3604.08,3638.42,3"
  },
  {
    "path": "datas/2006-day-002.txt",
    "chars": 6108,
    "preview": "Date,Open,High,Low,Close,Volume,OpenInterest\n2006-01-03,3578.73,3638.42,3578.73,3614.34,0,0\n2006-01-05,3615.23,3661.65,3"
  },
  {
    "path": "datas/2006-min-005.txt",
    "chars": 120002,
    "preview": "Date,Time,Open,High,Low,Close,Volume,OpenInterest\n2006-01-02,09:05:00,3578.73,3587.88,3578.73,3582.99,0,0\n2006-01-02,09:"
  },
  {
    "path": "datas/2006-month-001.txt",
    "chars": 609,
    "preview": "Date,Open,High,Low,Close,Volume,OpenInterest\n2006-01-31,3578.73,3707.63,3515.07,3691.41,0,0\n2006-02-28,3686.16,3840.56,3"
  },
  {
    "path": "datas/2006-volume-day-001.txt",
    "chars": 15130,
    "preview": "Date,Open,High,Low,Close,Volume,OpenInterest\r\n2006-01-02,3602.00,3624.00,3596.00,3617.00,164794,1511674\r\n2006-01-03,3623"
  },
  {
    "path": "datas/2006-week-001.txt",
    "chars": 2489,
    "preview": "Date,Open,High,Low,Close,Volume,OpenInterest\n2006-01-06,3578.73,3666.99,3578.73,3666.99,0,0\n2006-01-13,3667.10,3685.99,3"
  },
  {
    "path": "datas/2006-week-002.txt",
    "chars": 1267,
    "preview": "Date,Open,High,Low,Close,Volume,OpenInterest\n2006-01-13,3578.73,3685.99,3578.73,3629.25,0,0\n2006-01-27,3628.73,3685.48,3"
  },
  {
    "path": "datas/bidask.csv",
    "chars": 358,
    "preview": "TIMESTAMP,BID,ASK\n02/03/2010 16:53:50,0.5346,0.5347\n02/03/2010 16:53:51,0.5343,0.5347\n02/03/2010 16:53:52,0.5543,0.5545\n"
  },
  {
    "path": "datas/bidask2.csv",
    "chars": 543,
    "preview": "TimeStamp,cross,status (\"D\"= dealt) (only trades \"DEALT\"),bid, offer, vol bid, vol offer\n01/03/16,23:43:11,EUR/JPY,D,,13"
  },
  {
    "path": "datas/nvda-1999-2014.txt",
    "chars": 272573,
    "preview": "Date,Open,High,Low,Close,Adj Close,Volume\n1999-01-22,1.750000,1.953125,1.552083,1.640625,1.518424,67867200\n1999-01-25,1."
  },
  {
    "path": "datas/nvda-2014.txt",
    "chars": 17462,
    "preview": "Date,Open,High,Low,Close,Adj Close,Volume\n2014-01-02,15.920000,15.980000,15.720000,15.860000,15.096152,6502300\n2014-01-0"
  },
  {
    "path": "datas/orcl-1995-2014.txt",
    "chars": 345989,
    "preview": "Date,Open,High,Low,Close,Adj Close,Volume\n1995-01-03,2.179012,2.191358,2.117284,2.117284,1.883304,36301200\n1995-01-04,2."
  },
  {
    "path": "datas/orcl-2003-2005.txt",
    "chars": 52877,
    "preview": "Date,Open,High,Low,Close,Adj Close,Volume\n2003-01-02,10.940000,11.250000,10.800000,11.210000,9.971185,32064900\n2003-01-0"
  },
  {
    "path": "datas/orcl-2014.txt",
    "chars": 17638,
    "preview": "Date,Open,High,Low,Close,Adj Close,Volume\n2014-01-02,37.779999,38.029999,37.549999,37.840000,35.166069,18162100\n2014-01-"
  },
  {
    "path": "datas/ticksample.csv",
    "chars": 8207,
    "preview": "Datetime,Open,High,Low,Close,Volume,OpenInterest\n2015-09-23T20:57:42.146,3067.00,3067.00,3067.00,3067.00,180,0\n2015-09-2"
  }
]

// ... and 178 more files (download for full content)

About this extraction

This page contains the full source code of the mementum/backtrader GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 378 files (6.7 MB), approximately 1.8M tokens, and a symbol index with 2596 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!