Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/ccxt-dev/ccxt
Browse files Browse the repository at this point in the history
  • Loading branch information
kroitor committed Jun 6, 2018
2 parents 8556f47 + fa377b0 commit 175d2ab
Show file tree
Hide file tree
Showing 13 changed files with 120 additions and 35 deletions.
6 changes: 3 additions & 3 deletions build/ccxt.browser.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ccxt.js
Expand Up @@ -37,7 +37,7 @@ const Exchange = require ('./js/base/Exchange')
//-----------------------------------------------------------------------------
// this is updated by vss.js when building

const version = '1.14.140'
const version = '1.14.142'

Exchange.ccxtVersion = version

Expand Down
2 changes: 1 addition & 1 deletion js/coinmarketcap.js
Expand Up @@ -222,7 +222,7 @@ module.exports = class coinmarketcap extends Exchange {
let tickers = {};
for (let t = 0; t < response.length; t++) {
let ticker = response[t];
let currencyId = (currency in this.currencies) ? this.currencies[currency]['id'] : currency.toLowerCase ();
let currencyId = currency.toLowerCase ();
let id = ticker['id'] + '/' + currencyId;
let symbol = id;
let market = undefined;
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "ccxt",
"version": "1.14.140",
"version": "1.14.142",
"description": "A JavaScript / Python / PHP cryptocurrency trading library with support for 100+ exchanges",
"main": "./ccxt.js",
"unpkg": "build/ccxt.browser.js",
Expand Down
2 changes: 1 addition & 1 deletion php/Exchange.php
Expand Up @@ -30,7 +30,7 @@

namespace ccxt;

$version = '1.14.140';
$version = '1.14.142';

// rounding mode
const TRUNCATE = 0;
Expand Down
2 changes: 1 addition & 1 deletion php/coinmarketcap.php
Expand Up @@ -223,7 +223,7 @@ public function fetch_tickers ($currency = 'USD', $params = array ()) {
$tickers = array ();
for ($t = 0; $t < count ($response); $t++) {
$ticker = $response[$t];
$currencyId = (is_array ($this->currencies) && array_key_exists ($currency, $this->currencies)) ? $this->currencies[$currency]['id'] : strtolower ($currency);
$currencyId = strtolower ($currency);
$id = $ticker['id'] . '/' . $currencyId;
$symbol = $id;
$market = null;
Expand Down
2 changes: 1 addition & 1 deletion python/ccxt/__init__.py
Expand Up @@ -22,7 +22,7 @@

# ----------------------------------------------------------------------------

__version__ = '1.14.140'
__version__ = '1.14.142'

# ----------------------------------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion python/ccxt/async/__init__.py
Expand Up @@ -4,7 +4,7 @@

# -----------------------------------------------------------------------------

__version__ = '1.14.140'
__version__ = '1.14.142'

# -----------------------------------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion python/ccxt/async/base/exchange.py
Expand Up @@ -2,7 +2,7 @@

# -----------------------------------------------------------------------------

__version__ = '1.14.140'
__version__ = '1.14.142'

# -----------------------------------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion python/ccxt/async/coinmarketcap.py
Expand Up @@ -215,7 +215,7 @@ async def fetch_tickers(self, currency='USD', params={}):
tickers = {}
for t in range(0, len(response)):
ticker = response[t]
currencyId = self.currencies[currency]['id'] if (currency in list(self.currencies.keys())) else currency.lower()
currencyId = currency.lower()
id = ticker['id'] + '/' + currencyId
symbol = id
market = None
Expand Down
64 changes: 42 additions & 22 deletions python/ccxt/base/exchange.py
Expand Up @@ -4,7 +4,7 @@

# -----------------------------------------------------------------------------

__version__ = '1.14.140'
__version__ = '1.14.142'

# -----------------------------------------------------------------------------

Expand Down Expand Up @@ -665,11 +665,19 @@ def microseconds():
return int(time.time() * 1000000)

@staticmethod
def iso8601(timestamp):
def iso8601(timestamp=None):
if timestamp is None:
return timestamp
utc = datetime.datetime.utcfromtimestamp(int(round(timestamp / 1000)))
return utc.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-6] + "{:<03d}".format(int(timestamp) % 1000) + 'Z'
if not isinstance(timestamp, int):
return None
if int(timestamp) < 0:
return None

try:
utc = datetime.datetime.utcfromtimestamp(int(round(timestamp / 1000)))
return utc.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-6] + "{:<03d}".format(int(timestamp) % 1000) + 'Z'
except (TypeError, OverflowError, OSError):
return None

@staticmethod
def dmy(timestamp, infix='-'):
Expand All @@ -687,18 +695,25 @@ def ymdhms(timestamp, infix=' '):
return utc_datetime.strftime('%Y-%m-%d' + infix + '%H:%M:%S')

@staticmethod
def parse_date(timestamp):
def parse_date(timestamp=None):
if timestamp is None:
return timestamp
if not isinstance(timestamp, str):
return None
if 'GMT' in timestamp:
string = ''.join([str(value) for value in parsedate(timestamp)[:6]]) + '.000Z'
dt = datetime.datetime.strptime(string, "%Y%m%d%H%M%S.%fZ")
return calendar.timegm(dt.utctimetuple()) * 1000
try:
string = ''.join([str(value) for value in parsedate(timestamp)[:6]]) + '.000Z'
dt = datetime.datetime.strptime(string, "%Y%m%d%H%M%S.%fZ")
return calendar.timegm(dt.utctimetuple()) * 1000
except (TypeError, OverflowError, OSError):
return None
else:
return Exchange.parse8601(timestamp)

@staticmethod
def parse8601(timestamp):
def parse8601(timestamp=None):
if timestamp is None:
return timestamp
yyyy = '([0-9]{4})-?'
mm = '([0-9]{2})-?'
dd = '([0-9]{2})(?:T|[\\s])?'
Expand All @@ -708,19 +723,24 @@ def parse8601(timestamp):
ms = '(\\.[0-9]{1,3})?'
tz = '(?:(\\+|\\-)([0-9]{2})\\:?([0-9]{2})|Z)?'
regex = r'' + yyyy + mm + dd + h + m + s + ms + tz
match = re.search(regex, timestamp, re.IGNORECASE)
yyyy, mm, dd, h, m, s, ms, sign, hours, minutes = match.groups()
ms = ms or '.000'
msint = int(ms[1:])
sign = sign or ''
sign = int(sign + '1')
hours = int(hours or 0) * sign
minutes = int(minutes or 0) * sign
offset = datetime.timedelta(hours=hours, minutes=minutes)
string = yyyy + mm + dd + h + m + s + ms + 'Z'
dt = datetime.datetime.strptime(string, "%Y%m%d%H%M%S.%fZ")
dt = dt + offset
return calendar.timegm(dt.utctimetuple()) * 1000 + msint
try:
match = re.search(regex, timestamp, re.IGNORECASE)
if match is None:
return None
yyyy, mm, dd, h, m, s, ms, sign, hours, minutes = match.groups()
ms = ms or '.000'
msint = int(ms[1:])
sign = sign or ''
sign = int(sign + '1')
hours = int(hours or 0) * sign
minutes = int(minutes or 0) * sign
offset = datetime.timedelta(hours=hours, minutes=minutes)
string = yyyy + mm + dd + h + m + s + ms + 'Z'
dt = datetime.datetime.strptime(string, "%Y%m%d%H%M%S.%fZ")
dt = dt + offset
return calendar.timegm(dt.utctimetuple()) * 1000 + msint
except (TypeError, OverflowError, OSError, ValueError):
return None

@staticmethod
def hash(request, algorithm='md5', digest='hex'):
Expand Down
2 changes: 1 addition & 1 deletion python/ccxt/coinmarketcap.py
Expand Up @@ -215,7 +215,7 @@ def fetch_tickers(self, currency='USD', params={}):
tickers = {}
for t in range(0, len(response)):
ticker = response[t]
currencyId = self.currencies[currency]['id'] if (currency in list(self.currencies.keys())) else currency.lower()
currencyId = currency.lower()
id = ticker['id'] + '/' + currencyId
symbol = id
market = None
Expand Down
65 changes: 65 additions & 0 deletions python/test/test_exchange_datetime_functions.py
@@ -0,0 +1,65 @@
from unittest import TestCase

import os
import sys

# ------------------------------------------------------------------------------

root = os.path.dirname(os.path.abspath(__file__))
sys.path.append(root)

# ------------------------------------------------------------------------------

import ccxt # noqa: E402

# ------------------------------------------------------------------------------


exchange = ccxt.Exchange()


class TestExchange(TestCase):
def test_iso8601(self):
self.assertEqual(exchange.iso8601(714862627000), '1992-08-26T20:57:07.000Z')
self.assertEqual(exchange.iso8601(0), '1970-01-01T00:00:00.000Z')

self.assertEqual(exchange.iso8601(None), None)
self.assertEqual(exchange.iso8601(), None)
self.assertEqual(exchange.iso8601(-1), None)
self.assertEqual(exchange.iso8601({}), None)
self.assertEqual(exchange.iso8601(''), None)
self.assertEqual(exchange.iso8601('a'), None)
self.assertEqual(exchange.iso8601([]), None)
self.assertEqual(exchange.iso8601([1]), None)

def test_parse_date(self):
self.assertEqual(exchange.parse_date('1996-04-26 00:00:00'), 830476800000)
self.assertEqual(exchange.parse_date('1996-04-26T01:23:47.000Z'), 830481827000)
self.assertEqual(exchange.parse_date('1996-13-13 00:00:00'), None)

self.assertEqual(exchange.parse_date('Sun, 18 Mar 2012 05:50:34 GMT'), 1332049834000)

self.assertEqual(exchange.parse_date('GMT'), None)
self.assertEqual(exchange.parse_date('42 GMT'), None)

self.assertEqual(exchange.parse_date(None), None)
self.assertEqual(exchange.parse_date(), None)
self.assertEqual(exchange.parse_date(1), None)
self.assertEqual(exchange.parse_date({}), None)
self.assertEqual(exchange.parse_date([]), None)
self.assertEqual(exchange.parse_date([1]), None)

def test_parse8601(self):
self.assertEqual(exchange.parse8601('1986-04-26T01:23:47.000Z'), 514862627000)

self.assertEqual(exchange.parse8601('1986-14-26T23:01:47.000Z'), None)
self.assertEqual(exchange.parse8601('1986-04-26T25:71:47.000Z'), None)

self.assertEqual(exchange.parse8601(None), None)
self.assertEqual(exchange.parse8601(), None)
self.assertEqual(exchange.parse8601(''), None)
self.assertEqual(exchange.parse8601('1'), None)
self.assertEqual(exchange.parse8601(1), None)
self.assertEqual(exchange.parse8601({}), None)
self.assertEqual(exchange.parse8601([]), None)
self.assertEqual(exchange.parse8601([1]), None)

0 comments on commit 175d2ab

Please sign in to comment.