Showing preview only (528K chars total). Download the full file or copy to clipboard to get everything.
Repository: hootnot/oanda-api-v20
Branch: master
Commit: fe8a101cbcf9
Files: 187
Total size: 481.8 KB
Directory structure:
gitextract_zbddjf3w/
├── .gitignore
├── .landscape.yml
├── .travis.yml
├── CHANGELOG.rst
├── LICENSE.md
├── MANIFEST.in
├── README.rst
├── docs/
│ ├── Makefile
│ ├── conf.py
│ ├── contrib/
│ │ ├── factories/
│ │ │ └── instrumentscandlesfactory.rst
│ │ ├── factories.rst
│ │ ├── generic/
│ │ │ └── generic.rst
│ │ ├── generic.rst
│ │ ├── orders/
│ │ │ ├── limitorderrequest.rst
│ │ │ ├── marketorderrequest.rst
│ │ │ ├── mitorderrequest.rst
│ │ │ ├── positionscloserequest.rst
│ │ │ ├── stoplossorderrequest.rst
│ │ │ ├── stoporderrequest.rst
│ │ │ ├── takeprofitorderrequest.rst
│ │ │ ├── tradecloserequest.rst
│ │ │ └── trailingstoplossorderrequest.rst
│ │ ├── orders.rst
│ │ ├── support/
│ │ │ ├── clientextensions.rst
│ │ │ ├── stoplossdetails.rst
│ │ │ ├── takeprofitdetails.rst
│ │ │ └── trailingstoplossdetails.rst
│ │ └── support.rst
│ ├── dirstruct.py
│ ├── endpoints/
│ │ ├── accounts/
│ │ │ ├── accountchanges.rst
│ │ │ ├── accountconfiguration.rst
│ │ │ ├── accountdetails.rst
│ │ │ ├── accountinstruments.rst
│ │ │ ├── accountlist.rst
│ │ │ └── accountsummary.rst
│ │ ├── accounts.rst
│ │ ├── forexlabs/
│ │ │ ├── autochartist.rst
│ │ │ ├── calendar.rst
│ │ │ ├── commitmentsoftraders.rst
│ │ │ ├── historicalpositionratios.rst
│ │ │ ├── orderbookdata.rst
│ │ │ └── spreads.rst
│ │ ├── forexlabs.rst
│ │ ├── instruments/
│ │ │ ├── instrumentlist.rst
│ │ │ ├── instrumentorderbook.rst
│ │ │ └── instrumentpositionbook.rst
│ │ ├── instruments.rst
│ │ ├── orders/
│ │ │ ├── ordercancel.rst
│ │ │ ├── orderclientextensions.rst
│ │ │ ├── ordercreate.rst
│ │ │ ├── orderdetails.rst
│ │ │ ├── orderlist.rst
│ │ │ ├── orderreplace.rst
│ │ │ └── orderspending.rst
│ │ ├── orders.rst
│ │ ├── positions/
│ │ │ ├── openpositions.rst
│ │ │ ├── positionclose.rst
│ │ │ ├── positiondetails.rst
│ │ │ └── positionlist.rst
│ │ ├── positions.rst
│ │ ├── pricing/
│ │ │ ├── pricinginfo.rst
│ │ │ └── pricingstream.rst
│ │ ├── pricing.rst
│ │ ├── trades/
│ │ │ ├── opentrades.rst
│ │ │ ├── tradeCRCDO.rst
│ │ │ ├── tradeclientextensions.rst
│ │ │ ├── tradeclose.rst
│ │ │ ├── tradedetails.rst
│ │ │ └── tradeslist.rst
│ │ ├── trades.rst
│ │ ├── transactions/
│ │ │ ├── transactiondetails.rst
│ │ │ ├── transactionidrange.rst
│ │ │ ├── transactionlist.rst
│ │ │ ├── transactionssinceid.rst
│ │ │ └── transactionsstream.rst
│ │ └── transactions.rst
│ ├── examples.rst
│ ├── index.rst
│ ├── installation.rst
│ ├── oanda-api-v20.rst
│ ├── oandapyV20.contrib.rst
│ ├── oandapyV20.definitions.accounts.rst
│ ├── oandapyV20.definitions.instruments.rst
│ ├── oandapyV20.definitions.orders.rst
│ ├── oandapyV20.definitions.pricing.rst
│ ├── oandapyV20.definitions.rst
│ ├── oandapyV20.definitions.trades.rst
│ ├── oandapyV20.definitions.transactions.rst
│ ├── oandapyV20.endpoints.rst
│ ├── oandapyV20.types.rst
│ └── types/
│ ├── AccountID.rst
│ ├── AccountUnits.rst
│ ├── ClientComment.rst
│ ├── ClientID.rst
│ ├── ClientTag.rst
│ ├── DateTime.rst
│ ├── OrderID.rst
│ ├── OrderIdentifier.rst
│ ├── OrderSpecifier.rst
│ ├── PriceValue.rst
│ ├── TradeID.rst
│ └── Units.rst
├── examples/
│ └── README.rst
├── jupyter/
│ ├── account.txt
│ ├── accounts.ipynb
│ ├── exampleauth/
│ │ ├── __init__.py
│ │ └── exampleauth.py
│ ├── exceptions.ipynb
│ ├── historical.ipynb
│ ├── index.ipynb
│ ├── orders.ipynb
│ ├── positions.ipynb
│ ├── streams.ipynb
│ ├── token.txt
│ └── trades.ipynb
├── oandapyV20/
│ ├── __init__.py
│ ├── contrib/
│ │ ├── __init__.py
│ │ ├── factories/
│ │ │ ├── __init__.py
│ │ │ └── history.py
│ │ ├── generic.py
│ │ └── requests/
│ │ ├── __init__.py
│ │ ├── baserequest.py
│ │ ├── extensions.py
│ │ ├── limitorder.py
│ │ ├── marketorder.py
│ │ ├── mitorder.py
│ │ ├── onfill.py
│ │ ├── positionclose.py
│ │ ├── stoplossorder.py
│ │ ├── stoporder.py
│ │ ├── takeprofitorder.py
│ │ ├── tradeclose.py
│ │ └── trailingstoplossorder.py
│ ├── definitions/
│ │ ├── __init__.py
│ │ ├── accounts.py
│ │ ├── instruments.py
│ │ ├── orders.py
│ │ ├── pricing.py
│ │ ├── primitives.py
│ │ ├── trades.py
│ │ └── transactions.py
│ ├── endpoints/
│ │ ├── __init__.py
│ │ ├── accounts.py
│ │ ├── apirequest.py
│ │ ├── decorators.py
│ │ ├── forexlabs.py
│ │ ├── instruments.py
│ │ ├── orders.py
│ │ ├── positions.py
│ │ ├── pricing.py
│ │ ├── responses/
│ │ │ ├── __init__.py
│ │ │ ├── accounts.py
│ │ │ ├── forexlabs.py
│ │ │ ├── instruments.py
│ │ │ ├── orders.py
│ │ │ ├── positions.py
│ │ │ ├── pricing.py
│ │ │ ├── trades.py
│ │ │ └── transactions.py
│ │ ├── trades.py
│ │ └── transactions.py
│ ├── exceptions.py
│ ├── oandapyV20.py
│ └── types/
│ ├── __init__.py
│ └── types.py
├── readthedocs.yml
├── requirements.txt
├── setup.py
└── tests/
├── __init__.py
├── account.txt
├── test_accounts.py
├── test_contrib_factories.py
├── test_contrib_generic.py
├── test_contrib_orders.py
├── test_decorators.py
├── test_definitions.py
├── test_forexlabs.py
├── test_instruments.py
├── test_oandapyv20.py
├── test_orders.py
├── test_positions.py
├── test_pricing.py
├── test_trades.py
├── test_transactions.py
├── test_types.py
├── token.txt
└── unittestsetup.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml
# Translations
*.mo
*.pot
# Django stuff:
*.log
# Sphinx documentation
docs/_build/
# PyBuilder
target/
================================================
FILE: .landscape.yml
================================================
inherits: [flake8]
================================================
FILE: .travis.yml
================================================
language: python
python:
- '3.6'
- '3.7'
- '3.8'
- '3.9'
install:
- pip install --upgrade pip setuptools
- pip install requests-mock
- pip install coveralls
- pip install nose nose-parameterized
- pip install wheel
- pip install twine
script:
- coverage run --source=oandapyV20 setup.py test
after_success:
- coveralls
deploy:
provider: pypi
user: hootnot
password:
secure: Jr+/eYSrysSQcSaC8gW5TJak3AycoMlPe3QfOE/CV7n9RYn5JsXudUhWTFiC4c78CAGu14F3Iu6TQPiC0CZrWc04Gi9H1xnWniAXRsr8xKiSfyL1zpHRoBmP6zbdOGc6zk8Jjit1YUNSdp2W/YA7Ii1BwwLQ/h+er8IqZxoGNs3kh51G/2dYOU085VELbz9S1um27e+oJuAOurrfZiPGdjnnUVALfQcuRrEWRS3Cc+1LDiKbHWD1dBlVvf71okyBAd2gnT+bBjCpKiBmjHzEnRO2mdjPBA+2lOI8EOr0E3Ueb/9q3ID3H9UPnb2ZL9VhqxutLVB0fEbHpiAPcG7MPwKN8EWTDIPDGUP9/DEUDX0qV0eybP8yl/5+2l4np0a+cqSkHJfeLZwxixaOs02qP6SMScxfsf+N6BhlIKCpNnESkpsdESlkgG0lxkoJVOR8Pf0otTd0lIjLl/Iy4I7SoRwFNHiUg1naQHIVvbFdsYeM0KZQUQtLEUN/pcjZkRJsHkZHZNo/KSB27xECbPUcrzBorMc8EL1s9H51q8HhhDufnAel3Y0IW3aMR4cN3gX0H+udEEbWgeVf7p7xZESJgmntYoHWICpzK2uNvxJZ2+gkJQKPL4fERSskjo+7UUf6mwi32HNk0oAOyGDGxtgbCEyZ0GazZLzFYAIsiR1Uj88=
on:
tags: true
distributions: sdist bdist_wheel
repo: hootnot/oanda-api-v20
================================================
FILE: CHANGELOG.rst
================================================
Changelog
=========
[Unreleased]
------------
v0.7.2 (2021-08-26)
-------------------
Documentation Changes
~~~~~~~~~~~~~~~~~~~~~
- [endpoints] fix -> trades.TradeDetails
v0.7.1 (2021-08-15)
-------------------
Bug Fixes
~~~~~~~~~
- [types] make Units handle up to 2 decimals (was 1)
v0.7.0 (2021-05-25)
-------------------
Bug Fixes
~~~~~~~~~
- [test] test_orders: fix fail python 3.9
- [types] make Units handle up to 1 decimal
Documentation Changes
~~~~~~~~~~~~~~~~~~~~~
- using the with context
Administration and Chores
~~~~~~~~~~~~~~~~~~~~~~~~~
- rename CHANGES.txt -> CHANGELOG.rst
- [versions] support Python 3.5 - 3.9
Version 0.6.3
-------------
2018/04/12
update of definitions according v20-openapi release 3.0.22
Version 0.6.2
-------------
2018/04/07
granularity_to_time now also handles weekly 'W' as parameter,
see PR #119. Tests added.
Version 0.6.1
-------------
2018/03/31
InstrumentsCandlesFactory fix, incorrect handling of parameters
in the rare case one would not specify the 'from' parameter,
see PR #117
Version 0.6.0
-------------
2018/03/07
support added for the (legacy) forexlabs endpoints, #110. See
developer.oanda.com for details.
Version 0.5.0
-------------
2018/02/18
update various definitions as OANDA added these to their docs
Version 0.4.5
-------------
2017/09/25
force 'includeFirst' in InstrumentsCandlesFactory, #100
Version 0.4.4
-------------
2017/09/23
fix bug in InstrumentsCandlesFactory skipping the last request, #97
Version 0.4.3
-------------
2017/08/21
fix missing gtdTime in LimitOrderRequest, #94
Version 0.4.2
-------------
2017/07/24
fix possible 'date is in the future' error when retrieving candledata
using InstrumentsCandlesFactory
Version 0.4.1
-------------
2017/07/11:
bugfix, see pr #85
Version 0.4.0
-------------
2017/07/04:
contrib.factories added, pr #81:
InstrumentsCandlesFactory to generate InstrumentsCandles requests
Version 0.3.0
-------------
2017/06/28:
Recently released extra instruments endpoints added, pr #77:
/v3/instruments/{instrument}/orderBook
/v3/instruments/{instrument}/positionBook
Version 0.2.4
-------------
2017/05/15:
documentation fix regarding incorrect output references of
AccountList and AccountDetails, #pr 73
Version 0.2.3
-------------
2017/04/17:
fix: trades.TradesList unhandled params, issue #69
2017/03/09:
jupyter notebooks added
2017/02/08:
Python 3.6 added
2017/01/30:
datetime name conflict solved, issue #62
2016/12/05:
documentation: dynamically generated types directory tree
types: DateTime subsecond part fix
2016/12/05:
fixes OrderSpecifier
2016/12/01:
extend types with DateTime
2016/11/17:
bug streaming prices: list values need to be joined, solved #50
Version 0.2.2
-------------
2016/11/17:
extend types with AccountID
definitions
increase coverage
contrib.request classes timeInForce parameter add and/or verify
against allowed values
Version 0.2.1
-------------
2016/11/15:
* documentation updates
* missing requirement: six added
Version 0.2.0
-------------
2016/11/15:
* first release with coverage of all endpoints except the 'forexlabs'
* definitions covered as in the development documeintation
* types representing data types as in the development documeintation
* contrib.requests: classes to construct data for requestbodies
================================================
FILE: LICENSE.md
================================================
The MIT License (MIT)
Copyright (c) 2016 Feite Brekeveld
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: MANIFEST.in
================================================
include requirements.txt
include LICENSE.md
================================================
FILE: README.rst
================================================
OANDA REST-V20 API wrapper
==========================
.. _Top:
As of march 2018 OANDA no longer supports the v1 REST-API. The only pending
V20 endpoint was the *forexlabs endpoint*. Instead of launching *forexlabs*
as a *V20-endpoint*, OANDA choose to support this endpoint from the v1
REST interface, see: http://developer.oanda.com/rest-live-v20/forexlabs-ep/.
.. image:: https://travis-ci.org/hootnot/oanda-api-v20.svg?branch=master
:target: https://travis-ci.org/hootnot/oanda-api-v20
:alt: Build
.. image:: https://readthedocs.org/projects/oanda-api-v20/badge/?version=latest
:target: http://oanda-api-v20.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. image:: https://landscape.io/github/hootnot/oanda-api-v20/master/landscape.svg?style=flat
:target: https://landscape.io/github/hootnot/oanda-api-v20/master
:alt: Code Health
.. image:: https://coveralls.io/repos/github/hootnot/oanda-api-v20/badge.svg?branch=master
:target: https://coveralls.io/github/hootnot/oanda-api-v20?branch=master
:alt: Coverage
.. image:: https://badge.fury.io/py/oandapyV20.svg
:target: https://badge.fury.io/py/oandapyV20
:alt: Pypi
.. image:: https://img.shields.io/pypi/pyversions/oandapyV20.svg
:target: https://pypi.org/project/oandapyV20
:alt: Python versions
.. image:: https://api.codacy.com/project/badge/Grade/5946514e3a7c407291f76e630ce3553b
:target: https://www.codacy.com/app/hootnot/oandaapiv20utm_source=github.com&utm_medium=referral&utm_content=hootnot/oanda-api-v20&utm_campaign=Badge_Grade
:alt: Codacy
Interactive
-----------
.. image:: https://jupyter.readthedocs.io/en/latest/_static/_images/jupyter.svg
:target: ./jupyter
:alt: Jupyter
Using the Jupyter `notebook`_ it is easy to play with the
*oandapyV20* library.
.. _notebook: ./jupyter/index.ipynb
TOC
---
+ `Install`_
+ `Design`_
+ `Client`_
- `contrib.requests`_
- `contrib.factories`_
- `API-endpoint access`_
- `Placing a MarketOrder with TakeProfitOrder and StopLossOrder`_
- `Processing series of requests`_
- `Streaming endpoints`_
Install
-------
.. code-block:: bash
$ pip install oandapyV20
or the latest development version from github:
.. code-block:: bash
$ pip install git+https://github.com/hootnot/oanda-api-v20.git
If you want to run the tests, clone the repository:
.. code-block:: bash
$ git clone https://github.com/hootnot/oanda-api-v20
$ cd oanda-api-v20
# install necessary packages for testing
$ grep "\- pip install" .travis.yml |
> while read LNE
> do `echo $LNE| cut -c2-` ; done
$ python setup.py test
$ python setup.py install
Examples are provided in the https://github.com/hootnot/oandapyV20-examples
repository.
Design
------
In the V20-library endpoints are represented as APIRequest objects derived from the
APIRequest base class. Each endpoint group (accounts, trades, etc.) is represented
by it's own (abstract) class covering the functionality of all endpoints for that group. Each endpoint within that group is covered by a class derived from
the abstract class.
Top_
Client
~~~~~~
The V20-library has a client class (API) which processes APIRequest objects.
Top_
contrib.requests
~~~~~~~~~~~~~~~~
The contrib.request package offers classes providing an easy way
to construct the data for the *data* parameter of the OrderCreate endpoint
or the TradeCRCDO (Create/Replace/Cancel Dependent Orders).
.. code-block:: python
mktOrder = MarketOrderRequest(instrument="EUR_USD",
units=10000,
takeProfitOnFill=TakeProfitDetails(price=1.10).data,
stopLossOnFill=StopLossDetails(price=1.07).data
).data
instead of:
.. code-block:: python
mktOrder = {'order': {
'timeInForce': 'FOK',
'instrument': 'EUR_USD',
'positionFill': 'DEFAULT',
'units': '10000',
'type': 'MARKET',
'takeProfitOnFill': {
'timeInForce': 'GTC',
'price': '1.10000'}
}
'stopLossOnFill': {
'timeInForce': 'GTC',
'price': '1.07000'}
}
}
Top_
contrib.factories
~~~~~~~~~~~~~~~~~
The contrib.factories module offers classes providing an easy way
generate requests.
Downloading historical data is limited to 5000 records per request. This
means that you have to make consecutive requests with change of parameters
if you want more than 5000 records.
The *InstrumentsCandlesFactory* solves this by generating the requests for you,
example:
.. code-block:: python
import sys
import json
from oandapyV20.contrib.factories import InstrumentsCandlesFactory
from oandapyV20 import API
access_token = "..."
client = API(access_token=access_token)
_from = sys.argv[1]
_to = sys.argv[2]
gran = sys.argv[3]
instr = sys.argv[4]
params = {
"granularity": gran,
"from": _from,
"to": _to
}
def cnv(r, h):
for candle in r.get('candles'):
ctime = candle.get('time')[0:19]
try:
rec = "{time},{complete},{o},{h},{l},{c},{v}".format(
time=ctime,
complete=candle['complete'],
o=candle['mid']['o'],
h=candle['mid']['h'],
l=candle['mid']['l'],
c=candle['mid']['c'],
v=candle['volume'],
)
except Exception as e:
print(e, r)
else:
h.write(rec+"\n")
with open("/tmp/{}.{}.out".format(instr, gran), "w") as O:
for r in InstrumentsCandlesFactory(instrument=instr, params=params):
print("REQUEST: {} {} {}".format(r, r.__class__.__name__, r.params))
rv = client.request(r)
cnv(r.response, O)
When running this:
.. code-block:: shell
$ python oandahist.py 2017-01-01T00:00:00Z 2017-06-30T00:00:00Z H4 EUR_USD
REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles
{'to': '2017-03-25T08:00:00Z',
'from': '2017-01-01T00:00:00Z', 'granularity': 'H4'}
REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles
{'to': '2017-06-16T20:00:00Z', 'from': '2017-03-25T12:00:00Z',
'granularity': 'H4'}
REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles
{'to': '2017-06-30T00:00:00Z', 'from': '2017-06-17T00:00:00Z',
'granularity': 'H4'}
The output shows it processed three *InstrumentsCandles* requests. The
data can be found in */tmp/EUR_USD.H4.out*:
.. code-block:: shell
$ tail /tmp/EUR_USD.H4.out
...
2017-06-28T01:00:0,True,1.13397,1.13557,1.13372,1.13468,1534
2017-06-28T05:00:0,True,1.13465,1.13882,1.13454,1.13603,8486
2017-06-28T09:00:0,True,1.13606,1.13802,1.12918,1.13315,12815
2017-06-28T13:00:0,True,1.13317,1.13909,1.13283,1.13781,13255
2017-06-28T17:00:0,True,1.13783,1.13852,1.13736,1.13771,2104
2017-06-28T21:00:0,True,1.13789,1.13894,1.13747,1.13874,1454
Top_
Examples
--------
API-endpoint access
~~~~~~~~~~~~~~~~~~~
.. code-block:: python
import json
from oandapyV20 import API # the client
import oandapyV20.endpoints.trades as trades
access_token = "..."
accountID = "..."
client = API(access_token=access_token)
# request trades list
r = trades.TradesList(accountID)
rv = client.request(r)
print("RESPONSE:\n{}".format(json.dumps(rv, indent=2)))
Top_
Placing a *MarketOrder* with *TakeProfitOrder* and *StopLossOrder*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: python
import json
from oandapyV20.contrib.requests import MarketOrderRequest
from oandapyV20.contrib.requests import TakeProfitDetails, StopLossDetails
import oandapyV20.endpoints.orders as orders
import oandapyV20
from exampleauth import exampleAuth
accountID, access_token = exampleAuth()
api = oandapyV20.API(access_token=access_token)
# EUR_USD (today 1.0750)
EUR_USD_STOP_LOSS = 1.07
EUR_USD_TAKE_PROFIT = 1.10
mktOrder = MarketOrderRequest(
instrument="EUR_USD",
units=10000,
takeProfitOnFill=TakeProfitDetails(price=EUR_USD_TAKE_PROFIT).data,
stopLossOnFill=StopLossDetails(price=EUR_USD_STOP_LOSS).data)
# create the OrderCreate request
r = orders.OrderCreate(accountID, data=mktOrder.data)
try:
# create the OrderCreate request
rv = api.request(r)
except oandapyV20.exceptions.V20Error as err:
print(r.status_code, err)
else:
print(json.dumps(rv, indent=2))
Top_
Processing series of requests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Processing series of requests is also possible now by storing different requests in
an array or from some 'request-factory' class. Below an array example:
.. code-block:: python
import json
from oandapyV20 import API # the client
from oandapyV20.exceptions import V20Error
import oandapyV20.endpoints.accounts as accounts
import oandapyV20.endpoints.trades as trades
import oandapyV20.endpoints.pricing as pricing
access_token = "..."
accountID = "..."
client = API(access_token=access_token)
# list of requests
lor = []
# request trades list
lor.append(trades.TradesList(accountID))
# request accounts list
lor.append(accounts.AccountList())
# request pricing info
params={"instruments": "DE30_EUR,EUR_GBP"}
lor.append(pricing.PricingInfo(accountID, params=params))
for r in lor:
try:
rv = client.request(r)
# put request and response in 1 JSON structure
print("{}".format(json.dumps({"request": "{}".format(r),
"response": rv}, indent=2)))
except V20Error as e:
print("OOPS: {:d} {:s}".format(e.code, e.msg))
Output
``````
.. code-block:: json
{
"request": "v3/accounts/101-004-1435156-001/trades",
"response": {
"lastTransactionID": "1109",
"trades": [
{
"unrealizedPL": "23.0000",
"financing": "-0.5556",
"state": "OPEN",
"price": "10159.4",
"realizedPL": "0.0000",
"currentUnits": "-10",
"openTime": "2016-07-22T16:47:04.315211198Z",
"initialUnits": "-10",
"instrument": "DE30_EUR",
"id": "1105"
},
{
"unrealizedPL": "23.0000",
"financing": "-0.5556",
"state": "OPEN",
"price": "10159.4",
"realizedPL": "0.0000",
"currentUnits": "-10",
"openTime": "2016-07-22T16:47:04.141436468Z",
"initialUnits": "-10",
"instrument": "DE30_EUR",
"id": "1103"
}
]
}
}
{
"request": "v3/accounts",
"response": {
"accounts": [
{
"tags": [],
"id": "101-004-1435156-002"
},
{
"tags": [],
"id": "101-004-1435156-001"
}
]
}
}
{
"request": "v3/accounts/101-004-1435156-001/pricing",
"response": {
"prices": [
{
"status": "tradeable",
"quoteHomeConversionFactors": {
"negativeUnits": "1.00000000",
"positiveUnits": "1.00000000"
},
"asks": [
{
"price": "10295.1",
"liquidity": 25
},
{
"price": "10295.3",
"liquidity": 75
},
{
"price": "10295.5",
"liquidity": 150
}
],
"unitsAvailable": {
"default": {
"short": "60",
"long": "100"
},
"reduceOnly": {
"short": "0",
"long": "20"
},
"openOnly": {
"short": "60",
"long": "0"
},
"reduceFirst": {
"short": "60",
"long": "100"
}
},
"closeoutBid": "10293.5",
"bids": [
{
"price": "10293.9",
"liquidity": 25
},
{
"price": "10293.7",
"liquidity": 75
},
{
"price": "10293.5",
"liquidity": 150
}
],
"instrument": "DE30_EUR",
"time": "2016-09-29T17:07:19.598030528Z",
"closeoutAsk": "10295.5"
},
{
"status": "tradeable",
"quoteHomeConversionFactors": {
"negativeUnits": "1.15679152",
"positiveUnits": "1.15659083"
},
"asks": [
{
"price": "0.86461",
"liquidity": 1000000
},
{
"price": "0.86462",
"liquidity": 2000000
},
{
"price": "0.86463",
"liquidity": 5000000
},
{
"price": "0.86465",
"liquidity": 10000000
}
],
"unitsAvailable": {
"default": {
"short": "624261",
"long": "624045"
},
"reduceOnly": {
"short": "0",
"long": "0"
},
"openOnly": {
"short": "624261",
"long": "624045"
},
"reduceFirst": {
"short": "624261",
"long": "624045"
}
},
"closeoutBid": "0.86442",
"bids": [
{
"price": "0.86446",
"liquidity": 1000000
},
{
"price": "0.86445",
"liquidity": 2000000
},
{
"price": "0.86444",
"liquidity": 5000000
},
{
"price": "0.86442",
"liquidity": 10000000
}
],
"instrument": "EUR_GBP",
"time": "2016-09-29T17:07:19.994271769Z",
"closeoutAsk": "0.86465",
"type": "PRICE"
}
]
}
}
Top_
Streaming endpoints
~~~~~~~~~~~~~~~~~~~
Streaming quotes: use pricing.PricingStream.
Streaming transactions: use transactions.TransactionsEvents.
To fetch streaming data from a stream use the following pattern:
.. code-block:: python
import json
from oandapyV20 import API
from oandapyV20.exceptions import V20Error
from oandapyV20.endpoints.pricing import PricingStream
accountID = "..."
access_token="..."
api = API(access_token=access_token, environment="practice")
instruments = "DE30_EUR,EUR_USD,EUR_JPY"
s = PricingStream(accountID=accountID, params={"instruments":instruments})
try:
n = 0
for R in api.request(s):
print(json.dumps(R, indent=2))
n += 1
if n > 10:
s.terminate("maxrecs received: {}".format(MAXREC))
except V20Error as e:
print("Error: {}".format(e))
Check the 'examples' directory for more detailed examples.
Output
``````
.. code-block:: json
{
"status": "tradeable",
"asks": [
{
"price": "10547.0",
"liquidity": 25
},
{
"price": "10547.2",
"liquidity": 75
},
{
"price": "10547.4",
"liquidity": 150
}
],
"closeoutBid": "10546.6",
"bids": [
{
"price": "10547.0",
"liquidity": 25
},
{
"price": "10546.8",
"liquidity": 75
},
{
"price": "10546.6",
"liquidity": 150
}
],
"instrument": "DE30_EUR",
"time": "2016-10-17T12:25:28.158741026Z",
"closeoutAsk": "10547.4",
"type": "PRICE",
}
{
"type": "HEARTBEAT",
"time": "2016-10-17T12:25:37.447397298Z"
}
{
"status": "tradeable",
"asks": [
{
"price": "114.490",
"liquidity": 1000000
},
{
"price": "114.491",
"liquidity": 2000000
},
{
"price": "114.492",
"liquidity": 5000000
},
{
"price": "114.494",
"liquidity": 10000000
}
],
"closeoutBid": "114.469",
"bids": [
{
"price": "114.473",
"liquidity": 1000000
},
{
"price": "114.472",
"liquidity": 2000000
},
{
"price": "114.471",
"liquidity": 5000000
},
{
"price": "114.469",
"liquidity": 10000000
}
],
"instrument": "EUR_JPY",
"time": "2016-10-17T12:25:40.837289374Z",
"closeoutAsk": "114.494",
"type": "PRICE",
}
{
"type": "HEARTBEAT",
"time": "2016-10-17T12:25:42.447922336Z"
}
{
"status": "tradeable",
"asks": [
{
"price": "1.09966",
"liquidity": 10000000
},
{
"price": "1.09968",
"liquidity": 10000000
}
],
"closeoutBid": "1.09949",
"bids": [
{
"price": "1.09953",
"liquidity": 10000000
},
{
"price": "1.09951",
"liquidity": 10000000
}
],
"instrument": "EUR_USD",
"time": "2016-10-17T12:25:43.689619691Z",
"closeoutAsk": "1.09970",
"type": "PRICE"
}
{
"status": "tradeable",
"asks": [
{
"price": "114.486",
"liquidity": 1000000
},
{
"price": "114.487",
"liquidity": 2000000
},
{
"price": "114.488",
"liquidity": 5000000
},
{
"price": "114.490",
"liquidity": 10000000
}
],
"closeoutBid": "114.466",
"bids": [
{
"price": "114.470",
"liquidity": 1000000
},
{
"price": "114.469",
"liquidity": 2000000
},
{
"price": "114.468",
"liquidity": 5000000
},
{
"price": "114.466",
"liquidity": 10000000
}
],
"instrument": "EUR_JPY",
"time": "2016-10-17T12:25:43.635964725Z",
"closeoutAsk": "114.490",
"type": "PRICE"
}
{
"status": "tradeable",
"asks": [
{
"price": "10547.3",
"liquidity": 25
},
{
"price": "10547.5",
"liquidity": 75
},
{
"price": "10547.7",
"liquidity": 150
}
],
"closeoutBid": "10546.9",
"bids": [
{
"price": "10547.3",
"liquidity": 25
},
{
"price": "10547.1",
"liquidity": 75
},
{
"price": "10546.9",
"liquidity": 150
}
],
"instrument": "DE30_EUR",
"time": "2016-10-17T12:25:44.900162113Z",
"closeoutAsk": "10547.7",
"type": "PRICE"
}
{
"status": "tradeable",
"asks": [
{
"price": "10547.0",
"liquidity": 25
},
{
"price": "10547.2",
"liquidity": 75
},
{
"price": "10547.4",
"liquidity": 150
}
],
"closeoutBid": "10546.6",
"bids": [
{
"price": "10547.0",
"liquidity": 25
},
{
"price": "10546.8",
"liquidity": 75
},
{
"price": "10546.6",
"liquidity": 150
}
],
"instrument": "DE30_EUR",
"time": "2016-10-17T12:25:44.963539084Z",
"closeoutAsk": "10547.4",
"type": "PRICE"
}
{
"status": "tradeable",
"asks": [
{
"price": "114.491",
"liquidity": 1000000
},
{
"price": "114.492",
"liquidity": 2000000
},
{
"price": "114.493",
"liquidity": 5000000
},
{
"price": "114.495",
"liquidity": 10000000
}
],
"closeoutBid": "114.471",
"bids": [
{
"price": "114.475",
"liquidity": 1000000
},
{
"price": "114.474",
"liquidity": 2000000
},
{
"price": "114.473",
"liquidity": 5000000
},
{
"price": "114.471",
"liquidity": 10000000
}
],
"instrument": "EUR_JPY",
"time": "2016-10-17T12:25:45.586100087Z",
"closeoutAsk": "114.495",
"type": "PRICE"
}
Top_
About this software
-------------------
The *oanda-api-v20* software is a personal project.
I have no prior or existing relationship with OANDA.
If you have any questions regarding this software, please take a look at
the documentation first:
* oandapyV20 : http://oanda-api-v20.readthedocs.io/en/latest/?badge=latest
* OANDA developer docs : http://developer.oanda.com
* examples : https://github.com/hootnot/oandapyV20-examples
* Github: https://github.com/hootnot/oanda-api-v20 check the open and closed issues
If you still have questions/issues you can open an *issue* on Gitub: https://github.com/hootnot/oanda-api-v20
================================================
FILE: docs/Makefile
================================================
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " epub3 to make an epub3"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
@echo " dummy to check syntax errors of document sources"
.PHONY: clean
clean:
rm -rf $(BUILDDIR)/*
.PHONY: types
types: ../oandapyV20/types/types.py
@python dirstruct.py types oandapyV20.types
.PHONY: html
html: types
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
.PHONY: dirhtml
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
.PHONY: singlehtml
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
.PHONY: pickle
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
.PHONY: json
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
.PHONY: htmlhelp
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
.PHONY: qthelp
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/OANDAREST-V20API.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/OANDAREST-V20API.qhc"
.PHONY: applehelp
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
.PHONY: devhelp
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/OANDAREST-V20API"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/OANDAREST-V20API"
@echo "# devhelp"
.PHONY: epub
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
.PHONY: epub3
epub3:
$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
@echo
@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
.PHONY: latex
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
.PHONY: latexpdf
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: latexpdfja
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: text
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
.PHONY: man
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
.PHONY: texinfo
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
.PHONY: info
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
.PHONY: gettext
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
.PHONY: changes
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
.PHONY: linkcheck
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
.PHONY: doctest
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
.PHONY: coverage
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
.PHONY: xml
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
.PHONY: pseudoxml
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
.PHONY: dummy
dummy:
$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
@echo
@echo "Build finished. Dummy builder generates no files."
================================================
FILE: docs/conf.py
================================================
# -*- coding: utf-8 -*-
#
# OANDA REST-V20 API documentation build configuration file, created by
# sphinx-quickstart on Sun Jul 10 12:57:37 2016.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath('oandapyV20'))
import oandapyV20
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The encoding of source files.
#
# source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = getattr(sys.modules["oandapyV20"], "__title__")
copyright = getattr(sys.modules["oandapyV20"], "__copyright__")
author = getattr(sys.modules["oandapyV20"], "__author__")
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = getattr(sys.modules["oandapyV20"], "__version__")
# The full version, including alpha/beta/rc tags.
release = getattr(sys.modules["oandapyV20"], "__version__")
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#
# today = ''
#
# Else, today_fmt is used as the format for a strftime call.
#
# today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The reST default role (used for this markup: `text`) to use for all
# documents.
#
# default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#
# add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#
# add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#
# show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
# keep_warnings = False
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = []
# The name for this set of Sphinx documents.
# "<project> v<release> documentation" by default.
#
# html_title = u'OANDA REST-V20 API v0.1.0'
# A shorter title for the navigation bar. Default is the same as html_title.
#
# html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#
# html_logo = None
# The name of an image file (relative to this directory) to use as a favicon of
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#
# html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#
# html_extra_path = []
# If not None, a 'Last updated on:' timestamp is inserted at every page
# bottom, using the given strftime format.
# The empty string is equivalent to '%b %d, %Y'.
#
# html_last_updated_fmt = None
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#
# html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#
# html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#
# html_additional_pages = {}
# If false, no module index is generated.
#
# html_domain_indices = True
# If false, no index is generated.
#
# html_use_index = True
# If true, the index is split into individual pages for each letter.
#
# html_split_index = False
# If true, links to the reST sources are added to the pages.
#
# html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#
# html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#
# html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#
# html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = None
# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh'
#
# html_search_language = 'en'
# A dictionary with options for the search language support, empty by default.
# 'ja' uses this config value.
# 'zh' user can custom change `jieba` dictionary path.
#
# html_search_options = {'type': 'default'}
# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#
# html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
htmlhelp_basename = 'OANDAREST-V20APIdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'OANDAREST-V20API.tex', u'OANDA REST-V20 API Documentation',
u'Feite Brekeveld', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#
# latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#
# latex_use_parts = False
# If true, show page references after internal links.
#
# latex_show_pagerefs = False
# If true, show URL addresses after external links.
#
# latex_show_urls = False
# Documents to append as an appendix to all manuals.
#
# latex_appendices = []
# If false, no module index is generated.
#
# latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'oanda-api-v20', u'OANDA REST-V20 API Documentation',
[author], 1)
]
# If true, show URL addresses after external links.
#
# man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'OANDAREST-V20API', u'OANDA REST-V20 API Documentation',
author, 'OANDAREST-V20API', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#
# texinfo_appendices = []
# If false, no module index is generated.
#
# texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#
# texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#
# texinfo_no_detailmenu = False
# Napoleon settings
napoleon_google_docstring = True
napoleon_numpy_docstring = True
# napoleon_include_private_with_doc = False
# napoleon_include_special_with_doc = True
napoleon_use_admonition_for_examples = False
napoleon_use_admonition_for_notes = False
napoleon_use_admonition_for_references = False
napoleon_use_ivar = False
napoleon_use_param = True
napoleon_use_rtype = True
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
# custom directive (stackoverflow.com: 7250659)
from os.path import basename
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
from docutils import nodes, statemachine
from docutils.parsers.rst import Directive
class ExecDirective(Directive):
"""Execute the specified python code and insert the output into the document"""
has_content = True
def run(self):
oldStdout, sys.stdout = sys.stdout, StringIO()
tab_width = self.options.get('tab-width', self.state.document.settings.tab_width)
source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1)
try:
exec('\n'.join(self.content))
text = sys.stdout.getvalue()
lines = statemachine.string2lines(text, tab_width, convert_whitespace=True)
self.state_machine.insert_input(lines, source)
return []
except Exception:
return [nodes.error(None, nodes.paragraph(text = "Unable to execute python code at %s:%d:" % (basename(source), self.lineno)), nodes.paragraph(text = str(sys.exc_info()[1])))]
finally:
sys.stdout = oldStdout
def setup(app):
app.add_directive('exec', ExecDirective)
if not on_rtd: # only import and set the theme if we're building docs locally
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
================================================
FILE: docs/contrib/factories/instrumentscandlesfactory.rst
================================================
InstrumentsCandlesFactory
-------------------------
.. automodule:: oandapyV20.contrib.factories
:members:
================================================
FILE: docs/contrib/factories.rst
================================================
Factories
---------
The :mod:`oandapyV20.contrib.factories` module contains several classes /
methods that can be used optionally to generate requests.
.. toctree::
:maxdepth: 4
:glob:
factories/*
================================================
FILE: docs/contrib/generic/generic.rst
================================================
granularity_to_time
-------------------
.. automodule:: oandapyV20.contrib.generic
:members:
================================================
FILE: docs/contrib/generic.rst
================================================
Generic
---------
The :mod:`oandapyV20.contrib.generic` module contains several classes /
methods that serve a generic purpose.
.. toctree::
:maxdepth: 4
:glob:
generic/*
================================================
FILE: docs/contrib/orders/limitorderrequest.rst
================================================
LimitOrderRequest
------------------
.. autoclass:: oandapyV20.contrib.requests.LimitOrderRequest
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/contrib/orders/marketorderrequest.rst
================================================
MarketOrderRequest
------------------
.. autoclass:: oandapyV20.contrib.requests.MarketOrderRequest
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/contrib/orders/mitorderrequest.rst
================================================
MITOrderRequest
---------------
.. autoclass:: oandapyV20.contrib.requests.MITOrderRequest
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/contrib/orders/positionscloserequest.rst
================================================
PositionCloseRequest
--------------------
.. autoclass:: oandapyV20.contrib.requests.PositionCloseRequest
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/contrib/orders/stoplossorderrequest.rst
================================================
StopLossOrderRequest
--------------------
.. autoclass:: oandapyV20.contrib.requests.StopLossOrderRequest
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/contrib/orders/stoporderrequest.rst
================================================
StopOrderRequest
----------------
.. autoclass:: oandapyV20.contrib.requests.StopOrderRequest
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/contrib/orders/takeprofitorderrequest.rst
================================================
TakeProfitOrderRequest
----------------------
.. autoclass:: oandapyV20.contrib.requests.TakeProfitOrderRequest
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/contrib/orders/tradecloserequest.rst
================================================
TradeCloseRequest
-----------------
.. autoclass:: oandapyV20.contrib.requests.TradeCloseRequest
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/contrib/orders/trailingstoplossorderrequest.rst
================================================
TrailingStopLossOrderRequest
----------------------------
.. autoclass:: oandapyV20.contrib.requests.TrailingStopLossOrderRequest
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/contrib/orders.rst
================================================
Order Classes
-------------
The :mod:`oandapyV20.contrib.requests` module contains several classes
that can be used optionally when creating Order Requests.
When creating an order to create a position, it is possible to create
dependant orders that will be triggered when the position gets filled.
This goes typically for *Take Profit* and *Stop Loss*.
These order specifications and additional data that goes with these order
specifications can be created by the contrib.requests.*Order* classes and
the contrib.requests.*Details classes.
.. toctree::
:maxdepth: 4
:glob:
orders/*
================================================
FILE: docs/contrib/support/clientextensions.rst
================================================
Client Extensions
~~~~~~~~~~~~~~~~~
Client extensions can be used optionally on Order Requests. It allows
a client to set a custom ID, Tag and/or Comment.
.. autoclass:: oandapyV20.contrib.requests.ClientExtensions
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/contrib/support/stoplossdetails.rst
================================================
StopLossDetails
~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.contrib.requests.StopLossDetails
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/contrib/support/takeprofitdetails.rst
================================================
TakeProfitDetails
~~~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.contrib.requests.TakeProfitDetails
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/contrib/support/trailingstoplossdetails.rst
================================================
TrailingStopLossDetails
~~~~~~~~~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.contrib.requests.TrailingStopLossDetails
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/contrib/support.rst
================================================
support classes
---------------
The :mod:`oandapyV20.contrib.requests` module contains several classes
that can be used optionally when creating Order Requests.
When creating an order to create a position, it is possible to create
dependant orders that will be triggered when the position gets filled.
This goes typically for *Take Profit* and *Stop Loss*.
These order specifications and additional data that goes with these order
specifications can be created by the contrib.requests.*Order* classes and
the contrib.requests.*Details classes.
.. toctree::
:maxdepth: 4
:glob:
support/*
================================================
FILE: docs/dirstruct.py
================================================
# -*- coding: utf8 -*-
"""dirstruct.
generate document directory structure.
"""
import sys
import os
import inspect
from importlib import import_module
def get_classes(modName):
"""return a list of all classes in a module."""
classNames = []
for name, obj in inspect.getmembers(sys.modules[modName]):
if inspect.isclass(obj):
classNames.append(name)
return classNames
if __name__ == "__main__":
destDir = sys.argv[1]
modToDoc = sys.argv[2]
import_module(modToDoc)
if not os.path.exists(destDir):
os.makedirs(destDir)
for cls in get_classes(modToDoc):
with open(os.path.join(destDir, "{}.rst".format(cls)), "w") as F:
# :show-inheritance:\n
F.write("""{cls}\n"""
"""{ul}\n"""
"""\n"""
""".. autoclass:: {mod}.{cls}\n"""
""" :members:\n"""
""" :undoc-members:\n"""
""" :inherited-members:\n"""
""" :special-members: __init__\n""".format(
cls=cls,
ul=len(cls)*"~",
mod=modToDoc))
================================================
FILE: docs/endpoints/accounts/accountchanges.rst
================================================
AccountChanges
~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.accounts.AccountChanges
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/accounts/accountconfiguration.rst
================================================
AccountConfiguration
~~~~~~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.accounts.AccountConfiguration
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/accounts/accountdetails.rst
================================================
AccountDetails
~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.accounts.AccountDetails
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/accounts/accountinstruments.rst
================================================
AccountInstruments
~~~~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.accounts.AccountInstruments
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/accounts/accountlist.rst
================================================
AccountList
~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.accounts.AccountList
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/accounts/accountsummary.rst
================================================
AccountSummary
~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.accounts.AccountSummary
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/accounts.rst
================================================
oandapyV20.endpoints.accounts
-----------------------------
.. toctree::
:maxdepth: 4
:glob:
accounts/*
================================================
FILE: docs/endpoints/forexlabs/autochartist.rst
================================================
Autochartist
~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.forexlabs.Autochartist
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/forexlabs/calendar.rst
================================================
Calendar
~~~~~~~~
.. autoclass:: oandapyV20.endpoints.forexlabs.Calendar
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/forexlabs/commitmentsoftraders.rst
================================================
CommitmentsOfTraders
~~~~~~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.forexlabs.CommitmentsOfTraders
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/forexlabs/historicalpositionratios.rst
================================================
HistoricalPositionRatios
~~~~~~~~~~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.forexlabs.HistoricalPositionRatios
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/forexlabs/orderbookdata.rst
================================================
OrderbookData
~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.forexlabs.OrderbookData
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/forexlabs/spreads.rst
================================================
Spreads
~~~~~~~
.. autoclass:: oandapyV20.endpoints.forexlabs.Spreads
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/forexlabs.rst
================================================
oandapyV20.endpoints.forexlabs
------------------------------
.. toctree::
:maxdepth: 4
:glob:
forexlabs/*
================================================
FILE: docs/endpoints/instruments/instrumentlist.rst
================================================
InstrumentsCandles
~~~~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.instruments.InstrumentsCandles
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/instruments/instrumentorderbook.rst
================================================
InstrumentsOrderBook
~~~~~~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.instruments.InstrumentsOrderBook
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/instruments/instrumentpositionbook.rst
================================================
InstrumentsPositionBook
~~~~~~~~~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.instruments.InstrumentsPositionBook
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/instruments.rst
================================================
oandapyV20.endpoints.instruments
--------------------------------
.. toctree::
:maxdepth: 4
:glob:
instruments/*
================================================
FILE: docs/endpoints/orders/ordercancel.rst
================================================
OrderCancel
~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.orders.OrderCancel
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/orders/orderclientextensions.rst
================================================
OrderClientExtensions
~~~~~~~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.orders.OrderClientExtensions
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/orders/ordercreate.rst
================================================
OrderCreate
~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.orders.OrderCreate
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/orders/orderdetails.rst
================================================
OrderDetails
~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.orders.OrderDetails
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/orders/orderlist.rst
================================================
OrderList
~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.orders.OrderList
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/orders/orderreplace.rst
================================================
OrderReplace
~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.orders.OrderReplace
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/orders/orderspending.rst
================================================
OrdersPending
~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.orders.OrdersPending
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/orders.rst
================================================
oandapyV20.endpoints.orders
---------------------------
.. toctree::
:maxdepth: 4
:glob:
orders/*
================================================
FILE: docs/endpoints/positions/openpositions.rst
================================================
OpenPositions
~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.positions.OpenPositions
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/positions/positionclose.rst
================================================
PositionClose
~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.positions.PositionClose
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/positions/positiondetails.rst
================================================
PositionDetails
~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.positions.PositionDetails
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/positions/positionlist.rst
================================================
PositionList
~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.positions.PositionList
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/positions.rst
================================================
oandapyV20.endpoints.positions
------------------------------
.. toctree::
:maxdepth: 4
:glob:
positions/*
================================================
FILE: docs/endpoints/pricing/pricinginfo.rst
================================================
PricingInfo
~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.pricing.PricingInfo
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/pricing/pricingstream.rst
================================================
PricingStream
~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.pricing.PricingStream
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/pricing.rst
================================================
oandapyV20.endpoints.pricing
----------------------------
.. toctree::
:maxdepth: 4
:glob:
pricing/*
================================================
FILE: docs/endpoints/trades/opentrades.rst
================================================
OpenTrades
~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.trades.OpenTrades
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/trades/tradeCRCDO.rst
================================================
TradeCRCDO
~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.trades.TradeCRCDO
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/trades/tradeclientextensions.rst
================================================
TradeClientExtensions
~~~~~~~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.trades.TradeClientExtensions
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/trades/tradeclose.rst
================================================
TradeClose
~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.trades.TradeClose
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/trades/tradedetails.rst
================================================
TradeDetails
~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.trades.TradeDetails
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/trades/tradeslist.rst
================================================
TradesList
~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.trades.TradesList
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/trades.rst
================================================
oandapyV20.endpoints.trades
---------------------------
.. toctree::
:maxdepth: 4
:glob:
trades/*
================================================
FILE: docs/endpoints/transactions/transactiondetails.rst
================================================
TransactionDetails
~~~~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.transactions.TransactionDetails
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/transactions/transactionidrange.rst
================================================
TransactionIDRange
~~~~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.transactions.TransactionIDRange
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/transactions/transactionlist.rst
================================================
TransactionList
~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.transactions.TransactionList
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/transactions/transactionssinceid.rst
================================================
TransactionsSinceID
~~~~~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.transactions.TransactionsSinceID
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/transactions/transactionsstream.rst
================================================
TransactionsStream
~~~~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.endpoints.transactions.TransactionsStream
:members:
:undoc-members:
:show-inheritance:
:special-members: __init__
================================================
FILE: docs/endpoints/transactions.rst
================================================
oandapyV20.endpoints.transactions
---------------------------------
.. toctree::
:maxdepth: 4
:glob:
transactions/*
================================================
FILE: docs/examples.rst
================================================
Examples
--------
Examples can be found in the examples repositiory on github: examplesrepo_.
.. _examplesrepo: https://github.com/hootnot/oandapyV20-examples
Example for trades-endpoints
````````````````````````````
Take the script below and name it 'trades.py'. From the shell:
::
hootnot@dev:~/test$ python trades.py list
hootnot@dev:~/test$ python trades.py open
hootnot@dev:~/test$ python trades.py details <id1> [<id2> ...]
hootnot@dev:~/test$ python trades.py close <id1> <numunits> [<id2> <numunits>...]
hootnot@dev:~/test$ python trades.py clext <id1> [<id2> ...]
hootnot@dev:~/test$ python trades.py crc_do <id1> <takeprofit> <stoploss> [<id2> ...]
.. code-block:: python
# use of the Trades{..} classes
import json
import requests
from oandapyV20 import API
import oandapyV20.endpoints.trades as trades
import sys
access_token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
accountID = "zzz-zzzz-zzzzz"
api = API(access_token=access_token)
if chc == 'list':
r = trades.TradesList(accountID)
rv = api.request(r)
print("RESP:\n{} ".format(json.dumps(rv, indent=2)))
if chc == 'open':
r = trades.OpenTrades(accountID)
rv = api.request(r)
print("RESP:\n{} ".format(json.dumps(rv, indent=2)))
tradeIDs = [o["id"] for o in rv["trades"]]
print("TRADE IDS: {}".format(tradeIDs))
if chc == 'details':
for O in sys.argv[2:]:
r = trades.TradeDetails(accountID, tradeID=O)
rv = api.request(r)
print("RESP:\n{} ".format(json.dumps(rv, indent=2)))
if chc == 'close':
X = iter(sys.argv[2:])
for O in X:
cfg = { "units": X.next() }
r = trades.TradeClose(accountID, tradeID=O, data=cfg)
rv = api.request(r)
print("RESP:\n{} ".format(json.dumps(rv, indent=2)))
if chc == 'cltext':
for O in sys.argv[2:]: # tradeIDs
cfg = { "clientExtensions": {
"id": "myID{}".format(O),
"comment": "myComment",
}
}
r = trades.TradeClientExtensions(accountID, tradeID=O, data=cfg)
rv = api.request(r)
print("RESP:\n{} ".format(json.dumps(rv, indent=2)))
if chc == 'crc_do':
X = iter(sys.argv[2:])
for O in X:
cfg = {
"takeProfit": {
"timeInForce": "GTC",
"price": X.next(),
},
"stopLoss": {
"timeInForce": "GTC",
"price": X.next()
}
}
r = trades.TradeCRCDO(accountID, tradeID=O, data=cfg)
rv = api.request(r)
print("RESP:\n{} ".format(json.dumps(rv, indent=2)))
================================================
FILE: docs/index.rst
================================================
.. OANDA REST-V20 API documentation master file, created by
sphinx-quickstart on Sun Jul 10 12:57:37 2016.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
The oandapyV20 REST-V20 API wrapper documentation
=================================================
Contents:
.. toctree::
:maxdepth: 2
:caption: oandapyV20 REST-V20 API wrapper
installation
oanda-api-v20
oandapyV20.endpoints
oandapyV20.definitions
oandapyV20.types
oandapyV20.contrib
examples
.. modules
oandapyV20
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
================================================
FILE: docs/installation.rst
================================================
Introduction
============
The :mod:`oandapyV20` package offers an API to the OANDA V20 REST service.
To use the REST-API-service you will need a *token* and an *account*. This
applies for both *live* and *practice* accounts. For details check oanda.com_.
.. _oanda.com: https://oanda.com
Install
-------
Install the pypi package with pip::
$ pip install oandapyV20
Or alternatively install the latest development version from github::
$ pip install git+https://github.com/hootnot/oanda-api-v20.git
You may consider using *virtualenv* to create isolated Python environments. Python 3.4 has *pyvenv* providing
the same kind of functionality.
Download from Github
--------------------
If you want to run the tests, download the source from github::
$ git clone https://github.com/hootnot/oanda-api-v20.git
$ cd oanda-api-v20
$ python setup.py test
$ python setup.py install
================================================
FILE: docs/oanda-api-v20.rst
================================================
Interface OANDA's REST-V20
==========================
The client
----------
The :mod:`oandapyV20` package contains a client class, :class:`oandapyV20.API`, to
communicate with the REST-V20 interface. It processes requests that
can be created from the endpoint classes.
For it's communication it relies on: :py:mod:`requests`
(requests_).
.. _requests: http://docs.python-requests.org/en/master/
The client keeps no state of a requests.
The response of a request is assigned to the request instance. The response
is also returned as a return value by the client.
.. autoclass:: oandapyV20.API
:inherited-members:
:show-inheritance:
:special-members: __init__
Exceptions
----------
.. autoclass:: oandapyV20.V20Error
:inherited-members:
:show-inheritance:
:special-members: __init__
Logging
-------
The :mod:`oandapyV20` package has `logging` integrated. Logging can be
simply applied by enabling a `logger`.
The example below will log INFO-level logging to the file *v20.log*.
For details check the :py:mod:`logger` module in the standard Python
documentation.
.. code-block:: python
# code snippet
from oandapyV20 import API
import oandapyV20.endpoints.orders as orders
from oandapyV20.exceptions import V20Error
from exampleauth import exampleAuth
import logging
logging.basicConfig(
filename="v20.log",
level=logging.INFO,
format='%(asctime)s [%(levelname)s] %(name)s : %(message)s',
)
accountID, token = exampleAuth()
...
Resulting loglines:
.. code-block:: text
2016-10-22 17:50:37,988 [INFO] oandapyV20.oandapyV20 : setting up API-client for environment practice
2016-10-22 17:50:37,990 [INFO] oandapyV20.oandapyV20 : performing request https://api-fxpractice.oanda.com/v3/accounts/101-004-1435156-001/orders
2016-10-22 17:50:37,998 [INFO] requests.packages.urllib3.connectionpool : Starting new HTTPS connection (1): api-fxpractice.oanda.com
2016-10-22 17:50:38,866 [INFO] oandapyV20.oandapyV20 : performing request https://api-fxpractice.oanda.com/v3/accounts/101-004-1435156-001/orders
2016-10-22 17:50:39,066 [ERROR] oandapyV20.oandapyV20 : request https://api-fxpractice.oanda.com/v3/accounts/101-004-1435156-001/orders failed [400,{"errorMessage":"Invalid value specified for 'order.instrument'"}]
================================================
FILE: docs/oandapyV20.contrib.rst
================================================
oandapyV20.contrib
==================
.. toctree::
:maxdepth: 4
:glob:
contrib/*
================================================
FILE: docs/oandapyV20.definitions.accounts.rst
================================================
oandapyV20.definitions.accounts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. automodule:: oandapyV20.definitions.accounts
:members:
:undoc-members:
:show-inheritance:
:special-members: __getitem__
================================================
FILE: docs/oandapyV20.definitions.instruments.rst
================================================
oandapyV20.definitions.instruments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. automodule:: oandapyV20.definitions.instruments
:members:
:undoc-members:
:show-inheritance:
:special-members: __getitem__
================================================
FILE: docs/oandapyV20.definitions.orders.rst
================================================
oandapyV20.definitions.orders
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. automodule:: oandapyV20.definitions.orders
:members:
:undoc-members:
:show-inheritance:
:special-members: __getitem__
================================================
FILE: docs/oandapyV20.definitions.pricing.rst
================================================
oandapyV20.definitions.pricing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. automodule:: oandapyV20.definitions.pricing
:members:
:undoc-members:
:show-inheritance:
:special-members: __getitem__
================================================
FILE: docs/oandapyV20.definitions.rst
================================================
oandapyV20.definitions
======================
The :mod:`oandapyV20.definitions` module holds all the definitions as in the
definitions section of the REST-V20 specs of OANDA, see developer.oanda.com_.
.. _developer.oanda.com: http://developer.oanda.com
.. toctree::
:maxdepth: 3
oandapyV20.definitions.accounts
oandapyV20.definitions.instruments
oandapyV20.definitions.orders
oandapyV20.definitions.pricing
oandapyV20.definitions.trades
oandapyV20.definitions.transactions
================================================
FILE: docs/oandapyV20.definitions.trades.rst
================================================
oandapyV20.definitions.trades
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. automodule:: oandapyV20.definitions.trades
:members:
:undoc-members:
:show-inheritance:
:special-members: __getitem__
================================================
FILE: docs/oandapyV20.definitions.transactions.rst
================================================
oandapyV20.definitions.transactions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. automodule:: oandapyV20.definitions.transactions
:members:
:undoc-members:
:show-inheritance:
:special-members: __getitem__
================================================
FILE: docs/oandapyV20.endpoints.rst
================================================
oandapyV20.endpoints
====================
.. toctree::
:maxdepth: 4
:glob:
endpoints/*
================================================
FILE: docs/oandapyV20.types.rst
================================================
oandapyV20.types
================
The :mod:`oandapyV20.types` module contains the types representing the types
that are used in the API-specs of OANDA, check developer.oanda.com_.
These types offer a convenient interface between Python types and
the types used in the REST-API.
.. _developer.oanda.com: http://developer.oanda.com
Take for instance the `PriceValue` type. It is the string representation of
a float.
.. code-block:: python
from oandapyV20.types import PriceValue
pv1 = PriceValue(122.345)
pv2 = PriceValue("122.345")
pv1.value
"122.345"
pv1.value == pv2.value
True
Regardless the value we instantiate it with, a float or a string,
the PriceValue instance will allways be a string value.
The types also validate the values passed. Invalid values will raise an
exception.
.. toctree::
:maxdepth: 4
:glob:
types/*
================================================
FILE: docs/types/AccountID.rst
================================================
AccountID
~~~~~~~~~
.. autoclass:: oandapyV20.types.AccountID
:members:
:undoc-members:
:inherited-members:
:special-members: __init__
================================================
FILE: docs/types/AccountUnits.rst
================================================
AccountUnits
~~~~~~~~~~~~
.. autoclass:: oandapyV20.types.AccountUnits
:members:
:undoc-members:
:inherited-members:
:special-members: __init__
================================================
FILE: docs/types/ClientComment.rst
================================================
ClientComment
~~~~~~~~~~~~~
.. autoclass:: oandapyV20.types.ClientComment
:members:
:undoc-members:
:inherited-members:
:special-members: __init__
================================================
FILE: docs/types/ClientID.rst
================================================
ClientID
~~~~~~~~
.. autoclass:: oandapyV20.types.ClientID
:members:
:undoc-members:
:inherited-members:
:special-members: __init__
================================================
FILE: docs/types/ClientTag.rst
================================================
ClientTag
~~~~~~~~~
.. autoclass:: oandapyV20.types.ClientTag
:members:
:undoc-members:
:inherited-members:
:special-members: __init__
================================================
FILE: docs/types/DateTime.rst
================================================
DateTime
~~~~~~~~
.. autoclass:: oandapyV20.types.DateTime
:members:
:undoc-members:
:inherited-members:
:special-members: __init__
================================================
FILE: docs/types/OrderID.rst
================================================
OrderID
~~~~~~~
.. autoclass:: oandapyV20.types.OrderID
:members:
:undoc-members:
:inherited-members:
:special-members: __init__
================================================
FILE: docs/types/OrderIdentifier.rst
================================================
OrderIdentifier
~~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.types.OrderIdentifier
:members:
:undoc-members:
:inherited-members:
:special-members: __init__
================================================
FILE: docs/types/OrderSpecifier.rst
================================================
OrderSpecifier
~~~~~~~~~~~~~~
.. autoclass:: oandapyV20.types.OrderSpecifier
:members:
:undoc-members:
:inherited-members:
:special-members: __init__
================================================
FILE: docs/types/PriceValue.rst
================================================
PriceValue
~~~~~~~~~~
.. autoclass:: oandapyV20.types.PriceValue
:members:
:undoc-members:
:inherited-members:
:special-members: __init__
================================================
FILE: docs/types/TradeID.rst
================================================
TradeID
~~~~~~~
.. autoclass:: oandapyV20.types.TradeID
:members:
:undoc-members:
:inherited-members:
:special-members: __init__
================================================
FILE: docs/types/Units.rst
================================================
Units
~~~~~
.. autoclass:: oandapyV20.types.Units
:members:
:undoc-members:
:inherited-members:
:special-members: __init__
================================================
FILE: examples/README.rst
================================================
Examples
========
As of Nov 28th 2016 examples are in a separate repo: oandapyV20-examples_
.. _oandapyV20-examples: https://github.com/hootnot/oandapyV20-examples
================================================
FILE: jupyter/account.txt
================================================
xxx-yyy-zzzzzzz-aaa
================================================
FILE: jupyter/accounts.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"[index](./index.ipynb) | [accounts](./accounts.ipynb) | [orders](./orders.ipynb) | [trades](./trades.ipynb) | [positions](./positions.ipynb) | [historical](./historical.ipynb) | [streams](./streams.ipynb) | [errors](./exceptions.ipynb)\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## Account endpoints\n",
"\n",
"### Example: fetch account information\n",
"\n",
"A simple example to retrieve the accounts belonging to a *token*:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"accounts\": [\n",
" {\n",
" \"tags\": [],\n",
" \"id\": \"101-004-1435156-002\"\n",
" },\n",
" {\n",
" \"tags\": [],\n",
" \"id\": \"101-004-1435156-001\"\n",
" }\n",
" ]\n",
"}\n"
]
}
],
"source": [
"import json\n",
"import oandapyV20\n",
"import oandapyV20.endpoints.accounts as accounts\n",
"from exampleauth import exampleauth\n",
"\n",
"accountID, access_token = exampleauth.exampleAuth()\n",
"client = oandapyV20.API(access_token=access_token)\n",
"\n",
"r = accounts.AccountList()\n",
"response = client.request(r)\n",
"print(json.dumps(response, indent=2))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"### Request details\n",
"\n",
"Lets get some details from the request itself after the client performed the request:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"API-path: v3/accounts\n",
"METHOD: GET\n",
"Response status: 200\n",
"The account id's: ['101-004-1435156-002', '101-004-1435156-001']\n"
]
}
],
"source": [
"print(\"API-path: \" , r)\n",
"print(\"METHOD: \", r.method)\n",
"print(\"Response status: \", r.status_code)\n",
"print(\"The account id's: \", [acc.get('id') for acc in r.response.get('accounts')])"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
================================================
FILE: jupyter/exampleauth/__init__.py
================================================
================================================
FILE: jupyter/exampleauth/exampleauth.py
================================================
"""simple auth method for examples."""
def exampleAuth():
accountID, token = None, None
with open("account.txt") as I:
accountID = I.read().strip()
with open("token.txt") as I:
token = I.read().strip()
return accountID, token
================================================
FILE: jupyter/exceptions.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"[index](./index.ipynb) | [accounts](./accounts.ipynb) | [orders](./orders.ipynb) | [trades](./trades.ipynb) | [positions](./positions.ipynb) | [historical](./historical.ipynb) | [streams](./streams.ipynb) | [errors](./exceptions.ipynb)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## What about errors ?\n",
"\n",
"Errors can occur. Wrong parameters or connection errors for example. Lets take the example from [Orders](./orders.ipynb) and make the instrument one that does not exist. The orderspecfication itself is still valid. Wrap it up in a *try/except* to catch the error:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"V20Error occurred: {\"errorMessage\":\"Invalid value specified for 'order.instrument'\"}\n"
]
}
],
"source": [
"import json\n",
"import oandapyV20\n",
"from oandapyV20.exceptions import V20Error\n",
"import oandapyV20.endpoints.orders as orders\n",
"from oandapyV20.contrib.requests import (\n",
" MarketOrderRequest,\n",
" TakeProfitDetails,\n",
" StopLossDetails)\n",
"from exampleauth import exampleauth\n",
"\n",
"accountID, access_token = exampleauth.exampleAuth()\n",
"client = oandapyV20.API(access_token=access_token)\n",
"\n",
"mktOrder = MarketOrderRequest(instrument=\"EUR_UDS\", # EUR_UDS ... the faulty instrument\n",
" units=10000,\n",
" takeProfitOnFill=TakeProfitDetails(price=1.10).data,\n",
" stopLossOnFill=StopLossDetails(price=1.05).data\n",
" ).data\n",
"r = orders.OrderCreate(accountID=accountID, data=mktOrder)\n",
"try:\n",
" rv = client.request(r)\n",
"except V20Error as err:\n",
" print(\"V20Error occurred: {}\".format(err))\n",
"else:\n",
" print(\"Response: {}\\n{}\".format(r.status_code, json.dumps(rv, indent=2)))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"As we can see the REST-API returned an error response saying the instrument is invalid."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
================================================
FILE: jupyter/historical.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"[accounts](./accounts.ipynb) | [orders](./orders.ipynb) | [trades](./trades.ipynb) | [positions](./positions.ipynb) | [historical](./historical.ipynb) | [streams](./streams.ipynb) | [errors](./exceptions.ipynb)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"# Historical data\n",
"\n",
"OANDA provides access to historical data. The *oandapyV20* has a class to access this data: *oandapyV20.endpoints.instruments.InstrumentsCandles*.\n",
"\n",
"Lets give it a try and download some data for:\n",
" + instrument: EUR_USD\n",
" + granularity: H1\n",
" + from: 2017-01-01T00:00:00"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Request: v3/instruments/EUR_USD/candles #candles received: 9\n",
"{\n",
" \"instrument\": \"EUR_USD\", \n",
" \"candles\": [\n",
" {\n",
" \"volume\": 481, \n",
" \"mid\": {\n",
" \"h\": \"1.04712\", \n",
" \"c\": \"1.04662\", \n",
" \"l\": \"1.04572\", \n",
" \"o\": \"1.04577\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T00:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 664, \n",
" \"mid\": {\n",
" \"h\": \"1.04808\", \n",
" \"c\": \"1.04758\", \n",
" \"l\": \"1.04646\", \n",
" \"o\": \"1.04665\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T01:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 392, \n",
" \"mid\": {\n",
" \"h\": \"1.04780\", \n",
" \"c\": \"1.04721\", \n",
" \"l\": \"1.04709\", \n",
" \"o\": \"1.04761\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T02:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 394, \n",
" \"mid\": {\n",
" \"h\": \"1.04848\", \n",
" \"c\": \"1.04848\", \n",
" \"l\": \"1.04715\", \n",
" \"o\": \"1.04718\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T03:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 285, \n",
" \"mid\": {\n",
" \"h\": \"1.04898\", \n",
" \"c\": \"1.04884\", \n",
" \"l\": \"1.04820\", \n",
" \"o\": \"1.04852\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T04:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 250, \n",
" \"mid\": {\n",
" \"h\": \"1.04902\", \n",
" \"c\": \"1.04824\", \n",
" \"l\": \"1.04816\", \n",
" \"o\": \"1.04886\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T05:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 368, \n",
" \"mid\": {\n",
" \"h\": \"1.04892\", \n",
" \"c\": \"1.04882\", \n",
" \"l\": \"1.04813\", \n",
" \"o\": \"1.04821\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T06:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 1639, \n",
" \"mid\": {\n",
" \"h\": \"1.04888\", \n",
" \"c\": \"1.04602\", \n",
" \"l\": \"1.04536\", \n",
" \"o\": \"1.04885\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T07:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 2830, \n",
" \"mid\": {\n",
" \"h\": \"1.04658\", \n",
" \"c\": \"1.04353\", \n",
" \"l\": \"1.04207\", \n",
" \"o\": \"1.04606\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T08:00:00.000000000Z\"\n",
" }\n",
" ], \n",
" \"granularity\": \"H1\"\n",
"}\n"
]
}
],
"source": [
"import json\n",
"import oandapyV20\n",
"import oandapyV20.endpoints.instruments as instruments\n",
"from exampleauth import exampleauth\n",
"\n",
"accountID, access_token = exampleauth.exampleAuth()\n",
"client = oandapyV20.API(access_token=access_token)\n",
"\n",
"instrument = \"EUR_USD\"\n",
"params = {\n",
" \"from\": \"2017-01-01T00:00:00Z\",\n",
" \"granularity\": \"H1\",\n",
" \"count\": 10,\n",
"}\n",
"r = instruments.InstrumentsCandles(instrument=instrument, params=params)\n",
"response = client.request(r)\n",
"print(\"Request: {} #candles received: {}\".format(r, len(r.response.get('candles'))))\n",
"print(json.dumps(response, indent=2))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"So, that is 9 records?\n",
"... that can be fixed by including the parameter *includeFirst*, see the OANDA documentation for details."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Request: v3/instruments/EUR_USD/candles #candles received: 10\n",
"{\n",
" \"instrument\": \"EUR_USD\", \n",
" \"candles\": [\n",
" {\n",
" \"volume\": 974, \n",
" \"mid\": {\n",
" \"h\": \"1.04711\", \n",
" \"c\": \"1.04575\", \n",
" \"l\": \"1.04567\", \n",
" \"o\": \"1.04684\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-02T23:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 481, \n",
" \"mid\": {\n",
" \"h\": \"1.04712\", \n",
" \"c\": \"1.04662\", \n",
" \"l\": \"1.04572\", \n",
" \"o\": \"1.04577\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T00:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 664, \n",
" \"mid\": {\n",
" \"h\": \"1.04808\", \n",
" \"c\": \"1.04758\", \n",
" \"l\": \"1.04646\", \n",
" \"o\": \"1.04665\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T01:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 392, \n",
" \"mid\": {\n",
" \"h\": \"1.04780\", \n",
" \"c\": \"1.04721\", \n",
" \"l\": \"1.04709\", \n",
" \"o\": \"1.04761\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T02:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 394, \n",
" \"mid\": {\n",
" \"h\": \"1.04848\", \n",
" \"c\": \"1.04848\", \n",
" \"l\": \"1.04715\", \n",
" \"o\": \"1.04718\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T03:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 285, \n",
" \"mid\": {\n",
" \"h\": \"1.04898\", \n",
" \"c\": \"1.04884\", \n",
" \"l\": \"1.04820\", \n",
" \"o\": \"1.04852\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T04:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 250, \n",
" \"mid\": {\n",
" \"h\": \"1.04902\", \n",
" \"c\": \"1.04824\", \n",
" \"l\": \"1.04816\", \n",
" \"o\": \"1.04886\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T05:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 368, \n",
" \"mid\": {\n",
" \"h\": \"1.04892\", \n",
" \"c\": \"1.04882\", \n",
" \"l\": \"1.04813\", \n",
" \"o\": \"1.04821\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T06:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 1639, \n",
" \"mid\": {\n",
" \"h\": \"1.04888\", \n",
" \"c\": \"1.04602\", \n",
" \"l\": \"1.04536\", \n",
" \"o\": \"1.04885\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T07:00:00.000000000Z\"\n",
" }, \n",
" {\n",
" \"volume\": 2830, \n",
" \"mid\": {\n",
" \"h\": \"1.04658\", \n",
" \"c\": \"1.04353\", \n",
" \"l\": \"1.04207\", \n",
" \"o\": \"1.04606\"\n",
" }, \n",
" \"complete\": true, \n",
" \"time\": \"2017-01-03T08:00:00.000000000Z\"\n",
" }\n",
" ], \n",
" \"granularity\": \"H1\"\n",
"}\n"
]
}
],
"source": [
"instrument = \"EUR_USD\"\n",
"params = {\n",
" \"from\": \"2017-01-01T00:00:00Z\",\n",
" \"granularity\": \"H1\",\n",
" \"includeFirst\": True,\n",
" \"count\": 10,\n",
"}\n",
"r = instruments.InstrumentsCandles(instrument=instrument, params=params)\n",
"response = client.request(r)\n",
"print(\"Request: {} #candles received: {}\".format(r, len(r.response.get('candles'))))\n",
"print(json.dumps(response, indent=2))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"# Bulk history\n",
"\n",
"## InstrumentsCandles class\n",
"\n",
"It is likely that you want to retrieve more than 10 records. The OANDA docs say that the default number of records\n",
"is 500, in case you do not specify. You can specify the number of records to retrieve by using *count*, with a maximum of 5000. The *InstrumentsCandles* class enables you to retrieve the records.\n",
"\n",
"## InstrumentsCandlesFactory\n",
"\n",
"Now if you would like to retrieve a lot of history, you have to make consecutive requests. To make this an easy process the *oandapyV20* library comes with a so called *factory* named *InstrumentsCandlesFactory*.\n",
"\n",
"Using this class you can retrieve all history of an instrument from a certain date. The *InstrumentsCandlesFactory* acts as a generator generating *InstrumentCandles* requests until all data is retrieved. The number of requests can be influenced by specifying *count*. Setting *count* to 5000 would generate a tenth of the requests vs. the default of 500.\n",
"\n",
"Back to our example: lets make sure we request a lot of data, so we set the *granularity* to *M5* and leave the date at 2017-01-01T00:00:00. The will retrieve all records from that date up to today, because we did not specify the *to* parameter. \n"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-02T17:40:00Z', 'from': '2017-01-01T00:00:00Z', 'granularity': 'M5'}, received: 0\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-04T11:25:00Z', 'from': '2017-01-02T17:45:00Z', 'granularity': 'M5'}, received: 436\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-06T05:10:00Z', 'from': '2017-01-04T11:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-07T22:55:00Z', 'from': '2017-01-06T05:15:00Z', 'granularity': 'M5'}, received: 200\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-09T16:40:00Z', 'from': '2017-01-07T23:00:00Z', 'granularity': 'M5'}, received: 222\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-11T10:25:00Z', 'from': '2017-01-09T16:45:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-13T04:10:00Z', 'from': '2017-01-11T10:30:00Z', 'granularity': 'M5'}, received: 498\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-14T21:55:00Z', 'from': '2017-01-13T04:15:00Z', 'granularity': 'M5'}, received: 212\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-16T15:40:00Z', 'from': '2017-01-14T22:00:00Z', 'granularity': 'M5'}, received: 211\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-18T09:25:00Z', 'from': '2017-01-16T15:45:00Z', 'granularity': 'M5'}, received: 497\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-20T03:10:00Z', 'from': '2017-01-18T09:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-21T20:55:00Z', 'from': '2017-01-20T03:15:00Z', 'granularity': 'M5'}, received: 224\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-23T14:40:00Z', 'from': '2017-01-21T21:00:00Z', 'granularity': 'M5'}, received: 193\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-25T08:25:00Z', 'from': '2017-01-23T14:45:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-27T02:10:00Z', 'from': '2017-01-25T08:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-28T19:55:00Z', 'from': '2017-01-27T02:15:00Z', 'granularity': 'M5'}, received: 236\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-01-30T13:40:00Z', 'from': '2017-01-28T20:00:00Z', 'granularity': 'M5'}, received: 187\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-01T07:25:00Z', 'from': '2017-01-30T13:45:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-03T01:10:00Z', 'from': '2017-02-01T07:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-04T18:55:00Z', 'from': '2017-02-03T01:15:00Z', 'granularity': 'M5'}, received: 248\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-06T12:40:00Z', 'from': '2017-02-04T19:00:00Z', 'granularity': 'M5'}, received: 175\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-08T06:25:00Z', 'from': '2017-02-06T12:45:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-10T00:10:00Z', 'from': '2017-02-08T06:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-11T17:55:00Z', 'from': '2017-02-10T00:15:00Z', 'granularity': 'M5'}, received: 260\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-13T11:40:00Z', 'from': '2017-02-11T18:00:00Z', 'granularity': 'M5'}, received: 163\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-15T05:25:00Z', 'from': '2017-02-13T11:45:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-16T23:10:00Z', 'from': '2017-02-15T05:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-18T16:55:00Z', 'from': '2017-02-16T23:15:00Z', 'granularity': 'M5'}, received: 272\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-20T10:40:00Z', 'from': '2017-02-18T17:00:00Z', 'granularity': 'M5'}, received: 151\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-22T04:25:00Z', 'from': '2017-02-20T10:45:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-23T22:10:00Z', 'from': '2017-02-22T04:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-25T15:55:00Z', 'from': '2017-02-23T22:15:00Z', 'granularity': 'M5'}, received: 284\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-02-27T09:40:00Z', 'from': '2017-02-25T16:00:00Z', 'granularity': 'M5'}, received: 139\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-01T03:25:00Z', 'from': '2017-02-27T09:45:00Z', 'granularity': 'M5'}, received: 498\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-02T21:10:00Z', 'from': '2017-03-01T03:30:00Z', 'granularity': 'M5'}, received: 498\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-04T14:55:00Z', 'from': '2017-03-02T21:15:00Z', 'granularity': 'M5'}, received: 296\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-06T08:40:00Z', 'from': '2017-03-04T15:00:00Z', 'granularity': 'M5'}, received: 127\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-08T02:25:00Z', 'from': '2017-03-06T08:45:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-09T20:10:00Z', 'from': '2017-03-08T02:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-11T13:55:00Z', 'from': '2017-03-09T20:15:00Z', 'granularity': 'M5'}, received: 308\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-13T07:40:00Z', 'from': '2017-03-11T14:00:00Z', 'granularity': 'M5'}, received: 126\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-15T01:25:00Z', 'from': '2017-03-13T07:45:00Z', 'granularity': 'M5'}, received: 497\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-16T19:10:00Z', 'from': '2017-03-15T01:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-18T12:55:00Z', 'from': '2017-03-16T19:15:00Z', 'granularity': 'M5'}, received: 308\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-20T06:40:00Z', 'from': '2017-03-18T13:00:00Z', 'granularity': 'M5'}, received: 115\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-22T00:25:00Z', 'from': '2017-03-20T06:45:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-23T18:10:00Z', 'from': '2017-03-22T00:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-25T11:55:00Z', 'from': '2017-03-23T18:15:00Z', 'granularity': 'M5'}, received: 319\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-27T05:40:00Z', 'from': '2017-03-25T12:00:00Z', 'granularity': 'M5'}, received: 103\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-28T23:25:00Z', 'from': '2017-03-27T05:45:00Z', 'granularity': 'M5'}, received: 497\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-03-30T17:10:00Z', 'from': '2017-03-28T23:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-01T10:55:00Z', 'from': '2017-03-30T17:15:00Z', 'granularity': 'M5'}, received: 331\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-03T04:40:00Z', 'from': '2017-04-01T11:00:00Z', 'granularity': 'M5'}, received: 91\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-04T22:25:00Z', 'from': '2017-04-03T04:45:00Z', 'granularity': 'M5'}, received: 497\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-06T16:10:00Z', 'from': '2017-04-04T22:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-08T09:55:00Z', 'from': '2017-04-06T16:15:00Z', 'granularity': 'M5'}, received: 343\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-10T03:40:00Z', 'from': '2017-04-08T10:00:00Z', 'granularity': 'M5'}, received: 79\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-11T21:25:00Z', 'from': '2017-04-10T03:45:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-13T15:10:00Z', 'from': '2017-04-11T21:30:00Z', 'granularity': 'M5'}, received: 497\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-15T08:55:00Z', 'from': '2017-04-13T15:15:00Z', 'granularity': 'M5'}, received: 352\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-17T02:40:00Z', 'from': '2017-04-15T09:00:00Z', 'granularity': 'M5'}, received: 67\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-18T20:25:00Z', 'from': '2017-04-17T02:45:00Z', 'granularity': 'M5'}, received: 496\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-20T14:10:00Z', 'from': '2017-04-18T20:30:00Z', 'granularity': 'M5'}, received: 497\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-22T07:55:00Z', 'from': '2017-04-20T14:15:00Z', 'granularity': 'M5'}, received: 366\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-24T01:40:00Z', 'from': '2017-04-22T08:00:00Z', 'granularity': 'M5'}, received: 55\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-25T19:25:00Z', 'from': '2017-04-24T01:45:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-27T13:10:00Z', 'from': '2017-04-25T19:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-04-29T06:55:00Z', 'from': '2017-04-27T13:15:00Z', 'granularity': 'M5'}, received: 379\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-01T00:40:00Z', 'from': '2017-04-29T07:00:00Z', 'granularity': 'M5'}, received: 43\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-02T18:25:00Z', 'from': '2017-05-01T00:45:00Z', 'granularity': 'M5'}, received: 497\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-04T12:10:00Z', 'from': '2017-05-02T18:30:00Z', 'granularity': 'M5'}, received: 496\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-06T05:55:00Z', 'from': '2017-05-04T12:15:00Z', 'granularity': 'M5'}, received: 392\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-07T23:40:00Z', 'from': '2017-05-06T06:00:00Z', 'granularity': 'M5'}, received: 31\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-09T17:25:00Z', 'from': '2017-05-07T23:45:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-11T11:10:00Z', 'from': '2017-05-09T17:30:00Z', 'granularity': 'M5'}, received: 498\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-13T04:55:00Z', 'from': '2017-05-11T11:15:00Z', 'granularity': 'M5'}, received: 402\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-14T22:40:00Z', 'from': '2017-05-13T05:00:00Z', 'granularity': 'M5'}, received: 19\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-16T16:25:00Z', 'from': '2017-05-14T22:45:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-18T10:10:00Z', 'from': '2017-05-16T16:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-20T03:55:00Z', 'from': '2017-05-18T10:15:00Z', 'granularity': 'M5'}, received: 416\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-21T21:40:00Z', 'from': '2017-05-20T04:00:00Z', 'granularity': 'M5'}, received: 7\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-23T15:25:00Z', 'from': '2017-05-21T21:45:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-25T09:10:00Z', 'from': '2017-05-23T15:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-27T02:55:00Z', 'from': '2017-05-25T09:15:00Z', 'granularity': 'M5'}, received: 428\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-28T20:40:00Z', 'from': '2017-05-27T03:00:00Z', 'granularity': 'M5'}, received: 0\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-05-30T14:25:00Z', 'from': '2017-05-28T20:45:00Z', 'granularity': 'M5'}, received: 491\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-01T08:10:00Z', 'from': '2017-05-30T14:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-03T01:55:00Z', 'from': '2017-06-01T08:15:00Z', 'granularity': 'M5'}, received: 440\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-04T19:40:00Z', 'from': '2017-06-03T02:00:00Z', 'granularity': 'M5'}, received: 0\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-06T13:25:00Z', 'from': '2017-06-04T19:45:00Z', 'granularity': 'M5'}, received: 483\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-08T07:10:00Z', 'from': '2017-06-06T13:30:00Z', 'granularity': 'M5'}, received: 498\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-10T00:55:00Z', 'from': '2017-06-08T07:15:00Z', 'granularity': 'M5'}, received: 452\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-11T18:40:00Z', 'from': '2017-06-10T01:00:00Z', 'granularity': 'M5'}, received: 0\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-13T12:25:00Z', 'from': '2017-06-11T18:45:00Z', 'granularity': 'M5'}, received: 471\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-15T06:10:00Z', 'from': '2017-06-13T12:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-16T23:55:00Z', 'from': '2017-06-15T06:15:00Z', 'granularity': 'M5'}, received: 464\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-18T17:40:00Z', 'from': '2017-06-17T00:00:00Z', 'granularity': 'M5'}, received: 0\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-20T11:25:00Z', 'from': '2017-06-18T17:45:00Z', 'granularity': 'M5'}, received: 458\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-22T05:10:00Z', 'from': '2017-06-20T11:30:00Z', 'granularity': 'M5'}, received: 495\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-23T22:55:00Z', 'from': '2017-06-22T05:15:00Z', 'granularity': 'M5'}, received: 474\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-25T16:40:00Z', 'from': '2017-06-23T23:00:00Z', 'granularity': 'M5'}, received: 0\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-27T10:25:00Z', 'from': '2017-06-25T16:45:00Z', 'granularity': 'M5'}, received: 444\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-29T04:10:00Z', 'from': '2017-06-27T10:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-06-30T21:55:00Z', 'from': '2017-06-29T04:15:00Z', 'granularity': 'M5'}, received: 488\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-02T15:40:00Z', 'from': '2017-06-30T22:00:00Z', 'granularity': 'M5'}, received: 0\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-04T09:25:00Z', 'from': '2017-07-02T15:45:00Z', 'granularity': 'M5'}, received: 433\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-06T03:10:00Z', 'from': '2017-07-04T09:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-07T20:55:00Z', 'from': '2017-07-06T03:15:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-09T14:40:00Z', 'from': '2017-07-07T21:00:00Z', 'granularity': 'M5'}, received: 0\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-11T08:25:00Z', 'from': '2017-07-09T14:45:00Z', 'granularity': 'M5'}, received: 422\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-13T02:10:00Z', 'from': '2017-07-11T08:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-14T19:55:00Z', 'from': '2017-07-13T02:15:00Z', 'granularity': 'M5'}, received: 498\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-16T13:40:00Z', 'from': '2017-07-14T20:00:00Z', 'granularity': 'M5'}, received: 11\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-18T07:25:00Z', 'from': '2017-07-16T13:45:00Z', 'granularity': 'M5'}, received: 412\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-20T01:10:00Z', 'from': '2017-07-18T07:30:00Z', 'granularity': 'M5'}, received: 498\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-21T18:55:00Z', 'from': '2017-07-20T01:15:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-23T12:40:00Z', 'from': '2017-07-21T19:00:00Z', 'granularity': 'M5'}, received: 23\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-25T06:25:00Z', 'from': '2017-07-23T12:45:00Z', 'granularity': 'M5'}, received: 400\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-27T00:10:00Z', 'from': '2017-07-25T06:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-28T17:55:00Z', 'from': '2017-07-27T00:15:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-07-30T11:40:00Z', 'from': '2017-07-28T18:00:00Z', 'granularity': 'M5'}, received: 35\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-01T05:25:00Z', 'from': '2017-07-30T11:45:00Z', 'granularity': 'M5'}, received: 388\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-02T23:10:00Z', 'from': '2017-08-01T05:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-04T16:55:00Z', 'from': '2017-08-02T23:15:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-06T10:40:00Z', 'from': '2017-08-04T17:00:00Z', 'granularity': 'M5'}, received: 47\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-08T04:25:00Z', 'from': '2017-08-06T10:45:00Z', 'granularity': 'M5'}, received: 376\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-09T22:10:00Z', 'from': '2017-08-08T04:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-11T15:55:00Z', 'from': '2017-08-09T22:15:00Z', 'granularity': 'M5'}, received: 498\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-13T09:40:00Z', 'from': '2017-08-11T16:00:00Z', 'granularity': 'M5'}, received: 59\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-15T03:25:00Z', 'from': '2017-08-13T09:45:00Z', 'granularity': 'M5'}, received: 364\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-16T21:10:00Z', 'from': '2017-08-15T03:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-18T14:55:00Z', 'from': '2017-08-16T21:15:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-20T08:40:00Z', 'from': '2017-08-18T15:00:00Z', 'granularity': 'M5'}, received: 71\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-22T02:25:00Z', 'from': '2017-08-20T08:45:00Z', 'granularity': 'M5'}, received: 352\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-23T20:10:00Z', 'from': '2017-08-22T02:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-25T13:55:00Z', 'from': '2017-08-23T20:15:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-27T07:40:00Z', 'from': '2017-08-25T14:00:00Z', 'granularity': 'M5'}, received: 83\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-29T01:25:00Z', 'from': '2017-08-27T07:45:00Z', 'granularity': 'M5'}, received: 340\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-08-30T19:10:00Z', 'from': '2017-08-29T01:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-09-01T12:55:00Z', 'from': '2017-08-30T19:15:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-09-03T06:40:00Z', 'from': '2017-09-01T13:00:00Z', 'granularity': 'M5'}, received: 95\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-09-05T00:25:00Z', 'from': '2017-09-03T06:45:00Z', 'granularity': 'M5'}, received: 325\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-09-06T18:10:00Z', 'from': '2017-09-05T00:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-09-08T11:55:00Z', 'from': '2017-09-06T18:15:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-09-10T05:40:00Z', 'from': '2017-09-08T12:00:00Z', 'granularity': 'M5'}, received: 107\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-09-11T23:25:00Z', 'from': '2017-09-10T05:45:00Z', 'granularity': 'M5'}, received: 315\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-09-13T17:10:00Z', 'from': '2017-09-11T23:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-09-15T10:55:00Z', 'from': '2017-09-13T17:15:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-09-17T04:40:00Z', 'from': '2017-09-15T11:00:00Z', 'granularity': 'M5'}, received: 119\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-09-18T22:25:00Z', 'from': '2017-09-17T04:45:00Z', 'granularity': 'M5'}, received: 303\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-09-20T16:10:00Z', 'from': '2017-09-18T22:30:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-09-22T09:55:00Z', 'from': '2017-09-20T16:15:00Z', 'granularity': 'M5'}, received: 499\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-09-24T03:40:00Z', 'from': '2017-09-22T10:00:00Z', 'granularity': 'M5'}, received: 131\n",
"REQUEST: v3/instruments/EUR_USD/candles InstrumentsCandles {'to': '2017-09-24T17:54:30Z', 'from': '2017-09-24T03:45:00Z', 'granularity': 'M5'}, received: 0\n",
"Check the datafile: /tmp/EUR_USD.M5.out under /tmp!, it contains 54090 records\n"
]
}
],
"source": [
"import json\n",
"import oandapyV20\n",
"import oandapyV20.endpoints.instruments as instruments\n",
"from oandapyV20.contrib.factories import InstrumentsCandlesFactory\n",
"from exampleauth import exampleauth\n",
"\n",
"accountID, access_token = exampleauth.exampleAuth()\n",
"client = oandapyV20.API(access_token=access_token)\n",
"\n",
"instrument = \"EUR_USD\"\n",
"params = {\n",
" \"from\": \"2017-01-01T00:00:00Z\",\n",
" \"granularity\": \"M5\",\n",
"}\n",
"\n",
"def cnv(r, h):\n",
" # get all candles from the response and write them as a record to the filehandle h\n",
" for candle in r.get('candles'):\n",
" ctime = candle.get('time')[0:19]\n",
" try:\n",
" rec = \"{time},{complete},{o},{h},{l},{c},{v}\".format(\n",
" time=ctime,\n",
" complete=candle['complete'],\n",
" o=candle['mid']['o'],\n",
" h=candle['mid']['h'],\n",
" l=candle['mid']['l'],\n",
" c=candle['mid']['c'],\n",
" v=candle['volume'],\n",
" )\n",
" except Exception as e:\n",
" print(e, r)\n",
" else:\n",
" h.write(rec+\"\\n\")\n",
"\n",
"datafile = \"/tmp/{}.{}.out\".format(instrument, params['granularity'])\n",
"with open(datafile, \"w\") as O:\n",
" n = 0\n",
" for r in InstrumentsCandlesFactory(instrument=instrument, params=params):\n",
" rv = client.request(r)\n",
" cnt = len(r.response.get('candles'))\n",
" print(\"REQUEST: {} {} {}, received: {}\".format(r, r.__class__.__name__, r.params, cnt))\n",
" n += cnt\n",
" cnv(r.response, O)\n",
" print(\"Check the datafile: {} under /tmp!, it contains {} records\".format(datafile, n))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## ... that was easy ...\n",
"\n",
"All request were made on the default of max. 500 records per request. With a granularity of *M5* this means that we have 288 records per day. The algorithm of the factory does not check on weekends or holidays. Therefore some request only return a part of the 500 requested records because there simply are no more records within the specified timespan.\n",
"\n",
"If you want to decrease the number of requests and increase the number of records returned for a request, just specify *count* as a number higher than 500 and up to max. 5000."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
================================================
FILE: jupyter/index.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"[accounts](./accounts.ipynb) | [orders](./orders.ipynb) | [trades](./trades.ipynb) | [positions](./positions.ipynb) | [historical](./historical.ipynb) | [streams](./streams.ipynb) | [errors](./exceptions.ipynb)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"# Tutorial oandapyV20\n",
"\n",
"## Installing *oandapyV20*\n",
"\n",
"Installing oandapyV20 from pypi:\n",
"\n",
"```shell\n",
"$ pip install oandapyV20\n",
"```\n",
"\n",
"## Tests\n",
"\n",
"If you want to run the tests, clone the repository:\n",
"\n",
"```bash\n",
"\n",
" $ git clone https://github.com/hootnot/oanda-api-v20\n",
" $ cd oanda-api-v20\n",
"\n",
" # install necessary packages for testing\n",
" $ grep \"\\- pip install\" .travis.yml |\n",
" > while read LNE\n",
" > do `echo $LNE| cut -c2-` ; done\n",
"\n",
" $ python setup.py test\n",
" $ python setup.py install\n",
"```\n",
"\n",
"## Jupyter\n",
"\n",
"To use this *Jupyter notebook* you need to install *Jupyter*:\n",
"\n",
"```shell\n",
"$ pip install jupyter\n",
"```\n",
"\n",
"See, [http://jupyter.org/install.html]() for all details regarding Jupyter.\n",
"\n",
"When installed you can start Jupyter from the cloned repo directory:\n",
"\n",
"```shell\n",
"$ cd jupyter\n",
"# provide your V20-accountID and token by editing account.txt and token.txt\n",
"$ jupyter notebook\n",
"# ... will launch your brouwser with the notebook tree structure.\n",
"```\n",
"\n",
"\n",
"## Examples\n",
"\n",
"Examples are provided in the https://github.com/hootnot/oandapyV20-examples repository.\n",
"\n",
"\n",
"## Design\n",
"\n",
"The design of the oandapyV20 library differs from the library covering the REST-V1 interface:\n",
"https://github.com/oanda/oandapy (oandapy), which is based on 'mixin' classes.\n",
"\n",
"### Client\n",
"\n",
"The V20-library has a client class (API) which processes all APIRequest objects. Status\n",
"and response are properties of the request and are assigned by the client when performing \n",
"the request. The response is also returned by the client. \n",
"\n",
"### Requests\n",
"\n",
"In the V20-library endpoints are represented as APIRequest objects derived from the\n",
"APIRequest base class. Each endpoint group (accounts, trades, etc.) is represented\n",
"by it's own (abstract) class covering the functionality of all endpoints for that group.\n",
"Each endpoint within that group is covered by a class derived from the abstract class.\n",
"\n",
"## oandapyV20 step by step\n",
"\n",
"* [accounts](./accounts.ipynb)\n",
"* [orders](./orders.ipynb)\n",
"* [trades](./trades.ipynb)\n",
"* [positions](./positions.ipynb)\n",
"* [streams](./streams.ipynb)\n",
"* [errors](./exceptions.ipynb)\n",
"\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
================================================
FILE: jupyter/orders.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"[index](./index.ipynb) | [accounts](./accounts.ipynb) | [orders](./orders.ipynb) | [trades](./trades.ipynb) | [positions](./positions.ipynb) | [historical](./historical.ipynb) | [streams](./streams.ipynb) | [errors](./exceptions.ipynb)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## Orders\n",
"\n",
"This notebook provides an example of\n",
"\n",
" + a MarketOrder\n",
" + a simplyfied way for a MarketOrder by using contrib.requests.MarketOrderRequest\n",
" + a LimitOrder with an expiry datetime by using *GTD* and contrib.requests.LimitOrderRequest\n",
" + canceling a GTD order\n",
"\n",
"### create a marketorder request with a TakeProfit and a StopLoss order when it gets filled."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Request: v3/accounts/101-004-1435156-001/orders\n",
"MarketOrder specs: {\n",
" \"order\": {\n",
" \"timeInForce\": \"FOK\",\n",
" \"instrument\": \"EUR_USD\",\n",
" \"stopLossOnFill\": {\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.07\"\n",
" },\n",
" \"positionFill\": \"DEFAULT\",\n",
" \"units\": 10000,\n",
" \"takeProfitOnFill\": {\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": 1.1\n",
" },\n",
" \"type\": \"MARKET\"\n",
" }\n",
"}\n"
]
}
],
"source": [
"import json\n",
"import oandapyV20\n",
"import oandapyV20.endpoints.orders as orders\n",
"from exampleauth import exampleauth\n",
"\n",
"accountID, access_token = exampleauth.exampleAuth()\n",
"client = oandapyV20.API(access_token=access_token)\n",
"\n",
"\n",
"# create a market order to enter a LONG position 10000 EUR_USD, stopLoss @1.07 takeProfit @1.10 ( current: 1.055)\n",
"# according to the docs at developer.oanda.com the requestbody looks like:\n",
"\n",
"mktOrder = {\n",
" \"order\": {\n",
" \"timeInForce\": \"FOK\", # Fill-or-kill\n",
" \"instrument\": \"EUR_USD\",\n",
" \"positionFill\": \"DEFAULT\",\n",
" \"type\": \"MARKET\",\n",
" \"units\": 10000, # as integer\n",
" \"takeProfitOnFill\": {\n",
" \"timeInForce\": \"GTC\", # Good-till-cancelled\n",
" \"price\": 1.10 # as float\n",
" },\n",
" \"stopLossOnFill\": {\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.07\" # as string\n",
" }\n",
" }\n",
"}\n",
"r = orders.OrderCreate(accountID=accountID, data=mktOrder)\n",
"\n",
"print(\"Request: \", r)\n",
"print(\"MarketOrder specs: \", json.dumps(mktOrder, indent=2))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Well that looks fine, but constructing orderbodies that way is not really what we want. Types are not checked for instance and all the defaults need to be supplied.\n",
"\n",
"This kind of datastructures can become complex, are not easy to read or construct and are prone to errors.\n",
"\n",
"## Types and definitions\n",
"\n",
"Oanda uses several *types* and *definitions* througout their documentation. These types are covered by the *oandapyV20.types* package and the definitions by the *oandapyV20.definitions* package.\n",
"\n",
"## Contrib.requests\n",
"\n",
"The *oandapyV20.contrib.requests* package offers classes providing an easy way to construct the data for\n",
"the *data* parameter of the *OrderCreate* endpoint or the *TradeCRCDO* (Create/Replace/Cancel Dependent Orders). The *oandapyV20.contrib.requests* package makes use of the *oandapyV20.types* and *oandapyV20.definitions*.\n",
"\n",
"Let's improve the previous example by making use of *oandapyV20.contrib.requests*:\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Request: v3/accounts/101-004-1435156-001/orders\n",
"MarketOrder specs: {\n",
" \"order\": {\n",
" \"timeInForce\": \"FOK\",\n",
" \"instrument\": \"EUR_USD\",\n",
" \"positionFill\": \"DEFAULT\",\n",
" \"type\": \"MARKET\",\n",
" \"units\": \"10000\",\n",
" \"takeProfitOnFill\": {\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.10000\"\n",
" },\n",
" \"stopLossOnFill\": {\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.07000\"\n",
" }\n",
" }\n",
"}\n"
]
}
],
"source": [
"import json\n",
"import oandapyV20\n",
"import oandapyV20.endpoints.orders as orders\n",
"from oandapyV20.contrib.requests import (\n",
" MarketOrderRequest,\n",
" TakeProfitDetails,\n",
" StopLossDetails)\n",
"from exampleauth import exampleauth\n",
"\n",
"accountID, access_token = exampleauth.exampleAuth()\n",
"client = oandapyV20.API(access_token=access_token)\n",
"\n",
"# create a market order to enter a LONG position 10000 EUR_USD\n",
"mktOrder = MarketOrderRequest(instrument=\"EUR_USD\",\n",
" units=10000,\n",
" takeProfitOnFill=TakeProfitDetails(price=1.10).data,\n",
" stopLossOnFill=StopLossDetails(price=1.07).data\n",
" ).data\n",
"r = orders.OrderCreate(accountID=accountID, data=mktOrder)\n",
"\n",
"print(\"Request: \", r)\n",
"print(\"MarketOrder specs: \", json.dumps(mktOrder, indent=2))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"As you can see, the specs contain price values that were converted to strings and the defaults *positionFill* and *timeInForce* were added. Using *contrib.requests* makes it very easy to construct the orderdata body for order requests. Parameters for those requests are also validated.\n",
"\n",
"Next step, place the order:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Response: 201\n",
"{\n",
" \"orderCancelTransaction\": {\n",
" \"time\": \"2017-03-09T13:17:59.319422181Z\",\n",
" \"userID\": 1435156,\n",
" \"batchID\": \"7576\",\n",
" \"orderID\": \"7576\",\n",
" \"id\": \"7577\",\n",
" \"type\": \"ORDER_CANCEL\",\n",
" \"accountID\": \"101-004-1435156-001\",\n",
" \"reason\": \"STOP_LOSS_ON_FILL_LOSS\"\n",
" },\n",
" \"lastTransactionID\": \"7577\",\n",
" \"orderCreateTransaction\": {\n",
" \"timeInForce\": \"FOK\",\n",
" \"instrument\": \"EUR_USD\",\n",
" \"batchID\": \"7576\",\n",
" \"accountID\": \"101-004-1435156-001\",\n",
" \"units\": \"10000\",\n",
" \"takeProfitOnFill\": {\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.10000\"\n",
" },\n",
" \"time\": \"2017-03-09T13:17:59.319422181Z\",\n",
" \"userID\": 1435156,\n",
" \"positionFill\": \"DEFAULT\",\n",
" \"id\": \"7576\",\n",
" \"type\": \"MARKET_ORDER\",\n",
" \"stopLossOnFill\": {\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.07000\"\n",
" },\n",
" \"reason\": \"CLIENT_ORDER\"\n",
" },\n",
" \"relatedTransactionIDs\": [\n",
" \"7576\",\n",
" \"7577\"\n",
" ]\n",
"}\n"
]
}
],
"source": [
"rv = client.request(r)\n",
"print(\"Response: {}\\n{}\".format(r.status_code, json.dumps(rv, indent=2)))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Lets analyze that. We see an *orderCancelTransaction* and *reason* **STOP_LOSS_ON_FILL_LOSS**. So the order was not placed ? Well it was placed and cancelled right away. The marketprice of EUR_USD is at the moment of this writing 1.058. So the stopLoss order at 1.07 makes no sense. The status_code of 201 is as the specs say: http://developer.oanda.com/rest-live-v20/order-ep/ .\n",
"\n",
"Lets change the stopLoss level below the current price and place the order once again."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Response: 201\n",
"{\n",
" \"orderFillTransaction\": {\n",
" \"accountBalance\": \"102107.4442\",\n",
" \"instrument\": \"EUR_USD\",\n",
" \"batchID\": \"7578\",\n",
" \"pl\": \"0.0000\",\n",
" \"accountID\": \"101-004-1435156-001\",\n",
" \"units\": \"10000\",\n",
" \"tradeOpened\": {\n",
" \"tradeID\": \"7579\",\n",
" \"units\": \"10000\"\n",
" },\n",
" \"financing\": \"0.0000\",\n",
" \"price\": \"1.05563\",\n",
" \"userID\": 1435156,\n",
" \"orderID\": \"7578\",\n",
" \"time\": \"2017-03-09T13:22:13.832587780Z\",\n",
" \"id\": \"7579\",\n",
" \"type\": \"ORDER_FILL\",\n",
" \"reason\": \"MARKET_ORDER\"\n",
" },\n",
" \"lastTransactionID\": \"7581\",\n",
" \"orderCreateTransaction\": {\n",
" \"timeInForce\": \"FOK\",\n",
" \"instrument\": \"EUR_USD\",\n",
" \"batchID\": \"7578\",\n",
" \"accountID\": \"101-004-1435156-001\",\n",
" \"units\": \"10000\",\n",
" \"takeProfitOnFill\": {\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.10000\"\n",
" },\n",
" \"time\": \"2017-03-09T13:22:13.832587780Z\",\n",
" \"userID\": 1435156,\n",
" \"positionFill\": \"DEFAULT\",\n",
" \"id\": \"7578\",\n",
" \"type\": \"MARKET_ORDER\",\n",
" \"stopLossOnFill\": {\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.05000\"\n",
" },\n",
" \"reason\": \"CLIENT_ORDER\"\n",
" },\n",
" \"relatedTransactionIDs\": [\n",
" \"7578\",\n",
" \"7579\",\n",
" \"7580\",\n",
" \"7581\"\n",
" ]\n",
"}\n"
]
}
],
"source": [
"mktOrder = MarketOrderRequest(instrument=\"EUR_USD\",\n",
" units=10000,\n",
" takeProfitOnFill=TakeProfitDetails(price=1.10).data,\n",
" stopLossOnFill=StopLossDetails(price=1.05).data\n",
" ).data\n",
"r = orders.OrderCreate(accountID=accountID, data=mktOrder)\n",
"rv = client.request(r)\n",
"\n",
"print(\"Response: {}\\n{}\".format(r.status_code, json.dumps(rv, indent=2)))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"We now see an *orderFillTransaction* for 10000 units EUR_USD with *reason* **MARKET_ORDER**.\n",
"\n",
"Lets retrieve the orders. We should see the *stopLoss* and *takeProfit* orders as *pending*:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Response:\n",
" {\n",
" \"lastTransactionID\": \"7581\",\n",
" \"orders\": [\n",
" {\n",
" \"createTime\": \"2017-03-09T13:22:13.832587780Z\",\n",
" \"triggerCondition\": \"TRIGGER_DEFAULT\",\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.05000\",\n",
" \"tradeID\": \"7579\",\n",
" \"id\": \"7581\",\n",
" \"state\": \"PENDING\",\n",
" \"type\": \"STOP_LOSS\"\n",
" },\n",
" {\n",
" \"createTime\": \"2017-03-09T13:22:13.832587780Z\",\n",
" \"triggerCondition\": \"TRIGGER_DEFAULT\",\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.10000\",\n",
" \"tradeID\": \"7579\",\n",
" \"id\": \"7580\",\n",
" \"state\": \"PENDING\",\n",
" \"type\": \"TAKE_PROFIT\"\n",
" },\n",
" {\n",
" \"createTime\": \"2017-03-09T11:45:48.928448770Z\",\n",
" \"triggerCondition\": \"TRIGGER_DEFAULT\",\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.05000\",\n",
" \"tradeID\": \"7572\",\n",
" \"id\": \"7574\",\n",
" \"state\": \"PENDING\",\n",
" \"type\": \"STOP_LOSS\"\n",
" },\n",
" {\n",
" \"createTime\": \"2017-03-07T09:18:51.563637768Z\",\n",
" \"triggerCondition\": \"TRIGGER_DEFAULT\",\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.05000\",\n",
" \"tradeID\": \"7562\",\n",
" \"id\": \"7564\",\n",
" \"state\": \"PENDING\",\n",
" \"type\": \"STOP_LOSS\"\n",
" },\n",
" {\n",
" \"createTime\": \"2017-03-07T09:08:04.219010730Z\",\n",
" \"triggerCondition\": \"TRIGGER_DEFAULT\",\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.05000\",\n",
" \"tradeID\": \"7558\",\n",
" \"id\": \"7560\",\n",
" \"state\": \"PENDING\",\n",
" \"type\": \"STOP_LOSS\"\n",
" }\n",
" ]\n",
"}\n"
]
}
],
"source": [
"r = orders.OrdersPending(accountID=accountID)\n",
"rv = client.request(r)\n",
"print(\"Response:\\n\", json.dumps(rv, indent=2))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Depending on the state of your account you should see at least the orders associated with the previously executed marketorder. The *relatedTransactionIDs* should be in the *orders* output of OrdersPending().\n",
"\n",
"Now lets cancel all pending TAKE_PROFIT orders:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Request: v3/accounts/101-004-1435156-001/orders/7580/cancel ... response: {\n",
" \"orderCancelTransaction\": {\n",
" \"time\": \"2017-03-09T13:26:07.480994423Z\",\n",
" \"userID\": 1435156,\n",
" \"batchID\": \"7582\",\n",
" \"orderID\": \"7580\",\n",
" \"id\": \"7582\",\n",
" \"type\": \"ORDER_CANCEL\",\n",
" \"accountID\": \"101-004-1435156-001\",\n",
" \"reason\": \"CLIENT_REQUEST\"\n",
" },\n",
" \"lastTransactionID\": \"7582\",\n",
" \"relatedTransactionIDs\": [\n",
" \"7582\"\n",
" ]\n",
"}\n"
]
}
],
"source": [
"r = orders.OrdersPending(accountID=accountID)\n",
"rv = client.request(r)\n",
"idsToCancel = [order.get('id') for order in rv['orders'] if order.get('type') == \"TAKE_PROFIT\"]\n",
"for orderID in idsToCancel:\n",
" r = orders.OrderCancel(accountID=accountID, orderID=orderID)\n",
" rv = client.request(r)\n",
" print(\"Request: {} ... response: {}\".format(r, json.dumps(rv, indent=2)))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"### create a LimitOrder with a *GTD* \"good-til-date\"\n",
"\n",
"Create a LimitOrder and let it expire: *2018-07-02T00:00:00* using *GTD*. Make sure it is in the future\n",
"when you run this example!"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"order\": {\n",
" \"price\": \"1.08000\",\n",
" \"timeInForce\": \"GTD\",\n",
" \"positionFill\": \"DEFAULT\",\n",
" \"type\": \"LIMIT\",\n",
" \"instrument\": \"EUR_USD\",\n",
" \"gtdTime\": \"2018-07-02T00:00:00\",\n",
" \"units\": \"10000\"\n",
" }\n",
"}\n",
"{\n",
" \"relatedTransactionIDs\": [\n",
" \"8923\"\n",
" ],\n",
" \"lastTransactionID\": \"8923\",\n",
" \"orderCreateTransaction\": {\n",
" \"price\": \"1.08000\",\n",
" \"triggerCondition\": \"DEFAULT\",\n",
" \"positionFill\": \"DEFAULT\",\n",
" \"type\": \"LIMIT_ORDER\",\n",
" \"requestID\": \"42440345970496965\",\n",
" \"partialFill\": \"DEFAULT\",\n",
" \"gtdTime\": \"2018-07-02T04:00:00.000000000Z\",\n",
" \"batchID\": \"8923\",\n",
" \"id\": \"8923\",\n",
" \"userID\": 1435156,\n",
" \"accountID\": \"101-004-1435156-001\",\n",
" \"timeInForce\": \"GTD\",\n",
" \"reason\": \"CLIENT_ORDER\",\n",
" \"instrument\": \"EUR_USD\",\n",
" \"time\": \"2018-06-10T12:06:30.259079220Z\",\n",
" \"units\": \"10000\"\n",
" }\n",
"}\n"
]
}
],
"source": [
"from oandapyV20.contrib.requests import LimitOrderRequest\n",
"\n",
"# make sure GTD_TIME is in the future \n",
"# also make sure the price condition is not met\n",
"# and specify GTD_TIME as UTC or local\n",
"# GTD_TIME=\"2018-07-02T00:00:00Z\" # UTC\n",
"GTD_TIME=\"2018-07-02T00:00:00\"\n",
"ordr = LimitOrderRequest(instrument=\"EUR_USD\",\n",
" units=10000,\n",
" timeInForce=\"GTD\",\n",
" gtdTime=GTD_TIME,\n",
" price=1.08)\n",
"print(json.dumps(ordr.data, indent=4))\n",
"r = orders.OrderCreate(accountID=accountID, data=ordr.data)\n",
"rv = client.request(r)\n",
"print(json.dumps(rv, indent=2))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"### Request the pending orders"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"orders\": [\n",
" {\n",
" \"price\": \"1.08000\",\n",
" \"triggerCondition\": \"DEFAULT\",\n",
" \"state\": \"PENDING\",\n",
" \"positionFill\": \"DEFAULT\",\n",
" \"partialFill\": \"DEFAULT_FILL\",\n",
" \"gtdTime\": \"2018-07-02T04:00:00.000000000Z\",\n",
" \"id\": \"8923\",\n",
" \"timeInForce\": \"GTD\",\n",
" \"type\": \"LIMIT\",\n",
" \"instrument\": \"EUR_USD\",\n",
" \"createTime\": \"2018-06-10T12:06:30.259079220Z\",\n",
" \"units\": \"10000\"\n",
" }\n",
" ],\n",
" \"lastTransactionID\": \"8923\"\n",
"}\n"
]
}
],
"source": [
"r = orders.OrdersPending(accountID=accountID)\n",
"rv = client.request(r)\n",
"print(json.dumps(rv, indent=2))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"### Cancel the GTD order\n",
"\n",
"Fetch the *orderID* from the *pending orders* and cancel the order."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"relatedTransactionIDs\": [\n",
" \"8924\"\n",
" ],\n",
" \"orderCancelTransaction\": {\n",
" \"accountID\": \"101-004-1435156-001\",\n",
" \"time\": \"2018-06-10T12:07:35.453416669Z\",\n",
" \"orderID\": \"8923\",\n",
" \"reason\": \"CLIENT_REQUEST\",\n",
" \"requestID\": \"42440346243149289\",\n",
" \"type\": \"ORDER_CANCEL\",\n",
" \"batchID\": \"8924\",\n",
" \"id\": \"8924\",\n",
" \"userID\": 1435156\n",
" },\n",
" \"lastTransactionID\": \"8924\"\n",
"}\n"
]
}
],
"source": [
"r = orders.OrderCancel(accountID=accountID, orderID=8923)\n",
"rv = client.request(r)\n",
"print(json.dumps(rv, indent=2))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Request pendig orders once again ... the 8923 should be gone"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"orders\": [],\n",
" \"lastTransactionID\": \"8924\"\n",
"}\n"
]
}
],
"source": [
"r = orders.OrdersPending(accountID=accountID)\n",
"rv = client.request(r)\n",
"print(json.dumps(rv, indent=2))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
================================================
FILE: jupyter/positions.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"[index](./index.ipynb) | [accounts](./accounts.ipynb) | [orders](./orders.ipynb) | [trades](./trades.ipynb) | [positions](./positions.ipynb) | [historical](./historical.ipynb) | [streams](./streams.ipynb) | [errors](./exceptions.ipynb)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## Open Positions\n",
"\n",
"Lets get the open positions. It should show the total units LONG and SHORT per instrument and the *tradeID's* associated with the position."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Response: {\n",
" \"positions\": [\n",
" {\n",
" \"pl\": \"-752.7628\",\n",
" \"resettablePL\": \"-752.7628\",\n",
" \"unrealizedPL\": \"-128.4516\",\n",
" \"short\": {\n",
" \"units\": \"0\",\n",
" \"pl\": \"-101.7859\",\n",
" \"resettablePL\": \"-101.7859\",\n",
" \"unrealizedPL\": \"0.0000\"\n",
" },\n",
" \"instrument\": \"EUR_USD\",\n",
" \"long\": {\n",
" \"units\": \"50000\",\n",
" \"pl\": \"-650.9769\",\n",
" \"resettablePL\": \"-650.9769\",\n",
" \"averagePrice\": \"1.05836\",\n",
" \"unrealizedPL\": \"-128.4516\",\n",
" \"tradeIDs\": [\n",
" \"4224\",\n",
" \"7558\",\n",
" \"7562\",\n",
" \"7572\",\n",
" \"7579\"\n",
" ]\n",
" }\n",
" }\n",
" ],\n",
" \"lastTransactionID\": \"7582\"\n",
"}\n"
]
}
],
"source": [
"import json\n",
"import oandapyV20\n",
"import oandapyV20.endpoints.positions as positions\n",
"from exampleauth import exampleauth\n",
"\n",
"accountID, access_token = exampleauth.exampleAuth()\n",
"client = oandapyV20.API(access_token=access_token)\n",
"\n",
"r = positions.OpenPositions(accountID=accountID)\n",
"rv = client.request(r)\n",
"print(\"Response: \", json.dumps(rv, indent=2))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
================================================
FILE: jupyter/streams.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"[index](./index.ipynb) | [accounts](./accounts.ipynb) | [orders](./orders.ipynb) | [trades](./trades.ipynb) | [positions](./positions.ipynb) | [historical](./historical.ipynb) | [streams](./streams.ipynb) | [errors](./exceptions.ipynb)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## Streaming data (prices & events)\n",
"\n",
"The REST-V20 API offers *streaming prices* and *streaming events*. Both can be simply accessed as the next example will show."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'asks': [{'liquidity': 10000000.0, 'price': '1.05534'}, {'liquidity': 10000000.0, 'price': '1.05536'}], 'tradeable': True, 'instrument': 'EUR_USD', 'type': 'PRICE', 'closeoutAsk': '1.05538', 'closeoutBid': '1.05518', 'time': '2017-03-09T13:37:46.048197280Z', 'status': 'tradeable', 'bids': [{'liquidity': 10000000.0, 'price': '1.05522'}, {'liquidity': 10000000.0, 'price': '1.05520'}]}\n",
"{'asks': [{'liquidity': 1000000.0, 'price': '120.991'}, {'liquidity': 2000000.0, 'price': '120.992'}, {'liquidity': 5000000.0, 'price': '120.993'}, {'liquidity': 10000000.0, 'price': '120.995'}], 'tradeable': True, 'instrument': 'EUR_JPY', 'type': 'PRICE', 'closeoutAsk': '120.995', 'closeoutBid': '120.965', 'time': '2017-03-09T13:37:44.958026355Z', 'status': 'tradeable', 'bids': [{'liquidity': 1000000.0, 'price': '120.969'}, {'liquidity': 2000000.0, 'price': '120.968'}, {'liquidity': 5000000.0, 'price': '120.967'}, {'liquidity': 10000000.0, 'price': '120.965'}]}\n",
"{'asks': [{'liquidity': 1000000.0, 'price': '120.995'}, {'liquidity': 2000000.0, 'price': '120.996'}, {'liquidity': 5000000.0, 'price': '120.997'}, {'liquidity': 10000000.0, 'price': '120.999'}], 'tradeable': True, 'instrument': 'EUR_JPY', 'type': 'PRICE', 'closeoutAsk': '120.999', 'closeoutBid': '120.971', 'time': '2017-03-09T13:37:47.550550833Z', 'status': 'tradeable', 'bids': [{'liquidity': 1000000.0, 'price': '120.975'}, {'liquidity': 2000000.0, 'price': '120.974'}, {'liquidity': 5000000.0, 'price': '120.973'}, {'liquidity': 10000000.0, 'price': '120.971'}]}\n",
"{'asks': [{'liquidity': 10000000.0, 'price': '1.05527'}, {'liquidity': 10000000.0, 'price': '1.05529'}], 'tradeable': True, 'instrument': 'EUR_USD', 'type': 'PRICE', 'closeoutAsk': '1.05531', 'closeoutBid': '1.05510', 'time': '2017-03-09T13:37:49.349544372Z', 'status': 'tradeable', 'bids': [{'liquidity': 10000000.0, 'price': '1.05514'}, {'liquidity': 10000000.0, 'price': '1.05512'}]}\n",
"Stream processing ended because we made it stop after 3 ticks\n"
]
}
],
"source": [
"import json\n",
"import oandapyV20\n",
"import oandapyV20.endpoints.pricing as pricing\n",
"from oandapyV20.exceptions import StreamTerminated\n",
"from exampleauth import exampleauth\n",
"\n",
"accountID, access_token = exampleauth.exampleAuth()\n",
"client = oandapyV20.API(access_token=access_token)\n",
"\n",
"instruments = [\"EUR_USD\", \"EUR_JPY\"]\n",
"r = pricing.PricingStream(accountID=accountID, params={\"instruments\": \",\".join(instruments)})\n",
"\n",
"n = 0\n",
"stopAfter = 3 # let's terminate after receiving 3 ticks\n",
"try:\n",
" # the stream requests returns a generator so we can do ...\n",
" for tick in client.request(r):\n",
" print(tick)\n",
" if n >= stopAfter:\n",
" r.terminate()\n",
" n += 1\n",
" \n",
"except StreamTerminated as err:\n",
" print(\"Stream processing ended because we made it stop after {} ticks\".format(n))"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'lastTransactionID': '7582', 'time': '2017-03-09T15:08:57.512620407Z', 'type': 'HEARTBEAT'}\n",
"{'lastTransactionID': '7582', 'time': '2017-03-09T15:09:02.594588344Z', 'type': 'HEARTBEAT'}\n",
"{'lastTransactionID': '7582', 'time': '2017-03-09T15:09:07.657436396Z', 'type': 'HEARTBEAT'}\n",
"{'lastTransactionID': '7582', 'time': '2017-03-09T15:09:12.721645564Z', 'type': 'HEARTBEAT'}\n",
"Stream processing ended because we made it stop after 3 ticks\n"
]
}
],
"source": [
"import json\n",
"import oandapyV20\n",
"import oandapyV20.endpoints.transactions as trans\n",
"from oandapyV20.exceptions import StreamTerminated\n",
"from exampleauth import exampleauth\n",
"\n",
"accountID, access_token = exampleauth.exampleAuth()\n",
"client = oandapyV20.API(access_token=access_token)\n",
"\n",
"instruments = [\"EUR_USD\", \"EUR_JPY\"]\n",
"r = trans.TransactionsStream(accountID=accountID)\n",
"\n",
"n = 0\n",
"stopAfter = 3 # let's terminate after receiving 3 ticks\n",
"try:\n",
" # the stream requests returns a generator so we can do ...\n",
" for T in client.request(r):\n",
" print(T)\n",
" if n >= stopAfter:\n",
" r.terminate()\n",
" n += 1\n",
" \n",
"except StreamTerminated as err:\n",
" print(\"Stream processing ended because we made it stop after {} ticks\".format(n))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
================================================
FILE: jupyter/token.txt
================================================
aaaabbbbccccddddeeeeffffaaaabbbb-ccccbbbbaaaaeeeebbbbaaaaffffbbbb
================================================
FILE: jupyter/trades.ipynb
================================================
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"[index](./index.ipynb) | [accounts](./accounts.ipynb) | [orders](./orders.ipynb) | [trades](./trades.ipynb) | [positions](./positions.ipynb) | [historical](./historical.ipynb) | [streams](./streams.ipynb) | [errors](./exceptions.ipynb)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## Open Trades\n",
"\n",
"The previously executed Market-Order resulted in a *trade: LONG 10000 EUR_USD*. This results also in a *Position*.\n",
"The position will be 10000 units also unless there were other trades opened in the same instrument. In that case the last 10000 units will be added to it. \n",
"\n",
"Example: get the open trades. The trade that was opened has the id 7562. It should be in the list of trades that we get by performing an OpenTrades request. "
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Response: {\n",
" \"lastTransactionID\": \"7582\",\n",
" \"trades\": [\n",
" {\n",
" \"state\": \"OPEN\",\n",
" \"financing\": \"0.0000\",\n",
" \"stopLossOrder\": {\n",
" \"state\": \"PENDING\",\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.05000\",\n",
" \"triggerCondition\": \"TRIGGER_DEFAULT\",\n",
" \"createTime\": \"2017-03-09T13:22:13.832587780Z\",\n",
" \"id\": \"7581\",\n",
" \"type\": \"STOP_LOSS\",\n",
" \"tradeID\": \"7579\"\n",
" },\n",
" \"realizedPL\": \"0.0000\",\n",
" \"price\": \"1.05563\",\n",
" \"unrealizedPL\": \"-0.8526\",\n",
" \"instrument\": \"EUR_USD\",\n",
" \"initialUnits\": \"10000\",\n",
" \"id\": \"7579\",\n",
" \"openTime\": \"2017-03-09T13:22:13.832587780Z\",\n",
" \"currentUnits\": \"10000\"\n",
" },\n",
" {\n",
" \"state\": \"OPEN\",\n",
" \"financing\": \"0.0000\",\n",
" \"stopLossOrder\": {\n",
" \"state\": \"PENDING\",\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.05000\",\n",
" \"triggerCondition\": \"TRIGGER_DEFAULT\",\n",
" \"createTime\": \"2017-03-09T11:45:48.928448770Z\",\n",
" \"id\": \"7574\",\n",
" \"type\": \"STOP_LOSS\",\n",
" \"tradeID\": \"7572\"\n",
" },\n",
" \"realizedPL\": \"0.0000\",\n",
" \"price\": \"1.05580\",\n",
" \"unrealizedPL\": \"-2.4632\",\n",
" \"instrument\": \"EUR_USD\",\n",
" \"initialUnits\": \"10000\",\n",
" \"id\": \"7572\",\n",
" \"openTime\": \"2017-03-09T11:45:48.928448770Z\",\n",
" \"currentUnits\": \"10000\"\n",
" },\n",
" {\n",
" \"state\": \"OPEN\",\n",
" \"financing\": \"-0.2693\",\n",
" \"stopLossOrder\": {\n",
" \"state\": \"PENDING\",\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.05000\",\n",
" \"triggerCondition\": \"TRIGGER_DEFAULT\",\n",
" \"createTime\": \"2017-03-07T09:18:51.563637768Z\",\n",
" \"id\": \"7564\",\n",
" \"type\": \"STOP_LOSS\",\n",
" \"tradeID\": \"7562\"\n",
" },\n",
" \"realizedPL\": \"0.0000\",\n",
" \"price\": \"1.05837\",\n",
" \"unrealizedPL\": \"-26.8109\",\n",
" \"instrument\": \"EUR_USD\",\n",
" \"initialUnits\": \"10000\",\n",
" \"id\": \"7562\",\n",
" \"openTime\": \"2017-03-07T09:18:51.563637768Z\",\n",
" \"currentUnits\": \"10000\"\n",
" },\n",
" {\n",
" \"state\": \"OPEN\",\n",
" \"financing\": \"-0.2706\",\n",
" \"stopLossOrder\": {\n",
" \"state\": \"PENDING\",\n",
" \"timeInForce\": \"GTC\",\n",
" \"price\": \"1.05000\",\n",
" \"triggerCondition\": \"TRIGGER_DEFAULT\",\n",
" \"createTime\": \"2017-03-07T09:08:04.219010730Z\",\n",
" \"id\": \"7560\",\n",
" \"type\": \"STOP_LOSS\",\n",
" \"tradeID\": \"7558\"\n",
" },\n",
" \"realizedPL\": \"0.0000\",\n",
" \"price\": \"1.05820\",\n",
" \"unrealizedPL\": \"-25.2004\",\n",
" \"instrument\": \"EUR_USD\",\n",
" \"initialUnits\": \"10000\",\n",
" \"id\": \"7558\",\n",
" \"openTime\": \"2017-03-07T09:08:04.219010730Z\",\n",
" \"currentUnits\": \"10000\"\n",
" },\n",
" {\n",
" \"state\": \"OPEN\",\n",
" \"financing\": \"-4.7102\",\n",
" \"realizedPL\": \"0.0000\",\n",
" \"price\": \"1.06381\",\n",
" \"unrealizedPL\": \"-78.3485\",\n",
" \"instrument\": \"EUR_USD\",\n",
" \"initialUnits\": \"10000\",\n",
" \"id\": \"4224\",\n",
" \"openTime\": \"2017-02-10T21:50:02.670154087Z\",\n",
" \"currentUnits\": \"10000\"\n",
" }\n",
" ]\n",
"}\n"
]
}
],
"source": [
"import json\n",
"import oandapyV20\n",
"import oandapyV20.endpoints.trades as trades\n",
"from exampleauth import exampleauth\n",
"\n",
"accountID, access_token = exampleauth.exampleAuth()\n",
"client = oandapyV20.API(access_token=access_token)\n",
"\n",
"r = trades.OpenTrades(accountID=accountID)\n",
"rv = client.request(r)\n",
"print(\"Response: \", json.dumps(rv, indent=2))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
================================================
FILE: oandapyV20/__init__.py
================================================
import logging
from .oandapyV20 import API
from .exceptions import V20Error
__title__ = "OANDA REST V20 API Wrapper"
__version__ = "0.7.2"
__author__ = "Feite Brekeveld"
__license__ = "MIT"
__copyright__ = "Copyright 2016 - 2018 Feite Brekeveld"
# Version synonym
VERSION = __version__
# Set default logging handler to avoid "No handler found" warnings.
try:
from logging import NullHandler
except ImportError:
class NullHandler(logging.Handler):
def emit(self, record):
pass
logging.getLogger(__name__).addHandler(NullHandler())
__all__ = (
'API',
'V20Error'
)
================================================
FILE: oandapyV20/contrib/__init__.py
================================================
================================================
FILE: oandapyV20/contrib/factories/__init__.py
================================================
from .history import InstrumentsCandlesFactory
__all__ = (
'InstrumentsCandlesFactory',
)
================================================
FILE: oandapyV20/contrib/factories/history.py
================================================
# -*- coding: utf-8 -*-
from datetime import datetime
import calendar
import logging
import oandapyV20.endpoints.instruments as instruments
from oandapyV20.contrib.generic import granularity_to_time, secs2time
logger = logging.getLogger(__name__)
MAX_BATCH = 5000
DEFAULT_BATCH = 500
def InstrumentsCandlesFactory(instrument, params=None):
"""InstrumentsCandlesFactory - generate InstrumentCandles requests.
InstrumentsCandlesFactory is used to retrieve historical data by
automatically generating consecutive requests when the OANDA limit
of *count* records is exceeded.
This is known by calculating the number of candles between *from* and
*to*. If *to* is not specified *to* will be equal to *now*.
The *count* parameter is only used to control the number of records to
retrieve in a single request.
The *includeFirst* parameter is forced to make sure that results do
no have a 1-record gap between consecutive requests.
Parameters
----------
instrument : string (required)
the instrument to create the order for
params: params (optional)
the parameters to specify the historical range,
see the REST-V20 docs regarding 'instrument' at developer.oanda.com
If no params are specified, just a single InstrumentsCandles request
will be generated acting the same as if you had just created it
directly.
Example
-------
The *oandapyV20.API* client processes requests as objects. So,
downloading large historical batches simply comes down to:
>>> import json
>>> from oandapyV20 import API
>>> from oandapyV20.contrib.factories import InstrumentsCandlesFactory
>>>
>>> client = API(access_token=...)
>>> instrument, granularity = "EUR_USD", "M15"
>>> _from = "2017-01-01T00:00:00Z"
>>> params = {
... "from": _from,
... "granularity": granularity,
... "count": 2500,
... }
>>> with open("/tmp/{}.{}".format(instrument, granularity), "w") as OUT:
>>> # The factory returns a generator generating consecutive
>>> # requests to retrieve full history from date 'from' till 'to'
>>> for r in InstrumentsCandlesFactory(instrument=instrument,
... params=params)
>>> client.request(r)
>>> OUT.write(json.dumps(r.response.get('candles'), indent=2))
.. note:: Normally you can't combine *from*, *to* and *count*.
When *count* specified, it is used to calculate the gap between
*to* and *from*. The *params* passed to the generated request
itself does contain the *count* parameter.
"""
RFC3339 = "%Y-%m-%dT%H:%M:%SZ"
# if not specified use the default of 'S5' as OANDA does
gs = granularity_to_time(params.get('granularity', 'S5'))
_from = None
_epoch_from = None
if 'from' in params:
_from = datetime.strptime(params.get('from'), RFC3339)
_epoch_from = int(calendar.timegm(_from.timetuple()))
_to = datetime.utcnow()
if 'to' in params:
_tmp = datetime.strptime(params.get('to'), RFC3339)
# if specified datetime > now, we use 'now' instead
if _tmp > _to:
logger.info("datetime %s is in the future, will be set to 'now'",
params.get('to'))
else:
_to = _tmp
_epoch_to = int(calendar.timegm(_to.timetuple()))
_count = params.get('count', DEFAULT_BATCH)
# OANDA will respond with a V20Error if count > MAX_BATCH
if 'to' in params and 'from' not in params:
raise ValueError("'to' specified without 'from'")
if not params or 'from' not in params:
yield instruments.InstrumentsCandles(instrument=instrument,
params=params)
else:
delta = _epoch_to - _epoch_from
nbars = delta / gs
cpparams = params.copy()
for k in ['count', 'from', 'to']:
if k in cpparams:
del cpparams[k]
# force includeFirst
cpparams.update({"includeFirst": True})
# generate InstrumentsCandles requests for all 'bars', each request
# requesting max. count records
for _ in range(_count, int(((nbars//_count)+1))*_count+1, _count):
to = _epoch_from + _count * gs
if to > _epoch_to:
to = _epoch_to
yparams = cpparams.copy()
yparams.update({"from": secs2time(_epoch_from).strftime(RFC3339)})
yparams.update({"to": secs2time(to).strftime(RFC3339)})
yield instruments.InstrumentsCandles(instrument=instrument,
params=yparams)
_epoch_from = to
================================================
FILE: oandapyV20/contrib/generic.py
================================================
import re
import time
from datetime import datetime
def secs2time(e):
"""secs2time - convert epoch to datetime.
>>> d = secs2time(1497499200)
>>> d
datetime.datetime(2017, 6, 15, 4, 0)
>>> d.strftime("%Y%m%d-%H:%M:%S")
'20170615-04:00:00'
"""
w = time.gmtime(e)
return datetime(*list(w)[0:6])
def granularity_to_time(s):
"""convert a named granularity into seconds.
get value in seconds for named granularities: M1, M5 ... H1 etc.
>>> print(granularity_to_time("M5"))
300
"""
mfact = {
'S': 1,
'M': 60,
'H': 3600,
'D': 86400,
'W': 604800,
}
try:
f, n = re.match("(?P<f>[SMHDW])(?:(?P<n>\d+)|)", s).groups()
n = n if n else 1
return mfact[f] * int(n)
except Exception as e:
raise ValueError(e)
================================================
FILE: oandapyV20/contrib/requests/__init__.py
================================================
from .marketorder import MarketOrderRequest
from .limitorder import LimitOrderRequest
from .mitorder import MITOrderRequest
from .takeprofitorder import TakeProfitOrderRequest
from .stoplossorder import StopLossOrderRequest
from .trailingstoplossorder import TrailingStopLossOrderRequest
from .stoporder import StopOrderRequest
from .positionclose import PositionCloseRequest
from .tradeclose import TradeCloseRequest
from .onfill import (
TakeProfitDetails,
StopLossDetails,
TrailingStopLossDetails
)
from .extensions import ClientExtensions
__all__ = (
'MarketOrderRequest',
'LimitOrderRequest',
'MITOrderRequest',
'TakeProfitOrderRequest',
'StopLossOrderRequest',
'TrailingStopLossOrderRequest',
'StopOrderRequest',
'PositionCloseRequest',
'TradeCloseRequest',
'TakeProfitDetails',
'StopLossDetails',
'TrailingStopLossDetails',
'ClientExtensions',
)
================================================
FILE: oandapyV20/contrib/requests/baserequest.py
================================================
# -*- coding: utf-8 -*-
"""baserequest."""
import json
import six
from abc import ABCMeta, abstractmethod
@six.add_metaclass(ABCMeta)
class BaseRequest(object):
"""baseclass for request classes."""
@abstractmethod
def __init__(self):
self._data = dict()
def __repr__(self):
return json.dumps(self.__dict__)
@property
def data(self):
"""data - return the JSON body.
The data property returns a dict representing the
JSON-body needed for the API-request. All values that are
not set will be left out
"""
d = dict()
for k, v in self._data.items():
# skip unset properties
if v is None:
continue
d.update({k: v})
return d
def toJSON(self):
return json.dumps(self,
default=lambda o: o.__dict__,
sort_keys=True,
indent=4)
================================================
FILE: oandapyV20/contrib/requests/extensions.py
================================================
# -*- coding: utf-8 -*-
from .baserequest import BaseRequest
from oandapyV20.types import ClientID, ClientTag, ClientComment
class ClientExtensions(BaseRequest):
"""Representation of the ClientExtensions."""
def __init__(self,
clientID=None,
clientTag=None,
clientComment=None):
"""Instantiate ClientExtensions.
Parameters
----------
clientID : clientID (required)
the clientID
clientTag : clientTag (required)
the clientTag
clientComment : clientComment (required)
the clientComment
Example
-------
>>> import json
>>> from oandapyV20 import API
>>> import oandapyV20.endpoints.orders as orders
>>> from oandapyV20.contrib.requests import (
... MarketOrderRequest, TakeProfitDetails, ClientExtensions)
>>>
>>> accountID = "..."
>>> client = API(access_token=...)
>>> # at time of writing EUR_USD = 1.0740
>>> # let us take profit at 1.10, GoodTillCancel (default)
>>> # add clientExtensions to it also
>>> takeProfitOnFillOrder = TakeProfitDetails(
... price=1.10,
... clientExtensions=ClientExtensions(clientTag="mytag").data)
>>> print(takeProfitOnFillOrder.data)
{
'timeInForce': 'GTC',
'price": '1.10000',
'clientExtensions': {'tag': 'mytag'}
}
>>> ordr = MarketOrderRequest(
... instrument="EUR_USD",
... units=10000,
... takeProfitOnFill=takeProfitOnFillOrder.data
... )
>>> # or as shortcut ...
>>> # takeProfitOnFill=TakeProfitDetails(price=1.10).data
>>> print(json.dumps(ordr.data, indent=4))
>>> r = orders.OrderCreate(accountID, data=ordr.data)
>>> rv = client.request(r)
>>> ...
"""
super(ClientExtensions, self).__init__()
if not (clientID or clientTag or clientComment):
raise ValueError("clientID, clientTag, clientComment required")
if clientID:
self._data.update({"id": ClientID(clientID).value})
if clientTag:
self._data.update({"tag": ClientTag(clientTag).value})
if clientComment:
self._data.update({"comment": ClientComment(clientComment).value})
================================================
FILE: oandapyV20/contrib/requests/limitorder.py
================================================
# -*- coding: utf-8 -*-
from .baserequest import BaseRequest
from oandapyV20.types import Units, PriceValue
from oandapyV20.definitions.orders import (
OrderType,
TimeInForce,
OrderPositionFill)
class LimitOrderRequest(BaseRequest):
"""create a LimitOrderRequest.
LimitOrderRequest is used to build the body for a LimitOrder.
The body can be used to pass to the OrderCreate endpoint.
"""
def __init__(self,
instrument,
units,
price,
positionFill=OrderPositionFill.DEFAULT,
clientExtensions=None,
takeProfitOnFill=None,
timeInForce=TimeInForce.GTC,
gtdTime=None,
stopLossOnFill=None,
trailingStopLossOnFill=None,
tradeClientExtensions=None):
"""
Instantiate a LimitOrderRequest.
Parameters
----------
instrument : string (required)
the instrument to create the order for
units: integer (required)
the number of units. If positive the order results in a LONG
order. If negative the order results in a SHORT order
price: float (required)
the price indicating the limit.
Example
-------
>>> import json
>>> from oandapyV20 import API
>>> import oandapyV20.endpoints.orders as orders
>>> from oandapyV20.contrib.requests import LimitOrderRequest
>>>
>>> accountID = "..."
>>> client = API(access_token=...)
>>> ordr = LimitOrderRequest(instrument="EUR_USD",
... units=10000, price=1.08)
>>> print(json.dumps(ordr.data, indent=4))
{
"order": {
"timeInForce": "GTC",
"instrument": "EUR_USD",
"units": "10000",
"price": "1.08000",
"type": "LIMIT",
"positionFill": "DEFAULT"
}
}
>>> r = orders.orderCreate(accountID, data=ordr.data)
>>> rv = client.request(r)
>>>
"""
super(LimitOrderRequest, self).__init__()
# by default for a LIMIT order
self._data.update({"type": OrderType.LIMIT})
self._data.update({"timeInForce": timeInForce})
# required
self._data.update({"instrument": instrument})
self._data.update({"units": Units(units).value})
self._data.update({"price": PriceValue(price).value})
# optional, but required if timeInForce.GTD
self._data.update({"gtdTime": gtdTime})
if timeInForce == TimeInForce.GTD and not gtdTime:
raise ValueError("gtdTime missing")
# optional
self._data.update({"positionFill": positionFill})
self._data.update({"clientExtensions": clientExtensions})
self._data.update({"takeProfitOnFill": takeProfitOnFill})
self._data.update({"stopLossOnFill": stopLossOnFill})
self._data.update({"trailingStopLossOnFill": trailingStopLossOnFill})
self._data.update({"tradeClientExtensions": tradeClientExtensions})
@property
def data(self):
"""data property.
return the JSON order body
"""
return dict({"order": super(LimitOrderRequest, self).data})
================================================
FILE: oandapyV20/contrib/requests/marketorder.py
================================================
# -*- coding: utf-8 -*-
from .baserequest import BaseRequest
from oandapyV20.types import Units, PriceValue
from oandapyV20.definitions.orders import (
OrderType,
TimeInForce,
OrderPositionFill)
class MarketOrderRequest(BaseRequest):
"""create a MarketOrderRequest.
MarketOrderRequest is used to build the body for a MarketOrder.
The body can be used to pass to the OrderCreate endpoint.
"""
def __init__(self,
instrument,
units,
priceBound=None,
positionFill=OrderPositionFill.DEFAULT,
clientExtensions=None,
takeProfitOnFill=None,
timeInForce=TimeInForce.FOK,
stopLossOnFill=None,
trailingStopLossOnFill=None,
tradeClientExtensions=None):
"""
Instantiate a MarketOrderRequest.
Parameters
----------
instrument : string (required)
the instrument to create the order for
units: integer (required)
the number of units. If positive the order results in a LONG
order. If negative the order results in a SHORT order
Example
-------
>>> import json
>>> from oandapyV20 import API
>>> import oandapyV20.endpoints.orders as orders
>>> from oandapyV20.contrib.requests import MarketOrderRequest
>>>
>>> accountID = "..."
>>> client = API(access_token=...)
>>> mo = MarketOrderRequest(instrument="EUR_USD", units=10000)
>>> print(json.dumps(mo.data, indent=4))
{
"order": {
"type": "MARKET",
"positionFill": "DEFAULT",
"instrument": "EUR_USD",
"timeInForce": "FOK",
"units": "10000"
}
}
>>> # now we have the order specification, create the order request
>>> r = orders.OrderCreate(accountID, data=mo.data)
>>> # perform the request
>>> rv = client.request(r)
>>> print(rv)
>>> print(json.dumps(rv, indent=4))
{
"orderFillTransaction": {
"reason": "MARKET_ORDER",
"pl": "0.0000",
"accountBalance": "97864.8813",
"units": "10000",
"instrument": "EUR_USD",
"accountID": "101-004-1435156-001",
"time": "2016-11-11T19:59:43.253587917Z",
"type": "ORDER_FILL",
"id": "2504",
"financing": "0.0000",
"tradeOpened": {
"tradeID": "2504",
"units": "10000"
},
"orderID": "2503",
"userID": 1435156,
"batchID": "2503",
"price": "1.08463"
},
"lastTransactionID": "2504",
"relatedTransactionIDs": [
"2503",
"2504"
],
"orderCreateTransaction": {
"type": "MARKET_ORDER",
"reason": "CLIENT_ORDER",
"id": "2503",
"timeInForce": "FOK",
"units": "10000",
"time": "2016-11-11T19:59:43.253587917Z",
"positionFill": "DEFAULT",
"accountID": "101-004-1435156-001",
"instrument": "EUR_USD",
"batchID": "2503",
"userID": 1435156
}
}
>>>
"""
super(MarketOrderRequest, self).__init__()
# allowed: FOK/IOC
if timeInForce not in [TimeInForce.FOK,
TimeInForce.IOC]:
raise ValueError("timeInForce: {}".format(timeInForce))
# by default for a MARKET order
self._data.update({"type": OrderType.MARKET})
self._data.update({"timeInForce": timeInForce})
# required
self._data.update({"instrument": instrument})
self._data.update({"units": Units(units).value})
# optional
if priceBound:
self._data.update({"priceBound": PriceValue(priceBound).value})
if not hasattr(OrderPositionFill, positionFill):
raise ValueError("positionFill {}".format(positionFill))
self._data.update({"positionFill": positionFill})
self._data.update({"clientExtensions": clientExtensions})
self._data.update({"takeProfitOnFill": takeProfitOnFill})
self._data.update({"stopLossOnFill": stopLossOnFill})
self._data.update({"trailingStopLossOnFill": trailingStopLossOnFill})
self._data.update({"tradeClientExtensions": tradeClientExtensions})
@property
def data(self):
"""data property.
return the JSON body.
"""
return dict({"order": super(MarketOrderRequest, self).data})
==========================
gitextract_zbddjf3w/
├── .gitignore
├── .landscape.yml
├── .travis.yml
├── CHANGELOG.rst
├── LICENSE.md
├── MANIFEST.in
├── README.rst
├── docs/
│ ├── Makefile
│ ├── conf.py
│ ├── contrib/
│ │ ├── factories/
│ │ │ └── instrumentscandlesfactory.rst
│ │ ├── factories.rst
│ │ ├── generic/
│ │ │ └── generic.rst
│ │ ├── generic.rst
│ │ ├── orders/
│ │ │ ├── limitorderrequest.rst
│ │ │ ├── marketorderrequest.rst
│ │ │ ├── mitorderrequest.rst
│ │ │ ├── positionscloserequest.rst
│ │ │ ├── stoplossorderrequest.rst
│ │ │ ├── stoporderrequest.rst
│ │ │ ├── takeprofitorderrequest.rst
│ │ │ ├── tradecloserequest.rst
│ │ │ └── trailingstoplossorderrequest.rst
│ │ ├── orders.rst
│ │ ├── support/
│ │ │ ├── clientextensions.rst
│ │ │ ├── stoplossdetails.rst
│ │ │ ├── takeprofitdetails.rst
│ │ │ └── trailingstoplossdetails.rst
│ │ └── support.rst
│ ├── dirstruct.py
│ ├── endpoints/
│ │ ├── accounts/
│ │ │ ├── accountchanges.rst
│ │ │ ├── accountconfiguration.rst
│ │ │ ├── accountdetails.rst
│ │ │ ├── accountinstruments.rst
│ │ │ ├── accountlist.rst
│ │ │ └── accountsummary.rst
│ │ ├── accounts.rst
│ │ ├── forexlabs/
│ │ │ ├── autochartist.rst
│ │ │ ├── calendar.rst
│ │ │ ├── commitmentsoftraders.rst
│ │ │ ├── historicalpositionratios.rst
│ │ │ ├── orderbookdata.rst
│ │ │ └── spreads.rst
│ │ ├── forexlabs.rst
│ │ ├── instruments/
│ │ │ ├── instrumentlist.rst
│ │ │ ├── instrumentorderbook.rst
│ │ │ └── instrumentpositionbook.rst
│ │ ├── instruments.rst
│ │ ├── orders/
│ │ │ ├── ordercancel.rst
│ │ │ ├── orderclientextensions.rst
│ │ │ ├── ordercreate.rst
│ │ │ ├── orderdetails.rst
│ │ │ ├── orderlist.rst
│ │ │ ├── orderreplace.rst
│ │ │ └── orderspending.rst
│ │ ├── orders.rst
│ │ ├── positions/
│ │ │ ├── openpositions.rst
│ │ │ ├── positionclose.rst
│ │ │ ├── positiondetails.rst
│ │ │ └── positionlist.rst
│ │ ├── positions.rst
│ │ ├── pricing/
│ │ │ ├── pricinginfo.rst
│ │ │ └── pricingstream.rst
│ │ ├── pricing.rst
│ │ ├── trades/
│ │ │ ├── opentrades.rst
│ │ │ ├── tradeCRCDO.rst
│ │ │ ├── tradeclientextensions.rst
│ │ │ ├── tradeclose.rst
│ │ │ ├── tradedetails.rst
│ │ │ └── tradeslist.rst
│ │ ├── trades.rst
│ │ ├── transactions/
│ │ │ ├── transactiondetails.rst
│ │ │ ├── transactionidrange.rst
│ │ │ ├── transactionlist.rst
│ │ │ ├── transactionssinceid.rst
│ │ │ └── transactionsstream.rst
│ │ └── transactions.rst
│ ├── examples.rst
│ ├── index.rst
│ ├── installation.rst
│ ├── oanda-api-v20.rst
│ ├── oandapyV20.contrib.rst
│ ├── oandapyV20.definitions.accounts.rst
│ ├── oandapyV20.definitions.instruments.rst
│ ├── oandapyV20.definitions.orders.rst
│ ├── oandapyV20.definitions.pricing.rst
│ ├── oandapyV20.definitions.rst
│ ├── oandapyV20.definitions.trades.rst
│ ├── oandapyV20.definitions.transactions.rst
│ ├── oandapyV20.endpoints.rst
│ ├── oandapyV20.types.rst
│ └── types/
│ ├── AccountID.rst
│ ├── AccountUnits.rst
│ ├── ClientComment.rst
│ ├── ClientID.rst
│ ├── ClientTag.rst
│ ├── DateTime.rst
│ ├── OrderID.rst
│ ├── OrderIdentifier.rst
│ ├── OrderSpecifier.rst
│ ├── PriceValue.rst
│ ├── TradeID.rst
│ └── Units.rst
├── examples/
│ └── README.rst
├── jupyter/
│ ├── account.txt
│ ├── accounts.ipynb
│ ├── exampleauth/
│ │ ├── __init__.py
│ │ └── exampleauth.py
│ ├── exceptions.ipynb
│ ├── historical.ipynb
│ ├── index.ipynb
│ ├── orders.ipynb
│ ├── positions.ipynb
│ ├── streams.ipynb
│ ├── token.txt
│ └── trades.ipynb
├── oandapyV20/
│ ├── __init__.py
│ ├── contrib/
│ │ ├── __init__.py
│ │ ├── factories/
│ │ │ ├── __init__.py
│ │ │ └── history.py
│ │ ├── generic.py
│ │ └── requests/
│ │ ├── __init__.py
│ │ ├── baserequest.py
│ │ ├── extensions.py
│ │ ├── limitorder.py
│ │ ├── marketorder.py
│ │ ├── mitorder.py
│ │ ├── onfill.py
│ │ ├── positionclose.py
│ │ ├── stoplossorder.py
│ │ ├── stoporder.py
│ │ ├── takeprofitorder.py
│ │ ├── tradeclose.py
│ │ └── trailingstoplossorder.py
│ ├── definitions/
│ │ ├── __init__.py
│ │ ├── accounts.py
│ │ ├── instruments.py
│ │ ├── orders.py
│ │ ├── pricing.py
│ │ ├── primitives.py
│ │ ├── trades.py
│ │ └── transactions.py
│ ├── endpoints/
│ │ ├── __init__.py
│ │ ├── accounts.py
│ │ ├── apirequest.py
│ │ ├── decorators.py
│ │ ├── forexlabs.py
│ │ ├── instruments.py
│ │ ├── orders.py
│ │ ├── positions.py
│ │ ├── pricing.py
│ │ ├── responses/
│ │ │ ├── __init__.py
│ │ │ ├── accounts.py
│ │ │ ├── forexlabs.py
│ │ │ ├── instruments.py
│ │ │ ├── orders.py
│ │ │ ├── positions.py
│ │ │ ├── pricing.py
│ │ │ ├── trades.py
│ │ │ └── transactions.py
│ │ ├── trades.py
│ │ └── transactions.py
│ ├── exceptions.py
│ ├── oandapyV20.py
│ └── types/
│ ├── __init__.py
│ └── types.py
├── readthedocs.yml
├── requirements.txt
├── setup.py
└── tests/
├── __init__.py
├── account.txt
├── test_accounts.py
├── test_contrib_factories.py
├── test_contrib_generic.py
├── test_contrib_orders.py
├── test_decorators.py
├── test_definitions.py
├── test_forexlabs.py
├── test_instruments.py
├── test_oandapyv20.py
├── test_orders.py
├── test_positions.py
├── test_pricing.py
├── test_trades.py
├── test_transactions.py
├── test_types.py
├── token.txt
└── unittestsetup.py
SYMBOL INDEX (289 symbols across 49 files)
FILE: docs/conf.py
class ExecDirective (line 362) | class ExecDirective(Directive):
method run (line 366) | def run(self):
function setup (line 383) | def setup(app):
FILE: docs/dirstruct.py
function get_classes (line 12) | def get_classes(modName):
FILE: jupyter/exampleauth/exampleauth.py
function exampleAuth (line 4) | def exampleAuth():
FILE: oandapyV20/__init__.py
class NullHandler (line 18) | class NullHandler(logging.Handler):
method emit (line 19) | def emit(self, record):
FILE: oandapyV20/contrib/factories/history.py
function InstrumentsCandlesFactory (line 17) | def InstrumentsCandlesFactory(instrument, params=None):
FILE: oandapyV20/contrib/generic.py
function secs2time (line 6) | def secs2time(e):
function granularity_to_time (line 19) | def granularity_to_time(s):
FILE: oandapyV20/contrib/requests/baserequest.py
class BaseRequest (line 10) | class BaseRequest(object):
method __init__ (line 14) | def __init__(self):
method __repr__ (line 17) | def __repr__(self):
method data (line 21) | def data(self):
method toJSON (line 38) | def toJSON(self):
FILE: oandapyV20/contrib/requests/extensions.py
class ClientExtensions (line 7) | class ClientExtensions(BaseRequest):
method __init__ (line 10) | def __init__(self,
FILE: oandapyV20/contrib/requests/limitorder.py
class LimitOrderRequest (line 11) | class LimitOrderRequest(BaseRequest):
method __init__ (line 18) | def __init__(self,
method data (line 98) | def data(self):
FILE: oandapyV20/contrib/requests/marketorder.py
class MarketOrderRequest (line 11) | class MarketOrderRequest(BaseRequest):
method __init__ (line 18) | def __init__(self,
method data (line 143) | def data(self):
FILE: oandapyV20/contrib/requests/mitorder.py
class MITOrderRequest (line 11) | class MITOrderRequest(BaseRequest):
method __init__ (line 18) | def __init__(self,
method data (line 106) | def data(self):
FILE: oandapyV20/contrib/requests/onfill.py
class OnFill (line 11) | class OnFill(BaseRequest):
method __init__ (line 15) | def __init__(self,
class TakeProfitDetails (line 35) | class TakeProfitDetails(OnFill):
method __init__ (line 48) | def __init__(self,
class StopLossDetails (line 118) | class StopLossDetails(OnFill):
method __init__ (line 131) | def __init__(self,
class TrailingStopLossDetails (line 191) | class TrailingStopLossDetails(OnFill):
method __init__ (line 204) | def __init__(self,
FILE: oandapyV20/contrib/requests/positionclose.py
class PositionCloseRequest (line 8) | class PositionCloseRequest(BaseRequest):
method __init__ (line 15) | def __init__(self,
FILE: oandapyV20/contrib/requests/stoplossorder.py
class StopLossOrderRequest (line 8) | class StopLossOrderRequest(BaseRequest):
method __init__ (line 15) | def __init__(self,
method data (line 85) | def data(self):
FILE: oandapyV20/contrib/requests/stoporder.py
class StopOrderRequest (line 11) | class StopOrderRequest(BaseRequest):
method __init__ (line 18) | def __init__(self,
method data (line 103) | def data(self):
FILE: oandapyV20/contrib/requests/takeprofitorder.py
class TakeProfitOrderRequest (line 8) | class TakeProfitOrderRequest(BaseRequest):
method __init__ (line 15) | def __init__(self,
method data (line 84) | def data(self):
FILE: oandapyV20/contrib/requests/tradeclose.py
class TradeCloseRequest (line 7) | class TradeCloseRequest(BaseRequest):
method __init__ (line 14) | def __init__(self, units="ALL"):
FILE: oandapyV20/contrib/requests/trailingstoplossorder.py
class TrailingStopLossOrderRequest (line 8) | class TrailingStopLossOrderRequest(BaseRequest):
method __init__ (line 16) | def __init__(self,
method data (line 86) | def data(self):
FILE: oandapyV20/definitions/__init__.py
function make_definition_classes (line 40) | def make_definition_classes(mod):
FILE: oandapyV20/endpoints/accounts.py
class Accounts (line 9) | class Accounts(APIRequest):
method __init__ (line 17) | def __init__(self, accountID=None):
class AccountList (line 33) | class AccountList(Accounts):
method __init__ (line 37) | def __init__(self):
class AccountDetails (line 56) | class AccountDetails(Accounts):
method __init__ (line 65) | def __init__(self, accountID):
class AccountSummary (line 90) | class AccountSummary(Accounts):
method __init__ (line 94) | def __init__(self, accountID):
class AccountInstruments (line 119) | class AccountInstruments(Accounts):
method __init__ (line 129) | def __init__(self, accountID, params=None):
class AccountConfiguration (line 164) | class AccountConfiguration(Accounts):
method __init__ (line 170) | def __init__(self, accountID, data):
class AccountChanges (line 203) | class AccountChanges(Accounts):
method __init__ (line 211) | def __init__(self, accountID, params=None):
FILE: oandapyV20/endpoints/apirequest.py
class APIRequest (line 7) | class APIRequest(object):
method __init__ (line 11) | def __init__(self, endpoint, method="GET", expected_status=200):
method expected_status (line 30) | def expected_status(self):
method status_code (line 34) | def status_code(self):
method status_code (line 38) | def status_code(self, value):
method response (line 44) | def response(self):
method response (line 49) | def response(self, value):
method __str__ (line 53) | def __str__(self):
FILE: oandapyV20/endpoints/decorators.py
function dyndoc_insert (line 5) | def dyndoc_insert(src):
function endpoint (line 57) | def endpoint(url, method="GET", expected_status=200):
function abstractclass (line 72) | def abstractclass(cls):
class extendargs (line 109) | class extendargs(object):
method __init__ (line 115) | def __init__(self, *loa):
method __call__ (line 118) | def __call__(self, cls):
FILE: oandapyV20/endpoints/forexlabs.py
class ForexLabs (line 8) | class ForexLabs(APIRequest):
method __init__ (line 16) | def __init__(self):
class Calendar (line 24) | class Calendar(ForexLabs):
method __init__ (line 31) | def __init__(self, params):
class HistoricalPositionRatios (line 59) | class HistoricalPositionRatios(ForexLabs):
method __init__ (line 66) | def __init__(self, params):
class Spreads (line 94) | class Spreads(ForexLabs):
method __init__ (line 101) | def __init__(self, params):
class CommitmentsOfTraders (line 129) | class CommitmentsOfTraders(ForexLabs):
method __init__ (line 136) | def __init__(self, params):
class OrderbookData (line 164) | class OrderbookData(ForexLabs):
method __init__ (line 171) | def __init__(self, params):
class Autochartist (line 199) | class Autochartist(ForexLabs):
method __init__ (line 206) | def __init__(self, params=None):
FILE: oandapyV20/endpoints/instruments.py
class Instruments (line 9) | class Instruments(APIRequest):
method __init__ (line 17) | def __init__(self, instrument):
class InstrumentsCandles (line 32) | class InstrumentsCandles(Instruments):
method __init__ (line 36) | def __init__(self, instrument, params=None):
class InstrumentsOrderBook (line 76) | class InstrumentsOrderBook(Instruments):
method __init__ (line 80) | def __init__(self, instrument, params=None):
class InstrumentsPositionBook (line 120) | class InstrumentsPositionBook(Instruments):
method __init__ (line 124) | def __init__(self, instrument, params=None):
FILE: oandapyV20/endpoints/orders.py
class Orders (line 9) | class Orders(APIRequest):
method __init__ (line 18) | def __init__(self, accountID, orderID=None):
class OrderCreate (line 35) | class OrderCreate(Orders):
method __init__ (line 41) | def __init__(self, accountID, data):
class OrderList (line 74) | class OrderList(Orders):
method __init__ (line 78) | def __init__(self, accountID, params=None):
class OrdersPending (line 111) | class OrdersPending(Orders):
method __init__ (line 115) | def __init__(self, accountID):
class OrderDetails (line 143) | class OrderDetails(Orders):
method __init__ (line 147) | def __init__(self, accountID, orderID):
class OrderReplace (line 175) | class OrderReplace(Orders):
method __init__ (line 185) | def __init__(self, accountID, orderID, data):
class OrderCancel (line 222) | class OrderCancel(Orders):
method __init__ (line 226) | def __init__(self, accountID, orderID):
class OrderClientExtensions (line 257) | class OrderClientExtensions(Orders):
method __init__ (line 268) | def __init__(self, accountID, orderID, data):
FILE: oandapyV20/endpoints/positions.py
class Positions (line 8) | class Positions(APIRequest):
method __init__ (line 16) | def __init__(self, accountID, instrument=None):
class PositionList (line 35) | class PositionList(Positions):
method __init__ (line 43) | def __init__(self, accountID):
class OpenPositions (line 69) | class OpenPositions(Positions):
method __init__ (line 77) | def __init__(self, accountID):
class PositionDetails (line 103) | class PositionDetails(Positions):
method __init__ (line 111) | def __init__(self, accountID, instrument):
class PositionClose (line 141) | class PositionClose(Positions):
method __init__ (line 147) | def __init__(self, accountID, instrument, data):
FILE: oandapyV20/endpoints/pricing.py
class Pricing (line 11) | class Pricing(APIRequest):
method __init__ (line 18) | def __init__(self, accountID):
class PricingInfo (line 32) | class PricingInfo(Pricing):
method __init__ (line 40) | def __init__(self, accountID, params=None):
class PricingStream (line 76) | class PricingStream(Pricing):
method __init__ (line 86) | def __init__(self, accountID, params=None):
method terminate (line 122) | def terminate(self, message=""):
FILE: oandapyV20/endpoints/trades.py
class Trades (line 9) | class Trades(APIRequest):
method __init__ (line 17) | def __init__(self, accountID, tradeID=None):
class TradesList (line 34) | class TradesList(Trades):
method __init__ (line 38) | def __init__(self, accountID, params=None):
class OpenTrades (line 73) | class OpenTrades(Trades):
method __init__ (line 77) | def __init__(self, accountID):
class TradeDetails (line 103) | class TradeDetails(Trades):
method __init__ (line 107) | def __init__(self, accountID, tradeID):
class TradeClose (line 136) | class TradeClose(Trades):
method __init__ (line 145) | def __init__(self, accountID, tradeID, data=None):
class TradeClientExtensions (line 184) | class TradeClientExtensions(Trades):
method __init__ (line 194) | def __init__(self, accountID, tradeID, data=None):
class TradeCRCDO (line 237) | class TradeCRCDO(Trades):
method __init__ (line 243) | def __init__(self, accountID, tradeID, data):
FILE: oandapyV20/endpoints/transactions.py
class Transactions (line 11) | class Transactions(APIRequest):
method __init__ (line 19) | def __init__(self, accountID, transactionID=None):
class TransactionList (line 38) | class TransactionList(Transactions):
method __init__ (line 46) | def __init__(self, accountID, params=None):
class TransactionDetails (line 79) | class TransactionDetails(Transactions):
method __init__ (line 83) | def __init__(self, accountID, transactionID):
class TransactionIDRange (line 111) | class TransactionIDRange(Transactions):
method __init__ (line 118) | def __init__(self, accountID, params=None):
class TransactionsSinceID (line 153) | class TransactionsSinceID(Transactions):
method __init__ (line 161) | def __init__(self, accountID, params=None):
class TransactionsStream (line 196) | class TransactionsStream(Transactions):
method __init__ (line 206) | def __init__(self, accountID, params=None):
method terminate (line 243) | def terminate(self, message=""):
FILE: oandapyV20/exceptions.py
class StreamTerminated (line 4) | class StreamTerminated(Exception):
class V20Error (line 8) | class V20Error(Exception):
method __init__ (line 15) | def __init__(self, code, msg):
FILE: oandapyV20/oandapyV20.py
class API (line 29) | class API(object):
method __init__ (line 170) | def __init__(self, access_token, environment="practice",
method __enter__ (line 232) | def __enter__(self):
method __exit__ (line 235) | def __exit__(self, exc_type, exc_val, exc_tb):
method close (line 238) | def close(self):
method request_params (line 246) | def request_params(self):
method __request (line 250) | def __request(self, method, url, request_args, headers=None, stream=Fa...
method __stream_request (line 278) | def __stream_request(self, method, url, request_args, headers=None):
method request (line 294) | def request(self, endpoint):
FILE: oandapyV20/types/types.py
class OAType (line 11) | class OAType(object):
method value (line 15) | def value(self):
class AccountID (line 20) | class AccountID(OAType):
method __init__ (line 38) | def __init__(self, accountID):
class OrderID (line 48) | class OrderID(OAType):
method __init__ (line 66) | def __init__(self, orderID):
class DateTime (line 72) | class DateTime(OAType):
method __init__ (line 102) | def __init__(self, dateTime):
class TradeID (line 148) | class TradeID(OAType):
method __init__ (line 166) | def __init__(self, tradeID):
class AccountUnits (line 172) | class AccountUnits(OAType):
method __init__ (line 175) | def __init__(self, units):
class PriceValue (line 179) | class PriceValue(OAType):
method __init__ (line 182) | def __init__(self, priceValue):
class Units (line 186) | class Units(OAType):
method __init__ (line 189) | def __init__(self, units):
class ClientID (line 206) | class ClientID(OAType):
method __init__ (line 209) | def __init__(self, clientID):
class ClientTag (line 217) | class ClientTag(OAType):
method __init__ (line 220) | def __init__(self, clientTag):
class ClientComment (line 228) | class ClientComment(OAType):
method __init__ (line 231) | def __init__(self, clientComment):
class OrderIdentifier (line 239) | class OrderIdentifier(OAType):
method __init__ (line 242) | def __init__(self, orderID, clientID):
class OrderSpecifier (line 249) | class OrderSpecifier(OAType):
method __init__ (line 252) | def __init__(self, specifier):
FILE: setup.py
function get_version (line 8) | def get_version(package):
function read_all (line 16) | def read_all(f):
FILE: tests/test_accounts.py
class TestAccounts (line 27) | class TestAccounts(unittest.TestCase):
method setUp (line 30) | def setUp(self):
method test__account_list (line 54) | def test__account_list(self, mock_req):
method test__account_details (line 66) | def test__account_details(self, mock_req):
method test__get_account_summary (line 82) | def test__get_account_summary(self, accID, status_code,
method test__account_instruments (line 113) | def test__account_instruments(self, mock_req):
method test__account_configuration (line 125) | def test__account_configuration(self, mock_req):
method test__account_changes (line 137) | def test__account_changes(self, mock_get):
FILE: tests/test_contrib_factories.py
class TestContribFactories (line 14) | class TestContribFactories(unittest.TestCase):
method test__candlehistory (line 80) | def test__candlehistory(self, factory, instrument, inpar, refpar,
FILE: tests/test_contrib_generic.py
class TestContribGeneric (line 13) | class TestContribGeneric(unittest.TestCase):
method test__secs2time (line 16) | def test__secs2time(self):
method test__granularity_to_time (line 33) | def test__granularity_to_time(self, meth, granularity, refval, exc=None):
FILE: tests/test_contrib_orders.py
class TestContribRequests (line 15) | class TestContribRequests(unittest.TestCase):
method test__orders (line 232) | def test__orders(self, cls, inpar, refpar, exc=None):
method test__anonymous_body (line 379) | def test__anonymous_body(self, cls, inpar, refpar, exc=None):
FILE: tests/test_decorators.py
class TestDecorators (line 7) | class TestDecorators(unittest.TestCase):
method test__extendargs (line 10) | def test__extendargs(self):
method test__abstractclass (line 25) | def test__abstractclass(self):
FILE: tests/test_definitions.py
class TestDefinitions (line 7) | class TestDefinitions(unittest.TestCase):
method test__order_definitions (line 10) | def test__order_definitions(self):
method test__order_definitions_dictproperty (line 16) | def test__order_definitions_dictproperty(self):
FILE: tests/test_forexlabs.py
class TestForexLabs (line 20) | class TestForexLabs(unittest.TestCase):
method setUp (line 23) | def setUp(self):
method test__calendar (line 47) | def test__calendar(self, mock_get):
method test__histposratios (line 59) | def test__histposratios(self, mock_get):
method test__spreads (line 71) | def test__spreads(self, mock_get):
method test__commoftrad (line 83) | def test__commoftrad(self, mock_get):
method test__orderbookdata (line 95) | def test__orderbookdata(self, mock_get):
method test__autochartist (line 107) | def test__autochartist(self, mock_get):
FILE: tests/test_instruments.py
class TestInstruments (line 20) | class TestInstruments(unittest.TestCase):
method setUp (line 23) | def setUp(self):
method test__instruments_candles (line 47) | def test__instruments_candles(self, mock_get):
method test__instruments_orderbook (line 61) | def test__instruments_orderbook(self, mock_get):
method test__instruments_positionbook (line 75) | def test__instruments_positionbook(self, mock_get):
FILE: tests/test_oandapyv20.py
class TestOandapyV20 (line 13) | class TestOandapyV20(unittest.TestCase):
method setUp (line 16) | def setUp(self):
method test__oandapyv20_environment (line 38) | def test__oandapyv20_environment(self):
method test__requests_params (line 47) | def test__requests_params(self):
method test__requests_exception (line 56) | def test__requests_exception(self):
FILE: tests/test_orders.py
class TestOrders (line 20) | class TestOrders(unittest.TestCase):
method setUp (line 23) | def setUp(self):
method test__orders_base_exception (line 46) | def test__orders_base_exception(self):
method test__order_create (line 57) | def test__order_create(self, mock_post):
method test__order_clientextensions (line 70) | def test__order_clientextensions(self, mock_put):
method test__orders_pending (line 83) | def test__orders_pending(self, mock_get):
method test__orders_list (line 96) | def test__orders_list(self, mock_get):
method test__order_details (line 111) | def test__order_details(self, mock_get):
method test__order_cancel (line 126) | def test__order_cancel(self, mock_get):
method test__order_replace (line 142) | def test__order_replace(self, mock_put):
method test__order_replace_wrong_status_exception (line 165) | def test__order_replace_wrong_status_exception(self, mock_get):
FILE: tests/test_positions.py
class TestPositions (line 20) | class TestPositions(unittest.TestCase):
method setUp (line 23) | def setUp(self):
method test__positions_list (line 46) | def test__positions_list(self, mock_get):
method test__openpositions_list (line 58) | def test__openpositions_list(self, mock_get):
method test__positiondetails (line 70) | def test__positiondetails(self, mock_get):
method test__positionclose (line 82) | def test__positionclose(self, mock_put):
FILE: tests/test_pricing.py
class TestPricing (line 21) | class TestPricing(unittest.TestCase):
method setUp (line 24) | def setUp(self):
method test__pricing (line 47) | def test__pricing(self, mock_get):
method test__pricing_stream (line 61) | def test__pricing_stream(self, mock_get):
method test__pricing_stream_termination_1 (line 84) | def test__pricing_stream_termination_1(self):
FILE: tests/test_trades.py
class TestTrades (line 20) | class TestTrades(unittest.TestCase):
method setUp (line 23) | def setUp(self):
method test__trades_list (line 45) | def test__trades_list(self, mock_get):
method test__open_trades (line 57) | def test__open_trades(self, mock_get):
method test__trade_details (line 69) | def test__trade_details(self, mock_get):
method test__trade_close (line 81) | def test__trade_close(self, mock_put):
method test__trade_cltext (line 93) | def test__trade_cltext(self, mock_put):
method test__trade_crcdo (line 105) | def test__trade_crcdo(self, mock_put):
method test__trades_list_byids (line 117) | def test__trades_list_byids(self, mock_get):
FILE: tests/test_transactions.py
class TestTransactions (line 21) | class TestTransactions(unittest.TestCase):
method setUp (line 24) | def setUp(self):
method test__transactions (line 48) | def test__transactions(self, mock_get):
method test__transactions_details (line 60) | def test__transactions_details(self, mock_get):
method test__transactions_idrange (line 73) | def test__transactions_idrange(self, mock_get):
method test__transactions_sinceid (line 85) | def test__transactions_sinceid(self, mock_get):
method test__transaction_stream (line 97) | def test__transaction_stream(self, mock_get):
method test__transaction_stream_termination_1 (line 122) | def test__transaction_stream_termination_1(self):
FILE: tests/test_types.py
class TestTypes (line 16) | class TestTypes(unittest.TestCase):
method test__types (line 228) | def test__types(self, cls, inpar, reference, exc=None):
FILE: tests/unittestsetup.py
function fetchTestData (line 13) | def fetchTestData(responses, k):
class TestData (line 28) | class TestData(object):
method __init__ (line 30) | def __init__(self, responses, tid):
method resp (line 34) | def resp(self):
method body (line 38) | def body(self):
method params (line 42) | def params(self):
function auth (line 46) | def auth():
Condensed preview — 187 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (542K chars).
[
{
"path": ".gitignore",
"chars": 675,
"preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\n"
},
{
"path": ".landscape.yml",
"chars": 19,
"preview": "inherits: [flake8]\n"
},
{
"path": ".travis.yml",
"chars": 1159,
"preview": "language: python\npython:\n- '3.6'\n- '3.7'\n- '3.8'\n- '3.9'\ninstall:\n- pip install --upgrade pip setuptools\n- pip install r"
},
{
"path": "CHANGELOG.rst",
"chars": 3736,
"preview": "Changelog\n=========\n\n[Unreleased]\n------------\n\nv0.7.2 (2021-08-26)\n-------------------\n\nDocumentation Changes\n~~~~~~~~~"
},
{
"path": "LICENSE.md",
"chars": 1082,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2016 Feite Brekeveld\n\nPermission is hereby granted, free of charge, to any person o"
},
{
"path": "MANIFEST.in",
"chars": 44,
"preview": "include requirements.txt\ninclude LICENSE.md\n"
},
{
"path": "README.rst",
"chars": 22105,
"preview": "OANDA REST-V20 API wrapper\n==========================\n\n.. _Top:\n\nAs of march 2018 OANDA no longer supports the v1 REST-A"
},
{
"path": "docs/Makefile",
"chars": 7748,
"preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS =\nSPHINXBUILD "
},
{
"path": "docs/conf.py",
"chars": 11824,
"preview": "# -*- coding: utf-8 -*-\n#\n# OANDA REST-V20 API documentation build configuration file, created by\n# sphinx-quickstart on"
},
{
"path": "docs/contrib/factories/instrumentscandlesfactory.rst",
"chars": 111,
"preview": "InstrumentsCandlesFactory\n-------------------------\n\n.. automodule:: oandapyV20.contrib.factories\n :members:\n"
},
{
"path": "docs/contrib/factories.rst",
"chars": 210,
"preview": "Factories\n---------\n\nThe :mod:`oandapyV20.contrib.factories` module contains several classes /\nmethods that can be used "
},
{
"path": "docs/contrib/generic/generic.rst",
"chars": 97,
"preview": "granularity_to_time\n-------------------\n\n.. automodule:: oandapyV20.contrib.generic\n :members:\n"
},
{
"path": "docs/contrib/generic.rst",
"chars": 184,
"preview": "Generic\n---------\n\nThe :mod:`oandapyV20.contrib.generic` module contains several classes /\nmethods that serve a generic "
},
{
"path": "docs/contrib/orders/limitorderrequest.rst",
"chars": 187,
"preview": "LimitOrderRequest\n------------------\n\n.. autoclass:: oandapyV20.contrib.requests.LimitOrderRequest\n :members:\n :un"
},
{
"path": "docs/contrib/orders/marketorderrequest.rst",
"chars": 189,
"preview": "MarketOrderRequest\n------------------\n\n.. autoclass:: oandapyV20.contrib.requests.MarketOrderRequest\n :members:\n :"
},
{
"path": "docs/contrib/orders/mitorderrequest.rst",
"chars": 180,
"preview": "MITOrderRequest\n---------------\n\n.. autoclass:: oandapyV20.contrib.requests.MITOrderRequest\n :members:\n :undoc-mem"
},
{
"path": "docs/contrib/orders/positionscloserequest.rst",
"chars": 195,
"preview": "PositionCloseRequest\n--------------------\n\n.. autoclass:: oandapyV20.contrib.requests.PositionCloseRequest\n :members:"
},
{
"path": "docs/contrib/orders/stoplossorderrequest.rst",
"chars": 195,
"preview": "StopLossOrderRequest\n--------------------\n\n.. autoclass:: oandapyV20.contrib.requests.StopLossOrderRequest\n :members:"
},
{
"path": "docs/contrib/orders/stoporderrequest.rst",
"chars": 183,
"preview": "StopOrderRequest\n----------------\n\n.. autoclass:: oandapyV20.contrib.requests.StopOrderRequest\n :members:\n :undoc-"
},
{
"path": "docs/contrib/orders/takeprofitorderrequest.rst",
"chars": 201,
"preview": "TakeProfitOrderRequest\n----------------------\n\n.. autoclass:: oandapyV20.contrib.requests.TakeProfitOrderRequest\n :me"
},
{
"path": "docs/contrib/orders/tradecloserequest.rst",
"chars": 186,
"preview": "TradeCloseRequest\n-----------------\n\n.. autoclass:: oandapyV20.contrib.requests.TradeCloseRequest\n :members:\n :und"
},
{
"path": "docs/contrib/orders/trailingstoplossorderrequest.rst",
"chars": 219,
"preview": "TrailingStopLossOrderRequest\n----------------------------\n\n.. autoclass:: oandapyV20.contrib.requests.TrailingStopLossOr"
},
{
"path": "docs/contrib/orders.rst",
"chars": 598,
"preview": "Order Classes\n-------------\n\nThe :mod:`oandapyV20.contrib.requests` module contains several classes \nthat can be used op"
},
{
"path": "docs/contrib/support/clientextensions.rst",
"chars": 305,
"preview": "Client Extensions\n~~~~~~~~~~~~~~~~~\n\nClient extensions can be used optionally on Order Requests. It allows\na client to s"
},
{
"path": "docs/contrib/support/stoplossdetails.rst",
"chars": 180,
"preview": "StopLossDetails\n~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.contrib.requests.StopLossDetails\n :members:\n :undoc-mem"
},
{
"path": "docs/contrib/support/takeprofitdetails.rst",
"chars": 186,
"preview": "TakeProfitDetails\n~~~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.contrib.requests.TakeProfitDetails\n :members:\n :und"
},
{
"path": "docs/contrib/support/trailingstoplossdetails.rst",
"chars": 204,
"preview": "TrailingStopLossDetails\n~~~~~~~~~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.contrib.requests.TrailingStopLossDetails\n "
},
{
"path": "docs/contrib/support.rst",
"chars": 603,
"preview": "support classes\n---------------\n\nThe :mod:`oandapyV20.contrib.requests` module contains several classes \nthat can be use"
},
{
"path": "docs/dirstruct.py",
"chars": 1209,
"preview": "# -*- coding: utf8 -*-\n\"\"\"dirstruct.\n\ngenerate document directory structure.\n\"\"\"\nimport sys\nimport os\nimport inspect\nfro"
},
{
"path": "docs/endpoints/accounts/accountchanges.rst",
"chars": 179,
"preview": "AccountChanges\n~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.accounts.AccountChanges\n :members:\n :undoc-memb"
},
{
"path": "docs/endpoints/accounts/accountconfiguration.rst",
"chars": 197,
"preview": "AccountConfiguration\n~~~~~~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.accounts.AccountConfiguration\n :member"
},
{
"path": "docs/endpoints/accounts/accountdetails.rst",
"chars": 179,
"preview": "AccountDetails\n~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.accounts.AccountDetails\n :members:\n :undoc-memb"
},
{
"path": "docs/endpoints/accounts/accountinstruments.rst",
"chars": 191,
"preview": "AccountInstruments\n~~~~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.accounts.AccountInstruments\n :members:\n "
},
{
"path": "docs/endpoints/accounts/accountlist.rst",
"chars": 170,
"preview": "AccountList\n~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.accounts.AccountList\n :members:\n :undoc-members:\n "
},
{
"path": "docs/endpoints/accounts/accountsummary.rst",
"chars": 179,
"preview": "AccountSummary\n~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.accounts.AccountSummary\n :members:\n :undoc-memb"
},
{
"path": "docs/endpoints/accounts.rst",
"chars": 115,
"preview": "oandapyV20.endpoints.accounts\n-----------------------------\n\n.. toctree::\n :maxdepth: 4\n :glob:\n\n accounts/*\n"
},
{
"path": "docs/endpoints/forexlabs/autochartist.rst",
"chars": 174,
"preview": "Autochartist\n~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.forexlabs.Autochartist\n :members:\n :undoc-members:\n"
},
{
"path": "docs/endpoints/forexlabs/calendar.rst",
"chars": 162,
"preview": "Calendar\n~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.forexlabs.Calendar\n :members:\n :undoc-members:\n :show-in"
},
{
"path": "docs/endpoints/forexlabs/commitmentsoftraders.rst",
"chars": 198,
"preview": "CommitmentsOfTraders\n~~~~~~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.forexlabs.CommitmentsOfTraders\n :membe"
},
{
"path": "docs/endpoints/forexlabs/historicalpositionratios.rst",
"chars": 210,
"preview": "HistoricalPositionRatios\n~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.forexlabs.HistoricalPositionRatio"
},
{
"path": "docs/endpoints/forexlabs/orderbookdata.rst",
"chars": 177,
"preview": "OrderbookData\n~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.forexlabs.OrderbookData\n :members:\n :undoc-member"
},
{
"path": "docs/endpoints/forexlabs/spreads.rst",
"chars": 159,
"preview": "Spreads\n~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.forexlabs.Spreads\n :members:\n :undoc-members:\n :show-inher"
},
{
"path": "docs/endpoints/forexlabs.rst",
"chars": 118,
"preview": "oandapyV20.endpoints.forexlabs\n------------------------------\n\n.. toctree::\n :maxdepth: 4\n :glob:\n\n forexlabs/*\n"
},
{
"path": "docs/endpoints/instruments/instrumentlist.rst",
"chars": 194,
"preview": "InstrumentsCandles\n~~~~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.instruments.InstrumentsCandles\n :members:\n"
},
{
"path": "docs/endpoints/instruments/instrumentorderbook.rst",
"chars": 200,
"preview": "InstrumentsOrderBook\n~~~~~~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.instruments.InstrumentsOrderBook\n :mem"
},
{
"path": "docs/endpoints/instruments/instrumentpositionbook.rst",
"chars": 209,
"preview": "InstrumentsPositionBook\n~~~~~~~~~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.instruments.InstrumentsPositionBook"
},
{
"path": "docs/endpoints/instruments.rst",
"chars": 124,
"preview": "oandapyV20.endpoints.instruments\n--------------------------------\n\n.. toctree::\n :maxdepth: 4\n :glob:\n\n instrument"
},
{
"path": "docs/endpoints/orders/ordercancel.rst",
"chars": 168,
"preview": "OrderCancel\n~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.orders.OrderCancel\n :members:\n :undoc-members:\n :s"
},
{
"path": "docs/endpoints/orders/orderclientextensions.rst",
"chars": 198,
"preview": "OrderClientExtensions\n~~~~~~~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.orders.OrderClientExtensions\n :membe"
},
{
"path": "docs/endpoints/orders/ordercreate.rst",
"chars": 168,
"preview": "OrderCreate\n~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.orders.OrderCreate\n :members:\n :undoc-members:\n :s"
},
{
"path": "docs/endpoints/orders/orderdetails.rst",
"chars": 171,
"preview": "OrderDetails\n~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.orders.OrderDetails\n :members:\n :undoc-members:\n "
},
{
"path": "docs/endpoints/orders/orderlist.rst",
"chars": 164,
"preview": "OrderList\n~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.orders.OrderList\n :members:\n :undoc-members:\n :show-"
},
{
"path": "docs/endpoints/orders/orderreplace.rst",
"chars": 171,
"preview": "OrderReplace\n~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.orders.OrderReplace\n :members:\n :undoc-members:\n "
},
{
"path": "docs/endpoints/orders/orderspending.rst",
"chars": 174,
"preview": "OrdersPending\n~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.orders.OrdersPending\n :members:\n :undoc-members:\n"
},
{
"path": "docs/endpoints/orders.rst",
"chars": 109,
"preview": "oandapyV20.endpoints.orders\n---------------------------\n\n.. toctree::\n :maxdepth: 4\n :glob:\n\n orders/*\n"
},
{
"path": "docs/endpoints/positions/openpositions.rst",
"chars": 177,
"preview": "OpenPositions\n~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.positions.OpenPositions\n :members:\n :undoc-member"
},
{
"path": "docs/endpoints/positions/positionclose.rst",
"chars": 177,
"preview": "PositionClose\n~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.positions.PositionClose\n :members:\n :undoc-member"
},
{
"path": "docs/endpoints/positions/positiondetails.rst",
"chars": 183,
"preview": "PositionDetails\n~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.positions.PositionDetails\n :members:\n :undoc-"
},
{
"path": "docs/endpoints/positions/positionlist.rst",
"chars": 174,
"preview": "PositionList\n~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.positions.PositionList\n :members:\n :undoc-members:\n"
},
{
"path": "docs/endpoints/positions.rst",
"chars": 118,
"preview": "oandapyV20.endpoints.positions\n------------------------------\n\n.. toctree::\n :maxdepth: 4\n :glob:\n\n positions/*\n"
},
{
"path": "docs/endpoints/pricing/pricinginfo.rst",
"chars": 169,
"preview": "PricingInfo\n~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.pricing.PricingInfo\n :members:\n :undoc-members:\n :"
},
{
"path": "docs/endpoints/pricing/pricingstream.rst",
"chars": 175,
"preview": "PricingStream\n~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.pricing.PricingStream\n :members:\n :undoc-members:"
},
{
"path": "docs/endpoints/pricing.rst",
"chars": 112,
"preview": "oandapyV20.endpoints.pricing\n----------------------------\n\n.. toctree::\n :maxdepth: 4\n :glob:\n\n pricing/*\n"
},
{
"path": "docs/endpoints/trades/opentrades.rst",
"chars": 165,
"preview": "OpenTrades\n~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.trades.OpenTrades\n :members:\n :undoc-members:\n :show"
},
{
"path": "docs/endpoints/trades/tradeCRCDO.rst",
"chars": 165,
"preview": "TradeCRCDO\n~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.trades.TradeCRCDO\n :members:\n :undoc-members:\n :show"
},
{
"path": "docs/endpoints/trades/tradeclientextensions.rst",
"chars": 198,
"preview": "TradeClientExtensions\n~~~~~~~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.trades.TradeClientExtensions\n :membe"
},
{
"path": "docs/endpoints/trades/tradeclose.rst",
"chars": 165,
"preview": "TradeClose\n~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.trades.TradeClose\n :members:\n :undoc-members:\n :show"
},
{
"path": "docs/endpoints/trades/tradedetails.rst",
"chars": 171,
"preview": "TradeDetails\n~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.trades.TradeDetails\n :members:\n :undoc-members:\n "
},
{
"path": "docs/endpoints/trades/tradeslist.rst",
"chars": 165,
"preview": "TradesList\n~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.trades.TradesList\n :members:\n :undoc-members:\n :show"
},
{
"path": "docs/endpoints/trades.rst",
"chars": 109,
"preview": "oandapyV20.endpoints.trades\n---------------------------\n\n.. toctree::\n :maxdepth: 4\n :glob:\n\n trades/*\n"
},
{
"path": "docs/endpoints/transactions/transactiondetails.rst",
"chars": 195,
"preview": "TransactionDetails\n~~~~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.transactions.TransactionDetails\n :members:"
},
{
"path": "docs/endpoints/transactions/transactionidrange.rst",
"chars": 195,
"preview": "TransactionIDRange\n~~~~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.transactions.TransactionIDRange\n :members:"
},
{
"path": "docs/endpoints/transactions/transactionlist.rst",
"chars": 186,
"preview": "TransactionList\n~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.transactions.TransactionList\n :members:\n :und"
},
{
"path": "docs/endpoints/transactions/transactionssinceid.rst",
"chars": 198,
"preview": "TransactionsSinceID\n~~~~~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.transactions.TransactionsSinceID\n :membe"
},
{
"path": "docs/endpoints/transactions/transactionsstream.rst",
"chars": 195,
"preview": "TransactionsStream\n~~~~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.endpoints.transactions.TransactionsStream\n :members:"
},
{
"path": "docs/endpoints/transactions.rst",
"chars": 127,
"preview": "oandapyV20.endpoints.transactions\n---------------------------------\n\n.. toctree::\n :maxdepth: 4\n :glob:\n\n transact"
},
{
"path": "docs/examples.rst",
"chars": 2887,
"preview": "Examples\n--------\n\nExamples can be found in the examples repositiory on github: examplesrepo_.\n\n.. _examplesrepo: https:"
},
{
"path": "docs/index.rst",
"chars": 676,
"preview": ".. OANDA REST-V20 API documentation master file, created by\n sphinx-quickstart on Sun Jul 10 12:57:37 2016.\n You can"
},
{
"path": "docs/installation.rst",
"chars": 911,
"preview": "Introduction\n============\n\nThe :mod:`oandapyV20` package offers an API to the OANDA V20 REST service.\nTo use the REST-AP"
},
{
"path": "docs/oanda-api-v20.rst",
"chars": 2347,
"preview": "Interface OANDA's REST-V20\n==========================\n\nThe client\n----------\n\nThe :mod:`oandapyV20` package contains a c"
},
{
"path": "docs/oandapyV20.contrib.rst",
"chars": 92,
"preview": "oandapyV20.contrib\n==================\n\n.. toctree::\n :maxdepth: 4\n :glob:\n\n contrib/*\n"
},
{
"path": "docs/oandapyV20.definitions.accounts.rst",
"chars": 204,
"preview": "oandapyV20.definitions.accounts\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. automodule:: oandapyV20.definitions.accounts\n :me"
},
{
"path": "docs/oandapyV20.definitions.instruments.rst",
"chars": 213,
"preview": "oandapyV20.definitions.instruments\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. automodule:: oandapyV20.definitions.instrument"
},
{
"path": "docs/oandapyV20.definitions.orders.rst",
"chars": 198,
"preview": "oandapyV20.definitions.orders\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. automodule:: oandapyV20.definitions.orders\n :members:"
},
{
"path": "docs/oandapyV20.definitions.pricing.rst",
"chars": 201,
"preview": "oandapyV20.definitions.pricing\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. automodule:: oandapyV20.definitions.pricing\n :membe"
},
{
"path": "docs/oandapyV20.definitions.rst",
"chars": 499,
"preview": "oandapyV20.definitions\n======================\n\nThe :mod:`oandapyV20.definitions` module holds all the definitions as in "
},
{
"path": "docs/oandapyV20.definitions.trades.rst",
"chars": 198,
"preview": "oandapyV20.definitions.trades\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. automodule:: oandapyV20.definitions.trades\n :members:"
},
{
"path": "docs/oandapyV20.definitions.transactions.rst",
"chars": 216,
"preview": "oandapyV20.definitions.transactions\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. automodule:: oandapyV20.definitions.transact"
},
{
"path": "docs/oandapyV20.endpoints.rst",
"chars": 98,
"preview": "oandapyV20.endpoints\n====================\n\n.. toctree::\n :maxdepth: 4\n :glob:\n\n endpoints/*\n"
},
{
"path": "docs/oandapyV20.types.rst",
"chars": 874,
"preview": "oandapyV20.types\n================\n\nThe :mod:`oandapyV20.types` module contains the types representing the types\nthat are"
},
{
"path": "docs/types/AccountID.rst",
"chars": 152,
"preview": "AccountID\n~~~~~~~~~\n\n.. autoclass:: oandapyV20.types.AccountID\n :members:\n :undoc-members:\n :inherited-members:"
},
{
"path": "docs/types/AccountUnits.rst",
"chars": 161,
"preview": "AccountUnits\n~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.types.AccountUnits\n :members:\n :undoc-members:\n :inherited"
},
{
"path": "docs/types/ClientComment.rst",
"chars": 164,
"preview": "ClientComment\n~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.types.ClientComment\n :members:\n :undoc-members:\n :inheri"
},
{
"path": "docs/types/ClientID.rst",
"chars": 149,
"preview": "ClientID\n~~~~~~~~\n\n.. autoclass:: oandapyV20.types.ClientID\n :members:\n :undoc-members:\n :inherited-members:\n "
},
{
"path": "docs/types/ClientTag.rst",
"chars": 152,
"preview": "ClientTag\n~~~~~~~~~\n\n.. autoclass:: oandapyV20.types.ClientTag\n :members:\n :undoc-members:\n :inherited-members:"
},
{
"path": "docs/types/DateTime.rst",
"chars": 149,
"preview": "DateTime\n~~~~~~~~\n\n.. autoclass:: oandapyV20.types.DateTime\n :members:\n :undoc-members:\n :inherited-members:\n "
},
{
"path": "docs/types/OrderID.rst",
"chars": 146,
"preview": "OrderID\n~~~~~~~\n\n.. autoclass:: oandapyV20.types.OrderID\n :members:\n :undoc-members:\n :inherited-members:\n :"
},
{
"path": "docs/types/OrderIdentifier.rst",
"chars": 170,
"preview": "OrderIdentifier\n~~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.types.OrderIdentifier\n :members:\n :undoc-members:\n :"
},
{
"path": "docs/types/OrderSpecifier.rst",
"chars": 167,
"preview": "OrderSpecifier\n~~~~~~~~~~~~~~\n\n.. autoclass:: oandapyV20.types.OrderSpecifier\n :members:\n :undoc-members:\n :inh"
},
{
"path": "docs/types/PriceValue.rst",
"chars": 155,
"preview": "PriceValue\n~~~~~~~~~~\n\n.. autoclass:: oandapyV20.types.PriceValue\n :members:\n :undoc-members:\n :inherited-membe"
},
{
"path": "docs/types/TradeID.rst",
"chars": 146,
"preview": "TradeID\n~~~~~~~\n\n.. autoclass:: oandapyV20.types.TradeID\n :members:\n :undoc-members:\n :inherited-members:\n :"
},
{
"path": "docs/types/Units.rst",
"chars": 140,
"preview": "Units\n~~~~~\n\n.. autoclass:: oandapyV20.types.Units\n :members:\n :undoc-members:\n :inherited-members:\n :specia"
},
{
"path": "examples/README.rst",
"chars": 166,
"preview": "Examples\n========\n\nAs of Nov 28th 2016 examples are in a separate repo: oandapyV20-examples_\n\n.. _oandapyV20-examples: h"
},
{
"path": "jupyter/account.txt",
"chars": 20,
"preview": "xxx-yyy-zzzzzzz-aaa\n"
},
{
"path": "jupyter/accounts.ipynb",
"chars": 3017,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {\n \"deletable\": true,\n \"editable\": true\n },\n \"sou"
},
{
"path": "jupyter/exampleauth/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "jupyter/exampleauth/exampleauth.py",
"chars": 260,
"preview": "\"\"\"simple auth method for examples.\"\"\"\n\n\ndef exampleAuth():\n accountID, token = None, None\n with open(\"account.txt"
},
{
"path": "jupyter/exceptions.ipynb",
"chars": 3014,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {\n \"deletable\": true,\n \"editable\": true\n },\n \"sou"
},
{
"path": "jupyter/historical.ipynb",
"chars": 41406,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {\n \"deletable\": true,\n \"editable\": true\n },\n \"sou"
},
{
"path": "jupyter/index.ipynb",
"chars": 3666,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {\n \"deletable\": true,\n \"editable\": true\n },\n \"sou"
},
{
"path": "jupyter/orders.ipynb",
"chars": 22768,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {\n \"deletable\": true,\n \"editable\": true\n },\n \"sou"
},
{
"path": "jupyter/positions.ipynb",
"chars": 2901,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {\n \"deletable\": true,\n \"editable\": true\n },\n \"sou"
},
{
"path": "jupyter/streams.ipynb",
"chars": 6147,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {\n \"deletable\": true,\n \"editable\": true\n },\n \"sou"
},
{
"path": "jupyter/token.txt",
"chars": 66,
"preview": "aaaabbbbccccddddeeeeffffaaaabbbb-ccccbbbbaaaaeeeebbbbaaaaffffbbbb\n"
},
{
"path": "jupyter/trades.ipynb",
"chars": 6488,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {\n \"deletable\": true,\n \"editable\": true\n },\n \"sou"
},
{
"path": "oandapyV20/__init__.py",
"chars": 603,
"preview": "import logging\nfrom .oandapyV20 import API\nfrom .exceptions import V20Error\n\n__title__ = \"OANDA REST V20 API Wrapper\"\n__"
},
{
"path": "oandapyV20/contrib/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "oandapyV20/contrib/factories/__init__.py",
"chars": 95,
"preview": "from .history import InstrumentsCandlesFactory\n\n__all__ = (\n 'InstrumentsCandlesFactory',\n)\n"
},
{
"path": "oandapyV20/contrib/factories/history.py",
"chars": 4801,
"preview": "# -*- coding: utf-8 -*-\n\nfrom datetime import datetime\nimport calendar\nimport logging\n\nimport oandapyV20.endpoints.instr"
},
{
"path": "oandapyV20/contrib/generic.py",
"chars": 845,
"preview": "import re\nimport time\nfrom datetime import datetime\n\n\ndef secs2time(e):\n \"\"\"secs2time - convert epoch to datetime.\n\n "
},
{
"path": "oandapyV20/contrib/requests/__init__.py",
"chars": 919,
"preview": "from .marketorder import MarketOrderRequest\nfrom .limitorder import LimitOrderRequest\nfrom .mitorder import MITOrderRequ"
},
{
"path": "oandapyV20/contrib/requests/baserequest.py",
"chars": 972,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"baserequest.\"\"\"\n\nimport json\nimport six\nfrom abc import ABCMeta, abstractmethod\n\n\n@six.add_me"
},
{
"path": "oandapyV20/contrib/requests/extensions.py",
"chars": 2549,
"preview": "# -*- coding: utf-8 -*-\n\nfrom .baserequest import BaseRequest\nfrom oandapyV20.types import ClientID, ClientTag, ClientCo"
},
{
"path": "oandapyV20/contrib/requests/limitorder.py",
"chars": 3385,
"preview": "# -*- coding: utf-8 -*-\n\nfrom .baserequest import BaseRequest\nfrom oandapyV20.types import Units, PriceValue\nfrom oandap"
},
{
"path": "oandapyV20/contrib/requests/marketorder.py",
"chars": 4929,
"preview": "# -*- coding: utf-8 -*-\n\nfrom .baserequest import BaseRequest\nfrom oandapyV20.types import Units, PriceValue\nfrom oandap"
},
{
"path": "oandapyV20/contrib/requests/mitorder.py",
"chars": 3734,
"preview": "# -*- coding: utf-8 -*-\n\nfrom .baserequest import BaseRequest\nfrom oandapyV20.types import Units, PriceValue\nfrom oandap"
},
{
"path": "oandapyV20/contrib/requests/onfill.py",
"chars": 8933,
"preview": "# -*- coding: utf-8 -*-\nimport six\nfrom abc import ABCMeta, abstractmethod\n\nfrom .baserequest import BaseRequest\nfrom oa"
},
{
"path": "oandapyV20/contrib/requests/positionclose.py",
"chars": 2527,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"positionclose.\"\"\"\n\nfrom .baserequest import BaseRequest\nfrom oandapyV20.types import Units\n\n\n"
},
{
"path": "oandapyV20/contrib/requests/stoplossorder.py",
"chars": 2841,
"preview": "# -*- coding: utf-8 -*-\n\nfrom .baserequest import BaseRequest\nfrom oandapyV20.types import TradeID, PriceValue\nfrom oand"
},
{
"path": "oandapyV20/contrib/requests/stoporder.py",
"chars": 3646,
"preview": "# -*- coding: utf-8 -*-\n\nfrom .baserequest import BaseRequest\nfrom oandapyV20.types import Units, PriceValue\nfrom oandap"
},
{
"path": "oandapyV20/contrib/requests/takeprofitorder.py",
"chars": 2792,
"preview": "# -*- coding: utf-8 -*-\n\nfrom .baserequest import BaseRequest\nfrom oandapyV20.types import TradeID, PriceValue\nfrom oand"
},
{
"path": "oandapyV20/contrib/requests/tradeclose.py",
"chars": 1554,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"tradeclose.\"\"\"\n\nfrom .baserequest import BaseRequest\n\n\nclass TradeCloseRequest(BaseRequest):\n"
},
{
"path": "oandapyV20/contrib/requests/trailingstoplossorder.py",
"chars": 2920,
"preview": "# -*- coding: utf-8 -*-\n\nfrom .baserequest import BaseRequest\nfrom oandapyV20.types import TradeID, PriceValue\nfrom oand"
},
{
"path": "oandapyV20/definitions/__init__.py",
"chars": 3626,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"dynamically add the classes for definition representations.\n\nMost of the endpoint groups have"
},
{
"path": "oandapyV20/definitions/accounts.py",
"chars": 1759,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Account Definitions.\"\"\"\n\ndefinitions = {\n \"GuaranteedStopLossOrderMode\": {\n \"DISABL"
},
{
"path": "oandapyV20/definitions/instruments.py",
"chars": 1627,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Instruments Definitions.\"\"\"\n\ndefinitions = {\n \"PriceComponents\": {\n \"A\": \"Ask\",\n "
},
{
"path": "oandapyV20/definitions/orders.py",
"chars": 3242,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Order related definitions.\"\"\"\n\ndefinitions = {\n \"OrderType\": {\n \"MARKET\": \"A Market"
},
{
"path": "oandapyV20/definitions/pricing.py",
"chars": 365,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Pricing related Definitions.\"\"\"\n\ndefinitions = {\n \"PriceStatus\": {\n \"tradeable\": \"T"
},
{
"path": "oandapyV20/definitions/primitives.py",
"chars": 846,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Primitives definitions.\"\"\"\n\ndefinitions = {\n \"InstrumentType\": {\n \"CURRENCY\": \"Curr"
},
{
"path": "oandapyV20/definitions/trades.py",
"chars": 1326,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Trades definitions.\"\"\"\n\ndefinitions = {\n \"TradeState\": {\n \"OPEN\": \"The Trade is cur"
},
{
"path": "oandapyV20/definitions/transactions.py",
"chars": 38401,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Transactions definitions.\"\"\"\n\ndefinitions = {\n \"TransactionType\": {\n \"CREATE\": \"Acc"
},
{
"path": "oandapyV20/endpoints/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "oandapyV20/endpoints/accounts.py",
"chars": 6676,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Handle account endpoints.\"\"\"\nfrom .apirequest import APIRequest\nfrom .decorators import dyndo"
},
{
"path": "oandapyV20/endpoints/apirequest.py",
"chars": 1407,
"preview": "\"\"\"Handling of API requests.\"\"\"\nimport six\nfrom abc import ABCMeta, abstractmethod\n\n\n@six.add_metaclass(ABCMeta)\nclass A"
},
{
"path": "oandapyV20/endpoints/decorators.py",
"chars": 4031,
"preview": "# -*- coding: UTF-8 -*-\n\"\"\"decorators.\"\"\"\n\n\ndef dyndoc_insert(src):\n \"\"\"docstring_insert - a decorator to insert API-"
},
{
"path": "oandapyV20/endpoints/forexlabs.py",
"chars": 6040,
"preview": "\"\"\"Handle forexlabs endpoints.\"\"\"\nfrom .apirequest import APIRequest\nfrom .decorators import dyndoc_insert, endpoint\nfro"
},
{
"path": "oandapyV20/endpoints/instruments.py",
"chars": 4455,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Handle instruments endpoints.\"\"\"\nfrom .apirequest import APIRequest\nfrom .decorators import d"
},
{
"path": "oandapyV20/endpoints/orders.py",
"chars": 8187,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Handle orders and pendingOrders endpoints.\"\"\"\nfrom .apirequest import APIRequest\nfrom .decora"
},
{
"path": "oandapyV20/endpoints/positions.py",
"chars": 5453,
"preview": "\"\"\"Handle position endpoints.\"\"\"\nfrom .apirequest import APIRequest\nfrom .decorators import dyndoc_insert, endpoint\nfrom"
},
{
"path": "oandapyV20/endpoints/pricing.py",
"chars": 3677,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Handle pricing endpoints.\"\"\"\nfrom .apirequest import APIRequest\nfrom ..exceptions import Stre"
},
{
"path": "oandapyV20/endpoints/responses/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "oandapyV20/endpoints/responses/accounts.py",
"chars": 14603,
"preview": "\"\"\"Responses.\n\nresponses serve both testing purpose aswell as dynamic docstring replacement\n\"\"\"\nresponses = {\n \"_v3_a"
},
{
"path": "oandapyV20/endpoints/responses/forexlabs.py",
"chars": 17723,
"preview": "\"\"\"Responses.\n\nresponses serve both testing purpose aswell as dynamic docstring replacement\n\"\"\"\n\nresponses = {\n \"_v3_"
},
{
"path": "oandapyV20/endpoints/responses/instruments.py",
"chars": 12771,
"preview": "\"\"\"Responses.\n\nresponses serve both testing purpose aswell as dynamic docstring replacement\n\"\"\"\nresponses = {\n \"_v3_i"
},
{
"path": "oandapyV20/endpoints/responses/orders.py",
"chars": 7976,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Responses.\n\nresponses serve both testing purpose aswell as dynamic docstring replacement\n\"\"\"\n"
},
{
"path": "oandapyV20/endpoints/responses/positions.py",
"chars": 7561,
"preview": "\"\"\"Responses.\n\nresponses serve both testing purpose aswell as dynamic docstring replacement\n\"\"\"\nresponses = {\n \"_v3_a"
},
{
"path": "oandapyV20/endpoints/responses/pricing.py",
"chars": 8809,
"preview": "\"\"\"Responses.\n\nresponses serve both testing purpose aswell as dynamic docstring replacement\n\"\"\"\nresponses = {\n \"_v3_a"
},
{
"path": "oandapyV20/endpoints/responses/trades.py",
"chars": 7627,
"preview": "\"\"\"Responses.\n\nresponses serve both testing purpose aswell as dynamic docstring replacement\n\"\"\"\nresponses = {\n \"_v3_a"
},
{
"path": "oandapyV20/endpoints/responses/transactions.py",
"chars": 10554,
"preview": "\"\"\"Responses.\n\nresponses serve both testing purpose aswell as dynamic docstring replacement\n\"\"\"\nresponses = {\n \"_v3_a"
},
{
"path": "oandapyV20/endpoints/trades.py",
"chars": 7878,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Handle trades endpoints.\"\"\"\nfrom .apirequest import APIRequest\nfrom .decorators import dyndoc"
},
{
"path": "oandapyV20/endpoints/transactions.py",
"chars": 7344,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"Handle transactions endpoints.\"\"\"\nfrom .apirequest import APIRequest\nfrom ..exceptions import"
},
{
"path": "oandapyV20/exceptions.py",
"chars": 611,
"preview": "\"\"\"Exceptions.\"\"\"\n\n\nclass StreamTerminated(Exception):\n \"\"\"StreamTerminated.\"\"\"\n\n\nclass V20Error(Exception):\n \"\"\"G"
},
{
"path": "oandapyV20/oandapyV20.py",
"chars": 11242,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"OANDA API wrapper for OANDA's REST-V20 API.\"\"\"\n\nimport json\nimport requests\nimport logging\nfr"
},
{
"path": "oandapyV20/types/__init__.py",
"chars": 438,
"preview": "from .types import (\n AccountID,\n DateTime,\n OrderID,\n TradeID,\n AccountUnits,\n PriceValue,\n Units,"
},
{
"path": "oandapyV20/types/types.py",
"chars": 7102,
"preview": "# -*- coding: utf-8 -*-\n\"\"\"types.\"\"\"\n\nimport six\nimport re\nfrom abc import ABCMeta\nimport datetime as natdatetime # nat"
},
{
"path": "readthedocs.yml",
"chars": 69,
"preview": "requirements_file: requirements.txt\npython:\n setup_py_install: true\n"
},
{
"path": "requirements.txt",
"chars": 25,
"preview": "requests>=2.10\nsix>=1.10\n"
},
{
"path": "setup.py",
"chars": 2177,
"preview": "from setuptools import setup, find_packages\nimport os\nimport sys\nimport re\nimport shutil\n\n\ndef get_version(package):\n "
},
{
"path": "tests/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "tests/account.txt",
"chars": 24,
"preview": "101-004-1435156-001|EUR\n"
},
{
"path": "tests/test_accounts.py",
"chars": 5486,
"preview": "import sys\nimport unittest\nimport json\nfrom . import unittestsetup\nfrom .unittestsetup import environment as environment"
},
{
"path": "tests/test_contrib_factories.py",
"chars": 3077,
"preview": "import math\nimport unittest\n\ntry:\n from nose_parameterized import parameterized\nexcept ImportError:\n print(\"*** Pl"
},
{
"path": "tests/test_contrib_generic.py",
"chars": 1405,
"preview": "import unittest\n\ntry:\n from nose_parameterized import parameterized\nexcept ImportError:\n print(\"*** Please install"
},
{
"path": "tests/test_contrib_orders.py",
"chars": 11836,
"preview": "import unittest\n\ntry:\n from nose_parameterized import parameterized\nexcept:\n print(\"*** Please install 'nose_param"
},
{
"path": "tests/test_decorators.py",
"chars": 1697,
"preview": "import unittest\nfrom oandapyV20.endpoints.decorators import extendargs, abstractclass\nfrom abc import ABCMeta, abstractm"
},
{
"path": "tests/test_definitions.py",
"chars": 812,
"preview": "import unittest\n\nimport oandapyV20.definitions as allDEF\nfrom oandapyV20.definitions.orders import definitions as orderD"
},
{
"path": "tests/test_forexlabs.py",
"chars": 4242,
"preview": "import sys\nimport unittest\nimport json\nfrom . import unittestsetup\nfrom .unittestsetup import environment as environment"
},
{
"path": "tests/test_instruments.py",
"chars": 3276,
"preview": "import sys\nimport unittest\nimport json\nfrom . import unittestsetup\nfrom .unittestsetup import environment as environment"
},
{
"path": "tests/test_oandapyv20.py",
"chars": 2735,
"preview": "import sys\nimport unittest\nfrom . import unittestsetup\nfrom .unittestsetup import environment as environment\nfrom oandap"
},
{
"path": "tests/test_orders.py",
"chars": 7577,
"preview": "import sys\nimport unittest\nimport json\nfrom . import unittestsetup\nfrom .unittestsetup import environment as environment"
},
{
"path": "tests/test_positions.py",
"chars": 3373,
"preview": "import sys\nimport unittest\nimport json\nfrom . import unittestsetup\nfrom .unittestsetup import environment as environment"
},
{
"path": "tests/test_pricing.py",
"chars": 3220,
"preview": "import sys\nimport unittest\nimport json\nfrom . import unittestsetup\nfrom .unittestsetup import environment as environment"
},
{
"path": "tests/test_trades.py",
"chars": 4948,
"preview": "import sys\nimport unittest\nimport json\nfrom . import unittestsetup\nfrom .unittestsetup import environment as environment"
},
{
"path": "tests/test_transactions.py",
"chars": 4744,
"preview": "import sys\nimport unittest\nimport json\nfrom . import unittestsetup\nfrom .unittestsetup import environment as environment"
},
{
"path": "tests/test_types.py",
"chars": 6224,
"preview": "import unittest\nfrom datetime import datetime\n\ntry:\n from nose_parameterized import parameterized\nexcept:\n print(\""
},
{
"path": "tests/token.txt",
"chars": 66,
"preview": "aaaa9999bbbb8888cccc7777dddd6666-eeee5555ffff4444aaaa3333bbbb2222\n"
},
{
"path": "tests/unittestsetup.py",
"chars": 1613,
"preview": "\"\"\" initialization of unittests and data for unittests \"\"\"\n\nimport time\nenvironment = \"practice\"\n\n# calculate expiryDate"
}
]
About this extraction
This page contains the full source code of the hootnot/oanda-api-v20 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 187 files (481.8 KB), approximately 129.3k tokens, and a symbol index with 289 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.