mirror of
https://github.com/wassname/libcryptomarket.git
synced 2026-09-09 11:25:52 +08:00
Support Poloniex API
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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" +
|
||||
"¤cyPair={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
@@ -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
|
||||
Reference in New Issue
Block a user