├── .gitignore ├── .gitmodules ├── COPYING ├── README.md ├── __init__.py ├── distribute_setup.py ├── docs ├── Makefile ├── _build │ ├── doctrees │ │ ├── api.doctree │ │ ├── environment.pickle │ │ ├── finance-concepts.doctree │ │ ├── index.doctree │ │ ├── installation.doctree │ │ ├── modules │ │ │ └── models.doctree │ │ ├── user_guide.doctree │ │ └── userguide │ │ │ ├── admin.doctree │ │ │ ├── getting started.doctree │ │ │ ├── overview.doctree │ │ │ └── uploading transaction files.doctree │ └── html │ │ ├── .buildinfo │ │ ├── _sources │ │ ├── api.txt │ │ ├── finance-concepts.txt │ │ ├── index.txt │ │ ├── installation.txt │ │ ├── modules │ │ │ └── models.txt │ │ ├── user_guide.txt │ │ └── userguide │ │ │ ├── admin.txt │ │ │ ├── getting started.txt │ │ │ ├── overview.txt │ │ │ └── uploading transaction files.txt │ │ ├── _static │ │ ├── agogo.css │ │ ├── basic.css │ │ ├── bgfooter.png │ │ ├── bgtop.png │ │ ├── default.css │ │ ├── doctools.js │ │ ├── file.png │ │ ├── jquery.js │ │ ├── minus.png │ │ ├── plus.png │ │ ├── pygments.css │ │ ├── searchtools.js │ │ ├── sidebar.js │ │ └── underscore.js │ │ ├── api.html │ │ ├── finance-concepts.html │ │ ├── genindex.html │ │ ├── index.html │ │ ├── installation.html │ │ ├── modules │ │ └── models.html │ │ ├── objects.inv │ │ ├── search.html │ │ ├── searchindex.js │ │ ├── user_guide.html │ │ └── userguide │ │ ├── _sources │ │ ├── api.txt │ │ ├── finance-concepts.txt │ │ ├── index.txt │ │ ├── installation.txt │ │ ├── modules │ │ │ └── models.txt │ │ ├── user_guide.txt │ │ └── userguide │ │ │ ├── getting started.txt │ │ │ ├── overview.txt │ │ │ └── uploading transaction files.txt │ │ ├── _static │ │ ├── agogo.css │ │ ├── basic.css │ │ ├── bgfooter.png │ │ ├── bgtop.png │ │ ├── default.css │ │ ├── doctools.js │ │ ├── file.png │ │ ├── jquery.js │ │ ├── minus.png │ │ ├── plus.png │ │ ├── pygments.css │ │ ├── searchtools.js │ │ ├── sidebar.js │ │ └── underscore.js │ │ ├── admin.html │ │ ├── api.html │ │ ├── finance-concepts.html │ │ ├── genindex.html │ │ ├── getting started.html │ │ ├── index.html │ │ ├── installation.html │ │ ├── modules │ │ └── models.html │ │ ├── objects.inv │ │ ├── overview.html │ │ ├── search.html │ │ ├── searchindex.js │ │ ├── uploading transaction files.html │ │ └── user_guide.html ├── conf.py ├── finance-concepts.txt ├── globals.inc ├── index.txt ├── installation.txt ├── make_and_push_docs.sh ├── user_guide.txt ├── userguide │ ├── admin.txt │ ├── getting started.txt │ └── overview.txt └── ~ │ └── Dropbox │ └── Cochrane Davey │ └── Development │ └── openportfoliodocs │ ├── doctrees │ ├── environment.pickle │ ├── finance-concepts.doctree │ ├── index.doctree │ ├── installation.doctree │ ├── user_guide.doctree │ └── userguide │ │ ├── getting started.doctree │ │ ├── overview.doctree │ │ └── uploading transaction files.doctree │ └── html │ ├── .buildinfo │ ├── _sources │ ├── finance-concepts.txt │ ├── index.txt │ ├── installation.txt │ ├── user_guide.txt │ └── userguide │ │ ├── getting started.txt │ │ ├── overview.txt │ │ └── uploading transaction files.txt │ ├── _static │ ├── agogo.css │ ├── basic.css │ ├── bgfooter.png │ ├── bgtop.png │ ├── doctools.js │ ├── file.png │ ├── jquery.js │ ├── minus.png │ ├── plus.png │ ├── pygments.css │ ├── searchtools.js │ └── underscore.js │ ├── finance-concepts.html │ ├── genindex.html │ ├── index.html │ ├── installation.html │ ├── objects.inv │ ├── search.html │ ├── searchindex.js │ ├── user_guide.html │ └── userguide │ ├── getting started.html │ ├── overview.html │ └── uploading transaction files.html ├── fabfile.py ├── manage.py ├── openportfolioapp ├── __init__.py ├── admin.py ├── fixtures │ ├── build_testdata.sh │ └── initial_data.yaml ├── management │ ├── __init__.py │ └── commands │ │ ├── __init__.py │ │ ├── fetch-prices.py │ │ └── openportfolio-update.py ├── migrations │ ├── 0001_initial.py │ └── __init__.py ├── models │ ├── __init__.py │ ├── assetclass.py │ ├── company.py │ ├── currency.py │ ├── datafiles │ │ ├── __init__.py │ │ ├── datadefinition.py │ │ └── tradedatafile.py │ ├── gicssector.py │ ├── interestrate.py │ ├── investment.py │ ├── investments │ │ ├── __init__.py │ │ ├── listedequity.py │ │ └── savingsaccount.py │ ├── portfolio.py │ ├── price.py │ ├── prices │ │ ├── __init__.py │ │ ├── currencyprice.py │ │ ├── investmentprice.py │ │ ├── listedequityprice.py │ │ └── savingsaccountprice.py │ ├── subclassing.py │ ├── trade.py │ └── tradeallocation.py ├── static │ ├── Highcharts │ │ ├── examples │ │ │ ├── analytics.tsv │ │ │ ├── area-basic.htm │ │ │ ├── area-inverted.htm │ │ │ ├── area-missing.htm │ │ │ ├── area-negative.htm │ │ │ ├── area-stacked-percent.htm │ │ │ ├── area-stacked.htm │ │ │ ├── areaspline.htm │ │ │ ├── bar-basic.htm │ │ │ ├── bar-negative-stack.htm │ │ │ ├── bar-stacked.htm │ │ │ ├── column-basic.htm │ │ │ ├── column-drilldown.htm │ │ │ ├── column-negative.htm │ │ │ ├── column-parsed.htm │ │ │ ├── column-rotated-labels.htm │ │ │ ├── column-stacked-and-grouped.htm │ │ │ ├── column-stacked-percent.htm │ │ │ ├── column-stacked.htm │ │ │ ├── combo-dual-axes.htm │ │ │ ├── combo-multi-axes.htm │ │ │ ├── combo-regression.htm │ │ │ ├── combo.htm │ │ │ ├── dynamic-click-to-add.htm │ │ │ ├── dynamic-master-detail.htm │ │ │ ├── dynamic-update.htm │ │ │ ├── line-ajax.htm │ │ │ ├── line-basic.htm │ │ │ ├── line-labels.htm │ │ │ ├── line-time-series.htm │ │ │ ├── pie-basic.htm │ │ │ ├── pie-donut.htm │ │ │ ├── pie-legend.htm │ │ │ ├── scatter.htm │ │ │ ├── spline-inverted.htm │ │ │ ├── spline-irregular-time.htm │ │ │ ├── spline-plot-bands.htm │ │ │ └── spline-symbols.htm │ │ ├── exporting-server │ │ │ └── index.php │ │ ├── graphics │ │ │ ├── skies.jpg │ │ │ ├── snow.png │ │ │ └── sun.png │ │ ├── index.htm │ │ └── js │ │ │ ├── adapters │ │ │ ├── mootools-adapter.js │ │ │ ├── mootools-adapter.src.js │ │ │ ├── prototype-adapter.js │ │ │ └── prototype-adapter.src.js │ │ │ ├── highcharts.js │ │ │ ├── highcharts.src.js │ │ │ ├── modules │ │ │ ├── exporting.js │ │ │ └── exporting.src.js │ │ │ └── themes │ │ │ ├── dark-blue.js │ │ │ ├── dark-green.js │ │ │ ├── gray.js │ │ │ └── grid.js │ ├── Highstock │ │ ├── .DS_Store │ │ ├── examples │ │ │ ├── area │ │ │ │ └── index.htm │ │ │ ├── areaspline │ │ │ │ └── index.htm │ │ │ ├── basic-line │ │ │ │ └── index.htm │ │ │ ├── candlestick-and-volume │ │ │ │ └── index.htm │ │ │ ├── candlestick │ │ │ │ └── index.htm │ │ │ ├── column │ │ │ │ └── index.htm │ │ │ ├── compare │ │ │ │ └── index.htm │ │ │ ├── data-grouping │ │ │ │ └── index.htm │ │ │ ├── dynamic-update │ │ │ │ └── index.htm │ │ │ ├── flags-general │ │ │ │ ├── data.csv │ │ │ │ └── index.htm │ │ │ ├── flags-placement │ │ │ │ └── index.htm │ │ │ ├── flags-shapes │ │ │ │ └── index.htm │ │ │ ├── intraday │ │ │ │ └── index.htm │ │ │ ├── line-markers │ │ │ │ ├── data.csv │ │ │ │ └── index.htm │ │ │ ├── markers-only │ │ │ │ └── index.htm │ │ │ ├── navigator-disabled │ │ │ │ └── index.htm │ │ │ ├── ohlc │ │ │ │ └── index.htm │ │ │ ├── scrollbar-disabled │ │ │ │ └── index.htm │ │ │ ├── spline │ │ │ │ └── index.htm │ │ │ ├── step-line │ │ │ │ └── index.htm │ │ │ ├── styled-scrollbar │ │ │ │ └── index.htm │ │ │ ├── yaxis-plotbands │ │ │ │ └── index.htm │ │ │ ├── yaxis-plotlines │ │ │ │ └── index.htm │ │ │ └── yaxis-reversed │ │ │ │ └── index.htm │ │ ├── exporting-server │ │ │ ├── .DS_Store │ │ │ └── index.php │ │ ├── graphics │ │ │ ├── .DS_Store │ │ │ ├── skies.jpg │ │ │ ├── snow.png │ │ │ └── sun.png │ │ ├── index.htm │ │ └── js │ │ │ ├── .DS_Store │ │ │ ├── adapters │ │ │ ├── .DS_Store │ │ │ ├── mootools-adapter.js │ │ │ ├── mootools-adapter.src.js │ │ │ ├── prototype-adapter.js │ │ │ └── prototype-adapter.src.js │ │ │ ├── highstock.js │ │ │ ├── highstock.src.js │ │ │ ├── modules │ │ │ ├── exporting.js │ │ │ └── exporting.src.js │ │ │ └── themes │ │ │ ├── .DS_Store │ │ │ ├── dark-blue.js │ │ │ ├── dark-green.js │ │ │ ├── gray.js │ │ │ └── grid.js │ └── css │ │ ├── admin │ │ └── openportfolioapp.css │ │ ├── openportfolioapp.css │ │ └── print.css ├── templates │ ├── admin │ │ ├── base_site.html │ │ └── index.html │ ├── base.html │ ├── index.html │ ├── investment │ │ ├── list.html │ │ ├── price_chart.html │ │ ├── price_table.html │ │ └── report.html │ ├── login.html │ ├── logout.html │ └── portfolio │ │ ├── holdings_table.html │ │ ├── list.html │ │ ├── price_chart.html │ │ ├── price_table.html │ │ └── report.html ├── templatetags │ ├── __init__.py │ ├── openportfolioapp_extras.py │ └── pyformat.py ├── urls.py ├── utils │ ├── __init__.py │ ├── currencyhistory.py │ ├── ofx.py │ ├── update_helpers.py │ └── utils.py └── views │ ├── __init__.py │ ├── investment.py │ └── portfolio.py ├── requirements ├── development.txt ├── production.txt └── staging.txt ├── settings.py ├── settings_development.py ├── settings_production.py ├── settings_staging.py ├── setup.py ├── update.sh └── urls.py /.gitignore: -------------------------------------------------------------------------------- 1 | media/* 2 | sphinx/* 3 | docs/doctrees/* 4 | docs/latex/* 5 | datafiles/* 6 | dirhtml/* 7 | openportfolioapp/fixtures/* 8 | <<<<<<< HEAD 9 | initial_data.yaml 10 | ======= 11 | !initial_data.yaml 12 | >>>>>>> develop 13 | !media/admin/* 14 | build 15 | dist 16 | MANIFEST 17 | *.egg-info 18 | distribute-* 19 | *.db 20 | *.pyc 21 | *.swp 22 | install/staging.* 23 | install/production.* 24 | install/development.* 25 | install/org* 26 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "fabtools"] 2 | path = fabtools 3 | url = git@github.com:evandavey/FabTools.git 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Open Portfolio 2 | 3 | Open source django project for portfolio management. Aims to open up asset management tools used by professional fund managers. 4 | 5 | More information at: [project homepage](http://evandavey.github.io/django-openportfolio/) 6 | 7 | 8 | # License 9 | 10 | [Creative Commons Share Alike Non-Commercial](http://creativecommons.org/licenses/by-nc-sa/2.0/uk/deed.en_GB) 11 | 12 | #Change History 13 | 14 | v0.1: 15 | 16 | * implements basic functionality 17 | - create / edit objects through the django admin interface 18 | - trades can be uploaded as csv or ofx 19 | - portfolios can be grouped and assigned benchmarks 20 | - handles investments and reporting in cross currencies 21 | - management command to download prices, can be run as a scheduled task 22 | - Highcharts price charts for portfolios and investments 23 | - benchmark relative portfolio report showing holdings and returns over time 24 | - investment report showing price chart and other pricing data 25 | - pandas dataframes and panels used in backend giving substantial flexibility for future reporting enhancements (such as risk calculations, risk weighting analysis, gips compliant returns calcs...) 26 | - fifo / lifo trade allocations for profit calculations 27 | 28 | 29 | 30 | 31 | 32 | #Installation 33 | 34 | See [installation](http://evandavey.github.io/django-openportfolio/installation.html) 35 | 36 | #Project documentation 37 | 38 | See [project docs](http://evandavey.github.io/django-openportfolio/) 39 | 40 | 41 | #Author 42 | 43 | Evan Davey, evan.j.davey@gmail.com, www.twitter.com/evanjdavey/ 44 | 45 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/__init__.py -------------------------------------------------------------------------------- /docs/_build/doctrees/api.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/doctrees/api.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/doctrees/environment.pickle -------------------------------------------------------------------------------- /docs/_build/doctrees/finance-concepts.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/doctrees/finance-concepts.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/doctrees/index.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/installation.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/doctrees/installation.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/modules/models.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/doctrees/modules/models.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/user_guide.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/doctrees/user_guide.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/userguide/admin.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/doctrees/userguide/admin.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/userguide/getting started.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/doctrees/userguide/getting started.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/userguide/overview.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/doctrees/userguide/overview.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/userguide/uploading transaction files.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/doctrees/userguide/uploading transaction files.doctree -------------------------------------------------------------------------------- /docs/_build/html/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: 4ea958363fe679cc203eceb179e93fe3 4 | tags: fbb0d17656682115ca4d033fb2f83ba1 5 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/api.txt: -------------------------------------------------------------------------------- 1 | API Documentation 2 | ================= 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | 7 | modules/models 8 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/index.txt: -------------------------------------------------------------------------------- 1 | .. Open Financial Management documentation master file, created by 2 | sphinx-quickstart on Tue Jul 19 13:37:51 2011. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. include:: globals.inc 7 | 8 | 9 | Open Portfolio 10 | ============== 11 | 12 | |project-name| is a django-based portfolio management tool, motivated by tools used by professional fund managers. It can be used to manage and monitor the returns and risks of a portfolio of investments such as listed equities and fixed income securities. Version 1.0 aims to be as user friendly as possible. Nevertheless, experience in Python and django would be beneficial to the user. Please contact the project authors if you would like to contribute to this project. See :doc:`finance-concepts` for a user-friendly overview of financial concepts relevant to portfolio management. 13 | 14 | Main Features 15 | -------------- 16 | 17 | * trade input from csv and ofx files 18 | * price downloads from online sources where possible (downloads can be scheduled) 19 | * investment analysis - return and risk statistics and plots 20 | * portfolio reporting - returns and risk analysis 21 | * cross currency capability 22 | * focus on portfolio cash flows 23 | * aims to be GIPS compliant 24 | 25 | Why? 26 | ----- 27 | 28 | This project aims to make the tools of professional fund managers more open and accessible. Such tools are typically closed source, expensive and inflexible. As an open source platform, |project-name| offers the opportunity for everyday investors to better manage their portfolios - thereby being aware of their risks and having the ability to maximise their returns. 29 | 30 | 31 | The `OpenPortfolio`_ Project is hosted on github. 32 | 33 | 34 | Contents: 35 | 36 | .. toctree:: 37 | :maxdepth: 2 38 | 39 | installation 40 | user_guide 41 | finance-concepts 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/installation.txt: -------------------------------------------------------------------------------- 1 | .. include:: globals.inc 2 | 3 | Installation 4 | ============ 5 | 6 | The easy way... 7 | --------------- 8 | 9 | 10 | 1. Download the fabfile.py from `OpenPortfolio`_ 11 | 12 | 2. Modify the fabfile development settings to suit your requirements 13 | 14 | 3. Bootstrap your system to create a new virtual environment, download the latest stable version, install dependencies and sync the database:: 15 | 16 | $ fab development bootstrap 17 | 18 | 4. Run the development server:: 19 | 20 | $ fab development runserver 21 | 22 | .. note:: This procedure requires git, python, pip, virtualenv, virtualenvwrapper and fabric. See `Preparing your system`_ for further information. The fabfile includes additional commands to deploy to a staging or production environment (running apache2 and passenger) 23 | 24 | The long way... 25 | ---------------- 26 | 27 | Download 28 | ++++++++ 29 | 30 | Download the latest stable version from github 31 | 32 | .. parsed-literal:: 33 | 34 | $ git clone |stable-git-url| |project-name| 35 | 36 | Running on a local development server 37 | +++++++++++++++++++++++++++++++++++++ 38 | 39 | 1. Install the requirements file using pip (a virtual environment is recommended) 40 | 41 | .. parsed-literal:: 42 | 43 | $ cd |project-name| 44 | $ pip install -r requirements/development.txt 45 | 46 | 2. Create and sync the database 47 | 48 | .. parsed-literal:: 49 | 50 | $ ./manage.py syncdb --settings= |project-name|.settings_local 51 | $ ./manage.py migrate --all --settings= |project-name|.settings_local 52 | 53 | 3. Run the development server 54 | 55 | .. parsed-literal:: 56 | 57 | $ ./manage.py runserver 0.0.0.0:8080 --settings= |project-name|.settings_local 58 | 59 | The server can be accessed at: http://127.0.0.0.1:8080 60 | 61 | Preparing your system 62 | --------------------- 63 | 64 | The easy installation procedure assumes a system installed with python, pip, virtualenv, virtualenvwrapper and fabric. 65 | 66 | Git 67 | +++ 68 | 69 | Follow installation instructions at http://git-scm.com/. For Mac OSX, using `HomeBrew `_ is recommended instead. 70 | 71 | 72 | Python 73 | ++++++ 74 | 75 | Python installation is beyond the scope of this document. On unix based systems this should be straight-forward. Mac OS X comes with Python pre-installed. XCode is required and can be installed using the App store. Windows users face a more challenging scenario and should see http://www.python.org for installation instructions. 76 | 77 | 78 | Pip, virtualenv, virtualenvwrapper and fabric 79 | +++++++++++++++++++++++++++++++++++++++++++++ 80 | 81 | 1. Install easy_install by following instructions at http://pypi.python.org/pypi/setuptools 82 | 83 | 2. Install pip:: 84 | 85 | $ easy_install pip 86 | 87 | 3. Use pip to install remaining dependencies:: 88 | 89 | $ pip install virtualenv 90 | $ pip install virtualenvwrapper 91 | $ pip install fabric 92 | 93 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/modules/models.txt: -------------------------------------------------------------------------------- 1 | Models 2 | ================= 3 | 4 | .. automodule:: openportfolioapp.models 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/user_guide.txt: -------------------------------------------------------------------------------- 1 | User Guide 2 | ========== 3 | 4 | .. toctree:: 5 | :numbered: 6 | 7 | userguide/getting started 8 | userguide/admin 9 | 10 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/userguide/admin.txt: -------------------------------------------------------------------------------- 1 | .. include:: ../globals.inc 2 | 3 | Administration 4 | =============== 5 | 6 | Portfolios & Benchmarks 7 | ----------------------- 8 | 9 | 1. Open the Portfolio admin screen 10 | 11 | 2. Select an existing Portfolio to edit it or click to add a new one 12 | 13 | 3. Assign a name to your portfolio or benchmark 14 | 15 | 4. If desired, assign a parent to allow for a portfolio tree 16 | 17 | 5. If you are modifying a benchmark, leave benchmark blank 18 | 19 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/userguide/getting started.txt: -------------------------------------------------------------------------------- 1 | .. include:: ../globals.inc 2 | 3 | Getting Started 4 | =============== 5 | 6 | To use |project-name|, you must first populate the database with some data. 7 | 8 | Step 1 - Use the Admin interface to create some portfolio objects 9 | 10 | Detailed instructions on using this interface can be found here: :doc:`admin`. At a minimum you will need to: 11 | 12 | 1. Create a benchmark portfolio 13 | 14 | 2. Create a portfolio to hold your investments 15 | 16 | 3. Create an asset class and assign it to the benchmark portfolio 17 | 18 | 4. Create a currency eg: GBP 19 | 20 | 5. Create a company 21 | 22 | 6. Create a savings account or listed equity investment and assign it to the company 23 | 24 | 7. Enter portfolio trades 25 | 26 | 8. For savings accounts, you will also need to enter an Interest Rate 27 | 28 | 29 | Step 2 - Download price data 30 | 31 | The best way to perform the initial price data update is using fabric:: 32 | 33 | $ fab development openportfolio-update --initial 34 | 35 | See :doc:`../installation` for more information on how this process can be automated to maintain price data on an ongoing basis. 36 | 37 | The openportfolio-update script will perform a number of tasks: 38 | 39 | * update investment prices an the day specified in Settings 40 | * calculate and save portfolio level data 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/userguide/overview.txt: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | Main Objects 5 | ++++++++++++ 6 | 7 | Companies 8 | --------- 9 | 10 | * companies belong to a GICS Sector 11 | 12 | * companies issue investments 13 | 14 | Investments 15 | ----------- 16 | 17 | * investments belong to a company and an asset class 18 | 19 | * investments can be held by portfolios 20 | 21 | * investments can be transacted by portfolios 22 | 23 | * investments will have a price and dividend history 24 | 25 | * investments can be of type: bank account, savings account, listed equity 26 | 27 | * investments can be assigned to an accounting allocation 28 | 29 | InvestmentTransactions 30 | ---------------------- 31 | 32 | * investment transactions will be: buy, sell. dividend 33 | 34 | * each transaction will have a date, price, transaction cost, payee and memo 35 | 36 | * a transaction will be linked to a portfolio and investment 37 | 38 | Portfolios 39 | ---------- 40 | 41 | * portfolios can have a parent to create a portfolio tree 42 | 43 | * portfolios will hold and transact investments 44 | 45 | 46 | Asset Classes 47 | ------------- 48 | 49 | * each investment will belong to an Asset Class 50 | 51 | * each Asset Class can have a parent, allowing for an asset class tree 52 | 53 | * asset classes are used for portfolio reporting 54 | 55 | 56 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/userguide/uploading transaction files.txt: -------------------------------------------------------------------------------- 1 | Uploading Transaction Files 2 | =========================== 3 | 4 | * Click on InvestmentTransactionDownload 5 | 6 | * Click Add to add a new entry. You will be presented with the following menu. 7 | 8 | .. image:: images/upload_transaction.png 9 | 10 | 1. Choose a file to upload. This can be of type ofx,qfx or csv. For csv, a csv data definition is required. 11 | 12 | 2. Choose an investment to link the transactions to. 13 | 14 | 3. Choose a portfolio to link the transactions to. 15 | 16 | 4. Start date and end date will be automatically set from the data file. 17 | 18 | .. note:: This upload process is currently focussed on bank account and savings account data. Equity transactions are best entered manually. 19 | -------------------------------------------------------------------------------- /docs/_build/html/_static/bgfooter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/html/_static/bgfooter.png -------------------------------------------------------------------------------- /docs/_build/html/_static/bgtop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/html/_static/bgtop.png -------------------------------------------------------------------------------- /docs/_build/html/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/html/_static/file.png -------------------------------------------------------------------------------- /docs/_build/html/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/html/_static/minus.png -------------------------------------------------------------------------------- /docs/_build/html/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/html/_static/plus.png -------------------------------------------------------------------------------- /docs/_build/html/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/html/objects.inv -------------------------------------------------------------------------------- /docs/_build/html/userguide/_sources/api.txt: -------------------------------------------------------------------------------- 1 | API Documentation 2 | ================= 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | 7 | modules/models 8 | -------------------------------------------------------------------------------- /docs/_build/html/userguide/_sources/index.txt: -------------------------------------------------------------------------------- 1 | .. Open Financial Management documentation master file, created by 2 | sphinx-quickstart on Tue Jul 19 13:37:51 2011. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. include:: globals.inc 7 | 8 | 9 | Open Portfolio 10 | ============== 11 | 12 | |project-name| is a django-based portfolio management tool, based on tools used by professional fund managers. It can be used to manage and monitor the returns and risks of a portfolio of investments such as listed equities and fixed income securities. Version 1.0 aims to be as user friendly as possible. Nevertheless, experience in Python and django would be beneficial to the user. Please contact the project authors if you would like to contribute to this project. See :doc:`finance-concepts` for a user-friendly overview of financial concepts relevant to portfolio management. 13 | 14 | Main Features 15 | -------------- 16 | 17 | * trade input from csv and ofx files 18 | * price downloads from online sources where possible (downloads can be scheduled) 19 | * investment analysis - return and risk statistics and plots 20 | * portfolio reporting - returns and risk analysis 21 | * cross currency capability 22 | * focus on portfolio cash flows 23 | * aims to be GIPS compliant 24 | 25 | Why? 26 | ----- 27 | 28 | This project aims to make the tools of professional fund managers more open and accessible. Such tools are typically closed source, expensive and inflexible. As an open source platform, |project-name| offers the opportunity for everyday investors to better manage their portfolios - thereby being aware of their risks and having the ability to maximise their returns. 29 | 30 | 31 | The `OpenPortfolio`_ Project is hosted on github. 32 | 33 | 34 | Contents: 35 | 36 | .. toctree:: 37 | :maxdepth: 2 38 | 39 | installation 40 | user_guide 41 | finance-concepts 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /docs/_build/html/userguide/_sources/installation.txt: -------------------------------------------------------------------------------- 1 | .. include:: globals.inc 2 | 3 | Installation 4 | ============ 5 | 6 | The easy way... 7 | --------------- 8 | 9 | 10 | 1. Download the fabfile.py from `OpenPortfolio` 11 | 12 | 2. Modify the development settings to suit your requirements 13 | 14 | 3. Bootstrap your system to create a new virtual environment, downloaded the latest stable version and install dependencies:: 15 | 16 | $ fab development bootstrap 17 | 18 | 4. Sync then migrate the database:: 19 | 20 | $ fab development syncdb 21 | $ fab development migratedb 22 | 23 | 5. Run the development server:: 24 | 25 | $ fab development runserver 26 | 27 | .. note:: This procedure requires python, pip, virtualenv, virtualenvwrapper and fabric. See `Preparing your system`_ for further information. The fabfile includes additional commands to deploy to a staging or production environment (running apache2 and passenger) 28 | 29 | The long way... 30 | ---------------- 31 | 32 | Download 33 | ++++++++ 34 | 35 | Download the latest stable version from github 36 | 37 | .. parsed-literal:: 38 | 39 | $ git clone |stable-git-url| |project-name| 40 | 41 | Running on a local development server 42 | +++++++++++++++++++++++++++++++++++++ 43 | 44 | 1. Install the requirements file using pip (a virtual environment is recommended) 45 | 46 | .. parsed-literal:: 47 | 48 | $ cd |project-name| 49 | $ pip install -r requirements/development.txt 50 | 51 | 2. Create and sync the database 52 | 53 | .. parsed-literal:: 54 | 55 | $ ./manage.py syncdb --settings= |project-name|.settings_local 56 | $ ./manage.py schememigration |app-name| --settings= |project-name|.settings_local 57 | 58 | 3. Run the development server 59 | 60 | .. parsed-literal:: 61 | 62 | $ ./manage.py runserver 0.0.0.0:8080 --settings= |project-name|.settings_local 63 | 64 | The server can be accessed at: http://127.0.0.0.1:8080 65 | 66 | Preparing your system 67 | --------------------- 68 | 69 | The easy installation procedure assumes a system installed with python, pip, virtualenv, virtualenvwrapper and fabric. 70 | 71 | Python 72 | ++++++ 73 | 74 | Python installation is beyond the scope of this document. On unix based systems this should be straight-forward. Mac OS X comes with Python pre-installed. XCode is required and can be installed using the App store. Windows users face a more challenging scenario and should see http://www.python.org for installation instructions. 75 | 76 | 77 | Pip, virtualenv, virtualenvwrapper and fabric 78 | +++++++++++++++++++++++++++++++++++++++++++++ 79 | 80 | 1. Install easy_install by following instructions at http://pypi.python.org/pypi/setuptools 81 | 82 | 2. Install pip:: 83 | 84 | $ easy_install pip 85 | 86 | 3. Use pip to install remaining dependencies:: 87 | 88 | $ pip install virtualenv 89 | $ pip install virtualenvwrapper 90 | $ pip install fabric 91 | 92 | -------------------------------------------------------------------------------- /docs/_build/html/userguide/_sources/modules/models.txt: -------------------------------------------------------------------------------- 1 | Models 2 | ================= 3 | 4 | .. automodule:: openportfolioapp.models 5 | :members: 6 | 7 | -------------------------------------------------------------------------------- /docs/_build/html/userguide/_sources/user_guide.txt: -------------------------------------------------------------------------------- 1 | User Guide 2 | ========== 3 | 4 | .. toctree:: 5 | :numbered: 6 | 7 | userguide/overview 8 | userguide/getting started 9 | userguide/uploading transaction files 10 | -------------------------------------------------------------------------------- /docs/_build/html/userguide/_sources/userguide/getting started.txt: -------------------------------------------------------------------------------- 1 | Getting Started 2 | =============== 3 | 4 | * The openportfolioapp app runs under django admin 5 | 6 | * Open http:///admin/openportfolioapp/ 7 | 8 | * This will bring up the main menu. From here, you can add data or generate reports by selecting the relevant models. 9 | 10 | .. image:: images/main_menu.png 11 | :alt: Main Menu 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/_build/html/userguide/_sources/userguide/overview.txt: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | Main Objects 5 | ++++++++++++ 6 | 7 | Companies 8 | --------- 9 | 10 | * companies belong to a GICS Sector 11 | 12 | * companies issue investments 13 | 14 | Investments 15 | ----------- 16 | 17 | * investments belong to a company and an asset class 18 | 19 | * investments can be held by portfolios 20 | 21 | * investments can be transacted by portfolios 22 | 23 | * investments will have a price and dividend history 24 | 25 | * investments can be of type: bank account, savings account, listed equity 26 | 27 | * investments can be assigned to an accounting allocation 28 | 29 | InvestmentTransactions 30 | ---------------------- 31 | 32 | * investment transactions will be: buy, sell. dividend 33 | 34 | * each transaction will have a date, price, transaction cost, payee and memo 35 | 36 | * a transaction will be linked to a portfolio and investment 37 | 38 | Portfolios 39 | ---------- 40 | 41 | * portfolios can have a parent to create a portfolio tree 42 | 43 | * portfolios will hold and transact investments 44 | 45 | 46 | Asset Classes 47 | ------------- 48 | 49 | * each investment will belong to an Asset Class 50 | 51 | * each Asset Class can have a parent, allowing for an asset class tree 52 | 53 | * asset classes are used for portfolio reporting 54 | 55 | 56 | -------------------------------------------------------------------------------- /docs/_build/html/userguide/_sources/userguide/uploading transaction files.txt: -------------------------------------------------------------------------------- 1 | Uploading Transaction Files 2 | =========================== 3 | 4 | * Click on InvestmentTransactionDownload 5 | 6 | * Click Add to add a new entry. You will be presented with the following menu. 7 | 8 | .. image:: images/upload_transaction.png 9 | 10 | 1. Choose a file to upload. This can be of type ofx,qfx or csv. For csv, a csv data definition is required. 11 | 12 | 2. Choose an investment to link the transactions to. 13 | 14 | 3. Choose a portfolio to link the transactions to. 15 | 16 | 4. Start date and end date will be automatically set from the data file. 17 | 18 | .. note:: This upload process is currently focussed on bank account and savings account data. Equity transactions are best entered manually. 19 | -------------------------------------------------------------------------------- /docs/_build/html/userguide/_static/bgfooter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/html/userguide/_static/bgfooter.png -------------------------------------------------------------------------------- /docs/_build/html/userguide/_static/bgtop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/html/userguide/_static/bgtop.png -------------------------------------------------------------------------------- /docs/_build/html/userguide/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/html/userguide/_static/file.png -------------------------------------------------------------------------------- /docs/_build/html/userguide/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/html/userguide/_static/minus.png -------------------------------------------------------------------------------- /docs/_build/html/userguide/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/html/userguide/_static/plus.png -------------------------------------------------------------------------------- /docs/_build/html/userguide/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/_build/html/userguide/objects.inv -------------------------------------------------------------------------------- /docs/globals.inc: -------------------------------------------------------------------------------- 1 | .. |project-name| replace:: OpenPortfolio 2 | .. |app-name| replace:: openportfolioapp 3 | .. |stable-git-url| replace:: git://github.com/evandavey/OpenPortfolio.git 4 | 5 | .. _OpenPortfolio: http://github.com/evandavey/OpenPortfolio 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/index.txt: -------------------------------------------------------------------------------- 1 | .. Open Financial Management documentation master file, created by 2 | sphinx-quickstart on Tue Jul 19 13:37:51 2011. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. include:: globals.inc 7 | 8 | 9 | Open Portfolio 10 | ============== 11 | 12 | |project-name| is a django-based portfolio management tool, motivated by tools used by professional fund managers. It can be used to manage and monitor the returns and risks of a portfolio of investments such as listed equities and fixed income securities. Version 1.0 aims to be as user friendly as possible. Nevertheless, experience in Python and django would be beneficial to the user. Please contact the project authors if you would like to contribute to this project. See :doc:`finance-concepts` for a user-friendly overview of financial concepts relevant to portfolio management. 13 | 14 | Main Features 15 | -------------- 16 | 17 | * trade input from csv and ofx files 18 | * price downloads from online sources where possible (downloads can be scheduled) 19 | * investment analysis - return and risk statistics and plots 20 | * portfolio reporting - returns and risk analysis 21 | * cross currency capability 22 | * focus on portfolio cash flows 23 | * aims to be GIPS compliant 24 | 25 | Why? 26 | ----- 27 | 28 | This project aims to make the tools of professional fund managers more open and accessible. Such tools are typically closed source, expensive and inflexible. As an open source platform, |project-name| offers the opportunity for everyday investors to better manage their portfolios - thereby being aware of their risks and having the ability to maximise their returns. 29 | 30 | 31 | The `OpenPortfolio`_ Project is hosted on github. 32 | 33 | 34 | Contents: 35 | 36 | .. toctree:: 37 | :maxdepth: 2 38 | 39 | installation 40 | user_guide 41 | finance-concepts 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /docs/installation.txt: -------------------------------------------------------------------------------- 1 | .. include:: globals.inc 2 | 3 | Installation 4 | ============ 5 | 6 | The easy way... 7 | --------------- 8 | 9 | 10 | 1. Download the fabfile.py from `OpenPortfolio`_ 11 | 12 | 2. Modify the fabfile development settings to suit your requirements 13 | 14 | 3. Bootstrap your system to create a new virtual environment, download the latest stable version, install dependencies and sync the database:: 15 | 16 | $ fab development bootstrap 17 | 18 | 4. Run the development server:: 19 | 20 | $ fab development runserver 21 | 22 | .. note:: This procedure requires git, python, pip, virtualenv, virtualenvwrapper and fabric. See `Preparing your system`_ for further information. The fabfile includes additional commands to deploy to a staging or production environment (running apache2 and mod_wsgi) 23 | 24 | The long way... 25 | ---------------- 26 | 27 | Download 28 | ++++++++ 29 | 30 | Download the latest stable version from github 31 | 32 | .. parsed-literal:: 33 | 34 | $ git clone |stable-git-url| |project-name| 35 | 36 | Running on a local development server 37 | +++++++++++++++++++++++++++++++++++++ 38 | 39 | 1. Install the requirements file using pip (a virtual environment is recommended) 40 | 41 | .. parsed-literal:: 42 | 43 | $ cd |project-name| 44 | $ pip install -r requirements/development.txt 45 | 46 | 2. Create and sync the database 47 | 48 | .. parsed-literal:: 49 | 50 | $ ./manage.py syncdb --settings= |project-name|.settings_local 51 | $ ./manage.py migrate --all --settings= |project-name|.settings_local 52 | 53 | 3. Run the development server 54 | 55 | .. parsed-literal:: 56 | 57 | $ ./manage.py runserver 0.0.0.0:8080 --settings= |project-name|.settings_local 58 | 59 | The server can be accessed at: http://127.0.0.0.1:8080 60 | 61 | Preparing your system 62 | --------------------- 63 | 64 | The easy installation procedure assumes a system installed with python, pip, virtualenv, virtualenvwrapper and fabric. 65 | 66 | Git 67 | +++ 68 | 69 | Follow installation instructions at http://git-scm.com/. For Mac OSX, using `HomeBrew `_ is recommended instead. 70 | 71 | 72 | Python 73 | ++++++ 74 | 75 | Python installation is beyond the scope of this document. On unix based systems this should be straight-forward. Mac OS X comes with Python pre-installed. XCode is required and can be installed using the App store. Windows users face a more challenging scenario and should see http://www.python.org for installation instructions. 76 | 77 | 78 | Pip, virtualenv, virtualenvwrapper and fabric 79 | +++++++++++++++++++++++++++++++++++++++++++++ 80 | 81 | 1. Install easy_install by following instructions at http://pypi.python.org/pypi/setuptools 82 | 83 | 2. Install pip:: 84 | 85 | $ easy_install pip 86 | 87 | 3. Use pip to install remaining dependencies:: 88 | 89 | $ pip install virtualenv 90 | $ pip install virtualenvwrapper 91 | $ pip install fabric 92 | 93 | -------------------------------------------------------------------------------- /docs/make_and_push_docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | make html 4 | cd ../../docs-openportfolio 5 | git clean -dxf 6 | cp -r ../openportfolio/sphinx/_build/html/* . 7 | touch .nojekyll 8 | git add .nojekyll 9 | git add * 10 | git commit -m "Updated docs" 11 | git push origin gh-pages 12 | -------------------------------------------------------------------------------- /docs/user_guide.txt: -------------------------------------------------------------------------------- 1 | User Guide 2 | ========== 3 | 4 | .. toctree:: 5 | :numbered: 6 | 7 | userguide/getting started 8 | userguide/admin 9 | 10 | -------------------------------------------------------------------------------- /docs/userguide/admin.txt: -------------------------------------------------------------------------------- 1 | .. include:: ../globals.inc 2 | 3 | Administration 4 | =============== 5 | 6 | Portfolios & Benchmarks 7 | ----------------------- 8 | 9 | 1. Open the Portfolio admin screen 10 | 11 | 2. Select an existing Portfolio to edit it or click to add a new one 12 | 13 | 3. Assign a name to your portfolio or benchmark 14 | 15 | 4. If desired, assign a parent to allow for a portfolio tree 16 | 17 | 5. If you are modifying a benchmark, leave benchmark blank 18 | 19 | -------------------------------------------------------------------------------- /docs/userguide/getting started.txt: -------------------------------------------------------------------------------- 1 | .. include:: ../globals.inc 2 | 3 | Getting Started 4 | =============== 5 | 6 | To use |project-name|, you must first populate the database with some data. 7 | 8 | Step 1 - Use the Admin interface to create some portfolio objects 9 | ----------------------------------------------------------------- 10 | 11 | Detailed instructions on using this interface can be found here: :doc:`admin`. At a minimum you will need to: 12 | 13 | 1. Create a benchmark portfolio 14 | 15 | 2. Create a portfolio to hold your investments 16 | 17 | 3. Create an asset class and assign it to the benchmark portfolio 18 | 19 | 4. Create a currency eg: GBP 20 | 21 | 5. Create a company 22 | 23 | 6. Create a savings account or listed equity investment and assign it to the company 24 | 25 | 7. Enter portfolio trades 26 | 27 | 8. For savings accounts, you will also need to enter an Interest Rate 28 | 29 | 30 | Step 2 - Download price data 31 | ---------------------------- 32 | 33 | The best way to perform the initial price data update is using fabric:: 34 | 35 | $ fab development openportfolio-update --initial 36 | 37 | 38 | See :doc:`../installation` for more information on how this process can be automated to maintain price data on an ongoing basis. 39 | 40 | The openportfolio-update script will perform a number of tasks: 41 | 42 | * update investment prices an the day specified in Settings 43 | * calculate and save portfolio level data 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /docs/userguide/overview.txt: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | Main Objects 5 | ++++++++++++ 6 | 7 | Companies 8 | --------- 9 | 10 | * companies belong to a GICS Sector 11 | 12 | * companies issue investments 13 | 14 | Investments 15 | ----------- 16 | 17 | * investments belong to a company and an asset class 18 | 19 | * investments can be held by portfolios 20 | 21 | * investments can be transacted by portfolios 22 | 23 | * investments will have a price and dividend history 24 | 25 | * investments can be of type: bank account, savings account, listed equity 26 | 27 | * investments can be assigned to an accounting allocation 28 | 29 | InvestmentTransactions 30 | ---------------------- 31 | 32 | * investment transactions will be: buy, sell. dividend 33 | 34 | * each transaction will have a date, price, transaction cost, payee and memo 35 | 36 | * a transaction will be linked to a portfolio and investment 37 | 38 | Portfolios 39 | ---------- 40 | 41 | * portfolios can have a parent to create a portfolio tree 42 | 43 | * portfolios will hold and transact investments 44 | 45 | 46 | Asset Classes 47 | ------------- 48 | 49 | * each investment will belong to an Asset Class 50 | 51 | * each Asset Class can have a parent, allowing for an asset class tree 52 | 53 | * asset classes are used for portfolio reporting 54 | 55 | 56 | -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/environment.pickle -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/finance-concepts.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/finance-concepts.doctree -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/index.doctree -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/installation.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/installation.doctree -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/user_guide.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/user_guide.doctree -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/userguide/getting started.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/userguide/getting started.doctree -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/userguide/overview.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/userguide/overview.doctree -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/userguide/uploading transaction files.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/doctrees/userguide/uploading transaction files.doctree -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: 4ea958363fe679cc203eceb179e93fe3 4 | tags: fbb0d17656682115ca4d033fb2f83ba1 5 | -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_sources/index.txt: -------------------------------------------------------------------------------- 1 | .. Open Financial Management documentation master file, created by 2 | sphinx-quickstart on Tue Jul 19 13:37:51 2011. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. include:: globals.inc 7 | 8 | 9 | Open Portfolio 10 | ============== 11 | 12 | |project-name| is a django-based portfolio management tool, based on tools used by professional fund managers. It can be used to manage and monitor the returns and risks of a portfolio of investments such as listed equities and fixed income securities. Version 1.0 aims to be as user friendly as possible. Nevertheless, experience in Python and django would be beneficial to the user. Please contact the project authors if you would like to contribute to this project. See :doc:`finance-concepts` for a user-friendly overview of financial concepts relevant to portfolio management. 13 | 14 | Main Features 15 | -------------- 16 | 17 | * trade input from csv and ofx files 18 | * price downloads from online sources where possible (downloads can be scheduled) 19 | * investment analysis - return and risk statistics and plots 20 | * portfolio reporting - returns and risk analysis 21 | * cross currency capability 22 | * focus on portfolio cash flows 23 | * aims to be GIPS compliant 24 | 25 | Why? 26 | ----- 27 | 28 | This project aims to make the tools of professional fund managers more open and accessible. Such tools are typically closed source, expensive and inflexible. As an open source platform, |project-name| offers the opportunity for everyday investors to better manage their portfolios - thereby being aware of their risks and having the ability to maximise their returns. 29 | 30 | 31 | The `OpenPortfolio`_ Project is hosted on github. 32 | 33 | 34 | Contents: 35 | 36 | .. toctree:: 37 | :maxdepth: 2 38 | 39 | installation 40 | user_guide 41 | finance-concepts 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_sources/installation.txt: -------------------------------------------------------------------------------- 1 | .. include:: globals.inc 2 | 3 | Installation 4 | ============ 5 | 6 | The easy way... 7 | --------------- 8 | 9 | 10 | 1. Download the fabfile.py from `OpenPortfolio` 11 | 12 | 2. Modify the development settings to suit your requirements 13 | 14 | 3. Bootstrap your system to create a new virtual environment, downloaded the latest stable version and install dependencies:: 15 | 16 | $ fab development bootstrap 17 | 18 | 4. Sync then migrate the database:: 19 | 20 | $ fab development syncdb 21 | $ fab development migratedb 22 | 23 | 5. Run the development server:: 24 | 25 | $ fab development runserver 26 | 27 | .. note:: This procedure requires python, pip, virtualenv, virtualenvwrapper and fabric. See `Preparing your system`_ for further information. The fabfile includes additional commands to deploy to a staging or production environment (running apache2 and passenger) 28 | 29 | The long way... 30 | ---------------- 31 | 32 | Download 33 | ++++++++ 34 | 35 | Download the latest stable version from github 36 | 37 | .. parsed-literal:: 38 | 39 | $ git clone |stable-git-url| |project-name| 40 | 41 | Running on a local development server 42 | +++++++++++++++++++++++++++++++++++++ 43 | 44 | 1. Install the requirements file using pip (a virtual environment is recommended) 45 | 46 | .. parsed-literal:: 47 | 48 | $ cd |project-name| 49 | $ pip install -r requirements/development.txt 50 | 51 | 2. Create and sync the database 52 | 53 | .. parsed-literal:: 54 | 55 | $ ./manage.py syncdb --settings= |project-name|.settings_local 56 | $ ./manage.py schememigration |app-name| --settings= |project-name|.settings_local 57 | 58 | 3. Run the development server 59 | 60 | .. parsed-literal:: 61 | 62 | $ ./manage.py runserver 0.0.0.0:8080 --settings= |project-name|.settings_local 63 | 64 | The server can be accessed at: http://127.0.0.0.1:8080 65 | 66 | Preparing your system 67 | --------------------- 68 | 69 | The easy installation procedure assumes a system installed with python, pip, virtualenv, virtualenvwrapper and fabric. 70 | 71 | Python 72 | ++++++ 73 | 74 | Python installation is beyond the scope of this document. On unix based systems this should be straight-forward. Mac OS X comes with Python pre-installed. XCode is required and can be installed using the App store. Windows users face a more challenging scenario and should see http://www.python.org for installation instructions. 75 | 76 | 77 | Pip, virtualenv, virtualenvwrapper and fabric 78 | +++++++++++++++++++++++++++++++++++++++++++++ 79 | 80 | 1. Install easy_install by following instructions at http://pypi.python.org/pypi/setuptools 81 | 82 | 2. Install pip:: 83 | 84 | $ easy_install pip 85 | 86 | 3. Use pip to install remaining dependencies:: 87 | 88 | $ pip install virtualenv 89 | $ pip install virtualenvwrapper 90 | $ pip install fabric 91 | 92 | -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_sources/user_guide.txt: -------------------------------------------------------------------------------- 1 | User Guide 2 | ========== 3 | 4 | .. toctree:: 5 | :numbered: 6 | 7 | userguide/overview 8 | userguide/getting started 9 | userguide/uploading transaction files 10 | -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_sources/userguide/getting started.txt: -------------------------------------------------------------------------------- 1 | Getting Started 2 | =============== 3 | 4 | * The openportfolioapp app runs under django admin 5 | 6 | * Open http:///admin/openportfolioapp/ 7 | 8 | * This will bring up the main menu. From here, you can add data or generate reports by selecting the relevant models. 9 | 10 | .. image:: images/main_menu.png 11 | :alt: Main Menu 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_sources/userguide/overview.txt: -------------------------------------------------------------------------------- 1 | Overview 2 | ======== 3 | 4 | Main Objects 5 | ++++++++++++ 6 | 7 | Companies 8 | --------- 9 | 10 | * companies belong to a GICS Sector 11 | 12 | * companies issue investments 13 | 14 | Investments 15 | ----------- 16 | 17 | * investments belong to a company and an asset class 18 | 19 | * investments can be held by portfolios 20 | 21 | * investments can be transacted by portfolios 22 | 23 | * investments will have a price and dividend history 24 | 25 | * investments can be of type: bank account, savings account, listed equity 26 | 27 | * investments can be assigned to an accounting allocation 28 | 29 | InvestmentTransactions 30 | ---------------------- 31 | 32 | * investment transactions will be: buy, sell. dividend 33 | 34 | * each transaction will have a date, price, transaction cost, payee and memo 35 | 36 | * a transaction will be linked to a portfolio and investment 37 | 38 | Portfolios 39 | ---------- 40 | 41 | * portfolios can have a parent to create a portfolio tree 42 | 43 | * portfolios will hold and transact investments 44 | 45 | 46 | Asset Classes 47 | ------------- 48 | 49 | * each investment will belong to an Asset Class 50 | 51 | * each Asset Class can have a parent, allowing for an asset class tree 52 | 53 | * asset classes are used for portfolio reporting 54 | 55 | 56 | -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_sources/userguide/uploading transaction files.txt: -------------------------------------------------------------------------------- 1 | Uploading Transaction Files 2 | =========================== 3 | 4 | * Click on InvestmentTransactionDownload 5 | 6 | * Click Add to add a new entry. You will be presented with the following menu. 7 | 8 | .. image:: images/upload_transaction.png 9 | 10 | 1. Choose a file to upload. This can be of type ofx,qfx or csv. For csv, a csv data definition is required. 11 | 12 | 2. Choose an investment to link the transactions to. 13 | 14 | 3. Choose a portfolio to link the transactions to. 15 | 16 | 4. Start date and end date will be automatically set from the data file. 17 | 18 | .. note:: This upload process is currently focussed on bank account and savings account data. Equity transactions are best entered manually. 19 | -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_static/bgfooter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_static/bgfooter.png -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_static/bgtop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_static/bgtop.png -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_static/file.png -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_static/minus.png -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/_static/plus.png -------------------------------------------------------------------------------- /docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/docs/~/Dropbox/Cochrane Davey/Development/openportfoliodocs/html/objects.inv -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from django.core.management import execute_manager 3 | import imp 4 | try: 5 | imp.find_module('settings') # Assumed to be in the same directory. 6 | except ImportError: 7 | import sys 8 | sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n" % __file__) 9 | sys.exit(1) 10 | 11 | import settings 12 | 13 | if __name__ == "__main__": 14 | execute_manager(settings) 15 | -------------------------------------------------------------------------------- /openportfolioapp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/__init__.py -------------------------------------------------------------------------------- /openportfolioapp/fixtures/build_testdata.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo > initial_data.yaml 4 | cat assetclass.yaml >> initial_data.yaml 5 | cat gicssector.yaml >> initial_data.yaml 6 | cat company.yaml >> initial_data.yaml 7 | cat investment.yaml >> initial_data.yaml 8 | cat savingsaccount.yaml >> initial_data.yaml 9 | cat listedequity.yaml >> initial_data.yaml 10 | cat portfolio.yaml >> initial_data.yaml 11 | cat trade.yaml >> initial_data.yaml 12 | cat currency.yaml >> initial_data.yaml 13 | 14 | 15 | -------------------------------------------------------------------------------- /openportfolioapp/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/management/__init__.py -------------------------------------------------------------------------------- /openportfolioapp/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/management/commands/__init__.py -------------------------------------------------------------------------------- /openportfolioapp/management/commands/fetch-prices.py: -------------------------------------------------------------------------------- 1 | from django.core.management.base import BaseCommand, CommandError 2 | from openportfolioapp.utils.update_helpers import * 3 | 4 | from datetime import datetime 5 | 6 | class Command(BaseCommand): 7 | args = ' ' 8 | help = 'Fetches investment prices' 9 | 10 | def handle(self, *args, **options): 11 | 12 | if len(args) < 2: 13 | raise CommandError('Requires arguments %s' % self.args) 14 | 15 | 16 | try: 17 | startdate=datetime.strptime(args[0],'%Y%m%d') 18 | enddate=datetime.strptime(args[1],'%Y%m%d') 19 | except: 20 | raise CommandError('Date format must be YYYYMMDD') 21 | 22 | self.stdout.write('Fetching prices between %s and %s\n' % (startdate,enddate)) 23 | 24 | fetch_investment_prices(startdate,enddate) 25 | fetch_currency_prices(startdate,enddate) 26 | -------------------------------------------------------------------------------- /openportfolioapp/management/commands/openportfolio-update.py: -------------------------------------------------------------------------------- 1 | from django.core.management.base import BaseCommand, CommandError 2 | from openportfolioapp.app_settings import PRICE_DOWNLOAD_DAY 3 | from openportfolioapp.utils.update_helpers import * 4 | 5 | from datetime import * 6 | 7 | class Command(BaseCommand): 8 | args = '' 9 | help = 'Keeps OpenPortfolio up-to-date' 10 | 11 | def handle(self, *args, **options): 12 | 13 | today=datetime.today() 14 | 15 | startdate=today 16 | enddate=today-timedelta(days=1) 17 | 18 | 19 | fetch_investment_prices(startdate,enddate) 20 | -------------------------------------------------------------------------------- /openportfolioapp/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/migrations/__init__.py -------------------------------------------------------------------------------- /openportfolioapp/models/__init__.py: -------------------------------------------------------------------------------- 1 | from portfolio import Portfolio 2 | from assetclass import AssetClass 3 | from gicssector import GICSSector 4 | from company import Company 5 | from investment import Investment,InvestmentManager 6 | from currency import Currency 7 | from trade import Trade 8 | from tradeallocation import TradeAllocation 9 | from price import Price,PriceManager 10 | from prices import * 11 | from investments import * 12 | from datafiles import * 13 | from interestrate import InterestRate 14 | 15 | -------------------------------------------------------------------------------- /openportfolioapp/models/assetclass.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from openportfolioapp.utils import full_name 3 | 4 | class AssetClass(models.Model): 5 | """ An object to represent an investment AssetClass 6 | Each Investment will belong to a single AssetClass 7 | """ 8 | 9 | class Meta: 10 | verbose_name_plural = "Asset classes" #cleans up name in admin 11 | app_label = "openportfolioapp" 12 | 13 | name = models.CharField(max_length=255) 14 | parent = models.ForeignKey('self',blank=True,null=True,related_name='child') 15 | benchmark = models.ForeignKey("Portfolio") 16 | 17 | def _full_name(self): 18 | return full_name(self) 19 | 20 | full_name=property(_full_name) 21 | 22 | def __unicode__(self): 23 | """ Returns the custom output string for this object 24 | """ 25 | return self.full_name 26 | 27 | -------------------------------------------------------------------------------- /openportfolioapp/models/company.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | class Company(models.Model): 4 | """ A high level object to represent a company 5 | Companies can issue multiple Investments 6 | """ 7 | 8 | class Meta: 9 | verbose_name_plural = "Companies" #cleans up name in admin 10 | app_label = "openportfolioapp" 11 | 12 | 13 | name = models.CharField(max_length=255) 14 | gics_sector = models.ForeignKey("GICSSector") 15 | 16 | def __unicode__(self): 17 | """ Returns the custom output string for this object 18 | """ 19 | return self.name 20 | -------------------------------------------------------------------------------- /openportfolioapp/models/currency.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from openportfolioapp.utils.currencyhistory import * 3 | import sys 4 | from openportfolioapp.models.prices import CurrencyPrice 5 | 6 | class Currency(models.Model): 7 | code=models.CharField(max_length=6,primary_key=True) 8 | locale_code=models.CharField(max_length=6) 9 | 10 | def __unicode__(self): 11 | """ Returns the custom output string for this object 12 | """ 13 | return self.code 14 | 15 | class Meta: 16 | verbose_name_plural = "Currencies" #cleans up name in admin 17 | app_label = "openportfolioapp" 18 | 19 | @property 20 | def priceframe(self): 21 | """ 22 | Loads a currency queryset into a pandas dataframe 23 | """ 24 | 25 | return self.currencyprice_set.all().dataframe() 26 | 27 | 28 | def fetch_price_frame(self,startdate,enddate): 29 | 30 | """ 31 | Downloads data from the ukforex website, returning the result 32 | as a pandas dataframe 33 | """ 34 | 35 | try: 36 | 37 | df = fetch_ukforex_historical_exchange_rates(startdate,enddate,self.code,'USD') 38 | 39 | except: 40 | print "Error: ", sys.exc_info()[0] 41 | print "Error loading uk forex data for %s %s" % (self,str(startdate)) 42 | return None 43 | 44 | return df 45 | 46 | def save_price_frame(self,df): 47 | 48 | """ 49 | Saves a currency dataframe object to the database 50 | """ 51 | 52 | if df is None: 53 | return 54 | 55 | for dt in df.index: 56 | 57 | try: 58 | p=CurrencyPrice.objects.get(date=dt,currency=self) 59 | except: 60 | p=CurrencyPrice() 61 | 62 | xs=df.xs(dt) 63 | 64 | p.date=dt 65 | p.price=xs['crossrate'] 66 | p.currency=self 67 | 68 | p.save() 69 | 70 | -------------------------------------------------------------------------------- /openportfolioapp/models/datafiles/__init__.py: -------------------------------------------------------------------------------- 1 | from datadefinition import DataDefinition 2 | from tradedatafile import TradeDataFile -------------------------------------------------------------------------------- /openportfolioapp/models/datafiles/datadefinition.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from openportfolioapp.utils.ofx import * 3 | from openportfolioapp.models import Trade 4 | from datetime import * 5 | import csv 6 | 7 | class DataDefinition(models.Model): 8 | 9 | 10 | 11 | class Meta: 12 | verbose_name_plural = "Data Definitions" #cleans up name in admin 13 | app_label = "openportfolioapp" 14 | 15 | 16 | 17 | """ An object to define the structure of a csv download 18 | """ 19 | investment = models.ForeignKey("Investment") 20 | headers = models.CharField(max_length=255) 21 | skip_rows = models.IntegerField(default=0) 22 | date_col = models.IntegerField(default=0) 23 | memo_col = models.IntegerField(default=-1) 24 | payee_col = models.IntegerField(default=-1) 25 | debit_col = models.IntegerField(default=-1) 26 | credit_col = models.IntegerField(default=-1) 27 | balance_col = models.IntegerField(default=-1) 28 | price_col = models.IntegerField(default=-1) 29 | cost_col = models.IntegerField(default=-1) 30 | date_format = models.CharField(max_length=10,default='%d/%m/%Y') 31 | 32 | def __unicode__(self): 33 | return str(self.investment) 34 | -------------------------------------------------------------------------------- /openportfolioapp/models/gicssector.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from openportfolioapp.utils import full_name 3 | 4 | class GICSSector(models.Model): 5 | """ An object to represent the S&P GICS sector structure 6 | Each Company will belong to a single GICS sector 7 | The GICS sectors hieracy defines levels of Sector,IndustryGroup,Industry and SubIndustry 8 | GICS data will be populated from a (manipulated) csv file downloaded from S&P 9 | Note that the ASX company data populates GICS sectors at the IndustryGroup level 10 | S&P use an id scheme that allows the parent/child relationship to be determined from the id 11 | For example, an Industry of id 102030 will belong to IndustryGroup id 1020 and Sector 10 12 | """ 13 | 14 | class Meta: 15 | verbose_name_plural = "GICS Sectors" #cleans up name in admin 16 | app_label = "openportfolioapp" 17 | 18 | 19 | 20 | GICS_LEVELS=( 21 | ('Industry','Industry'), 22 | ('SubIndustry','Sub-Industry'), 23 | ('IndustryGroup','Industry-Group'), 24 | ('Sector','Sector'), 25 | 26 | ) 27 | 28 | code=models.CharField(max_length=8,primary_key=True) #The S&P id scheme, SubIndustries have at most 8 characters 29 | name = models.CharField(max_length=255) 30 | description=models.TextField(blank=True) #Available for subindustry only 31 | level = models.CharField(max_length=13,choices=GICS_LEVELS,blank=False) 32 | parent = models.ForeignKey('self',blank=True,null=True,related_name='child') 33 | 34 | def _full_name(self): 35 | return full_name(self) 36 | 37 | full_name=property(_full_name) 38 | 39 | def __unicode__(self): 40 | """ Returns the custom output string for this object 41 | """ 42 | return self.full_name 43 | 44 | def _get_sector(self): 45 | """ Gets the linked Sector level name 46 | """ 47 | 48 | if self.level=='SubIndustry': 49 | return self.parent.parent.parent.name 50 | elif self.level=='Industry': 51 | return self.parent.parent.name 52 | elif self.level=='IndustryGroup': 53 | return self.parent.name 54 | else: 55 | return self.name 56 | 57 | 58 | sector = property(_get_sector) 59 | 60 | def _get_industry_group(self): 61 | """ Gets the linked Industry Group level name 62 | """ 63 | 64 | if self.level=='SubIndustry': 65 | return self.parent.parent.name 66 | elif self.level=='Industry': 67 | return self.parent.name 68 | elif self.level=='IndustryGroup': 69 | return self.name 70 | else: 71 | return 'Not Available' 72 | 73 | industry_group = property(_get_industry_group) 74 | 75 | def _get_industry(self): 76 | """ Gets the linked Industry level name 77 | """ 78 | 79 | if self.level=='SubIndustry': 80 | return self.parent.name 81 | elif self.level=='Industry': 82 | return self.name 83 | else: 84 | return 'Not Available' 85 | 86 | industry = property(_get_industry) 87 | -------------------------------------------------------------------------------- /openportfolioapp/models/interestrate.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class InterestRate(models.Model): 5 | """ 6 | """ 7 | 8 | class Meta: 9 | verbose_name_plural = "Interest Rates" #cleans up name in admin 10 | app_label = "openportfolioapp" 11 | 12 | 13 | investment=models.ForeignKey("Investment") 14 | date = models.DateField() 15 | annualrate=models.DecimalField(decimal_places=4,max_digits=20,default=-1) 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /openportfolioapp/models/investments/__init__.py: -------------------------------------------------------------------------------- 1 | from openportfolioapp.models.investment import Investment 2 | from listedequity import ListedEquity 3 | from savingsaccount import SavingsAccount 4 | -------------------------------------------------------------------------------- /openportfolioapp/models/investments/savingsaccount.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from openportfolioapp.models import Investment,InvestmentManager 3 | import pandas as ps 4 | from openportfolioapp.models.interestrate import InterestRate 5 | from datetime import * 6 | from pandas.core.datetools import bday,DateOffset 7 | from decimal import * 8 | from openportfolioapp.models.prices import SavingsAccountPrice 9 | import numpy as np 10 | 11 | class SavingsAccount(Investment): 12 | """ A savings account Investment object 13 | """ 14 | 15 | class Meta: 16 | verbose_name_plural = "Savings Accounts" #cleans up name in admin 17 | app_label = "openportfolioapp" 18 | 19 | investment_type='SavingsAccount' 20 | objects=InvestmentManager() 21 | 22 | def __unicode__(self): 23 | """ Returns the custom output string for this object 24 | """ 25 | return self.investment_type + ":" + self.name 26 | 27 | def fetch_price_frame(self,startdate,enddate): 28 | 29 | dts=ps.DateRange(start=startdate,end=enddate,offset=bday) 30 | 31 | i=0 32 | dividends=[] 33 | prices=[] 34 | 35 | for dt in dts: 36 | 37 | irs=InterestRate.objects.filter(date__lte=dt,investment=self).order_by('-date') 38 | 39 | if len(irs) == 0: 40 | return None 41 | else: 42 | ir=irs[0] 43 | 44 | prices.append(Decimal(1.0)) 45 | dividends.append(ir.annualrate/365) 46 | 47 | data={ 48 | 'price':prices, 49 | 'dividend':dividends, 50 | 51 | } 52 | df=ps.DataFrame(data,index=dts) 53 | 54 | return df 55 | 56 | 57 | 58 | def save_price_frame(self,df): 59 | 60 | if df is None: 61 | return 62 | 63 | 64 | 65 | for dt in df.index: 66 | 67 | try: 68 | p=SavingsAccountPrice.objects.get(date=dt,investment=self) 69 | except: 70 | p=SavingsAccountPrice() 71 | 72 | xs=df.xs(dt) 73 | 74 | p.date=dt 75 | p.investment=self 76 | 77 | p.dividend=xs['dividend'] 78 | p.price=xs['price'] 79 | 80 | p.save() 81 | 82 | def fetch_prices(self,startdate,enddate): 83 | 84 | return 1 85 | 86 | def price_as_at(self,date): 87 | 88 | p=SavingsAccountPrice.objects.filter(date__lte=date,investment=self).order_by('-date') 89 | 90 | if len(p)==0: 91 | return None 92 | 93 | p=p[0] 94 | return p.price,p.date 95 | 96 | def dividend_as_at(self,date): 97 | 98 | p=SavingsAccountPrice.objects.filter(date__lte=date,investment=self).order_by('-date') 99 | 100 | if len(p)==0: 101 | return None 102 | 103 | p=p[0] 104 | return p.dividend,p.date 105 | 106 | def process_trade(self,trade): 107 | 108 | 109 | 110 | 111 | return -------------------------------------------------------------------------------- /openportfolioapp/models/price.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.contrib.contenttypes.models import ContentType 3 | from openportfolioapp.models.subclassing import SubclassingQuerySet 4 | import pandas as ps 5 | import numpy as np 6 | 7 | 8 | class PriceQuerySet(SubclassingQuerySet): 9 | """ 10 | A queryset object that contains a date field for conversion into a pandas data frame 11 | """ 12 | def dataframe(self): 13 | 14 | qs=self 15 | 16 | if len(qs)==0: 17 | return [] 18 | 19 | dates=list(qs.dates('date','day')) 20 | 21 | vlqs = qs.values_list() 22 | r = np.core.records.fromrecords(vlqs, names=[f.name for f in self.model._meta.fields]) 23 | 24 | df=ps.DataFrame(r,index=dates) 25 | 26 | return df 27 | 28 | class PriceManager(models.Manager): 29 | def get_query_set(self): 30 | return PriceQuerySet(self.model) 31 | 32 | 33 | class Price(models.Model): 34 | """ A base Price object 35 | 36 | """ 37 | 38 | class Meta: 39 | verbose_name_plural = "Prices" #cleans up name in admin 40 | app_label = "openportfolioapp" 41 | 42 | 43 | date = models.DateField() 44 | price=models.DecimalField(decimal_places=4,max_digits=20,default=-1) 45 | 46 | content_type = models.ForeignKey(ContentType,editable=False,null=True) 47 | objects = PriceManager() 48 | 49 | def save(self, *args, **kwargs): 50 | if(not self.content_type): 51 | self.content_type = ContentType.objects.get_for_model(self.__class__) 52 | super(Price, self).save(*args, **kwargs) 53 | 54 | def as_leaf_class(self): 55 | content_type = self.content_type 56 | model = content_type.model_class() 57 | if (model == Price): 58 | return self 59 | return model.objects.get(id=self.id) 60 | 61 | def __unicode__(self): 62 | """ Returns the custom output string for this object 63 | """ 64 | return "%s : %f" % (self.date,self.price) 65 | 66 | -------------------------------------------------------------------------------- /openportfolioapp/models/prices/__init__.py: -------------------------------------------------------------------------------- 1 | from listedequityprice import ListedEquityPrice 2 | from currencyprice import CurrencyPrice 3 | from savingsaccountprice import SavingsAccountPrice 4 | from investmentprice import InvestmentPrice 5 | -------------------------------------------------------------------------------- /openportfolioapp/models/prices/currencyprice.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from openportfolioapp.models.price import Price,PriceManager 3 | 4 | class CurrencyPrice(Price): 5 | """ A listed Equity price object 6 | """ 7 | 8 | 9 | currency=models.ForeignKey("Currency") 10 | 11 | objects = PriceManager() 12 | 13 | class Meta: 14 | verbose_name_plural = "Currency Prices" #cleans up name in admin 15 | app_label = "openportfolioapp" 16 | 17 | 18 | def __unicode__(self): 19 | """ Returns the custom output string for this object 20 | """ 21 | return "%s - %s : %f" % (self.currency,self.date,self.price) -------------------------------------------------------------------------------- /openportfolioapp/models/prices/investmentprice.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.contrib.contenttypes.models import ContentType 3 | 4 | from openportfolioapp.models.price import Price,PriceManager,PriceQuerySet 5 | import pandas as ps 6 | 7 | DEFAULT_CURRENCY='AUD' 8 | 9 | class InvestmentPriceQuerySet(PriceQuerySet): 10 | """ 11 | A queryset object that contains a date field for conversion into a pandas data frame 12 | """ 13 | 14 | 15 | 16 | def dataframe(self,basecurrency,crosscurrency): 17 | 18 | 19 | df=super(InvestmentPriceQuerySet,self).dataframe() 20 | 21 | if len(df)==0: 22 | return [] 23 | 24 | base_df=basecurrency.priceframe 25 | cross_df=crosscurrency.priceframe 26 | 27 | currdata={'base_currency':base_df.reindex(df.index,method='ffill')['price'], 28 | 'cross_currency':cross_df.reindex(df.index,method='ffill')['price'] 29 | } 30 | 31 | curr_df=ps.DataFrame(currdata,index=df.index) 32 | 33 | curr_df=curr_df.applymap(float) 34 | curr_df['xrate']=curr_df['base_currency']/curr_df['cross_currency'] 35 | 36 | df=df.join(curr_df['xrate']) 37 | 38 | return df 39 | 40 | class InvestmentPriceManager(models.Manager): 41 | def get_query_set(self): 42 | return InvestmentPriceQuerySet(self.model) 43 | 44 | 45 | class InvestmentPrice(Price): 46 | """ A listed Equity price object 47 | """ 48 | 49 | investment=models.ForeignKey("Investment") 50 | dividend=models.DecimalField(decimal_places=10,max_digits=20,default=-1) 51 | 52 | 53 | objects = InvestmentPriceManager() 54 | 55 | class Meta: 56 | verbose_name_plural = "Investment Prices" #cleans up name in admin 57 | app_label = "openportfolioapp" 58 | 59 | 60 | def as_leaf_class(self): 61 | content_type = self.content_type 62 | model = content_type.model_class() 63 | if (model == InvestmentPrice): 64 | return self 65 | return model.objects.get(id=self.id) 66 | 67 | def __unicode__(self): 68 | """ Returns the custom output string for this object 69 | """ 70 | return "%s - %s : %f" % (self.investment,self.date,self.price) 71 | -------------------------------------------------------------------------------- /openportfolioapp/models/prices/listedequityprice.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from openportfolioapp.models.prices.investmentprice import InvestmentPrice,InvestmentPriceManager 3 | 4 | class ListedEquityPrice(InvestmentPrice): 5 | """ A listed Equity price object 6 | """ 7 | 8 | close=models.DecimalField(decimal_places=4,max_digits=20,default=-1) 9 | adj_close=models.DecimalField(decimal_places=4,max_digits=20,default=-1) 10 | high=models.DecimalField(decimal_places=4,max_digits=20,default=-1) 11 | low=models.DecimalField(decimal_places=4,max_digits=20,default=-1) 12 | open=models.DecimalField(decimal_places=4,max_digits=20,default=-1) 13 | volume=models.DecimalField(decimal_places=0,max_digits=20,default=-1) 14 | 15 | objects = InvestmentPriceManager() 16 | 17 | class Meta: 18 | verbose_name_plural = "Equities Prices" #cleans up name in admin 19 | app_label = "openportfolioapp" 20 | 21 | 22 | def __unicode__(self): 23 | """ Returns the custom output string for this object 24 | """ 25 | return "%s - %s : %f" % (self.investment,self.date,self.price) -------------------------------------------------------------------------------- /openportfolioapp/models/prices/savingsaccountprice.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from openportfolioapp.models.prices.investmentprice import InvestmentPrice,InvestmentPriceManager 3 | 4 | class SavingsAccountPrice(InvestmentPrice): 5 | """ A listed Equity price object 6 | """ 7 | 8 | 9 | 10 | class Meta: 11 | verbose_name_plural = "Savings Account Prices" #cleans up name in admin 12 | app_label = "openportfolioapp" 13 | 14 | objects = InvestmentPriceManager() 15 | 16 | 17 | def __unicode__(self): 18 | """ Returns the custom output string for this object 19 | """ 20 | return "%s - %s : %f" % (self.investment,self.date,self.price) -------------------------------------------------------------------------------- /openportfolioapp/models/subclassing.py: -------------------------------------------------------------------------------- 1 | from django.db.models.query import QuerySet 2 | from django.db import models 3 | import pandas as ps 4 | from pandas.core.datetools import MonthEnd 5 | import numpy as np 6 | 7 | 8 | 9 | class SubclassingQuerySet(QuerySet): 10 | def __getitem__(self, k): 11 | result = super(SubclassingQuerySet, self).__getitem__(k) 12 | if isinstance(result, models.Model) : 13 | return result.as_leaf_class() 14 | else : 15 | return result 16 | def __iter__(self): 17 | for item in super(SubclassingQuerySet, self).__iter__(): 18 | yield item.as_leaf_class() 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /openportfolioapp/models/trade.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from openportfolioapp.models.investment import Investment 3 | from openportfolioapp.models.tradeallocation import TradeAllocation 4 | class Trade(models.Model): 5 | """ An object to represent an investment AssetClass 6 | Each Investment will belong to a single AssetClass 7 | """ 8 | 9 | class Meta: 10 | verbose_name_plural = "Trades" #cleans up name in admin 11 | app_label = "openportfolioapp" 12 | 13 | TRADE_TYPES=( 14 | ('BUY','Buy'), 15 | ('SEL','Sell'), 16 | ('DIV','Dividend'), 17 | ('XFR','Transfer'), 18 | ('OUT','Outflow'), 19 | ('INF','Inflow'), 20 | ) 21 | 22 | date = models.DateField() 23 | volume = models.DecimalField(decimal_places=2,max_digits=20) 24 | price = models.DecimalField(decimal_places=6,max_digits=20) 25 | cost = models.DecimalField(decimal_places=2,max_digits=20) 26 | trade_type = models.CharField(max_length=3, choices=TRADE_TYPES,blank=False) 27 | memo = models.CharField(max_length=255,null=True,blank=True) 28 | payee = models.CharField(max_length=255,null=True,blank=True) 29 | portfolio = models.ForeignKey("Portfolio") 30 | investment = models.ForeignKey("Investment",editable=True) 31 | transid = models.CharField(max_length=255, null=True,blank=True) 32 | 33 | 34 | def __unicode__(self): 35 | return str(self.date) + ":" + self.investment.name + ":" + str(self.volume) + ":" + str(self.price) 36 | 37 | def _set_trade_type(self): 38 | 39 | if self.volume < 0.0: 40 | self.trade_type='SEL' 41 | elif 'INTEREST' in self.memo.upper() or 'DIVIDEND' in self.memo.upper(): 42 | self.trade_type='DIV' 43 | else: 44 | self.trade_type='BUY' 45 | 46 | def save(self, *args, **kwargs): 47 | 48 | self._set_trade_type() 49 | 50 | 51 | super(Trade, self).save(*args, **kwargs) # Call the "real" save() method. 52 | 53 | #workaround code to trigger subclass process trade function 54 | i=self.investment 55 | content_type = i.content_type 56 | model = content_type.model_class() 57 | 58 | i=model.objects.get(pk=i.id) 59 | 60 | i.process_trade(self) 61 | 62 | def profit(self): 63 | 64 | if self.trade_type=='SEL': 65 | alloc=TradeAllocation.objects.filter(sell_trade=self) 66 | 67 | if len(alloc)==0: 68 | return None 69 | 70 | else: 71 | profit=0 72 | for a in alloc: 73 | profit+=a.profit 74 | 75 | return profit 76 | 77 | 78 | return None 79 | 80 | -------------------------------------------------------------------------------- /openportfolioapp/models/tradeallocation.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | class TradeAllocation(models.Model): 4 | """ Object to allocate sell trades against buy trades 5 | """ 6 | 7 | class Meta: 8 | verbose_name_plural = "Trade Allocations" #cleans up name in admin 9 | app_label = "openportfolioapp" 10 | 11 | buy_trade=models.ForeignKey("Trade",related_name='+') 12 | sell_trade=models.ForeignKey("Trade") 13 | volume=models.DecimalField(decimal_places=2,max_digits=20) 14 | #cost_allocation=models.DecimalField(decimal_places=2,max_digits=20) 15 | 16 | 17 | def _profit(self): 18 | 19 | return ((self.sell_price-self.buy_price)*self.volume)-self.cost 20 | 21 | profit=property(_profit) 22 | 23 | 24 | def _investment(self): 25 | return self.sell_trade.investment 26 | investment=property(_investment) 27 | 28 | def _portfolio(self): 29 | return self.sell_trade.portfolio 30 | portfolio=property(_portfolio) 31 | 32 | def _date(self): 33 | return self.sell_trade.date 34 | date=property(_date) 35 | 36 | def _sell_price(self): 37 | return self.sell_trade.price 38 | sell_price=property(_sell_price) 39 | 40 | def _buy_price(self): 41 | return self.buy_trade.price 42 | buy_price=property(_buy_price) 43 | 44 | def _cost(self): 45 | cost=0 46 | cost+=(self.buy_trade.cost/self.buy_trade.volume)*self.volume 47 | cost+=self.sell_trade.cost 48 | 49 | return cost 50 | 51 | cost=property(_cost) -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/area-inverted.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 98 | 99 | 100 | 101 | 102 | 103 |
104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/area-missing.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 92 | 93 | 94 | 95 | 96 | 97 |
98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/area-negative.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 62 | 63 | 64 | 65 | 66 | 67 |
68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/area-stacked-percent.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 89 | 90 | 91 | 92 | 93 | 94 |
95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/area-stacked.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 93 | 94 | 95 | 96 | 97 | 98 |
99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/areaspline.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 92 | 93 | 94 | 95 | 96 | 97 |
98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/bar-basic.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 93 | 94 | 95 | 96 | 97 | 98 |
99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/bar-stacked.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 74 | 75 | 76 | 77 | 78 | 79 |
80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/column-negative.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 62 | 63 | 64 | 65 | 66 | 67 |
68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/column-stacked-and-grouped.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 86 | 87 | 88 | 89 | 90 | 91 |
92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/column-stacked-percent.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 70 | 71 | 72 | 73 | 74 | 75 |
76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/combo-regression.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 66 | 67 | 68 | 69 | 70 | 71 |
72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/dynamic-click-to-add.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 95 | 96 | 97 | 98 | 99 | 100 |
101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/line-basic.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 88 | 89 | 90 | 91 | 92 | 93 |
94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/line-labels.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 73 | 74 | 75 | 76 | 77 | 78 |
79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/pie-basic.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 76 | 77 | 78 | 79 | 80 | 81 |
82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/pie-legend.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 72 | 73 | 74 | 75 | 76 | 77 |
78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/spline-inverted.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 94 | 95 | 96 | 97 | 98 | 99 |
100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/examples/spline-symbols.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highcharts Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 94 | 95 | 96 | 97 | 98 | 99 |
100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/exporting-server/index.php: -------------------------------------------------------------------------------- 1 | $output"; 74 | echo "Error while converting SVG"; 75 | } 76 | 77 | // stream it 78 | else { 79 | header("Content-Disposition: attachment; filename=$filename.$ext"); 80 | header("Content-Type: $type"); 81 | echo file_get_contents($outfile); 82 | } 83 | 84 | // delete it 85 | unlink("temp/$tempName.svg"); 86 | unlink($outfile); 87 | 88 | // SVG can be streamed directly back 89 | } else if ($ext == 'svg') { 90 | header("Content-Disposition: attachment; filename=$filename.$ext"); 91 | header("Content-Type: $type"); 92 | echo $svg; 93 | 94 | } else { 95 | echo "Invalid type"; 96 | } 97 | ?> 98 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/graphics/skies.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/static/Highcharts/graphics/skies.jpg -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/graphics/snow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/static/Highcharts/graphics/snow.png -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/graphics/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/static/Highcharts/graphics/sun.png -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/js/adapters/mootools-adapter.js: -------------------------------------------------------------------------------- 1 | /* 2 | Highcharts JS v2.1.9 (2011-11-11) 3 | MooTools adapter 4 | 5 | (c) 2010-2011 Torstein H?nsi 6 | 7 | License: www.highcharts.com/license 8 | */ 9 | (function(){var e=window,h=e.MooTools.version.substring(0,3),i=h==="1.2"||h==="1.1",m=i||h==="1.3",j=e.$extend||function(){return Object.append.apply(Object,arguments)};e.HighchartsAdapter={init:function(a){var b=Fx.prototype,c=b.start,d=Fx.Morph.prototype,g=d.compute;b.start=function(f){var k=this.element;if(f.d)this.paths=a.init(k,k.d,this.toD);c.apply(this,arguments);return this};d.compute=function(f,k,n){var l=this.paths;if(l)this.element.attr("d",a.step(l[0],l[1],n,this.toD));else return g.apply(this, 10 | arguments)}},animate:function(a,b,c){var d=a.attr,g=c&&c.complete;if(d&&!a.setStyle){a.getStyle=a.attr;a.setStyle=function(){var f=arguments;a.attr.call(a,f[0],f[1][0])};a.$family=a.uid=true}e.HighchartsAdapter.stop(a);c=new Fx.Morph(d?a:$(a),j({transition:Fx.Transitions.Quad.easeInOut},c));if(b.d)c.toD=b.d;g&&c.addEvent("complete",g);c.start(b);a.fx=c},each:function(a,b){return i?$each(a,b):a.each(b)},map:function(a,b){return a.map(b)},grep:function(a,b){return a.filter(b)},merge:function(){var a= 11 | arguments,b=[{}],c=a.length;if(i)a=$merge.apply(null,a);else{for(;c--;)if(typeof a[c]!=="boolean")b[c+1]=a[c];a=Object.merge.apply(Object,b)}return a},extendWithEvents:function(a){a.addEvent||(a.nodeName?$(a):j(a,new Events))},addEvent:function(a,b,c){if(typeof b==="string"){if(b==="unload")b="beforeunload";e.HighchartsAdapter.extendWithEvents(a);a.addEvent(b,c)}},removeEvent:function(a,b,c){if(typeof a!=="string"){e.HighchartsAdapter.extendWithEvents(a);if(b){if(b==="unload")b="beforeunload";c?a.removeEvent(b, 12 | c):a.removeEvents(b)}else a.removeEvents()}},fireEvent:function(a,b,c,d){b={type:b,target:a};b=m?new Event(b):new DOMEvent(b);b=j(b,c);b.preventDefault=function(){d=null};a.fireEvent&&a.fireEvent(b.type,b);d&&d(b)},stop:function(a){a.fx&&a.fx.cancel()}}})(); 13 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highcharts/js/themes/grid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Grid theme for Highcharts JS 3 | * @author Torstein Hønsi 4 | */ 5 | 6 | Highcharts.theme = { 7 | colors: ['#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4'], 8 | chart: { 9 | backgroundColor: { 10 | linearGradient: [0, 0, 500, 500], 11 | stops: [ 12 | [0, 'rgb(255, 255, 255)'], 13 | [1, 'rgb(240, 240, 255)'] 14 | ] 15 | }, 16 | borderWidth: 2, 17 | plotBackgroundColor: 'rgba(255, 255, 255, .9)', 18 | plotShadow: true, 19 | plotBorderWidth: 1 20 | }, 21 | title: { 22 | style: { 23 | color: '#000', 24 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif' 25 | } 26 | }, 27 | subtitle: { 28 | style: { 29 | color: '#666666', 30 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif' 31 | } 32 | }, 33 | xAxis: { 34 | gridLineWidth: 1, 35 | lineColor: '#000', 36 | tickColor: '#000', 37 | labels: { 38 | style: { 39 | color: '#000', 40 | font: '11px Trebuchet MS, Verdana, sans-serif' 41 | } 42 | }, 43 | title: { 44 | style: { 45 | color: '#333', 46 | fontWeight: 'bold', 47 | fontSize: '12px', 48 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 49 | 50 | } 51 | } 52 | }, 53 | yAxis: { 54 | minorTickInterval: 'auto', 55 | lineColor: '#000', 56 | lineWidth: 1, 57 | tickWidth: 1, 58 | tickColor: '#000', 59 | labels: { 60 | style: { 61 | color: '#000', 62 | font: '11px Trebuchet MS, Verdana, sans-serif' 63 | } 64 | }, 65 | title: { 66 | style: { 67 | color: '#333', 68 | fontWeight: 'bold', 69 | fontSize: '12px', 70 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 71 | } 72 | } 73 | }, 74 | legend: { 75 | itemStyle: { 76 | font: '9pt Trebuchet MS, Verdana, sans-serif', 77 | color: 'black' 78 | 79 | }, 80 | itemHoverStyle: { 81 | color: '#039' 82 | }, 83 | itemHiddenStyle: { 84 | color: 'gray' 85 | } 86 | }, 87 | labels: { 88 | style: { 89 | color: '#99b' 90 | } 91 | } 92 | }; 93 | 94 | // Apply the theme 95 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme); 96 | 97 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/static/Highstock/.DS_Store -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/area/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 | 61 | 62 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/areaspline/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 | 61 | 62 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/basic-line/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
51 | 52 | 53 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/candlestick/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 | 53 | 54 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/column/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 | 53 | 54 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/compare/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
86 | 87 | 88 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/dynamic-update/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 |
88 | 89 | 90 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/flags-general/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 84 | 85 | 86 | 87 | 88 | 89 | 90 |
91 | 92 | 93 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/flags-placement/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 67 | 68 | 69 | 70 | 71 | 72 | 73 |
74 | 75 | 76 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/flags-shapes/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 95 | 96 | 97 | 98 | 99 | 100 | 101 |
102 | 103 | 104 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/intraday/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 50 | 51 | 52 | 53 | 54 |
55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/line-markers/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
54 | 55 | 56 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/markers-only/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
50 | 51 | 52 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/navigator-disabled/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
49 | 50 | 51 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/ohlc/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 | 53 | 54 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/scrollbar-disabled/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
49 | 50 | 51 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/spline/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
49 | 50 | 51 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/step-line/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
49 | 50 | 51 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/styled-scrollbar/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 50 | 51 | 52 | 53 | 54 | 55 | 56 |
57 | 58 | 59 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/yaxis-plotbands/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 52 | 53 | 54 | 55 | 56 | 57 | 58 |
59 | 60 | 61 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/yaxis-plotlines/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 61 | 62 | 63 | 64 | 65 | 66 | 67 |
68 | 69 | 70 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/examples/yaxis-reversed/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Example 6 | 7 | 8 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
61 | 62 | 63 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/exporting-server/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/static/Highstock/exporting-server/.DS_Store -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/exporting-server/index.php: -------------------------------------------------------------------------------- 1 | $output"; 74 | echo "Error while converting SVG"; 75 | } 76 | 77 | // stream it 78 | else { 79 | header("Content-Disposition: attachment; filename=$filename.$ext"); 80 | header("Content-Type: $type"); 81 | echo file_get_contents($outfile); 82 | } 83 | 84 | // delete it 85 | unlink("temp/$tempName.svg"); 86 | unlink($outfile); 87 | 88 | // SVG can be streamed directly back 89 | } else if ($ext == 'svg') { 90 | header("Content-Disposition: attachment; filename=$filename.$ext"); 91 | header("Content-Type: $type"); 92 | echo $svg; 93 | 94 | } else { 95 | echo "Invalid type"; 96 | } 97 | ?> 98 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/graphics/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/static/Highstock/graphics/.DS_Store -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/graphics/skies.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/static/Highstock/graphics/skies.jpg -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/graphics/snow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/static/Highstock/graphics/snow.png -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/graphics/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/static/Highstock/graphics/sun.png -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Highstock Examples 6 | 7 | 8 |

Highstock Examples

9 |

General

10 | 26 |

Chart types

27 | 47 |

Various features

48 | 62 |

Flags

63 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/js/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/static/Highstock/js/.DS_Store -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/js/adapters/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/static/Highstock/js/adapters/.DS_Store -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/js/adapters/mootools-adapter.js: -------------------------------------------------------------------------------- 1 | /* 2 | Highstock JS v1.0.2 (2011-11-08) 3 | MooTools adapter 4 | 5 | (c) 2010-2011 Torstein H?nsi 6 | 7 | License: www.highcharts.com/license 8 | */ 9 | (function(){var e=window,h=e.MooTools.version.substring(0,3),i=h==="1.2"||h==="1.1",m=i||h==="1.3",j=e.$extend||function(){return Object.append.apply(Object,arguments)};e.HighchartsAdapter={init:function(a){var b=Fx.prototype,c=b.start,d=Fx.Morph.prototype,g=d.compute;b.start=function(f){var k=this.element;if(f.d)this.paths=a.init(k,k.d,this.toD);c.apply(this,arguments);return this};d.compute=function(f,k,n){var l=this.paths;if(l)this.element.attr("d",a.step(l[0],l[1],n,this.toD));else return g.apply(this, 10 | arguments)}},animate:function(a,b,c){var d=a.attr,g=c&&c.complete;if(d&&!a.setStyle){a.getStyle=a.attr;a.setStyle=function(){var f=arguments;a.attr.call(a,f[0],f[1][0])};a.$family=a.uid=true}e.HighchartsAdapter.stop(a);c=new Fx.Morph(d?a:$(a),j({transition:Fx.Transitions.Quad.easeInOut},c));if(b.d)c.toD=b.d;g&&c.addEvent("complete",g);c.start(b);a.fx=c},each:function(a,b){return i?$each(a,b):a.each(b)},map:function(a,b){return a.map(b)},grep:function(a,b){return a.filter(b)},merge:function(){var a= 11 | arguments,b=[{}],c=a.length;if(i)a=$merge.apply(null,a);else{for(;c--;)if(typeof a[c]!=="boolean")b[c+1]=a[c];a=Object.merge.apply(Object,b)}return a},extendWithEvents:function(a){a.addEvent||(a.nodeName?$(a):j(a,new Events))},addEvent:function(a,b,c){if(typeof b==="string"){if(b==="unload")b="beforeunload";e.HighchartsAdapter.extendWithEvents(a);a.addEvent(b,c)}},removeEvent:function(a,b,c){if(typeof a!=="string"){e.HighchartsAdapter.extendWithEvents(a);if(b){if(b==="unload")b="beforeunload";c?a.removeEvent(b, 12 | c):a.removeEvents(b)}else a.removeEvents()}},fireEvent:function(a,b,c,d){b={type:b,target:a};b=m?new Event(b):new DOMEvent(b);b=j(b,c);b.preventDefault=function(){d=null};a.fireEvent&&a.fireEvent(b.type,b);d&&d(b)},stop:function(a){a.fx&&a.fx.cancel()}}})(); 13 | -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/js/themes/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/static/Highstock/js/themes/.DS_Store -------------------------------------------------------------------------------- /openportfolioapp/static/Highstock/js/themes/grid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Grid theme for Highcharts JS 3 | * @author Torstein Hønsi 4 | */ 5 | 6 | Highcharts.theme = { 7 | colors: ['#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4'], 8 | chart: { 9 | backgroundColor: { 10 | linearGradient: [0, 0, 500, 500], 11 | stops: [ 12 | [0, 'rgb(255, 255, 255)'], 13 | [1, 'rgb(240, 240, 255)'] 14 | ] 15 | }, 16 | borderWidth: 2, 17 | plotBackgroundColor: 'rgba(255, 255, 255, .9)', 18 | plotShadow: true, 19 | plotBorderWidth: 1 20 | }, 21 | title: { 22 | style: { 23 | color: '#000', 24 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif' 25 | } 26 | }, 27 | subtitle: { 28 | style: { 29 | color: '#666666', 30 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif' 31 | } 32 | }, 33 | xAxis: { 34 | gridLineWidth: 1, 35 | lineColor: '#000', 36 | tickColor: '#000', 37 | labels: { 38 | style: { 39 | color: '#000', 40 | font: '11px Trebuchet MS, Verdana, sans-serif' 41 | } 42 | }, 43 | title: { 44 | style: { 45 | color: '#333', 46 | fontWeight: 'bold', 47 | fontSize: '12px', 48 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 49 | 50 | } 51 | } 52 | }, 53 | yAxis: { 54 | minorTickInterval: 'auto', 55 | lineColor: '#000', 56 | lineWidth: 1, 57 | tickWidth: 1, 58 | tickColor: '#000', 59 | labels: { 60 | style: { 61 | color: '#000', 62 | font: '11px Trebuchet MS, Verdana, sans-serif' 63 | } 64 | }, 65 | title: { 66 | style: { 67 | color: '#333', 68 | fontWeight: 'bold', 69 | fontSize: '12px', 70 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 71 | } 72 | } 73 | }, 74 | legend: { 75 | itemStyle: { 76 | font: '9pt Trebuchet MS, Verdana, sans-serif', 77 | color: 'black' 78 | 79 | }, 80 | itemHoverStyle: { 81 | color: '#039' 82 | }, 83 | itemHiddenStyle: { 84 | color: 'gray' 85 | } 86 | }, 87 | labels: { 88 | style: { 89 | color: '#99b' 90 | } 91 | } 92 | }; 93 | 94 | // Apply the theme 95 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme); 96 | -------------------------------------------------------------------------------- /openportfolioapp/static/css/print.css: -------------------------------------------------------------------------------- 1 | /*Reset Style*/ 2 | body {margin:0; padding:0; line-height: 1.4em; word-spacing:1px; letter-spacing:0.2px; font: 13px Arial, Helvetica,"Lucida Grande", serif; color: #000;} 3 | 4 | /*Remove Element*/ 5 | #header,#footer,#available {display:none;} 6 | 7 | /* Show URL */ 8 | a:link, a:visited {background: transparent; color:#333; text-decoration:none;} 9 | a:link[href^="http://"]:after, a[href^="http://"]:visited:after {content: " (" attr(href) ") "; font-size: 11px;} 10 | a[href^="http://"] {color:#000;} 11 | -------------------------------------------------------------------------------- /openportfolioapp/templates/admin/base_site.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base.html" %} 2 | {% load i18n %} 3 | {% block extrastyle %} 4 | 5 | {% endblock %} 6 | 7 | {% block title %}{{ title }} | {% trans 'Open Portfolio' %}{% endblock %} 8 | 9 | {% block branding %} 10 |

{% trans 'Open Portfolio' %}

11 | {% endblock %} 12 | 13 | {% block nav-global %}{% endblock %} 14 | -------------------------------------------------------------------------------- /openportfolioapp/templates/base.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | OpenPortfolio: {% block title %}Home{% endblock %} 6 | 7 | 8 | 9 | 10 | {% block feeds %}{% endblock %} 11 | 12 | {% block extra_scripts %}{% endblock %} 13 | {% url 'admin:jsi18n' as jsi18nurl %} 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 36 | 37 | 38 | 39 | {% if messages %} 40 | {% for message in messages %} 41 |
42 |

{{ message }}

43 |
44 | {% endfor %} 45 | {% endif %} 46 | 47 |

{% block content_header %}{% endblock %}

48 |
49 |
50 | {% block content %} 51 | {% endblock %} 52 |
53 |
54 | 55 | 67 | 68 | -------------------------------------------------------------------------------- /openportfolioapp/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block title %}Open Portfolio{% endblock %} 3 | {% block content %} 4 | 5 |

Welcome

6 |

Open Portfolio can be used to manage and monitor the returns and risks of a portfolio of investments such as listed equities and fixed income securities.

7 | 8 | 13 | {% endblock %} -------------------------------------------------------------------------------- /openportfolioapp/templates/investment/list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load openportfolioapp_extras %} 3 | 4 | {% block title %}Investments{% endblock %} 5 | {% block content %} 6 | 7 | {% if investment_list %} 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {% for i in investment_list %} 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | {% endfor %} 29 | 30 | 31 |
InvestmentLatest PricePrice Date 
{{i.name}}{{i.latest_price}}{{i.latest_price_date}}Edit | Report
32 | 33 | {% else %} 34 | No entries 35 | {% endif %} 36 | {% endblock %} -------------------------------------------------------------------------------- /openportfolioapp/templates/investment/price_chart.html: -------------------------------------------------------------------------------- 1 | 77 |
-------------------------------------------------------------------------------- /openportfolioapp/templates/investment/price_table.html: -------------------------------------------------------------------------------- 1 | {% load pyformat %} 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% for p in prices %} 14 | 15 | 16 | 17 | 18 | 19 | {% endfor %} 20 |
DatePriceReturn
{{p.date|date:"M-Y"}}{% pyformat p.price "{0:.2f}" %}{% pyformat p.return format %}
21 |
-------------------------------------------------------------------------------- /openportfolioapp/templates/investment/report.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load openportfolioapp_extras %} 3 | 4 | {% block title %}Investment Analysis{% endblock %} 5 | {% block content %} 6 | 7 |

Summary

8 | 9 | Name: {{ object.name }}
10 | Company: {{ object.company.name }}
11 | Asset Class: {{ object.asset_class.name }}
12 | Sector: {{ object.company.gics_sector.name }}
13 | Currency: {{ object.currency.code }}
14 | Latest Price: {{ object.latest_price|currency:object.currency.locale_code}} ({{object.latest_price_date|date:"d-M-Y"}})
15 | Mean: {{ object.mean|currency:object.currency.locale_code }}
16 | 17 | 18 | {% if object.content_type.model == 'listedequity' %} 19 | 20 |

Price Chart

21 | {{object.investment_chart}} 22 | 23 | {% endif %} 24 | 25 |

Price Table

26 | {{object.price_table}} 27 | 28 | {% endblock %} -------------------------------------------------------------------------------- /openportfolioapp/templates/login.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load url from future %} 3 | 4 | {% block content %} 5 | 6 | {% if form.errors %} 7 |

Your username and password didn't match. Please try again.

8 | {% endif %} 9 | 10 |
11 | {% csrf_token %} 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
{{ form.username.label_tag }}{{ form.username }}
{{ form.password.label_tag }}{{ form.password }}
22 | 23 | 24 | 25 |
26 | 27 | {% endblock %} -------------------------------------------------------------------------------- /openportfolioapp/templates/logout.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Open Portfolio{% endblock %} 4 | {% block content %} 5 | 6 | 7 | You have been successfully logged out. 8 | 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /openportfolioapp/templates/portfolio/holdings_table.html: -------------------------------------------------------------------------------- 1 | {% load openportfolioapp_extras %} 2 | {% load pyformat %} 3 | 4 | 5 | 6 | 7 | {% for f in fields %} 8 | {% if f.format == 'rc' %} 9 | 10 | {%else%} 11 | 12 | {%endif%} 13 | {% endfor %} 14 | 15 | 16 | 17 | {% for i in df.index %} 18 | {% dataframe_xs df,i as xs %} 19 | 20 | 21 | 22 | {% for f in fields %} 23 | 24 | {% if f.format == 'lc' %} 25 | 26 | {%else%} 27 | {% if f.format == 'rc' %} 28 | 29 | {%else%} 30 | 31 | {%endif%} 32 | {%endif%} 33 | {% endfor %} 34 | 35 | {%endfor%} 36 | 37 | 38 | 39 | 40 | {% for f in fields %} 41 | {% if f.total == None %} 42 | 43 | {%else%} 44 | {% if f.format == 'rc' %} 45 | 46 | {%else%} 47 | 48 | {%endif%} 49 | {%endif%} 50 | {% endfor %} 51 | 52 | 53 | 54 | 55 | 56 |
Name{{f.label}} ({{report_currency.code}}){{f.label}}
{{i.name}}{{xs|hash:f.key|currency:i.currency.locale_code}}{{xs|hash:f.key|currency:report_currency.locale_code}}{% pyformat xs|hash:f.key f.format %}
TOTAL {{df|hash:f.key|call:f.total|currency:report_currency.locale_code}}{% pyformat df|hash:f.key|call:f.total f.format %}
-------------------------------------------------------------------------------- /openportfolioapp/templates/portfolio/list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block title %}Portfolios{% endblock %} 3 | {% block content %} 4 | 5 | {% if portfolio_list %} 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | {% for p in portfolio_list %} 17 | 18 | 19 | 20 | 21 | 22 | {% endfor %} 23 | 24 | 25 |
Portfolio 
{{p.full_name}}Edit | Report
26 | 27 | {% else %} 28 | No entries 29 | {% endif %} 30 | {% endblock %} -------------------------------------------------------------------------------- /openportfolioapp/templates/portfolio/price_chart.html: -------------------------------------------------------------------------------- 1 | 85 |
-------------------------------------------------------------------------------- /openportfolioapp/templates/portfolio/price_table.html: -------------------------------------------------------------------------------- 1 | {% load pyformat %} 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {% for p in prices %} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | {% endfor %} 25 |
DatePortfolioReturnBenchmarkReturnActive Return
{{p.date|date:"M-Y"}}{% pyformat p.MVp "{0:.2f}" %}{% pyformat p.Rp format %}{% pyformat p.MVb "{0:.2f}" %}{% pyformat p.Rb format %}{% pyformat p.Ra format %}
26 |
-------------------------------------------------------------------------------- /openportfolioapp/templates/portfolio/report.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load openportfolioapp_extras %} 3 | 4 | {% block title %}Portfolio Analysis{% endblock %} 5 | {% block content %} 6 | 7 |

