在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:hootnot/oanda-api-v20开源软件地址:https://github.com/hootnot/oanda-api-v20开源编程语言:Python 78.7%开源软件介绍:OANDA REST-V20 API wrapperAs 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/. InteractiveUsing the Jupyter notebook it is easy to play with the oandapyV20 library. TOCInstall$ pip install oandapyV20 or the latest development version from github: $ pip install git+https://github.com/hootnot/oanda-api-v20.git If you want to run the tests, clone the repository: $ 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. DesignIn 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. ClientThe V20-library has a client class (API) which processes APIRequest objects. contrib.requestsThe 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). mktOrder = MarketOrderRequest(instrument="EUR_USD",
units=10000,
takeProfitOnFill=TakeProfitDetails(price=1.10).data,
stopLossOnFill=StopLossDetails(price=1.07).data
).data
instead of: 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'}
}
} contrib.factoriesThe 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: 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: $ 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: $ 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 ExamplesAPI-endpoint accessimport 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))) Placing a MarketOrder with TakeProfitOrder and StopLossOrderimport 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)) Processing series of requestsProcessing series of requests is also possible now by storing different requests in an array or from some 'request-factory' class. Below an array example: 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{
"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"
}
]
}
} Streaming endpointsStreaming quotes: use pricing.PricingStream. Streaming transactions: use transactions.TransactionsEvents. To fetch streaming data from a stream use the following pattern: 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
全部评论
专题导读
上一篇:rvuduc/cse6040fa16labs: Georgia Tech, CSE 6040 Jupyter notebooks发布时间:2022-07-09下一篇:awjuliani/oreilly-rl-tutorial: Contains Jupyter notebooks associated with the &q ...发布时间:2022-07-09热门推荐
热门话题
阅读排行榜
|
请发表评论