Support Poloniex API

This commit is contained in:
AuroraTradingTeam
2017-11-12 20:06:04 +00:00
parent 60e2ce0379
commit 2a10783f1f
3 changed files with 166 additions and 60 deletions
+22 -3
View File
@@ -16,8 +16,13 @@ Python 3.5+
## Installation
To install the library, please run the command to install via pip
You can install it via pip for static version
```
pip install libcryptomarket
```
or development version
```
pip install git+https://github.com/libcryptomarket/libcryptomarket.git
@@ -39,13 +44,17 @@ instruments = get_instruments()
### Historical
Run
Currently, multiple data sources of historical data are supported.
For example, for the source of [Cryptocompare](https://www.cryptocompare.com/api/#),
run
```
from datetime import datetime
from libcryptomarket.historical import get_historical_prices
prices = get_historical_prices(symbol='LTCBTC',
prices = get_historical_prices(source='cryptocompare',
symbol='LTC/BTC',
exchange='Poloniex',
period="hour",
from_time=datetime(2017, 5, 1),
@@ -56,6 +65,16 @@ Then you can get historical price in ascending order seamlessly, even though
the limit has exceeded the source limit. The application helps continue
querying until the data reaches the requirements.
For the source of [Poloniex](https://poloniex.com/support/api/), run
```
prices = get_historical_prices(source='Poloniex',
symbol='LTC/BTC',
period="30m",
from_time=datetime(2016, 1, 1),
to_time=datetime(2017, 8, 1))
```
## Contribution
The project is targeting as a core but generic toolkit to query cryptocurrency
+32
View File
@@ -0,0 +1,32 @@
#!/bin/python
import requests
from datetime import datetime
import logging
API_URL = "https://poloniex.com/public?command="
VALID_PERIODS = [300, 900, 1800, 7200, 14400, 86400]
def get_return_chart_data(currency_pair, period, start, end=None):
"""Return returnChartData.
:param currency_pair: Currency pair. For example, BTC_XMR.
:param period: Period. Valid values are 300, 900, 1800, 7200, 14400 and
86400.
:param start: Start time in unix timestamp.
:param end: End time in unix timestamp. Optional.
"""
assert period in VALID_PERIODS, (
"Period is not in the valid periods (%s)" % VALID_PERIODS)
url = (API_URL + "returnChartData" +
"&currencyPair={0}".format(currency_pair) +
"&period={0}".format(period) +
"&start={0}".format(start))
if end is not None:
url += "&end={0}".format(end)
r = requests.get(url)
r.raise_for_status()
return r.json()
+112 -57
View File
@@ -1,11 +1,8 @@
from functools import partial
from datetime import datetime
import pandas as pd
from libcryptomarket.api.cryptocompare_api import (
get_histo, CryptocompareHisto
)
def get_historical_prices(source='cryptocompare', symbol=None, exchange=None,
period=None, limit=0, from_time=None, to_time=None):
@@ -23,6 +20,8 @@ def get_historical_prices(source='cryptocompare', symbol=None, exchange=None,
:param to_time: To time. Default is None, which follows the source default
value.
"""
source = source.lower()
if source == 'cryptocompare':
if period is None:
raise ValueError("Input parameter period cannot be None.")
@@ -39,64 +38,120 @@ def get_historical_prices(source='cryptocompare', symbol=None, exchange=None,
raise ValueError("Cannot accept either from_time or to_time is "
"None")
# Parse from (first 3) and to (last 3) symbol from the parameter
# symbol.
from_sym = symbol[:3]
to_sym = symbol[3:]
return _get_historical_prices_cryptocompare(symbol, exchange, period,
limit, from_time, to_time)
elif source == 'poloniex':
if exchange is not None:
raise ValueError("Poloniex does not need exchange parameter.")
func = partial(get_histo, period=period, fsym=from_sym, tsym=to_sym,
e=exchange)
# Validate and transform symbol
symbol = symbol.replace("/", "_").upper()
data = []
if limit > 0:
# Get the data by limit of records
to_time = 0
while limit > 0:
if to_time == 0:
response = func(limit=limit)['Data']
else:
response = func(limit=limit, toTs=to_time)['Data']
if len(response) == 0:
# Terminate if no further response
break
else:
data += response
limit -= len(response)
to_time = response[0]['time'] - 1
elif from_time is not None and to_time is not None:
# Get the data by time range
from libcryptomarket.api.cryptocompare_api import MAX_QUERY_LIMIT
from_time_ts = int(from_time.timestamp())
to_time_ts = int(to_time.timestamp())
while from_time_ts < to_time_ts:
response = func(limit=MAX_QUERY_LIMIT,
toTs=to_time_ts)['Data']
if len(response) == 0:
# Terminate if no further response
break
else:
data += response
to_time_ts = response[0]['time'] - 1
# Validate and transform periods
valid_periods = {
"5m": 300,
"15m": 900,
"30m": 1800,
"2h": 7200,
"4h": 14400,
"1d": 86400
}
period = period.lower()
if period not in valid_periods.keys():
raise ValueError("Periods is not valid. " +
("Valid values (%s)" % str(valid_periods)))
else:
data += func()['Data']
period = valid_periods[period]
if len(data) == 0:
return data
# Validate and transform to_time and from_time
from_time = from_time.timestamp()
to_time = to_time.timestamp() if to_time is not None else 9999999999
if to_time <= from_time:
raise ValueError("From time should not be greater than or "
"equal to to time.")
data = pd.DataFrame([CryptocompareHisto(**e).__dict__ for e in data])
# Filter only valid time range
if from_time is not None and to_time is not None:
data = data[(data['r_time'] >= from_time) &
(data['r_time'] <= to_time)]
data = data.set_index(['r_time'])
data.index.name = 'datetime'
return data
return _get_historical_prices_poloniex(symbol, period,
from_time, to_time)
else:
raise ValueError("No source is called {0}".format(source))
def _get_historical_prices_cryptocompare(symbol, exchange, period,
limit, from_time, to_time):
from libcryptomarket.api.cryptocompare_api import (
get_histo, CryptocompareHisto
)
from_sym = symbol.split('/')[0]
to_sym = symbol.split('/')[1]
func = partial(get_histo, period=period, fsym=from_sym, tsym=to_sym,
e=exchange)
data = []
if limit > 0:
# Get the data by limit of records
to_time = 0
while limit > 0:
if to_time == 0:
response = func(limit=limit)['Data']
else:
response = func(limit=limit, toTs=to_time)['Data']
if len(response) == 0:
# Terminate if no further response
break
else:
data += response
limit -= len(response)
to_time = response[0]['time'] - 1
elif from_time is not None and to_time is not None:
# Get the data by time range
from libcryptomarket.api.cryptocompare_api import MAX_QUERY_LIMIT
from_time_ts = int(from_time.timestamp())
to_time_ts = int(to_time.timestamp())
while from_time_ts < to_time_ts:
response = func(limit=MAX_QUERY_LIMIT,
toTs=to_time_ts)['Data']
if len(response) == 0:
# Terminate if no further response
break
else:
data += response
to_time_ts = response[0]['time'] - 1
else:
data += func()['Data']
if len(data) == 0:
return data
data = pd.DataFrame([CryptocompareHisto(**e).__dict__ for e in data])
# Filter only valid time range
if from_time is not None and to_time is not None:
data = data[(data['r_time'] >= from_time) &
(data['r_time'] <= to_time)]
data = data.set_index(['r_time'])
data.index.name = 'datetime'
return data
def _get_historical_prices_poloniex(symbol, period, from_time, to_time):
from libcryptomarket.api.poloniex_api import get_return_chart_data
data = get_return_chart_data(symbol, period, from_time, to_time)
if len(data) == 0 or isinstance(data, dict):
raise ValueError("Poloniex data is not in a right format.\n{0}".format(
data))
data = pd.DataFrame(data)
data['date'] = data['date'].map(lambda x: pd.Timestamp(datetime.fromtimestamp(x)))
data.columns = "r_" + data.columns.str.lower()
data = data.set_index(['r_date'])
data.index.name = 'datetime'
return data