Portfolio Report as at {{end_dt|date:"d-M-Y"}}

8 | 9 | Name: {{ portfolio.name }}
10 | Benchmark: {{ portfolio.bm.name }}
11 | Market Value: {{portfolio|args:end_dt|args:report_currency|call:"market_value_as_at"|currency:report_currency.locale_code}} 12 | 13 | 14 | 15 |

Holdings

16 | 17 | {{ holdings_table}} 18 | 19 |

Price Chart

20 | {{portfolio.price_chart}} 21 | 22 |

Price Table

23 | 24 | {{ price_table}} 25 | 26 | 27 | 28 | 29 | {% endblock %} -------------------------------------------------------------------------------- /openportfolioapp/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evandavey/django-openportfolio/6192d1ed4d80db4baec412a4332f9c4b244f0414/openportfolioapp/templatetags/__init__.py -------------------------------------------------------------------------------- /openportfolioapp/templatetags/pyformat.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from django.conf import settings 3 | 4 | class PyFormatNode(template.Node): 5 | def __init__(self, variable, format_str): 6 | self.variable = variable 7 | self.format_str = format_str 8 | 9 | def render(self, context): 10 | try: 11 | var = self.variable.resolve(context) 12 | format = self.format_str.resolve(context) 13 | 14 | return format . format(var) 15 | except: 16 | if settings.TEMPLATE_DEBUG: 17 | raise 18 | return '' 19 | 20 | def do_pyformat(parser, token): 21 | tag_name, variable, format_str = token.split_contents() 22 | return PyFormatNode(parser.compile_filter(variable), 23 | parser.compile_filter(format_str), 24 | ) 25 | 26 | register = template.Library() 27 | register.tag('pyformat', do_pyformat) -------------------------------------------------------------------------------- /openportfolioapp/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls.defaults import * 2 | from openportfolioapp.models import Investment,Portfolio 3 | from django.views.generic import DetailView, ListView 4 | from django.conf import settings 5 | 6 | 7 | urlpatterns = patterns('', 8 | 9 | (r'^$', 10 | ListView.as_view( 11 | queryset=Investment.objects.all, 12 | context_object_name='investment_list', 13 | template_name='index.html')), 14 | 15 | ) 16 | 17 | 18 | 19 | """ 20 | URLS - Portfolio 21 | """ 22 | urlpatterns += patterns('openportfolioapp.views.portfolio', 23 | (r'^portfolio/(?P\d+)/report/(?:(?P\w+)/(?P
\d+)/)?$', 24 | 'report', 25 | None, 26 | 'portfolio_report'), 27 | 28 | 29 | (r'^portfolio/$', 30 | 'list', 31 | None, 32 | 'portfolio_list'), 33 | 34 | ) 35 | 36 | 37 | 38 | """ 39 | URLS - Investment 40 | """ 41 | urlpatterns += patterns('openportfolioapp.views.investment', 42 | 43 | (r'^investment/$', 44 | 'list', 45 | None, 46 | 'investment_list'), 47 | 48 | (r'^investment/(?P\d+)/report/(?:(?P\d+)/(?P\d+)/)?$', 49 | 'report', 50 | None, 51 | 'investment_report'), 52 | ) 53 | -------------------------------------------------------------------------------- /openportfolioapp/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from utils import * -------------------------------------------------------------------------------- /openportfolioapp/utils/currencyhistory.py: -------------------------------------------------------------------------------- 1 | import urllib 2 | import urllib2 3 | from datetime import * 4 | from BeautifulSoup import BeautifulSoup 5 | import re 6 | from decimal import * 7 | import pandas as ps 8 | 9 | def fetch_ukforex_historical_exchange_rates(startdate,enddate,curr1,curr2): 10 | 11 | 12 | sStartDate=startdate.strftime('%Y-%m-%d') 13 | sEndDate=enddate.strftime('%Y-%m-%d') 14 | 15 | print 'Getting exchange rates....%s%s' % (curr1,curr2) 16 | 17 | url = 'http://www.chartflow.com/fx/historybasic.asp' 18 | values = {'dateFrom1' : sStartDate, 19 | 'dateTo1' : sEndDate, 20 | 'ccy1' : curr1, 21 | 'ccy2' : curr2, 22 | 'rounder': 6, 23 | 'period' : 'exact' 24 | } 25 | 26 | data = urllib.urlencode(values) 27 | req = urllib2.Request(url, data) 28 | response = urllib2.urlopen(req) 29 | html = response.read() 30 | 31 | 32 | 33 | soup = BeautifulSoup(''.join(html)) 34 | dataTable=soup.find(text=re.compile("Results Of")).findPrevious('table') 35 | 36 | cols = dataTable.findAll('td') 37 | 38 | dates = [datetime.strptime(cols[i].string,'%d/%m/%Y') for i in range(2,len(cols)-2,2)] 39 | values = [Decimal(cols[i].string) for i in range(3,len(cols)-2,2)] 40 | 41 | 42 | df=ps.DataFrame({'crossrate':values},index=dates) 43 | 44 | print "...fetched" 45 | 46 | return df 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /openportfolioapp/utils/update_helpers.py: -------------------------------------------------------------------------------- 1 | from openportfolioapp.models import Investment 2 | from openportfolioapp.models import Currency 3 | from openportfolioapp.models import Portfolio 4 | 5 | def fetch_investment_prices(startdate,enddate): 6 | 7 | print 'updating prices between %s-%s' % (startdate,enddate) 8 | for i in Investment.objects.all(): 9 | 10 | pdf=i.fetch_price_frame(startdate,enddate) 11 | 12 | if pdf is not None: 13 | i.save_price_frame(pdf) 14 | 15 | pdf=None 16 | 17 | def fetch_currency_prices(startdate,enddate): 18 | 19 | for c in Currency.objects.all(): 20 | pdf=c.fetch_price_frame(startdate,enddate) 21 | 22 | if pdf is not None: 23 | c.save_price_frame(pdf) 24 | 25 | pdf=None 26 | 27 | def update_portfolio_prices(startdate,endate): 28 | 29 | for p in Portfolio.objects.all(): 30 | 31 | pdf=p.load_holdings_frame(startdate,enddate) 32 | 33 | if pdf is not None: 34 | p.save_holdings_frame(pdf) 35 | 36 | pdf=None 37 | 38 | -------------------------------------------------------------------------------- /openportfolioapp/utils/utils.py: -------------------------------------------------------------------------------- 1 | 2 | def full_name(obj): 3 | """ Returns a parent/child representation of this object 4 | eg: parent::child1::child_of_child1 5 | """ 6 | p_list=[] #empty list to store parent names 7 | parent=None 8 | while True: 9 | try: 10 | if parent is None: #first time through loop 11 | parent=obj.parent 12 | else: 13 | parent=parent.parent 14 | 15 | #No parent, stop looping. ObjectDoesNotExist doesn't seem to trigger on new save() 16 | if parent is None: 17 | break 18 | 19 | p_list.append(parent.name) 20 | except ObjectDoesNotExist: #No parent, stop looping 21 | break 22 | 23 | p_list.reverse() 24 | p_list.append(obj.name) 25 | 26 | return "::".join(p_list) -------------------------------------------------------------------------------- /openportfolioapp/views/__init__.py: -------------------------------------------------------------------------------- 1 | from portfolio import * 2 | from investment import * 3 | -------------------------------------------------------------------------------- /openportfolioapp/views/investment.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render_to_response 2 | from django.template import RequestContext 3 | from django.contrib.auth.decorators import login_required 4 | 5 | 6 | from datetime import * 7 | 8 | from openportfolioapp.models import Investment 9 | from pandas.core.datetools import MonthEnd 10 | 11 | @login_required(login_url='/accounts/login') 12 | def list(request): 13 | 14 | 15 | ct={'investment_list':Investment.objects.all()} 16 | 17 | 18 | return render_to_response('investment/list.html',ct,context_instance=RequestContext(request)) 19 | 20 | 21 | @login_required(login_url='/accounts/login') 22 | def report(request,investment_id,enddate=None,startdate=None): 23 | 24 | #workaround subclassing not working on objects.get() 25 | investment=Investment.objects.filter(pk=investment_id) 26 | investment=investment[0] 27 | 28 | if enddate is None: 29 | enddate = datetime.today() 30 | 31 | else: 32 | enddate=datetime.strptime(enddate,'%Y%m%d') 33 | 34 | if startdate is None: 35 | startdate = enddate-12*MonthEnd() 36 | else: 37 | startdate=datetime.strptime(startdate,'%Y%m%d') 38 | 39 | 40 | ct={'object':investment, 41 | 'end_dt':enddate, 42 | 'start_dt':startdate, 43 | 44 | } 45 | 46 | 47 | return render_to_response('investment/report.html',ct,context_instance=RequestContext(request)) 48 | 49 | -------------------------------------------------------------------------------- /openportfolioapp/views/portfolio.py: -------------------------------------------------------------------------------- 1 | from datetime import * 2 | from django.template import Context, loader 3 | from django.shortcuts import render_to_response 4 | from django.template import RequestContext 5 | from openportfolioapp.models import Portfolio,Currency,Trade 6 | from pandas.core.datetools import MonthEnd,YearEnd 7 | 8 | from django.contrib.auth.decorators import login_required 9 | 10 | DEFAULT_CURRENCY='AUD' 11 | DEFAULT_ANALYSIS_FIELD='asset_class' 12 | 13 | 14 | @login_required(login_url='/accounts/login') 15 | def list(request): 16 | 17 | 18 | ct={'portfolio_list':Portfolio.objects.all()} 19 | 20 | 21 | return render_to_response('portfolio/list.html',ct,context_instance=RequestContext(request)) 22 | 23 | @login_required(login_url='/accounts/login') 24 | def report(request,portfolio_id,currency='AUD',dt=None,startdate=None): 25 | 26 | portfolio=Portfolio.objects.get(pk=portfolio_id) 27 | 28 | 29 | if currency is None: 30 | currency=DEFAULT_CURRENCY 31 | 32 | if dt is None: 33 | dt=datetime.today()-MonthEnd() 34 | else: 35 | dt=datetime.strptime(dt,'%Y%m%d') 36 | 37 | 38 | end_dt=datetime(dt.year,dt.month,1)+MonthEnd() 39 | 40 | if startdate is None: 41 | start_dt=end_dt-MonthEnd() 42 | 43 | 44 | rc=Currency.objects.get(pk=currency) 45 | 46 | ct={'portfolio':portfolio, 47 | 'holdings_table':portfolio.holdings_table(start_dt,end_dt,rc), 48 | 'price_table':portfolio.price_table(start_dt,end_dt,rc), 49 | 'report_currency': rc, 50 | 'end_dt':end_dt, 51 | 'start_dt':start_dt, 52 | 53 | } 54 | 55 | 56 | return render_to_response('portfolio/report.html',ct,context_instance=RequestContext(request)) 57 | 58 | -------------------------------------------------------------------------------- /requirements/development.txt: -------------------------------------------------------------------------------- 1 | #core libraries 2 | django 3 | PyYAML 4 | mysql-python 5 | south 6 | 7 | #html parsing for fx downloads 8 | BeautifulSoup 9 | 10 | #maths libraries 11 | numpy 12 | pandas 13 | -e git://github.com/matplotlib/matplotlib.git#egg=matplotlib 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /requirements/production.txt: -------------------------------------------------------------------------------- 1 | #core libraries 2 | django 3 | PyYAML 4 | mysql-python 5 | south 6 | 7 | #html parsing for fx downloads 8 | BeautifulSoup 9 | 10 | #maths libraries 11 | numpy 12 | pandas 13 | -e git://github.com/matplotlib/matplotlib.git#egg=matplotlib 14 | -------------------------------------------------------------------------------- /requirements/staging.txt: -------------------------------------------------------------------------------- 1 | #core libraries 2 | django 3 | PyYAML 4 | mysql-python 5 | south 6 | 7 | #html parsing for fx downloads 8 | BeautifulSoup 9 | 10 | #maths libraries 11 | numpy 12 | pandas 13 | -e git://github.com/matplotlib/matplotlib.git#egg=matplotlib 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /settings_development.py: -------------------------------------------------------------------------------- 1 | from openportfolio.settings import * 2 | 3 | DEBUG = True 4 | 5 | TEMPLATE_DIRS=('/Users/evandavey/Documents/openportfolio/openportfolioapp/templates/') 6 | 7 | DATABASE_ENGINE = 'sqlite3' 8 | DATABASE_NAME = 'openportfolio.db' 9 | -------------------------------------------------------------------------------- /settings_production.py: -------------------------------------------------------------------------------- 1 | from openportfolio.settings import * 2 | 3 | DEBUG = False 4 | 5 | 6 | STATIC_ROOT = '/usr/local/web/django/www/production/openportfolio/static' 7 | MEDIA_ROOT = '/usr/local/web/django/www/production/openportfolio/media' 8 | 9 | TEMPLATE_DIRS = ('/usr/local/web/django/www/production/openportfolio/openportfolioapp/templates') 10 | 11 | DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. 12 | DATABASE_NAME = 'openportfolio' # Or path to database file if using sqlite3. 13 | DATABASE_USER = 'openportfolio' # Not used with sqlite3. 14 | DATABASE_PASSWORD = 'openportfolio' # Not used with sqlite3. 15 | DATABASE_HOST = 'localhost' # Set to empty string for localhost. Not used with sqlite3. 16 | DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. 17 | 18 | -------------------------------------------------------------------------------- /settings_staging.py: -------------------------------------------------------------------------------- 1 | from openportfolio.settings import * 2 | 3 | DEBUG = True 4 | 5 | 6 | STATIC_ROOT = '/usr/local/web/django/www/staging/openportfolio/static' 7 | MEDIA_ROOT = '/usr/local/web/django/www/staging/openportfolio/media' 8 | 9 | TEMPLATE_DIRS = ('/usr/local/web/django/www/staging/openportfolio/openportfolioapp/templates') 10 | 11 | 12 | DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. 13 | DATABASE_NAME = 'staging_openportfolio' # Or path to database file if using sqlite3. 14 | DATABASE_USER = 'openportfolio' # Not used with sqlite3. 15 | DATABASE_PASSWORD = 'openportfolio' # Not used with sqlite3. 16 | DATABASE_HOST = 'localhost' # Set to empty string for localhost. Not used with sqlite3. 17 | DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. 18 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # This program is free software: you can redistribute it and/or modify 2 | # it under the terms of the GNU Affero General Public License as 3 | # published by the Free Software Foundation, either version 3 of the 4 | # License, or (at your option) any later version. 5 | # 6 | # This program is distributed in the hope that it will be useful, 7 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | # GNU Affero General Public License for more details. 10 | # 11 | # You should have received a copy of the GNU Affero General Public License 12 | # along with this program. If not, see . 13 | 14 | import distribute_setup 15 | distribute_setup.use_setuptools('0.6.10') 16 | 17 | from setuptools import setup, find_packages 18 | 19 | try: 20 | README = open('README.md').read() 21 | except: 22 | README = None 23 | 24 | try: 25 | REQUIREMENTS = open('requirements/apps.txt').read() 26 | except: 27 | REQUIREMENTS = None 28 | 29 | setup( 30 | name = 'django-openportfolio', 31 | version = "0.1.0", 32 | description = 'Django app for managing personal finances', 33 | long_description = README, 34 | install_requires=REQUIREMENTS, 35 | author = 'Evan Davey', 36 | author_email = 'evan.j.davey@gmail.com', 37 | url = 'http://github.com/evandavey/OpenPortfolio/', 38 | packages = find_packages(), 39 | include_package_data = True, 40 | classifiers = ['Development Status :: 1 - Planning', 41 | 'Environment :: Web Environment', 42 | 'Framework :: Django', 43 | 'Intended Audience :: Developers', 44 | 'License :: OSI Approved :: GNU Affero General Public License v3', 45 | 'Operating System :: OS Independent', 46 | 'Programming Language :: Python', 47 | 'Topic :: Utilities'], 48 | ) 49 | -------------------------------------------------------------------------------- /update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | source /usr/local/web/django/www/production/env/openportfolio/bin/activate 3 | /usr/local/web/django/www/production/openportfolio/manage.py openportfolio-update --settings=openportfolio.settings_production 4 | -------------------------------------------------------------------------------- /urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls.defaults import patterns, include, url 2 | from django.conf import settings 3 | 4 | # Uncomment the next two lines to enable the admin: 5 | from django.contrib import admin 6 | admin.autodiscover() 7 | 8 | urlpatterns = patterns('', 9 | # Examples: 10 | # url(r'^$', 'django_cochranedavey.views.home', name='home'), 11 | 12 | (r'^$',include('openportfolioapp.urls')), 13 | 14 | url(r'^openportfolioapp/', include('openportfolioapp.urls')), 15 | 16 | # Uncomment the admin/doc line below to enable admin documentation: 17 | # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), 18 | 19 | # Uncomment the next line to enable the admin: 20 | url(r'^admin/', include(admin.site.urls)), 21 | ) 22 | 23 | """ 24 | URLS - Accounts 25 | """ 26 | urlpatterns += patterns('', 27 | (r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}), 28 | (r'^accounts/logout/$', 'django.contrib.auth.views.logout',{'template_name': 'logout.html'}) 29 | ) 30 | 31 | if settings.DEBUG: 32 | urlpatterns += patterns('', 33 | (r'^static/(?P.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}), 34 | (r'^media/(?P.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT,}), 35 | ) --------------------------------------------------------------------------------