From 61d9da02fda3a81c2e92d0e973cf5beb2b4444cb Mon Sep 17 00:00:00 2001 From: cclauss Date: Fri, 12 Jul 2019 20:28:31 +0200 Subject: [PATCH] Modernize Python 2 code to prepare for Python 3 --- .travis.yml | 19 ++++++- gryphon/dashboards/app.py | 6 +- gryphon/dashboards/handlers/admin_base.py | 5 +- gryphon/dashboards/handlers/block_times.py | 5 +- gryphon/dashboards/handlers/home.py | 3 +- gryphon/dashboards/handlers/ledger.py | 4 +- gryphon/dashboards/handlers/status.py | 2 +- gryphon/dashboards/handlers/tick_times.py | 5 +- gryphon/dashboards/models/base.py | 5 +- gryphon/dashboards/settings.py | 3 +- gryphon/dashboards/util/balances.py | 6 +- .../auditors/orderbook_auditor.py | 4 +- .../data_service/exchange_volume_consumer.py | 2 +- gryphon/data_service/migrations/env.py | 2 +- gryphon/data_service/orderbook_consumer.py | 2 +- .../orderbook/kraken_cad_orderbook_poller.py | 3 +- .../orderbook/kraken_usd_orderbook_poller.py | 3 +- .../websocket/bitfinex_orderbook_websocket.py | 4 +- .../websocket/bitstamp_orderbook_websocket.py | 14 ++--- .../websocket/coinbase_orderbook_websocket.py | 4 +- .../pollers/trades/trades_poller.py | 5 +- gryphon/data_service/runt.py | 2 +- .../data_service/scripts/autobahn-tester.py | 1 + gryphon/data_service/scripts/benchmark.py | 3 +- .../scripts/historical_trade_collector.py | 17 +++--- gryphon/data_service/trades_consumer.py | 7 ++- gryphon/execution/app.py | 4 +- gryphon/execution/bots/overwatch.py | 2 +- gryphon/execution/bots/shoebox.py | 2 +- gryphon/execution/console.py | 2 +- gryphon/execution/controllers/balance.py | 1 + .../controllers/create_dashboard_user.py | 21 ++++--- gryphon/execution/controllers/fee_buyback.py | 5 +- .../controllers/initialize_ledger.py | 13 +++-- gryphon/execution/controllers/order_book.py | 3 +- .../execution/controllers/run_migrations.py | 4 +- .../harness/exchange_coordinator.pyx | 20 +++---- gryphon/execution/harness/harness.pyx | 4 +- gryphon/execution/lib/auditing.py | 4 +- gryphon/execution/lib/config.py | 7 ++- gryphon/execution/lib/config_helper.py | 7 +-- gryphon/execution/lib/tick_profiling.py | 2 +- gryphon/execution/live_runner.py | 7 ++- gryphon/execution/migrations/env.py | 6 +- .../execution/models/backtesting/result.py | 13 +++-- gryphon/execution/scripts/itbit_auth_test.py | 3 +- gryphon/execution/scripts/ledger_export.py | 4 +- gryphon/execution/scripts/reset_balance.py | 2 +- gryphon/execution/strategies/base.pyx | 7 +-- .../builtin/fundamental_value/v1.py | 2 +- .../builtin/fundamental_value/v2.py | 2 +- .../builtin/fundamental_value/v3.py | 2 +- gryphon/lib/__init__.py | 1 + .../lib/analysis/legacy/average_true_range.py | 13 +++-- .../lib/analysis/legacy/chaikin_volatility.py | 9 +-- gryphon/lib/analysis/legacy/chart.py | 10 ++-- .../lib/analysis/legacy/ease_of_movement.py | 7 ++- .../lib/analysis/legacy/elder_force_index.py | 3 +- gryphon/lib/analysis/legacy/gapo.py | 3 +- gryphon/lib/analysis/legacy/swing_index.py | 27 ++++----- gryphon/lib/analysis/legacy/volatility.py | 8 +-- gryphon/lib/arbitrage.py | 9 ++- gryphon/lib/bitcoinwisdom.py | 14 ++--- gryphon/lib/configuration.py | 12 ++-- gryphon/lib/debugging/bitstamp_cert_error.py | 32 ++++++----- gryphon/lib/exchange/bitfinex_btc_usd.py | 11 ++-- gryphon/lib/exchange/bitme.py | 7 ++- gryphon/lib/exchange/bitstamp_btc_usd.py | 17 +++--- gryphon/lib/exchange/buttercoin.py | 7 ++- gryphon/lib/exchange/cavirtex.py | 7 ++- gryphon/lib/exchange/coinbase_btc_usd.py | 5 +- gryphon/lib/exchange/exchange_order.pyx | 30 +++++----- gryphon/lib/exchange/exchange_trade.pyx | 15 ++--- gryphon/lib/exchange/gemini_btc_usd.py | 9 +-- gryphon/lib/exchange/itbit_btc_usd.py | 5 +- gryphon/lib/exchange/kraken_btc_eur.py | 33 +++++------ gryphon/lib/exchange/okcoin_btc_usd.py | 25 ++++---- gryphon/lib/exchange/poloniex_eth_btc.py | 5 +- gryphon/lib/exchange/quadriga_btc_cad.py | 57 ++++++++++--------- gryphon/lib/exchange/vault_of_satoshi.py | 7 ++- gryphon/lib/gryphonfury/fees.py | 5 ++ gryphon/lib/gryphonfury/revenue.py | 8 +-- gryphon/lib/hackernewsie.py | 2 +- gryphon/lib/models/atlaszero/base.py | 3 +- gryphon/lib/models/atlaszero/metric.py | 8 ++- gryphon/lib/models/atlaszero/metric_types.py | 5 +- gryphon/lib/models/base.pyx | 5 +- gryphon/lib/models/datum.py | 7 ++- gryphon/lib/models/emeraldhavoc/base.py | 5 +- .../models/emeraldhavoc/exchange_volume.py | 5 +- gryphon/lib/models/emeraldhavoc/orderbook.pyx | 19 ++++--- gryphon/lib/models/emeraldhavoc/trade.py | 9 +-- gryphon/lib/models/event.py | 25 ++++---- gryphon/lib/models/exchange.pyx | 11 ++-- gryphon/lib/models/liability.py | 9 +-- gryphon/lib/models/market_data.py | 20 ++++--- gryphon/lib/models/order.pyx | 29 +++++----- gryphon/lib/models/orderbook_snapshot.py | 16 +++--- gryphon/lib/models/ticker.py | 15 ++--- gryphon/lib/models/trade.pyx | 21 +++---- gryphon/lib/models/transaction.py | 27 ++++----- gryphon/lib/money.py | 3 +- gryphon/lib/scrapers/bmo.py | 7 ++- gryphon/lib/scrapers/boa.py | 5 +- gryphon/lib/scripts/bitstamp_auth_test.py | 24 ++++---- .../scripts/test_fast_revenue_fees_profit.py | 21 +++---- gryphon/lib/util/profile.py | 3 +- .../exchange_coordinator/auth_methods.py | 4 +- .../exchange_coordinator/bitstamp.py | 32 +++++------ .../exchange_coordinator/kraken.py | 5 +- .../exchange_coordinator/public_methods.py | 2 +- .../exchange_wrappers/auth_methods.py | 4 +- .../exchange_wrappers/bitstamp_auth.py | 2 +- .../exchange_wrappers/bitstamp_live_orders.py | 2 +- .../exchange_wrappers/coinbase_auth.py | 2 +- .../exchange_wrappers/coinbase_live_orders.py | 2 +- .../exchange_wrappers/gemini_auth.py | 2 +- .../exchange_wrappers/gemini_live_orders.py | 2 +- .../exchange_wrappers/itbit_auth.py | 2 +- .../exchange_wrappers/itbit_live_orders.py | 2 +- .../exchange_wrappers/kraken_auth.py | 2 +- .../exchange_wrappers/kraken_live_orders.py | 2 +- .../exchange_wrappers/live_orders.py | 8 +-- .../exchange_wrappers/quadriga_auth.py | 2 +- .../exchange_wrappers/quadriga_live_orders.py | 2 +- gryphon/tests/extra/libraries/sharpe_test.py | 2 +- gryphon/tests/logic/auditing/auditing_test.py | 2 +- .../tests/logic/configuration/base_test.py | 40 +++++++------ .../configuration/bitstamp_bch_btc_test.py | 2 +- .../configuration/bitstamp_bch_eur_test.py | 2 +- .../configuration/bitstamp_bch_usd_test.py | 2 +- .../configuration/bitstamp_btc_eur_test.py | 2 +- .../configuration/bitstamp_eth_btc_test.py | 2 +- .../configuration/bitstamp_eth_eur_test.py | 2 +- .../configuration/bitstamp_eth_usd_test.py | 2 +- .../logic/configuration/bitstamp_test.py | 2 +- .../logic/configuration/coinbase_test.py | 2 +- gryphon/tests/logic/configuration/exchange.py | 4 +- .../configuration/execution_config_test.py | 14 ++--- .../configuration/gemini_eth_btc_test.py | 2 +- .../configuration/gemini_eth_usd_test.py | 2 +- .../tests/logic/configuration/gemini_test.py | 2 +- .../tests/logic/configuration/itbit_test.py | 2 +- .../logic/configuration/kraken_cad_test.py | 2 +- .../tests/logic/configuration/kraken_test.py | 2 +- .../logic/configuration/kraken_usd_test.py | 2 +- .../logic/configuration/quadriga_test.py | 2 +- .../configuration/strategy_config_test.py | 4 +- .../logic/exchange_wrappers/bitstamp_test.py | 2 +- .../tests/logic/exchange_wrappers/coinbase.py | 2 +- .../logic/exchange_wrappers/gemini_test.py | 2 +- .../tests/logic/exchange_wrappers/itbit.py | 2 +- .../tests/logic/exchange_wrappers/kraken.py | 2 +- .../logic/exchange_wrappers/public_methods.py | 2 +- .../tests/logic/exchange_wrappers/quadriga.py | 2 +- .../tests/logic/libraries/arbitrage_test.py | 2 +- .../logic/libraries/close_options_test.py | 2 +- .../logic/libraries/market_making_test.py | 2 +- .../tests/logic/libraries/midpoint_test.py | 2 +- gryphon/tests/logic/libraries/money_test.py | 2 +- .../logic/libraries/order_sliding_test.py | 4 +- .../libraries/orderbook_strength_test.py | 8 +-- gryphon/tests/logic/libraries/revenue_test.py | 12 ++-- .../logic/libraries/volume_available_test.py | 10 ++-- gryphon/tests/logic/models/balance_test.py | 2 +- gryphon/tests/logic/models/liability_test.py | 2 +- gryphon/tests/logic/models/order_test.py | 2 +- gryphon/tests/logic/models/trade_test.py | 2 +- .../tests/logic/models/transaction_test.py | 2 +- gryphon/tests/logic/strategies/multi_test.py | 2 +- gryphon/tests/runtests.py | 2 +- setup.py | 10 ++-- 172 files changed, 677 insertions(+), 574 deletions(-) diff --git a/.travis.yml b/.travis.yml index ac271b3..7f53d66 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,29 @@ dist: xenial language: python addons: - apt: + apt: packages: - libmysqlclient-dev python: - - "2.7" + - 2.7 + - 3.6 + - 3.7 + +matrix: + allow_failures: + - python: 3.7 # blocked until rkern/line_profiler#153 is merged and pushed to pypi install: - pip install . +before_script: + - pip install flake8 + - LEGACY="./gryphon/lib/analysis/legacy/" + - UTIL="./gryphon/dashboards/util/" + - EXCLUDE="${LEGACY}standard_deviation.py,${LEGACY}bollinger_bands.py,${UTIL}queries.py" + - flake8 . --count --exclude=${EXCLUDE} --select=E9,F63,F7,F82 --show-source --statistics + # TODO: Fix the flake8 tests and then remove "|| true" + - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics || true + script: gryphon-runtests diff --git a/gryphon/dashboards/app.py b/gryphon/dashboards/app.py index 6c3f1c1..65c456a 100755 --- a/gryphon/dashboards/app.py +++ b/gryphon/dashboards/app.py @@ -13,7 +13,7 @@ from gryphon.lib import environment environment.load_environment_variables() -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import gryphon.lib; gryphon.lib.prepare() from gryphon.dashboards.routes import url_patterns @@ -50,7 +50,7 @@ def __init__(self): self.gds_db = None self.configuration = configuration.read_config_from_file('dashboards.conf') - + def main(): tornadotoad.register( @@ -58,7 +58,7 @@ def main(): environment=os.environ.get('APP_ENV'), ) - app = PentecostApp() + app = PentecostApp() http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start() diff --git a/gryphon/dashboards/handlers/admin_base.py b/gryphon/dashboards/handlers/admin_base.py index 83d2056..0de5623 100755 --- a/gryphon/dashboards/handlers/admin_base.py +++ b/gryphon/dashboards/handlers/admin_base.py @@ -2,6 +2,7 @@ import logging import traceback +from six import text_type import tornado.web from gryphon.dashboards.handlers.base import BaseHandler @@ -27,7 +28,7 @@ def write_error(self, status_code, **kwargs): exc_info = kwargs.get('exc_info') error_readout = [ - unicode(line, 'utf8') for line in traceback.format_exception(*exc_info) + text_type(line, 'utf8') for line in traceback.format_exception(*exc_info) ] logger.critical(u''.join(error_readout)) @@ -47,7 +48,7 @@ def get_current_user(self): def get_secure_cookie(self, name, include_name=True, value=None): cookie_value = super(AdminBaseHandler, self).get_secure_cookie(name) - return unicode(cookie_value or '', 'utf8') + return text_type(cookie_value or b'', 'utf8') def show_error_message(self, message): self.set_secure_cookie('error_message', message) diff --git a/gryphon/dashboards/handlers/block_times.py b/gryphon/dashboards/handlers/block_times.py index 61e7784..85d6b9a 100755 --- a/gryphon/dashboards/handlers/block_times.py +++ b/gryphon/dashboards/handlers/block_times.py @@ -1,7 +1,8 @@ -from admin_base import AdminBaseHandler +from __future__ import absolute_import +from .admin_base import AdminBaseHandler import tornado.web -from mixins.start_and_end_time import StartAndEndTimeMixin +from .mixins.start_and_end_time import StartAndEndTimeMixin import util.tick_times as tick_times diff --git a/gryphon/dashboards/handlers/home.py b/gryphon/dashboards/handlers/home.py index 06f2263..b30b8c5 100755 --- a/gryphon/dashboards/handlers/home.py +++ b/gryphon/dashboards/handlers/home.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- +from __future__ import absolute_import import tornado.web -from admin_base import AdminBaseHandler +from .admin_base import AdminBaseHandler class HomeHandler(AdminBaseHandler): diff --git a/gryphon/dashboards/handlers/ledger.py b/gryphon/dashboards/handlers/ledger.py index 59cfe5c..0d3edf6 100755 --- a/gryphon/dashboards/handlers/ledger.py +++ b/gryphon/dashboards/handlers/ledger.py @@ -142,7 +142,7 @@ def get_exchange_for_address(self, address): """ if address and address in self.address_map: - return address_map[address] + return self.address_map[address] else: return 'External transfer' @@ -261,7 +261,7 @@ def table_entries_from_transaction(self, transaction): entry['date'] = date entry['details'] = ''.join([ '%s:%s ' % (k, v) - for k, v in transaction.transaction_details.iteritems() + for k, v in transaction.transaction_details.items() if k in ['external_transaction_id', 'notes'] and v not in ['xxx'] ]) diff --git a/gryphon/dashboards/handlers/status.py b/gryphon/dashboards/handlers/status.py index 9a620af..90b175a 100755 --- a/gryphon/dashboards/handlers/status.py +++ b/gryphon/dashboards/handlers/status.py @@ -140,7 +140,7 @@ def get_system_balances(self, exchanges): system_balance += e.exchange_account_db_object(self.trading_db).balance total_fiat = sum([ - balance.to("USD") for currency, balance in system_balance.iteritems() + balance.to("USD") for currency, balance in system_balance.items() if currency not in Money.CRYPTO_CURRENCIES ]) diff --git a/gryphon/dashboards/handlers/tick_times.py b/gryphon/dashboards/handlers/tick_times.py index 3a72039..4347a6a 100755 --- a/gryphon/dashboards/handlers/tick_times.py +++ b/gryphon/dashboards/handlers/tick_times.py @@ -1,7 +1,8 @@ -from admin_base import AdminBaseHandler +from __future__ import absolute_import +from .admin_base import AdminBaseHandler import tornado.web -from mixins.start_and_end_time import StartAndEndTimeMixin +from .mixins.start_and_end_time import StartAndEndTimeMixin from tinkerpy.exchange.exchange_factory import all_exchanges import util.tick_times as tick_times diff --git a/gryphon/dashboards/models/base.py b/gryphon/dashboards/models/base.py index 3d30076..ac67fc5 100755 --- a/gryphon/dashboards/models/base.py +++ b/gryphon/dashboards/models/base.py @@ -1,13 +1,14 @@ # -*- coding: utf-8 -*- +from six import text_type from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() metadata = Base.metadata def unicode_string(self): - return unicode(self).encode('utf-8') + return text_type(self).encode('utf-8') -Base.__str__ == unicode_string +Base.__str__ == unicode_string # How to migrate a database diff --git a/gryphon/dashboards/settings.py b/gryphon/dashboards/settings.py index bfe88d2..6f33fd8 100755 --- a/gryphon/dashboards/settings.py +++ b/gryphon/dashboards/settings.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from __future__ import absolute_import import logging import tornado import tornado.template @@ -6,7 +7,7 @@ from os.path import dirname, abspath from tornado.options import define, options from gryphon.lib.logperf import log_request_perf -import uimodules +from . import uimodules # Make filepaths relative to settings. path = lambda root,*a: os.path.join(root, *a) diff --git a/gryphon/dashboards/util/balances.py b/gryphon/dashboards/util/balances.py index 38fc9e9..7a67279 100755 --- a/gryphon/dashboards/util/balances.py +++ b/gryphon/dashboards/util/balances.py @@ -12,7 +12,7 @@ def get_balance_time_series_from_audits(audits): fiat_balances = [] btc_balances = [] - + for audit in audits: timestamp = int(Delorean(audit.time_created, "UTC").epoch) * 1000 @@ -34,7 +34,7 @@ def get_balance_time_series_from_audits(audits): continue # convert to Money objects - for currency, balance_str in balance_data.iteritems(): + for currency, balance_str in balance_data.items(): balance_data[currency] = Money.loads(balance_str) balance = Balance(balance_data) @@ -103,7 +103,7 @@ def get_drift_from_audits(audits): if 'drift' in audit.data: data = json.loads(audit.data) - for currency, str_amount in data['drift'].iteritems(): + for currency, str_amount in data['drift'].items(): drift_by_currency += Money.loads(str_amount) return drift_by_currency diff --git a/gryphon/data_service/auditors/orderbook_auditor.py b/gryphon/data_service/auditors/orderbook_auditor.py index 2852622..9737494 100755 --- a/gryphon/data_service/auditors/orderbook_auditor.py +++ b/gryphon/data_service/auditors/orderbook_auditor.py @@ -242,7 +242,7 @@ def audit_orderbook(self, orderbook, orderbook_timestamp): if not our_orderbooks: log.msg('No orderbooks to audit against') - for key, value in fundamental_values.iteritems(): + for key, value in fundamental_values.items(): log.msg( '------ Fundamental Value Closeness:%.6f, DBfv:%s, HTTPfv:%s' % ( key, @@ -250,7 +250,7 @@ def audit_orderbook(self, orderbook, orderbook_timestamp): value['http_fundamental_value'] )) - for key, value in change_dict.iteritems(): + for key, value in change_dict.items(): log.msg('------ Change Count: %s' % key) log.msg( diff --git a/gryphon/data_service/exchange_volume_consumer.py b/gryphon/data_service/exchange_volume_consumer.py index 8644fc7..321d735 100755 --- a/gryphon/data_service/exchange_volume_consumer.py +++ b/gryphon/data_service/exchange_volume_consumer.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import json import os diff --git a/gryphon/data_service/migrations/env.py b/gryphon/data_service/migrations/env.py index 6838420..7034650 100755 --- a/gryphon/data_service/migrations/env.py +++ b/gryphon/data_service/migrations/env.py @@ -1,5 +1,5 @@ from __future__ import with_statement -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from logging.config import fileConfig from alembic import context diff --git a/gryphon/data_service/orderbook_consumer.py b/gryphon/data_service/orderbook_consumer.py index c563a9c..0cb28cc 100755 --- a/gryphon/data_service/orderbook_consumer.py +++ b/gryphon/data_service/orderbook_consumer.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import json import os import subprocess diff --git a/gryphon/data_service/pollers/orderbook/kraken_cad_orderbook_poller.py b/gryphon/data_service/pollers/orderbook/kraken_cad_orderbook_poller.py index e91067c..28573e2 100755 --- a/gryphon/data_service/pollers/orderbook/kraken_cad_orderbook_poller.py +++ b/gryphon/data_service/pollers/orderbook/kraken_cad_orderbook_poller.py @@ -1,4 +1,5 @@ -from kraken_orderbook_poller import KrakenOrderbook +from __future__ import absolute_import +from .kraken_orderbook_poller import KrakenOrderbook class KrakenCADOrderbook(KrakenOrderbook): diff --git a/gryphon/data_service/pollers/orderbook/kraken_usd_orderbook_poller.py b/gryphon/data_service/pollers/orderbook/kraken_usd_orderbook_poller.py index 191b145..90efd67 100755 --- a/gryphon/data_service/pollers/orderbook/kraken_usd_orderbook_poller.py +++ b/gryphon/data_service/pollers/orderbook/kraken_usd_orderbook_poller.py @@ -1,4 +1,5 @@ -from kraken_orderbook_poller import KrakenOrderbook +from __future__ import absolute_import +from .kraken_orderbook_poller import KrakenOrderbook class KrakenUSDOrderbook(KrakenOrderbook): diff --git a/gryphon/data_service/pollers/orderbook/websocket/bitfinex_orderbook_websocket.py b/gryphon/data_service/pollers/orderbook/websocket/bitfinex_orderbook_websocket.py index 736b8f2..4525c61 100755 --- a/gryphon/data_service/pollers/orderbook/websocket/bitfinex_orderbook_websocket.py +++ b/gryphon/data_service/pollers/orderbook/websocket/bitfinex_orderbook_websocket.py @@ -130,11 +130,11 @@ def get_orderbook_to_publish(self): bids = [] asks = [] - for price, volume in sorted(self.bids_dict.iteritems(), reverse=True): + for price, volume in sorted(self.bids_dict.items(), reverse=True): if volume > 0: bids.append([str(price), str(volume), '']) - for price, volume in sorted(self.asks_dict.iteritems()): + for price, volume in sorted(self.asks_dict.items()): if volume > 0: asks.append([str(price), str(volume), '']) diff --git a/gryphon/data_service/pollers/orderbook/websocket/bitstamp_orderbook_websocket.py b/gryphon/data_service/pollers/orderbook/websocket/bitstamp_orderbook_websocket.py index 8935921..0ea61d6 100755 --- a/gryphon/data_service/pollers/orderbook/websocket/bitstamp_orderbook_websocket.py +++ b/gryphon/data_service/pollers/orderbook/websocket/bitstamp_orderbook_websocket.py @@ -211,26 +211,26 @@ def apply_change_to_orderbook(self, change): # Remove the 0 volumes from the orderbook. self.orderbook['bids'].update(bids_changes) - for k, v in self.orderbook['bids'].iteritems(): + for k, v in self.orderbook['bids'].items(): if v == "0": self.orderbook['bids'].pop(k) # Re-sort the bids. self.orderbook['bids'] = OrderedDict(sorted( - self.orderbook['bids'].iteritems(), - key=lambda (k, v): float(k), + self.orderbook['bids'].items(), + key=lambda k_v1: float(k_v1[0]), reverse=True, )) self.orderbook['asks'].update(asks_changes) - for k, v in self.orderbook['asks'].iteritems(): + for k, v in self.orderbook['asks'].items(): if v == "0": self.orderbook['asks'].pop(k) # Re-sort the asks. self.orderbook['asks'] = OrderedDict( - sorted(self.orderbook['asks'].iteritems(), key=lambda (k, v): float(k)), + sorted(self.orderbook['asks'].items(), key=lambda k_v: float(k_v[0])), ) def parse_orders(self, orders): @@ -247,7 +247,7 @@ def get_orderbook_to_publish(self): price_key_orderbook = self.orderbook return { - 'bids': [[k, v, ''] for k, v in price_key_orderbook['bids'].iteritems()], - 'asks': [[k, v, ''] for k, v in price_key_orderbook['asks'].iteritems()], + 'bids': [[k, v, ''] for k, v in price_key_orderbook['bids'].items()], + 'asks': [[k, v, ''] for k, v in price_key_orderbook['asks'].items()], } diff --git a/gryphon/data_service/pollers/orderbook/websocket/coinbase_orderbook_websocket.py b/gryphon/data_service/pollers/orderbook/websocket/coinbase_orderbook_websocket.py index 18e3fe5..aefb1cd 100755 --- a/gryphon/data_service/pollers/orderbook/websocket/coinbase_orderbook_websocket.py +++ b/gryphon/data_service/pollers/orderbook/websocket/coinbase_orderbook_websocket.py @@ -309,13 +309,13 @@ def get_orderbook_to_publish(self): sorted_bid_keys = sorted( fancy_orderbook['bids'].keys(), - key=lambda (k): float(k), + key=lambda k: float(k), reverse=True, ) sorted_ask_keys = sorted( fancy_orderbook['asks'].keys(), - key=lambda (k): float(k), + key=lambda k: float(k), ) bids = [[k, str(fancy_orderbook['bids'][k]), ''] for k in sorted_bid_keys] diff --git a/gryphon/data_service/pollers/trades/trades_poller.py b/gryphon/data_service/pollers/trades/trades_poller.py index 0a802de..38d7462 100755 --- a/gryphon/data_service/pollers/trades/trades_poller.py +++ b/gryphon/data_service/pollers/trades/trades_poller.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import json +from six import text_type import termcolor as tc from twisted.internet import defer from twisted.internet.task import LoopingCall @@ -50,9 +51,9 @@ def parse_response(self, resp_obj): for trade in trades: if trade['trade_id'] > self.most_recent_trade_id: trade['price_currency'] = trade['price'].currency - trade['price'] = unicode(trade['price'].amount) + trade['price'] = text_type(trade['price'].amount) trade['volume_currency'] = trade['volume'].currency - trade['volume'] = unicode(trade['volume'].amount) + trade['volume'] = text_type(trade['volume'].amount) trade['timestamp'] = int(trade['timestamp']) trade_string = json.dumps(trade, ensure_ascii=False) self.producer.publish_message(trade_string) diff --git a/gryphon/data_service/runt.py b/gryphon/data_service/runt.py index 53ec662..2f78aed 100755 --- a/gryphon/data_service/runt.py +++ b/gryphon/data_service/runt.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import logging import logging.handlers import os diff --git a/gryphon/data_service/scripts/autobahn-tester.py b/gryphon/data_service/scripts/autobahn-tester.py index 9680871..af6dcf6 100755 --- a/gryphon/data_service/scripts/autobahn-tester.py +++ b/gryphon/data_service/scripts/autobahn-tester.py @@ -1,3 +1,4 @@ +from __future__ import print_function ############################################################################### ## ## Copyright (C) 2011-2013 Tavendo GmbH diff --git a/gryphon/data_service/scripts/benchmark.py b/gryphon/data_service/scripts/benchmark.py index a347bb7..d7f2cd5 100755 --- a/gryphon/data_service/scripts/benchmark.py +++ b/gryphon/data_service/scripts/benchmark.py @@ -1,3 +1,4 @@ +from __future__ import print_function # Simple test script for benchmarking regular python logging vs twisted's logging. import logging @@ -25,7 +26,7 @@ def tx_log(): def stop(): - print "Log Counter: %s" % log_counter + print("Log Counter: %s" % log_counter) reactor.stop() diff --git a/gryphon/data_service/scripts/historical_trade_collector.py b/gryphon/data_service/scripts/historical_trade_collector.py index 8c93789..5bf99c5 100755 --- a/gryphon/data_service/scripts/historical_trade_collector.py +++ b/gryphon/data_service/scripts/historical_trade_collector.py @@ -1,3 +1,4 @@ +from __future__ import print_function import csv from datetime import timedelta import gzip @@ -161,7 +162,7 @@ def get_our_recorded_ticker_volume_for_period(exchange, start_date, end_date): def audit_ticker_volume_individual_days(exchange_list, start_date=test_start_date, end_date=test_end_date): d = start_date while d < test_end_date: - print '\n\nAuditing: %s' % d + print('\n\nAuditing: %s' % d) day_after = d + timedelta(days=1) audit_all_ticker_volume(exchange_list, d, day_after) d = day_after @@ -191,12 +192,12 @@ def audit_ticker_volume(exchange, start_date, end_date): end_date, ) - print '%s Our Volume:%s Ticker Volume:%s, Accuracy: %s' % ( + print('%s Our Volume:%s Ticker Volume:%s, Accuracy: %s' % ( exchange, our_volume, ticker_volume, our_volume / ticker_volume, - ) + )) def audit_bw_volume(exchange, start_date, end_date): @@ -204,7 +205,7 @@ def audit_bw_volume(exchange, start_date, end_date): bw_volume = bw_exchange.volume_in_period(start_date, end_date) our_volume = get_our_recorded_exchange_trade_volume_for_period(exchange, start_date, end_date) - print '%s Our Volume:%s BW Volume:%s, Accuracy: %s' % (exchange, our_volume, bw_volume, our_volume / bw_volume) + print('%s Our Volume:%s BW Volume:%s, Accuracy: %s' % (exchange, our_volume, bw_volume, our_volume / bw_volume)) def compare_all_exchanges(): @@ -222,15 +223,15 @@ def compare_ours_to_history(our_exchange_id, exchange, price_currency, volume_cu start = parse('2015-11-27 0:0:0').datetime.replace(tzinfo=None) end = parse('2015-11-27 11:59:59').datetime.replace(tzinfo=None) - print our_exchange_id.upper() + print(our_exchange_id.upper()) hist_in_range = [t for t in hist_trades if t[0] >= start and t[0] <= end] ours_in_range = [t for t in our_trades if t[0] >= start and t[0] <= end] for t in hist_in_range: if t not in ours_in_range: - print 'Hist Trade not in ours: %s' % t + print('Hist Trade not in ours: %s' % t) for t in ours_in_range: if t not in hist_in_range: - print'Our trade not in history: %s' % t - print'\n\n\n\n\n' + print('Our trade not in history: %s' % t) + print('\n\n\n\n\n') diff --git a/gryphon/data_service/trades_consumer.py b/gryphon/data_service/trades_consumer.py index 0f2f99b..3c6f757 100755 --- a/gryphon/data_service/trades_consumer.py +++ b/gryphon/data_service/trades_consumer.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import json import os @@ -6,6 +6,7 @@ from delorean import epoch from raven import Client +from six import text_type from sqlalchemy import exc from gryphon.data_service.consts import * @@ -27,9 +28,9 @@ def trades_consumer_function(message, db): t = Trade( price=Money(trade_json['price'], price_currency), volume=Money(trade_json['volume'], volume_currency), - exchange=unicode(trade_json['exchange']), + exchange=text_type(trade_json['exchange']), timestamp=timestamp, - exchange_trade_id=unicode(trade_json['trade_id']), + exchange_trade_id=text_type(trade_json['trade_id']), ) db.add(t) diff --git a/gryphon/execution/app.py b/gryphon/execution/app.py index f0faa36..e4fea72 100755 --- a/gryphon/execution/app.py +++ b/gryphon/execution/app.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import importlib import logging @@ -132,7 +132,7 @@ def strategy(self): command_line_configuration = config_helper.get_command_line_configuration( self.app.pargs, - self.app.args.unknown_args, + self.app.args.unknown_args, ) final_configuration = config_helper.combine_file_and_command_line_config( diff --git a/gryphon/execution/bots/overwatch.py b/gryphon/execution/bots/overwatch.py index ab6912a..6d00863 100755 --- a/gryphon/execution/bots/overwatch.py +++ b/gryphon/execution/bots/overwatch.py @@ -220,7 +220,7 @@ def check_spreads_are_normal(db): sanity = True - for exchange_name, fv in native_fvs.iteritems(): + for exchange_name, fv in native_fvs.items(): if abs(fv - current_core_fv) > INTER_EXCHANGE_SPREAD_THRESHOLD: sanity = False break diff --git a/gryphon/execution/bots/shoebox.py b/gryphon/execution/bots/shoebox.py index 0c89cc0..6fb70c7 100755 --- a/gryphon/execution/bots/shoebox.py +++ b/gryphon/execution/bots/shoebox.py @@ -301,7 +301,7 @@ def manual_btc_withdrawals(db): logger.info('Running manual BTC withdrawals') - for name, target in MANUAL_BTC_EXCHANGES.iteritems(): + for name, target in MANUAL_BTC_EXCHANGES.items(): exchange_db = exchange_factory.make_exchange_data_from_key(name, db) if exchange_db.balance['BTC'] > target: withdrawal_amount = exchange_db.balance['BTC'] - target diff --git a/gryphon/execution/console.py b/gryphon/execution/console.py index 9ab2e7b..4edbdef 100755 --- a/gryphon/execution/console.py +++ b/gryphon/execution/console.py @@ -14,7 +14,7 @@ strategy config files. """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from datetime import datetime, timedelta import logging diff --git a/gryphon/execution/controllers/balance.py b/gryphon/execution/controllers/balance.py index 1365c5a..a642e11 100755 --- a/gryphon/execution/controllers/balance.py +++ b/gryphon/execution/controllers/balance.py @@ -1,3 +1,4 @@ +from __future__ import print_function from gryphon.execution.lib.exchange_color import exchange_color from gryphon.lib.exchange.exchange_factory import * from gryphon.lib.logger import get_logger diff --git a/gryphon/execution/controllers/create_dashboard_user.py b/gryphon/execution/controllers/create_dashboard_user.py index 7beefd4..f1141e8 100755 --- a/gryphon/execution/controllers/create_dashboard_user.py +++ b/gryphon/execution/controllers/create_dashboard_user.py @@ -5,11 +5,14 @@ Usage: gryphon-exec create-dashboard-user [--execute] """ +from __future__ import print_function import getpass import termcolor as tc import os +from six.moves import input + from gryphon.lib import session from gryphon.dashboards.models.user import User from gryphon.dashboards.models.columns.password_column import Password @@ -43,29 +46,29 @@ def main(execute): - print tc.colored(WARNING_MESSAGE, 'red') - informed_consent = raw_input(WARNING_PROMPT) + print(tc.colored(WARNING_MESSAGE, 'red')) + informed_consent = input(WARNING_PROMPT).strip() if informed_consent != 'y': - print EXIT_MESSAGE + print(EXIT_MESSAGE) return else: - print CONTINUE_MESSAGE + print(CONTINUE_MESSAGE) dashboard_db = session.get_a_dashboard_db_mysql_session() - username = raw_input(ENTER_USERNAME_MESSAGE) + username = input(ENTER_USERNAME_MESSAGE).strip() password_text = getpass.getpass(ENTER_PASSWORD_MESSAGE) password = Password(plain=password_text) - + user = User(username, password) if execute is True: dashboard_db.add(user) dashboard_db.commit() - print tc.colored(SUCCESS_MESSAGE, 'green') + print(tc.colored(SUCCESS_MESSAGE, 'green')) else: - print SUCCESS_NO_EXECUTE_MESSAGE - + print(SUCCESS_NO_EXECUTE_MESSAGE) + diff --git a/gryphon/execution/controllers/fee_buyback.py b/gryphon/execution/controllers/fee_buyback.py index 78a03c3..dd66301 100755 --- a/gryphon/execution/controllers/fee_buyback.py +++ b/gryphon/execution/controllers/fee_buyback.py @@ -1,3 +1,4 @@ +from __future__ import print_function import prompter import termcolor as tc @@ -14,7 +15,7 @@ def buyback(): prompt_msg = tc.colored('Did you stop the Coinbase Bot before running this?', 'red') bot_stopped = prompter.yesno(prompt_msg) if not bot_stopped: - print tc.colored('Go stop the bot first.', 'red') + print(tc.colored('Go stop the bot first.', 'red')) return db = session.get_a_trading_db_mysql_session() @@ -33,7 +34,7 @@ def buyback(): transactions_buyback_amount = sum([t.fee for t in transactions_with_outstanding_fees]) btc_buyback_amount = trades_buyback_amount + transactions_buyback_amount - print 'Go buy %s on Coinbase (not the exchange)' % btc_buyback_amount + print('Go buy %s on Coinbase (not the exchange)' % btc_buyback_amount) prompt_msg = 'How much USD did it cost (total including Coinbase Fee): USD' raw_usd_cost = prompter.prompt(prompt_msg) diff --git a/gryphon/execution/controllers/initialize_ledger.py b/gryphon/execution/controllers/initialize_ledger.py index 029a8d0..4a0ab82 100755 --- a/gryphon/execution/controllers/initialize_ledger.py +++ b/gryphon/execution/controllers/initialize_ledger.py @@ -15,8 +15,9 @@ [comma-separated list of exchange pairs, e.g. 'bitstamp_btc_usd,gemini_btc_usd'] [--execute] """ +from __future__ import print_function -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import os @@ -53,7 +54,7 @@ def initialize_exchange_ledger(db, wrapper_obj): pass finally: if db_obj is not None: - print ALREADY_INITIALIZED_ERR_MESSAGE % wrapper_obj.name + print(ALREADY_INITIALIZED_ERR_MESSAGE % wrapper_obj.name) return # Create the entry in the Exchange table. @@ -66,12 +67,12 @@ def initialize_exchange_ledger(db, wrapper_obj): try: balance = wrapper_obj.get_balance() except KeyError as e: - print NO_API_CREDENTIALS_ERR_MESSAGE % wrapper_obj.name - print e + print(NO_API_CREDENTIALS_ERR_MESSAGE % wrapper_obj.name) + print(e) return except Exception as e: - print UNKNOWN_ERR_MESSAGE % wrapper_obj.name - print e + print(UNKNOWN_ERR_MESSAGE % wrapper_obj.name) + print(e) return price_currency = wrapper_obj.currency diff --git a/gryphon/execution/controllers/order_book.py b/gryphon/execution/controllers/order_book.py index 83b3a5e..70539dd 100755 --- a/gryphon/execution/controllers/order_book.py +++ b/gryphon/execution/controllers/order_book.py @@ -1,3 +1,4 @@ +from __future__ import print_function import termcolor as tc from gryphon.execution.lib.exchange_color import exchange_color, legend @@ -96,7 +97,7 @@ def order_book(exchange_name, include_our_orders=False, include_fees=False): for order in asks + bids: order.apply_fee() - print + print() # if we are showing a consolidated orderbook if not exchange_name: print(legend() + "\n") diff --git a/gryphon/execution/controllers/run_migrations.py b/gryphon/execution/controllers/run_migrations.py index 8697b31..b0eb9b0 100755 --- a/gryphon/execution/controllers/run_migrations.py +++ b/gryphon/execution/controllers/run_migrations.py @@ -6,7 +6,7 @@ gryphon-exec run-migrations [GDS | TRADING | DASHBOARD] [--execute] """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import logging import os @@ -45,7 +45,7 @@ def run_migrations(target_db): location = resource_filename(PACKAGE_NAME, DASHBOARD_CONFIG_RELATIVE_PATH) elif target_db == TRADING_DB_NAME: location = resource_filename(PACKAGE_NAME, TRADING_CONFIG_RELATIVE_PATH) - + alembic_cfg = Config(location) command.upgrade(alembic_cfg, 'head') diff --git a/gryphon/execution/harness/exchange_coordinator.pyx b/gryphon/execution/harness/exchange_coordinator.pyx index e36071c..08c19a5 100755 --- a/gryphon/execution/harness/exchange_coordinator.pyx +++ b/gryphon/execution/harness/exchange_coordinator.pyx @@ -13,9 +13,7 @@ it makes sure that our database does not get out of sync with our our account wi exchange. """ -import pyximport; pyximport.install() - -from sets import Set +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from cdecimal import Decimal, ROUND_UP, ROUND_DOWN from delorean import Delorean @@ -62,7 +60,7 @@ class ExchangeCoordinator(object): # or audit() for this exchange. Potentially, we could make this even less # strict, setting this to False whenever there are no orders left on the books. self.is_active = False - + """ This actually means that we won't audit in no-execute mode. We do want audits to take place even if nothing has happened... hmm... @@ -81,9 +79,9 @@ class ExchangeCoordinator(object): @tick_profile def _get_current_orders(self, exchange_open_orders): db_open_orders = self._get_db_open_orders() - db_open_order_ids = Set([o.exchange_order_id for o in db_open_orders]) + db_open_order_ids = set([o.exchange_order_id for o in db_open_orders]) - exchange_open_order_ids = Set([o['id'] for o in exchange_open_orders]) + exchange_open_order_ids = set([o['id'] for o in exchange_open_orders]) eaten_order_ids = db_open_order_ids - exchange_open_order_ids current_order_ids = db_open_order_ids & exchange_open_order_ids @@ -144,7 +142,7 @@ class ExchangeCoordinator(object): )[0] # Partially filled. - if (current_order_from_exchange['volume_remaining'] + if (current_order_from_exchange['volume_remaining'] < current_order_from_db.volume_remaining): details_result = self.get_multi_order_details( @@ -225,8 +223,8 @@ class ExchangeCoordinator(object): def update_position(self, position_change, position_change_no_fees): """ Formerly harness:update_position. - """ - for currency_code, position in position_change.iteritems(): + """ + for currency_code, position in position_change.items(): self.exchange_account.position[currency_code] += position self.exchange_account.balance[currency_code] += position @@ -315,7 +313,7 @@ class ExchangeCoordinator(object): '1', self.exchange_wrapper.currency, ).to('USD').amount - + if extra_data: order.datums = self._create_datums_from_extra_data(extra_data) @@ -507,7 +505,7 @@ class ExchangeCoordinator(object): self.reopen_orders(e.exchange, failed_order_ids) # There aren't any open orders because we're in an audit. - eaten_order_ids, current_orders = self._get_current_orders([]) + eaten_order_ids, current_orders = self._get_current_orders([]) self._run_accounting(eaten_order_ids, current_orders) # Now we retry the original audit. If it fails again this will cause a diff --git a/gryphon/execution/harness/harness.pyx b/gryphon/execution/harness/harness.pyx index e0d88e0..dba2d34 100755 --- a/gryphon/execution/harness/harness.pyx +++ b/gryphon/execution/harness/harness.pyx @@ -11,12 +11,12 @@ backtesting. For this, you can write another harness (so long as it conforms to interface), and reimplement the interface functions in a different way. """ -from sets import Set import termcolor as tc import time from cdecimal import ROUND_UP, ROUND_DOWN from delorean import Delorean +from six import text_type from sqlalchemy.orm import joinedload from gryphon.execution.lib import auditing @@ -227,7 +227,7 @@ class Harness(ConfigurableObject): This function simply attaches the date and colours to a log message, and then dispatches to the appropriate logger function. """ - timestamp = unicode(Delorean().datetime.strftime('%d/%m/%y %H:%M:%S %Z')) + timestamp = text_type(Delorean().datetime.strftime('%d/%m/%y %H:%M:%S %Z')) result_string = u'[%s] (%s) %s' % ( self.strategy.name if self.strategy else 'HARNESS_SETUP', diff --git a/gryphon/execution/lib/auditing.py b/gryphon/execution/lib/auditing.py index 1e5a9dd..3f1571e 100755 --- a/gryphon/execution/lib/auditing.py +++ b/gryphon/execution/lib/auditing.py @@ -150,7 +150,7 @@ def order_audit(db, exchange, skip_recent=0, tolerance=Decimal('0')): failed_order_data = [] - for exchange_order_id, exchange_volume_filled in audit_data.iteritems(): + for exchange_order_id, exchange_volume_filled in audit_data.items(): try: db_volume_filled = db_order_hash[exchange_order_id] @@ -287,7 +287,7 @@ def balance_equality(balance_a, balance_b): are fixing it here with the intention of a later fix to the core lib. """ - currencies = set(balance_a.keys() + balance_b.keys()) + currencies = set(list(balance_a.keys()) + list(balance_b.keys())) for currency in currencies: if currency in balance_a and currency in balance_b: diff --git a/gryphon/execution/lib/config.py b/gryphon/execution/lib/config.py index ffb1d2e..9580330 100755 --- a/gryphon/execution/lib/config.py +++ b/gryphon/execution/lib/config.py @@ -1,4 +1,5 @@ -import ConfigParser +from __future__ import print_function +from six.moves.configparser import RawConfigParser from gryphon.lib.logger import get_logger @@ -6,9 +7,9 @@ def get_config_var(filepath, section, key): - print filepath + print(filepath) - config = ConfigParser.RawConfigParser() + config = RawConfigParser() config.read(filepath) section_dict = dict(config.items('live')) diff --git a/gryphon/execution/lib/config_helper.py b/gryphon/execution/lib/config_helper.py index 4da43d2..ddf0bc3 100755 --- a/gryphon/execution/lib/config_helper.py +++ b/gryphon/execution/lib/config_helper.py @@ -6,7 +6,7 @@ Just a few functions that make our configuration handling cleaner. -The rule is: +The rule is: 1) From any source, if something isn't specified explicitly, it is left out of the dictionary, or put as None, and any other value from any source will override it. @@ -14,7 +14,6 @@ 3) At no point is there a any guarantee a setting is in the configuration object. """ -import ConfigParser import argparse from cdecimal import Decimal, InvalidOperation @@ -70,7 +69,7 @@ def parse_extra_strategy_args(args): """ settings = [x for x in args if x[:2] == '--'] - + parser = argparse.ArgumentParser() for setting_name in settings: @@ -86,7 +85,7 @@ def parse_extra_strategy_args(args): def get_conf_file_configuration(conf_filename, strategy_name): """ If there was a config file specified, load it. If not, look for [strategy_name].conf - in the current directory. If neither is found just return an initialized + in the current directory. If neither is found just return an initialized configuration object that is otherwise empty. """ diff --git a/gryphon/execution/lib/tick_profiling.py b/gryphon/execution/lib/tick_profiling.py index 9595fa7..968fb70 100755 --- a/gryphon/execution/lib/tick_profiling.py +++ b/gryphon/execution/lib/tick_profiling.py @@ -21,7 +21,7 @@ def record_tick_data(tick_start, strategy_name): def record_tick_block_data(algo, tick_count, strategy_name): - for function_name, profile_times in tick_profile_data.iteritems(): + for function_name, profile_times in tick_profile_data.items(): datum_name = datum_name_for_function_block(strategy_name, function_name) for block_time in profile_times: diff --git a/gryphon/execution/live_runner.py b/gryphon/execution/live_runner.py index 78e448d..e134b60 100755 --- a/gryphon/execution/live_runner.py +++ b/gryphon/execution/live_runner.py @@ -1,4 +1,5 @@ -import pyximport; pyximport.install() +from __future__ import print_function +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from cdecimal import Decimal import inspect import os @@ -192,7 +193,7 @@ def exception_retry_loop(harness, sentry, db): return - # This is necessary to flush local db cache and pick up changes other processes + # This is necessary to flush local db cache and pick up changes other processes # have made. For example, if this is a balance mismatch which was fixed by the # withdrawal tool. session.commit_mysql_session(db) @@ -253,7 +254,7 @@ def live_run(configuration): while True: try: tick_start = Delorean().epoch - print '\n\n%s' % strategy.name + print('\n\n%s' % strategy.name) if warm_shutdown_flag: return # This takes us into the finally block. diff --git a/gryphon/execution/migrations/env.py b/gryphon/execution/migrations/env.py index 1f2c073..152ff4a 100755 --- a/gryphon/execution/migrations/env.py +++ b/gryphon/execution/migrations/env.py @@ -1,5 +1,5 @@ from __future__ import with_statement -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from alembic import context from sqlalchemy import engine_from_config, pool, create_engine from logging.config import fileConfig @@ -72,9 +72,9 @@ def run_migrations_online(): and associate a connection with the context. """ - + engine = create_engine(os.environ.get('TRADING_DB_CRED')) - + # engine = engine_from_config( # config.get_section(config.config_ini_section), # prefix='sqlalchemy.', diff --git a/gryphon/execution/models/backtesting/result.py b/gryphon/execution/models/backtesting/result.py index f9bee4c..a393a2e 100755 --- a/gryphon/execution/models/backtesting/result.py +++ b/gryphon/execution/models/backtesting/result.py @@ -2,6 +2,7 @@ from datetime import datetime import uuid +from six import text_type from sqlalchemy import Column, Unicode, UnicodeText, DateTime, Integer, Numeric from sqlalchemy.orm import relationship, backref @@ -23,11 +24,11 @@ class Result(Base): _usd = Column('usd', Numeric(precision=20, scale=10)) _btc = Column('btc', Numeric(precision=20, scale=10)) time_created = Column(DateTime, nullable=False) - + trades = relationship('ResultTrade', cascade="all,delete-orphan", backref='result') - + def __init__(self, usd, btc, trading_volume, algorithm, batch, ticks): - self.unique_id = unicode(uuid.uuid4().hex) + self.unique_id = text_type(uuid.uuid4().hex) self.time_created = datetime.utcnow() self.algorithm = algorithm self.batch = batch @@ -35,7 +36,7 @@ def __init__(self, usd, btc, trading_volume, algorithm, batch, ticks): self.btc = btc self.ticks = ticks self.trading_volume = trading_volume - + @property def trading_volume(self): return Money(self._trading_volume, 'BTC') @@ -43,7 +44,7 @@ def trading_volume(self): @trading_volume.setter def trading_volume(self, value): self._trading_volume = value.amount - + @property def btc(self): return Money(self._btc, 'BTC') @@ -59,4 +60,4 @@ def usd(self): @usd.setter def usd(self, value): self._usd = value.amount - + diff --git a/gryphon/execution/scripts/itbit_auth_test.py b/gryphon/execution/scripts/itbit_auth_test.py index 08cdaac..ff91f34 100755 --- a/gryphon/execution/scripts/itbit_auth_test.py +++ b/gryphon/execution/scripts/itbit_auth_test.py @@ -2,6 +2,7 @@ This is a minimal script that demonstrates authentication on itbit. This is useful for debugging if you ever run into issues with authenticating on itbit. """ +from __future__ import print_function import base64 import hashlib @@ -59,5 +60,5 @@ def main(script_arguments, execute): full_url = 'https://api.itbit.com/v1' + url - print requests.get(full_url, data=request_args).text + print(requests.get(full_url, data=request_args).text) diff --git a/gryphon/execution/scripts/ledger_export.py b/gryphon/execution/scripts/ledger_export.py index edf29bc..a2b9354 100755 --- a/gryphon/execution/scripts/ledger_export.py +++ b/gryphon/execution/scripts/ledger_export.py @@ -182,7 +182,7 @@ def table_entries_from_transaction(transaction): entry['date'] = date entry['details'] = ''.join([ '%s:%s ' % (k, v) - for k, v in transaction.transaction_details.iteritems() + for k, v in transaction.transaction_details.items() if k in ['external_transaction_id', 'notes'] and v not in ['xxx'] ]) @@ -238,7 +238,7 @@ def export_ledger_for_exchange(exchange_name, start_time, end_time): fiat_balance, date, ) - + filename = '%s_ledger_%s_%s.csv' % ( exchange_name.lower(), start_time.strftime('%Y-%m-%d'), diff --git a/gryphon/execution/scripts/reset_balance.py b/gryphon/execution/scripts/reset_balance.py index 1c005aa..fd64b79 100755 --- a/gryphon/execution/scripts/reset_balance.py +++ b/gryphon/execution/scripts/reset_balance.py @@ -16,7 +16,7 @@ account database object. It's really just a cache. """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import os import sys diff --git a/gryphon/execution/strategies/base.pyx b/gryphon/execution/strategies/base.pyx index ab1d3ec..fed7a2a 100755 --- a/gryphon/execution/strategies/base.pyx +++ b/gryphon/execution/strategies/base.pyx @@ -1,4 +1,3 @@ -import ConfigParser from delorean import Delorean import pickle import random @@ -41,7 +40,7 @@ class Strategy(ConfigurableObject): # Exchanges that the strategy declares it's interested in up-front. It's # convenient to have these at startup sometimes. - self.target_exchanges = [] + self.target_exchanges = [] if strategy_configuration: self.configure(strategy_configuration) @@ -99,8 +98,8 @@ class Strategy(ConfigurableObject): Use it for things that aren't mission-critical, like to make log messages nice. """ return self.__class__.__name__ - - @property + + @property def position(self): if self._position is not None: return self._position diff --git a/gryphon/execution/strategies/builtin/fundamental_value/v1.py b/gryphon/execution/strategies/builtin/fundamental_value/v1.py index 76c1ab9..17c9baa 100755 --- a/gryphon/execution/strategies/builtin/fundamental_value/v1.py +++ b/gryphon/execution/strategies/builtin/fundamental_value/v1.py @@ -30,7 +30,7 @@ def calculate(algo, fundamental_value_balance_map): # Determine which exchanges should participate in the bid and which in the ask # and sum them up appropriately. - for exchange_name, exchange in fundamental_value_balance_map.iteritems(): + for exchange_name, exchange in fundamental_value_balance_map.items(): # You may sell if you have enough bitcoin to place an order and don't have # too much fiat. if (exchange[algo.volume_currency.lower()] > buffer_value and diff --git a/gryphon/execution/strategies/builtin/fundamental_value/v2.py b/gryphon/execution/strategies/builtin/fundamental_value/v2.py index 1526dff..6c8e433 100755 --- a/gryphon/execution/strategies/builtin/fundamental_value/v2.py +++ b/gryphon/execution/strategies/builtin/fundamental_value/v2.py @@ -20,7 +20,7 @@ def calculate(algo, fundamental_value_balance_map): participating_exchanges = [] - for exchange_name, exchange in fundamental_value_balance_map.iteritems(): + for exchange_name, exchange in fundamental_value_balance_map.items(): # If you have bitcoin and are below your maximum fiat, you can sell. can_sell = ( exchange[algo.volume_currency.lower()] > buffer_value and diff --git a/gryphon/execution/strategies/builtin/fundamental_value/v3.py b/gryphon/execution/strategies/builtin/fundamental_value/v3.py index e8b7004..334d8b4 100755 --- a/gryphon/execution/strategies/builtin/fundamental_value/v3.py +++ b/gryphon/execution/strategies/builtin/fundamental_value/v3.py @@ -34,7 +34,7 @@ def calculate(algo, fundamental_value_balance_map): # Determine which exchanges should participate in the bid and which in the ask # and sum them up appropriately. - for exchange_name, exchange in fundamental_value_balance_map.iteritems(): + for exchange_name, exchange in fundamental_value_balance_map.items(): # You may sell if you have enough bitcoin to place an order and don't have # too much fiat. exchange_weight = conf.fv_v3_weights[algo.volume_currency][exchange_name] diff --git a/gryphon/lib/__init__.py b/gryphon/lib/__init__.py index adac250..f345a4f 100755 --- a/gryphon/lib/__init__.py +++ b/gryphon/lib/__init__.py @@ -1,3 +1,4 @@ +from __future__ import print_function __version__ = '0.1' def main(): diff --git a/gryphon/lib/analysis/legacy/average_true_range.py b/gryphon/lib/analysis/legacy/average_true_range.py index b6572ef..2e7a57f 100755 --- a/gryphon/lib/analysis/legacy/average_true_range.py +++ b/gryphon/lib/analysis/legacy/average_true_range.py @@ -1,3 +1,4 @@ +from __future__ import print_function import numpy as np from exponential_moving_average import ExpMovingAverage @@ -12,9 +13,9 @@ def TR(d,c,h,l,o,yc): y = abs(h-yc) z = abs(l-yc) - print x - print y - print z + print(x) + print(y) + print(z) if y <= x >= z: TR = x @@ -23,7 +24,7 @@ def TR(d,c,h,l,o,yc): elif x <= z >= y: TR = z - print d, TR + print(d, TR) return d, TR x = 1 @@ -39,7 +40,7 @@ def TR(d,c,h,l,o,yc): -print len(TrueRanges) +print(len(TrueRanges)) ATR = ExpMovingAverage(TrueRanges,14) -print ATR +print(ATR) diff --git a/gryphon/lib/analysis/legacy/chaikin_volatility.py b/gryphon/lib/analysis/legacy/chaikin_volatility.py index fa0f210..609b342 100755 --- a/gryphon/lib/analysis/legacy/chaikin_volatility.py +++ b/gryphon/lib/analysis/legacy/chaikin_volatility.py @@ -1,3 +1,4 @@ +from __future__ import print_function import numpy as np import time @@ -32,10 +33,10 @@ def chaikinVolCalc(emaUsed,periodsAgo): highMlow.append(hml) x += 1 - print len(date) - print len(highMlow) + print(len(date)) + print(len(highMlow)) highMlowEMA = ExpMovingAverage(highMlow,emaUsed) - print len(highMlowEMA) + print(len(highMlowEMA)) y = emaUsed + periodsAgo while y < len(date): @@ -43,7 +44,7 @@ def chaikinVolCalc(emaUsed,periodsAgo): chaikin_volatility.append(cvc) y+=1 - print len(date[emaUsed+periodsAgo:]) + print(len(date[emaUsed+periodsAgo:])) return date[emaUsed+periodsAgo:], chaikin_volatility diff --git a/gryphon/lib/analysis/legacy/chart.py b/gryphon/lib/analysis/legacy/chart.py index b5d121f..a4ce791 100755 --- a/gryphon/lib/analysis/legacy/chart.py +++ b/gryphon/lib/analysis/legacy/chart.py @@ -61,6 +61,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ''' +from __future__ import print_function +from __future__ import absolute_import import urllib2 import time @@ -72,8 +74,8 @@ from matplotlib.finance import candlestick import matplotlib import pylab -from simple_moving_average import movingaverage -from rsi import rsiFunc +from .simple_moving_average import movingaverage +from .rsi import rsiFunc matplotlib.rcParams.update({'font.size': 9}) @@ -207,8 +209,8 @@ def graphData(stock,MA1,MA2): plt.show() fig.savefig('example.png',facecolor=fig.get_facecolor()) - except Exception,e: - print 'main loop',str(e) + except Exception as e: + print('main loop',str(e)) while True: graphData('YHOO',10,50) diff --git a/gryphon/lib/analysis/legacy/ease_of_movement.py b/gryphon/lib/analysis/legacy/ease_of_movement.py index a33bb1e..0201e64 100755 --- a/gryphon/lib/analysis/legacy/ease_of_movement.py +++ b/gryphon/lib/analysis/legacy/ease_of_movement.py @@ -1,3 +1,4 @@ +from __future__ import print_function import numpy as np import time @@ -25,13 +26,13 @@ def EMV(d,c,h,l,o,v,tf): boxr = ( (v[x]/1000000.00)/ (h[x]-l[x]) ) OnepEMVs = movement / boxr OnepEMV.append(OnepEMVs) - print OnepEMVs + print(OnepEMVs) x += 1 tfEMV = movingaverage(OnepEMV,tf) - print len(tfEMV) - print len(d[tf:]) + print(len(tfEMV)) + print(len(d[tf:])) return d[tf:],tfEMV diff --git a/gryphon/lib/analysis/legacy/elder_force_index.py b/gryphon/lib/analysis/legacy/elder_force_index.py index 408620c..45daac5 100755 --- a/gryphon/lib/analysis/legacy/elder_force_index.py +++ b/gryphon/lib/analysis/legacy/elder_force_index.py @@ -1,3 +1,4 @@ +from __future__ import print_function import numpy as np import time @@ -23,7 +24,7 @@ def EFI(d,c,v,tf): x = 1 while x < len(d): forceIndex = (c[x] - c[x-1]) * v[x] - print forceIndex + print(forceIndex) efi.append(forceIndex) x+=1 efitf = ExpMovingAverage(efi,tf) diff --git a/gryphon/lib/analysis/legacy/gapo.py b/gryphon/lib/analysis/legacy/gapo.py index ab5e4cc..ca0c077 100755 --- a/gryphon/lib/analysis/legacy/gapo.py +++ b/gryphon/lib/analysis/legacy/gapo.py @@ -1,3 +1,4 @@ +from __future__ import print_function import numpy as np import time import math @@ -23,7 +24,7 @@ def GAPO(d,h,l,tf): gapos = ( (math.log(HighestHigh - LowestLow)) / math.log(tf)) - print gapos + print(gapos) gapo.append(gapos) x+=1 return d[tf:],gapo diff --git a/gryphon/lib/analysis/legacy/swing_index.py b/gryphon/lib/analysis/legacy/swing_index.py index 0ce4d21..d465850 100755 --- a/gryphon/lib/analysis/legacy/swing_index.py +++ b/gryphon/lib/analysis/legacy/swing_index.py @@ -1,3 +1,4 @@ +from __future__ import print_function #November 11th 2013: open1 = 1286.50 high1 = 1287.70 @@ -18,25 +19,25 @@ def calc_R(H2,C1,L2,O1,LM): x = H2-C1 y = L2-C1 z = H2-L2 - print x - print y - print z + print(x) + print(y) + print(z) if z < x > y: - print 'x wins!' + print('x wins!') R = (H2-C1)-(.5*(L2-C1))+(.25*(C1-O1)) - print R + print(R) return R elif x < y > z: - print 'y wins!' + print('y wins!') R = (L2-C1)-(.5*(H2-C1))+(.25*(C1-O1)) - print R + print(R) return R elif x < z > y: - print 'z wins!' + print('z wins!') R = (H2-L2)+(.25*(C1-O1)) - print R + print(R) return R @@ -46,11 +47,11 @@ def calc_K(H2,L2,C1): if x > y: K=x - print K + print(K) return K elif x < y: K=y - print K + print(K) return K L = LM @@ -58,8 +59,8 @@ def calc_K(H2,L2,C1): K = calc_K(H2,L2,C1) SwIn = 50*((C2-C1+(.5*(C2-O2))+(.25*(C1-O1)))/R)*(K/L) - print '###' - print SwIn + print('###') + print(SwIn) diff --git a/gryphon/lib/analysis/legacy/volatility.py b/gryphon/lib/analysis/legacy/volatility.py index 9bba332..b33af31 100755 --- a/gryphon/lib/analysis/legacy/volatility.py +++ b/gryphon/lib/analysis/legacy/volatility.py @@ -339,15 +339,15 @@ def volatility(values, timestamps, window_time=10000): for j in range(len(timestamps)): index = j+i if index > len(timestamps)-1: - break + break elif noted_timestamp - timestamps[index] < window_time: relevant_values.append(values[index]) relevant_timestamps.append(noted_timestamp - timestamps[index]) else: break - - standard_deviation = np.std(relevant_values) - mean = np.mean(relevant_values) + + standard_deviation = numpy.std(relevant_values) + mean = numpy.mean(relevant_values) #volatility = Decimal(standard_deviation)/Decimal(mean) vols.append(standard_deviation) vols.reverse() diff --git a/gryphon/lib/arbitrage.py b/gryphon/lib/arbitrage.py index cd5aaf9..96c4aa1 100755 --- a/gryphon/lib/arbitrage.py +++ b/gryphon/lib/arbitrage.py @@ -61,7 +61,14 @@ def price_currency(self): def profit(self): return self.revenue - self.fees - def __nonzero__(self): + def __nonzero__(self): # Python 2 + """ + A cross is falsy if there is no overlap volume. + """ + return bool(self.volume) + + + def __bool__(self): # Python 3 """ A cross is falsy if there is no overlap volume. """ diff --git a/gryphon/lib/bitcoinwisdom.py b/gryphon/lib/bitcoinwisdom.py index dc2271a..c837167 100755 --- a/gryphon/lib/bitcoinwisdom.py +++ b/gryphon/lib/bitcoinwisdom.py @@ -23,7 +23,7 @@ def __init__(self, exchange='bitstamp'): self.symbol = 'btccad' elif self.exchange == 'kraken': self.symbol = 'btceur' - + self.steps ={ '1m': 60,'3m': 180,'5m': 300,'15m': 900,'30m':1800, '1h':3600,'2h':7200,'4h':14400,'6h':21600,'12h':43200, @@ -32,7 +32,7 @@ def __init__(self, exchange='bitstamp'): # currently caching for a day, maybe longer in the future @cache_me(time=86400, ignore_self=True) - def req_with_cache(self, url): + def req_with_cache(self, url): return self.req(url) def req(self, url): @@ -47,7 +47,7 @@ def create_url(self, step): url = 'period?step=%s&symbol=%s%s' % (step_seconds, self.exchange, self.symbol) url = self.base_url % url return url - + def determine_step(self, start_date, end_date): if (end_date - start_date) >= timedelta(days=1): step = '1d' @@ -56,8 +56,8 @@ def determine_step(self, start_date, end_date): else: step = '1m' return step - - + + def period(self, start_date, end_date, step='1d', sid=''): if self.should_cache_this_result(start_date, end_date): points = self.req_with_cache(self.create_url(step)) @@ -70,7 +70,7 @@ def period(self, start_date, end_date, step='1d', sid=''): for p in points: point_hash[epoch(p[0]).naive] = Money(str(p[7]), 'BTC') return point_hash - + def volume_in_period(self, start_date, end_date): start_date = Delorean(start_date, 'UTC').datetime @@ -83,7 +83,7 @@ def volume_in_period(self, start_date, end_date): step=self.determine_step(start_date, end_date), ) - for k,v in periods.iteritems(): + for k, v in periods.items(): t=Delorean(k, 'UTC').datetime vol=v if t >= start_date and t < end_date: diff --git a/gryphon/lib/configuration.py b/gryphon/lib/configuration.py index c3547f4..2d9c496 100755 --- a/gryphon/lib/configuration.py +++ b/gryphon/lib/configuration.py @@ -4,8 +4,8 @@ import argparse from collections import defaultdict -import ConfigParser -import StringIO +import six +from six.moves.configparser import ConfigParser, RawConfigParser from cdecimal import Decimal, InvalidOperation @@ -19,7 +19,7 @@ def read_config_from_file(config_filename): Section titles of the form [x:y] are parsed into sub-dictionaries under the key x. """ - parser = ConfigParser.RawConfigParser() + parser = RawConfigParser() parser.read(config_filename) configuration = parse_sections(parser) @@ -31,8 +31,8 @@ def _get_parser_for_string_config(string_config): """ This should only be used for unit testing. """ - buf = StringIO.StringIO(string_config) - parser = ConfigParser.ConfigParser() + buf = six.StringIO(string_config) + parser = ConfigParser() parser.readfp(buf) return parser @@ -112,6 +112,6 @@ def dict_update_override(dicta, dictb): iii) does override a valid value in a with a valid value from b """ dicta.update( - {k: v for k, v in dictb.iteritems() if v or (k not in dicta)} + {k: v for k, v in dictb.items() if v or (k not in dicta)} ) diff --git a/gryphon/lib/debugging/bitstamp_cert_error.py b/gryphon/lib/debugging/bitstamp_cert_error.py index 7b28087..e33709f 100755 --- a/gryphon/lib/debugging/bitstamp_cert_error.py +++ b/gryphon/lib/debugging/bitstamp_cert_error.py @@ -1,7 +1,7 @@ """ Prepared by Gareth MacLeod, 3 April 2018. -This demonstrates that python 2.7 is having series issues with authenticated requests +This demonstrates that python 2.7 is having series issues with authenticated requests to the bitstamp API. This script fails on fresh installs of Ubuntu 14.04 LTS and 16 LTS. The deepest I've gotten into this bug is this: the requests.Session() object can make @@ -44,6 +44,7 @@ Make sure you have yoru bitstamp credentials in a .env file in the directory you are running from. """ +from __future__ import print_function import requests import hmac @@ -54,6 +55,7 @@ import dotenv import os import os.path +from six import text_type dotenv_path = os.path.join(os.path.dirname(__file__), '.env') dotenv.load_dotenv(dotenv_path) @@ -67,10 +69,10 @@ def requests_dot_post(): - print '---' - print "Trying requests.post" + print('---') + print("Trying requests.post") - nonce = unicode(int(round(time.time() * 1000))) + nonce = text_type(int(round(time.time() * 1000))) message = nonce + CLIENT_ID + API_KEY sig = hmac.new(SECRET, msg=message, digestmod=hashlib.sha256).hexdigest().upper() @@ -82,30 +84,30 @@ def requests_dot_post(): result = requests.post(API_BALANCE_URL, data=payload).text - print 'Response from bitstamp: %s' % result[:50] + print('Response from bitstamp: %s' % result[:50]) try: assert('btc_available' in result) - print 'requests.post succeeded!' + print('requests.post succeeded!') except Exception as e: - print 'requests.post failed: %s' % str(e) + print('requests.post failed: %s' % str(e)) def session_post(session=None, clear_cookies=None): - print '---' + print('---') if session is None: - print "Trying with a new session" + print("Trying with a new session") session = requests.Session() else: - print "Trying with an extant session" + print("Trying with an extant session") if clear_cookies is True: - print "Clearing the session's cookies" + print("Clearing the session's cookies") session.cookies.clear() - nonce = unicode(int(round(time.time() * 1000))) + nonce = text_type(int(round(time.time() * 1000))) message = nonce + CLIENT_ID + API_KEY sig = hmac.new(SECRET, msg=message, digestmod=hashlib.sha256).hexdigest().upper() @@ -117,13 +119,13 @@ def session_post(session=None, clear_cookies=None): result = session.post(API_BALANCE_URL, payload).text - print 'Response from bitstamp: %s' % result[:50] + print('Response from bitstamp: %s' % result[:50]) try: assert('btc_available' in result) - print 'Session succeeded!' + print('Session succeeded!') except Exception as e: - print 'Session failed: %s' % str(e) + print('Session failed: %s' % str(e)) return session diff --git a/gryphon/lib/exchange/bitfinex_btc_usd.py b/gryphon/lib/exchange/bitfinex_btc_usd.py index 4c5f148..f002667 100755 --- a/gryphon/lib/exchange/bitfinex_btc_usd.py +++ b/gryphon/lib/exchange/bitfinex_btc_usd.py @@ -9,6 +9,7 @@ import cdecimal from cdecimal import Decimal from delorean import Delorean, parse +from six import string_types, text_type from gryphon.lib.exchange import exceptions from gryphon.lib.exchange.consts import Consts @@ -90,13 +91,13 @@ def trades_for_orders_req(self): return self.all_trades_req() def trades_for_orders_resp(self, req, order_ids): - order_ids = [unicode(o) for o in order_ids] + order_ids = [text_type(o) for o in order_ids] trades = self.all_trades_resp(req) matching_trades = {} for trade in trades: - oid = unicode(trade['order_id']) + oid = text_type(trade['order_id']) if oid in order_ids: if not oid in matching_trades: matching_trades[oid] = [] @@ -262,7 +263,7 @@ def multi_order_details_req(self): return self.trades_for_orders_req() def multi_order_details_resp(self, req, order_ids): - order_ids = [unicode(o) for o in order_ids] + order_ids = [text_type(o) for o in order_ids] multi_trades = self.trades_for_orders_resp(req, order_ids) data = {} @@ -294,7 +295,7 @@ def multi_order_details_resp(self, req, order_ids): our_trades.append({ 'time': int(float(t['timestamp'])), - 'trade_id': unicode(t['tid']), + 'trade_id': text_type(t['tid']), 'fee': fee, 'btc': btc_amount, 'fiat': usd_amount, @@ -328,7 +329,7 @@ def cancel_order_resp(self, req): return {'success': True} def withdraw_crypto_req(self, address, volume): - if not isinstance(address, basestring): + if not isinstance(address, string_types): raise TypeError('Withdrawal address must be a string') if not isinstance(volume, Money) or volume.currency != 'BTC': diff --git a/gryphon/lib/exchange/bitme.py b/gryphon/lib/exchange/bitme.py index ca11d00..953f044 100755 --- a/gryphon/lib/exchange/bitme.py +++ b/gryphon/lib/exchange/bitme.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from __future__ import absolute_import import time import os import datetime @@ -15,9 +16,9 @@ from gryphon.lib.exchange.consts import Consts from gryphon.lib.money import Money -from base import * -from exceptions import * -from exchange_order import Order +from .base import * +from .exceptions import * +from .exchange_order import Order from gryphon.lib.models.exchange import Balance from cdecimal import * diff --git a/gryphon/lib/exchange/bitstamp_btc_usd.py b/gryphon/lib/exchange/bitstamp_btc_usd.py index 5dc8484..987f223 100755 --- a/gryphon/lib/exchange/bitstamp_btc_usd.py +++ b/gryphon/lib/exchange/bitstamp_btc_usd.py @@ -12,6 +12,7 @@ from delorean import Delorean, epoch from requests_futures.sessions import FuturesSession from requests_toolbelt.cookies.forgetful import ForgetfulCookieJar +from six import text_type from gryphon.lib.exchange import exceptions from gryphon.lib.exchange import order_types @@ -111,9 +112,9 @@ def get_ticker_resp(self, req): } def order_is_open(self, order_id): - order_id = unicode(order_id) + order_id = text_type(order_id) open_orders = self.open_orders() - matching_orders = [o for o in open_orders if unicode(o.get('id')) == order_id] + matching_orders = [o for o in open_orders if text_type(o.get('id')) == order_id] is_open = len(matching_orders) > 0 return is_open @@ -154,13 +155,13 @@ def trades_for_orders_req(self): return self.all_trades_req() def trades_for_orders_resp(self, req, order_ids): - order_ids = [unicode(o) for o in order_ids] + order_ids = [text_type(o) for o in order_ids] trades = self.all_trades_resp(req) matching_trades = {} for trade in trades: - oid = unicode(trade['order_id']) + oid = text_type(trade['order_id']) if oid in order_ids: if oid not in matching_trades: @@ -194,7 +195,7 @@ def auth_request(self, req_method, url, request_args): payload = request_args['data'] = {} # TODO: fix nonce collisions - nonce = unicode(int(round(time.time() * 1000))) + nonce = text_type(int(round(time.time() * 1000))) message = nonce + self.client_id + self.api_key sig = hmac.new( @@ -289,7 +290,7 @@ def place_order_resp(self, req): response = self.resp(req) try: - return {'success': True, 'order_id': unicode(response['id'])} + return {'success': True, 'order_id': text_type(response['id'])} except KeyError: raise exceptions.ExchangeAPIErrorException( self, @@ -339,7 +340,7 @@ def get_multi_order_details_req(self): return self.trades_for_orders_req() def get_multi_order_details_resp(self, req, order_ids): - order_ids = [unicode(o) for o in order_ids] + order_ids = [text_type(o) for o in order_ids] multi_trades = self.trades_for_orders_resp(req, order_ids) data = {} @@ -377,7 +378,7 @@ def get_multi_order_details_resp(self, req, order_ids): our_trades.append({ 'time': int(parse(t['datetime']).epoch), - 'trade_id': unicode(t['id']), + 'trade_id': text_type(t['id']), 'fee': fee, vol_currency_key: volume_currency_amount, 'fiat': price_currency_amount, diff --git a/gryphon/lib/exchange/buttercoin.py b/gryphon/lib/exchange/buttercoin.py index f8d38b6..728cf79 100755 --- a/gryphon/lib/exchange/buttercoin.py +++ b/gryphon/lib/exchange/buttercoin.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from __future__ import absolute_import import time import os import datetime @@ -14,9 +15,9 @@ from gryphon.lib.exchange.consts import Consts from gryphon.lib.money import Money -from base import * -from exceptions import * -from exchange_order import Order +from .base import * +from .exceptions import * +from .exchange_order import Order from gryphon.lib.models.exchange import Balance from gryphon.lib.models.datum import DatumRecorder diff --git a/gryphon/lib/exchange/cavirtex.py b/gryphon/lib/exchange/cavirtex.py index 6e0cc14..682aa35 100755 --- a/gryphon/lib/exchange/cavirtex.py +++ b/gryphon/lib/exchange/cavirtex.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from __future__ import absolute_import import time import os import datetime @@ -15,9 +16,9 @@ from gryphon.lib.exchange.consts import Consts from gryphon.lib.money import Money -from exchange_order import Order -from base import * -from exceptions import * +from .exchange_order import Order +from .base import * +from .exceptions import * from gryphon.lib.models.exchange import Balance from cdecimal import * diff --git a/gryphon/lib/exchange/coinbase_btc_usd.py b/gryphon/lib/exchange/coinbase_btc_usd.py index dd5b44f..636eed7 100755 --- a/gryphon/lib/exchange/coinbase_btc_usd.py +++ b/gryphon/lib/exchange/coinbase_btc_usd.py @@ -12,6 +12,7 @@ from cdecimal import Decimal import coinbase.client +from six import string_types, text_type from gryphon.lib.exchange import exceptions from gryphon.lib.exchange import order_types @@ -298,7 +299,7 @@ def auth_request(self, req_method, url, request_args): self.load_creds() req_method = req_method.upper() - timestamp = unicode(int(round(time.time()))) + timestamp = text_type(int(round(time.time()))) # This has already been dumped to json by req(). body = request_args['data'] @@ -538,7 +539,7 @@ def cancel_order_resp(self, req): raise exceptions.CancelOrderNotFoundError() def withdraw_crypto(self, address, volume): - if not isinstance(address, basestring): + if not isinstance(address, string_types): raise TypeError('Withdrawal address must be a string') if not isinstance(volume, Money) or volume.currency != 'BTC': diff --git a/gryphon/lib/exchange/exchange_order.pyx b/gryphon/lib/exchange/exchange_order.pyx index 829ab8d..be9c0c3 100755 --- a/gryphon/lib/exchange/exchange_order.pyx +++ b/gryphon/lib/exchange/exchange_order.pyx @@ -1,3 +1,5 @@ +from six import text_type + from gryphon.lib.money import Money from gryphon.lib.exchange.consts import Consts @@ -14,8 +16,8 @@ class Order(object): CANCELLED = u'CANCELLED' # we use this to flag our orders in an orderbook FLAGGED = u'FLAGGED' - - + + def __init__(self, price, volume, exchange, type, order_id=None, status=None): self.status = status if status else Order.OPEN self.order_id = order_id @@ -29,33 +31,33 @@ class Order(object): (self.type, self.exchange.name, self.volume, self.price, self.status, self.order_id)) def __repr__(self): - return "<" + unicode(self) + ">" + return "<" + text_type(self) + ">" def __eq__(self, other): - return (self.order_id == other.order_id and - self.price == other.price and - self.volume == other.volume and + return (self.order_id == other.order_id and + self.price == other.price and + self.volume == other.volume and self.type == other.type and self.exchange == other.exchange) - + def __lt__(self, other): return self.price < other.price - + def apply_fee(self): if self.type == Order.ASK: self.price += (self.price * self.exchange.fee) elif self.type == Order.BID: self.price -= (self.price * self.exchange.fee) - - + + @staticmethod def scopy(order_to_copy): return Order( order_to_copy.price, order_to_copy.volume, - order_to_copy.exchange, + order_to_copy.exchange, order_to_copy.type, - order_to_copy.order_id, + order_to_copy.order_id, order_to_copy.status) @staticmethod @@ -63,8 +65,8 @@ class Order(object): return Order( Money(order_to_copy.price.amount, order_to_copy.price.currency), Money(order_to_copy.volume.amount, order_to_copy.volume.currency), - order_to_copy.exchange, + order_to_copy.exchange, order_to_copy.type, - order_to_copy.order_id, + order_to_copy.order_id, order_to_copy.status) diff --git a/gryphon/lib/exchange/exchange_trade.pyx b/gryphon/lib/exchange/exchange_trade.pyx index 89bec25..55c8750 100755 --- a/gryphon/lib/exchange/exchange_trade.pyx +++ b/gryphon/lib/exchange/exchange_trade.pyx @@ -1,25 +1,26 @@ import uuid +from six import text_type from gryphon.lib.exchange.base import Exchange from gryphon.lib.exchange.consts import Consts class Trade(object): - __slots__ = ('ask', 'volume', 'trade_id', 'price', 'bid', 'tick') - def __init__(self, price, volume, bid_order, ask_order, trade_id=uuid.uuid4().hex, tick=0): - + __slots__ = ('ask', 'volume', 'trade_id', 'price', 'bid', 'tick') + def __init__(self, price, volume, bid_order, ask_order, trade_id=uuid.uuid4().hex, tick=0): + self.trade_id = trade_id self.bid = bid_order self.ask = ask_order self.price = price self.volume = volume self.tick = tick - + def __str__(self): - return (u'[EXCHANGE Trade] - [%s BTC @ %s USD/BTC] - Bid:%s, Ask:%s' % + return (u'[EXCHANGE Trade] - [%s BTC @ %s USD/BTC] - Bid:%s, Ask:%s' % (self.volume, self.price, self.bid.order_id, self.ask.order_id)) def __repr__(self): - return "<" + unicode(self) + ">" - + return "<" + text_type(self) + ">" + @property def trade_type(self): if self.bid.order_id: diff --git a/gryphon/lib/exchange/gemini_btc_usd.py b/gryphon/lib/exchange/gemini_btc_usd.py index e3ba828..e005987 100755 --- a/gryphon/lib/exchange/gemini_btc_usd.py +++ b/gryphon/lib/exchange/gemini_btc_usd.py @@ -11,6 +11,7 @@ import time from cdecimal import * +from six import text_type from gryphon.lib.exchange.consts import Consts from gryphon.lib.exchange.exchange_api_wrapper import ExchangeAPIWrapper @@ -146,13 +147,13 @@ def trades_for_orders_req(self): return self.all_trades_req() def trades_for_orders_resp(self, req, order_ids): - order_ids = [unicode(o) for o in order_ids] + order_ids = [text_type(o) for o in order_ids] trades = self.all_trades_resp(req) matching_trades = {} for trade in trades: - oid = unicode(trade['order_id']) + oid = text_type(trade['order_id']) if oid in order_ids: if not oid in matching_trades: @@ -270,7 +271,7 @@ def get_multi_order_details_req(self): return self.trades_for_orders_req() def get_multi_order_details_resp(self, req, order_ids): - order_ids = [unicode(o) for o in order_ids] + order_ids = [text_type(o) for o in order_ids] multi_trades = self.trades_for_orders_resp(req, order_ids) data = {} @@ -296,7 +297,7 @@ def get_multi_order_details_resp(self, req, order_ids): our_trades.append({ 'time': int(float(t['timestamp'])), - 'trade_id': unicode(t['tid']), + 'trade_id': text_type(t['tid']), 'fee': fee, self.volume_currency.lower(): volume_amount, 'fiat': price_currency_amount, diff --git a/gryphon/lib/exchange/itbit_btc_usd.py b/gryphon/lib/exchange/itbit_btc_usd.py index 4634c99..d1c5621 100755 --- a/gryphon/lib/exchange/itbit_btc_usd.py +++ b/gryphon/lib/exchange/itbit_btc_usd.py @@ -13,6 +13,7 @@ import cdecimal from cdecimal import Decimal +from six import string_types from gryphon.lib.exchange import exceptions from gryphon.lib.exchange import order_types @@ -438,7 +439,7 @@ def cancel_order_resp(self, req): return {'success': True} def withdraw_crypto_req(self, address, volume): - if not isinstance(address, basestring): + if not isinstance(address, string_types): raise TypeError('Withdrawal address must be a string') if not isinstance(volume, Money) or volume.currency != self.volume_currency: @@ -469,7 +470,7 @@ def get_order_audit_data(self, skip_recent=0, page=1): Dropped the skip_recent flag because we don't seem to be using it anywhere. """ if skip_recent != 0: - raise ValueEror('skip_recent is deprecated') + raise ValueError('skip_recent is deprecated') orders = OrderedDict() trades_to_audit = self.all_trades(page=page) diff --git a/gryphon/lib/exchange/kraken_btc_eur.py b/gryphon/lib/exchange/kraken_btc_eur.py index 5437039..db91471 100755 --- a/gryphon/lib/exchange/kraken_btc_eur.py +++ b/gryphon/lib/exchange/kraken_btc_eur.py @@ -10,6 +10,7 @@ from cdecimal import Decimal from delorean import Delorean from more_itertools import chunked +from six import string_types, text_type from gryphon.lib.exchange import exceptions from gryphon.lib.exchange import order_types @@ -147,7 +148,7 @@ def get_trades_info_from_ledger(self, trade_ids, order_open_timestamp, order_clo 'fiat_fee': Money(0, self.currency), } - for ledger_id, entry in entries.iteritems(): + for ledger_id, entry in entries.items(): trade_id = entry['refid'] if trade_id not in trade_ids: @@ -263,7 +264,7 @@ def closed_orders_resp(self, req): count = int(response['count']) closed_orders = [] - for order_id, raw_order in response['closed'].iteritems(): + for order_id, raw_order in response['closed'].items(): raw_order['order_id'] = order_id closed_orders.append(raw_order) @@ -288,7 +289,7 @@ def auth_request(self, req_method, url, request_args): endpoint = url.replace(self.base_url, '') endpoint = '/0' + endpoint - nonce = unicode(int(round(time.time() * 1000))) + nonce = text_type(int(round(time.time() * 1000))) try: payload = request_args['data'] @@ -374,8 +375,8 @@ def place_order_req(self, mode, volume, price, order_type=order_types.LIMIT_ORDE 'pair': self.pair, 'type': mode, 'ordertype': 'limit', - 'price': unicode(price.amount), - 'volume': unicode(volume.amount), + 'price': text_type(price.amount), + 'volume': text_type(volume.amount), } except AttributeError: @@ -387,7 +388,7 @@ def place_order_resp(self, req): response = self.resp(req) try: - return {'success': True, 'order_id': unicode(response['txid'][0])} + return {'success': True, 'order_id': text_type(response['txid'][0])} except KeyError: raise exceptions.ExchangeAPIErrorException( self, @@ -405,7 +406,7 @@ def get_open_orders_resp(self, req): try: raw_open_orders = response['open'] - for order_id, raw_order in raw_open_orders.iteritems(): + for order_id, raw_order in raw_open_orders.items(): if raw_order['status'] == 'open': mode = self._order_mode_to_const(raw_order['descr']['type']) volume = Money(raw_order['vol'], 'BTC') @@ -437,13 +438,13 @@ def get_order_details_req(self, order_id): def get_order_details_resp(self, req, order_id): return self.get_multi_order_details_resp(req, [order_id])[order_id] - + def get_multi_order_details(self, order_ids): req = self.get_multi_order_details_req(order_ids) return self.get_multi_order_details_resp(req, order_ids) - + def get_multi_order_details_req(self, order_ids): - order_ids = [unicode(o) for o in order_ids] + order_ids = [text_type(o) for o in order_ids] payload = { 'trades': True, @@ -482,7 +483,7 @@ def get_multi_order_details_resp(self, req, order_ids): closetm, ) - for t_id, t in trades.iteritems(): + for t_id, t in trades.items(): fiat = abs(t['fiat']) btc = abs(t['btc']) @@ -504,7 +505,7 @@ def get_multi_order_details_resp(self, req, order_ids): our_trades.append({ 'time': int(t['time']), - 'trade_id': unicode(t_id), + 'trade_id': text_type(t_id), 'fee': fee, 'btc': btc, 'fiat': fiat, @@ -522,7 +523,7 @@ def get_multi_order_details_resp(self, req, order_ids): def cancel_order_req(self, order_id): payload = { - 'txid': unicode(order_id), + 'txid': text_type(order_id), } return self.req('post', '/private/CancelOrder', data=payload) @@ -539,7 +540,7 @@ def cancel_order_resp(self, req): ) def withdraw_crypto_req(self, address, volume): - if not isinstance(address, basestring): + if not isinstance(address, string_types): raise TypeError('Withdrawal address must be a string') if self.volume_currency != 'BTC': @@ -554,12 +555,12 @@ def withdraw_crypto_req(self, address, volume): # find the corresponding exchange name, which we then pass to Kraken. deposit_addresses = { name: addr - for name, addr in os.environ.iteritems() if '_DEPOSIT_ADDRESS' in name + for name, addr in os.environ.items() if '_DEPOSIT_ADDRESS' in name } address_to_name_map = { addr: name.replace('_DEPOSIT_ADDRESS', '') - for name, addr in deposit_addresses.iteritems() + for name, addr in deposit_addresses.items() } try: diff --git a/gryphon/lib/exchange/okcoin_btc_usd.py b/gryphon/lib/exchange/okcoin_btc_usd.py index 63afabd..beb1ff6 100755 --- a/gryphon/lib/exchange/okcoin_btc_usd.py +++ b/gryphon/lib/exchange/okcoin_btc_usd.py @@ -5,6 +5,7 @@ import cdecimal from cdecimal import Decimal from delorean import Delorean, parse +from six import string_types from gryphon.lib.exchange import exceptions from gryphon.lib.exchange.consts import Consts @@ -138,7 +139,7 @@ def ticker_resp(self, req): def all_transactions(self, page=0, unfilled_orders=None): req = self.all_transactions_req( - page=page, + page=page, unfilled_orders=unfilled_orders ) @@ -183,7 +184,7 @@ def auth_request(self, req_method, url, request_args): payload = request_args['data'] except KeyError: payload = request_args['data'] = {} - + payload.update({ 'api_key': self.api_key, }) @@ -232,7 +233,7 @@ def balance_resp(self, req): def _get_order_book_req(self, verify=True): return self.req('get', '/depth.do', no_auth=True, verify=verify) - + def create_trade_req(self, mode, volume, price, is_market_order=False): volume = self.round(volume) price = self.round(price) @@ -257,7 +258,7 @@ def create_trade_resp(self, req): try: return { - 'success': True, + 'success': True, 'order_id': str(response['order_id']) } @@ -283,7 +284,7 @@ def order_fee_req(self, order_id): def order_fee_resp(self, req): try: response = self.resp(req) - except CancelOrderNotFoundError: + except exceptions.CancelOrderNotFoundError: # OkCoin has started returning this error on non-executed orders or orders # with no fees. return Money('0', 'USD') @@ -418,7 +419,7 @@ def multi_order_details_resp(self, reqs, order_ids_not_used): for order_id, req in reqs['fees'].items(): response = self.order_fee_resp(req) fees[order_id] = response - + data = {} for raw_order in raw_orders: @@ -431,7 +432,7 @@ def multi_order_details_resp(self, reqs, order_ids_not_used): def parse_raw_order(self, raw_order, fee): mode = self._order_mode_to_const(raw_order['type']) - + timestamp = int(float(raw_order['create_date'])) / 1000 btc_total = Money(raw_order['deal_amount'], 'BTC') @@ -440,7 +441,7 @@ def parse_raw_order(self, raw_order, fee): total_usd = self.round(avg_price * btc_total.amount) # okcoin does not have seperate notions of trade and raw_order - # so if we see a partially filled raw_order here, treat it as a + # so if we see a partially filled raw_order here, treat it as a # full trade trades = [] @@ -452,7 +453,7 @@ def parse_raw_order(self, raw_order, fee): 'fee': fee, 'btc': btc_total, 'fiat': total_usd, - } + } trades.append(fake_trade) @@ -468,7 +469,7 @@ def parse_raw_order(self, raw_order, fee): return order def cancel_order_req(self, order_id): - payload = { + payload = { 'symbol': 'btc_usd', 'order_id': order_id, } @@ -480,7 +481,7 @@ def cancel_order_resp(self, req): return {'success': True} def withdraw_crypto_req(self, address, volume): - if not isinstance(address, basestring): + if not isinstance(address, string_types): raise TypeError('Withdrawal address must be a string') if not isinstance(volume, Money) or volume.currency != self.volume_currency: @@ -526,7 +527,7 @@ def audit(self, skip_recent=0): status = order['status'] volume_filled = Money(order['deal_amount'], 'BTC') - if (status == self.ORDER_STATUS_PARTIALLY_FILLED + if (status == self.ORDER_STATUS_PARTIALLY_FILLED or status == self.ORDER_STATUS_FULLY_FILLED): orders[order_id] = volume_filled diff --git a/gryphon/lib/exchange/poloniex_eth_btc.py b/gryphon/lib/exchange/poloniex_eth_btc.py index 3ed8b1b..160d1be 100755 --- a/gryphon/lib/exchange/poloniex_eth_btc.py +++ b/gryphon/lib/exchange/poloniex_eth_btc.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from __future__ import absolute_import import base64 from collections import OrderedDict import decimal @@ -9,8 +10,8 @@ from cdecimal import * -from base import * -from exceptions import * +from .base import * +from .exceptions import * from gryphon.lib.models.exchange import Balance from gryphon.lib.money import Money diff --git a/gryphon/lib/exchange/quadriga_btc_cad.py b/gryphon/lib/exchange/quadriga_btc_cad.py index 54ee2c6..5811b26 100755 --- a/gryphon/lib/exchange/quadriga_btc_cad.py +++ b/gryphon/lib/exchange/quadriga_btc_cad.py @@ -8,6 +8,7 @@ from cdecimal import * from delorean import Delorean from collections import OrderedDict, defaultdict +from six import text_type from gryphon.lib.exchange import exceptions from gryphon.lib.exchange import order_types @@ -85,13 +86,13 @@ def transactions_req(self): } return self.req('post', '/user_transactions', data=payload) - + def transactions_resp(self, req): return self.resp(req) - + def transactions(self): - return self.transactions_resp(self.transactions_req()) - + return self.transactions_resp(self.transactions_req()) + def trades(self): raw_transactions = self.transactions() trades = [] @@ -135,21 +136,21 @@ def trades(self): else: raise exceptions.ExchangeAPIErrorException( self, - 'Zero volume Trade #%s, so API doesn\'t tell us the side.' % ( + 'Zero volume Trade #%s, so API doesn\'t tell us the side.' % ( raw_transaction['id'], )) trades.append({ 'time': self._datetime_to_timestamp(raw_transaction['datetime']), - 'trade_id': unicode(raw_transaction['id']), - 'order_id': unicode(raw_transaction['order_id']), + 'trade_id': text_type(raw_transaction['id']), + 'order_id': text_type(raw_transaction['order_id']), 'btc': btc, 'fiat': fiat, 'fee': fee, }) return trades - + def trades_for_order(self, order_id): trades = self.trades() return [t for t in trades if t['order_id'] == order_id] @@ -177,7 +178,7 @@ def auth_request(self, req_method, url, request_args): except KeyError: payload = request_args['data'] = {} - nonce = unicode(int(round(time.time() * 1000))) + nonce = text_type(int(round(time.time() * 1000))) message= nonce + self.api_key + self.client_id sig = hmac.new( @@ -191,7 +192,7 @@ def auth_request(self, req_method, url, request_args): 'key': self.api_key, 'signature':sig }) - + def get_balance_req(self): return self.req('post', '/balance') @@ -209,10 +210,10 @@ def get_balance_resp(self, req): data['CAD'] = cad_balance return data - + def _get_orderbook_from_api_req(self, verify=True): return self.req('get', '/order_book', no_auth=True, verify=verify) - + def place_order_req(self, mode, volume, price, order_type=order_types.LIMIT_ORDER): payload = { 'amount': '%.8f' % volume.amount, @@ -230,16 +231,16 @@ def place_order_resp(self, req): response = self.resp(req) try: - return {'success': True, 'order_id': unicode(response['id'])} + return {'success': True, 'order_id': text_type(response['id'])} except KeyError: raise exceptions.ExchangeAPIErrorException( self, 'response does not contain an order_id. Response: %s' % response, ) - + def get_open_orders_req(self): return self.req('post', '/open_orders') - + def get_open_orders_resp(self, req): raw_open_orders = self.resp(req) raw_open_orders = raw_open_orders if raw_open_orders else [] @@ -262,14 +263,14 @@ def get_open_orders_resp(self, req): def get_order_details(self, order_id): req = self.get_order_details_req(order_id) return self.get_order_details_resp(req) - + def get_order_details_req(self, order_id): payload = { - 'id': unicode(order_id), + 'id': text_type(order_id), } return self.req('post', '/lookup_order', data=payload) - + def get_order_details_resp(self, req): order = self.resp(req) @@ -277,7 +278,7 @@ def get_order_details_resp(self, req): order = order[0] except KeyError as e: ExchangeAPIErrorException(self, 'malformed response: %s' % order) - + trades = self.trades_for_order(order['id']) time_created = self._datetime_to_timestamp(order['created']) mode = self._order_mode_to_const(str(order['type'])) @@ -291,7 +292,7 @@ def get_order_details_resp(self, req): } return result - + def get_multi_order_details_req(self, order_ids): data = {} @@ -299,7 +300,7 @@ def get_multi_order_details_req(self, order_ids): data[oid] = self.get_order_details_req(oid) return data - + def get_multi_order_details_resp(self, reqs): data = {} @@ -310,7 +311,7 @@ def get_multi_order_details_resp(self, reqs): def get_ticker_req(self, verify=True): return self.req('get', '/ticker', no_auth=True, verify=verify) - + def get_ticker_resp(self, req): response = self.resp(req) @@ -320,14 +321,14 @@ def get_ticker_resp(self, req): 'last': Money(response['last'], 'CAD'), 'volume': Money(response['volume'], 'BTC'), } - + def cancel_order_req(self, order_id): payload = { 'id': order_id, } return self.req('post', '/cancel_order', data=payload) - + def cancel_order_resp(self, req): response = self.resp(req) return {'success': True} @@ -352,12 +353,12 @@ def withdraw_crypto_resp(self, req): def get_order_audit_data(self, skip_recent=0): """ - Returns an OrderedDict of order ids mapped to their filled volume (only include + Returns an OrderedDict of order ids mapped to their filled volume (only include orders that have some trades) - """ + """ orders = OrderedDict() trades_to_audit = self.trades() - + # Trades from the same order aren't guaranteed to be next to each other, so we # need to group them. trades_to_audit.sort(key=lambda t:(t['time']), reverse=True) @@ -369,7 +370,7 @@ def get_order_audit_data(self, skip_recent=0): except KeyError: orders[order_id] = abs(trade['btc']) - # Remove the oldest 2 orders, because its trades might be wrapped around a page + # Remove the oldest 2 orders, because its trades might be wrapped around a page # gap this would give us an innacurate volume_filled number. We need to remove # 2 because there could be an ask and a bid try: diff --git a/gryphon/lib/exchange/vault_of_satoshi.py b/gryphon/lib/exchange/vault_of_satoshi.py index 27aa51c..cddadfd 100755 --- a/gryphon/lib/exchange/vault_of_satoshi.py +++ b/gryphon/lib/exchange/vault_of_satoshi.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from __future__ import absolute_import import time import os import datetime @@ -15,10 +16,10 @@ from gryphon.lib.money import Money from gryphon.lib.models.datum import DatumRecorder -from exchange_order import Order +from .exchange_order import Order from gryphon.lib.exchange.consts import Consts -from base import * -from exceptions import * +from .base import * +from .exceptions import * from gryphon.lib.models.exchange import Balance from gryphon.lib.logger import get_logger diff --git a/gryphon/lib/gryphonfury/fees.py b/gryphon/lib/gryphonfury/fees.py index a2a8256..e3e08c0 100755 --- a/gryphon/lib/gryphonfury/fees.py +++ b/gryphon/lib/gryphonfury/fees.py @@ -2,6 +2,8 @@ from sqlalchemy import func +#from gryphon.lib.gryphonfury.revenue import (get_start_and_end_position, +# get_start_and_end_position_trades) from gryphon.lib.logger import get_logger from gryphon.lib.models.order import Order from gryphon.lib.models.trade import Trade @@ -97,6 +99,9 @@ def get_matched_trading_fees_in_period(db, start_time, end_time): of the period are removed. """ + global get_start_and_end_position # workaround for circular imports + global get_start_and_end_position_trades # workaround for circular imports + fees = get_all_fees_in_period_in_usd(db, start_time, end_time) start_position, end_position = get_start_and_end_position(db, start_time, end_time) diff --git a/gryphon/lib/gryphonfury/revenue.py b/gryphon/lib/gryphonfury/revenue.py index bd7a6fe..538ebf6 100755 --- a/gryphon/lib/gryphonfury/revenue.py +++ b/gryphon/lib/gryphonfury/revenue.py @@ -28,7 +28,7 @@ def fast_revenue_in_period(db, start_time, end_time): better queries. Previous function is roughly O(n^2) in the number of trades in the period and this one is likely O(logn) for a low constant. - Refer to the helper function + Refer to the helper function get_revenue_in_period_given_positions_and_position_trades to see the heavy lifting """ @@ -341,7 +341,7 @@ def open_pl(open_position_trades, fundamental_value, price_currency=None, volume Take in an open_position_trades object and the current fundamental value, and use that to calculate our current unrealized profit on that position. This is done simply because the fiat position on those open_position_trades is the price we - paid to open that position, and then the unrealized profit is our current + paid to open that position, and then the unrealized profit is our current expectation of the value of that position (position * fundamental_value). """ @@ -592,12 +592,12 @@ def open_position_trades(open_position_offset, db, start_time, volume_currency=' # Filter out trades we already got. query = query.filter( ~Trade.unique_id.in_([t.unique_id for t in open_position_trades]) - ) + ) trades_batch = query.limit(10).all() for trade in trades_batch: - if (sum([t.volume for t in open_position_trades]) + if (sum([t.volume for t in open_position_trades]) < abs(open_position_offset)): open_position_trades.append(trade) diff --git a/gryphon/lib/hackernewsie.py b/gryphon/lib/hackernewsie.py index 666600c..c6cf29c 100755 --- a/gryphon/lib/hackernewsie.py +++ b/gryphon/lib/hackernewsie.py @@ -27,7 +27,7 @@ def get_hn_breaking_news(keywords={'bitcoin': 3, 'bitstamp': 0}): one_day_ago = Delorean().last_day(1).epoch - for keyword, upvote_threshold in keywords.iteritems(): + for keyword, upvote_threshold in keywords.items(): # We quote the keywords so they don't match things that are close # Prompted by Bitcoin matching Ditchin (https://news.ycombinator.com/item?id=10850368) keyword = '"%s"' % keyword diff --git a/gryphon/lib/models/atlaszero/base.py b/gryphon/lib/models/atlaszero/base.py index 6b768cf..4d2e807 100755 --- a/gryphon/lib/models/atlaszero/base.py +++ b/gryphon/lib/models/atlaszero/base.py @@ -4,6 +4,7 @@ # share some table names. # Reference: http://stackoverflow.com/questions/8264686/sqlalchemy-multiple-databases-with-same-table-names-not-working +from six import text_type from sqlalchemy.ext.declarative import declarative_base AtlasZeroBase = declarative_base() @@ -11,7 +12,7 @@ def unicode_string(self): - return unicode(self).encode('utf-8') + return text_type(self).encode('utf-8') AtlasZeroBase.__str__ == unicode_string diff --git a/gryphon/lib/models/atlaszero/metric.py b/gryphon/lib/models/atlaszero/metric.py index ddddb30..6d99313 100755 --- a/gryphon/lib/models/atlaszero/metric.py +++ b/gryphon/lib/models/atlaszero/metric.py @@ -1,13 +1,15 @@ +from __future__ import absolute_import import json from datetime import datetime import numpy as np import pandas as pd +from six import text_type from sqlalchemy.dialects.mysql import DATETIME from sqlalchemy import Column, Integer, Numeric, Index, DateTime -from metric_types import get_metric_type_int -from base import AtlasZeroBase +from .metric_types import get_metric_type_int +from .base import AtlasZeroBase metadata = AtlasZeroBase.metadata @@ -34,7 +36,7 @@ def __init__(self, metric_type, value, timestamp): self.value = value def __unicode__(self): - return unicode(repr(self)) + return text_type(repr(self)) def __repr__(self): d = { diff --git a/gryphon/lib/models/atlaszero/metric_types.py b/gryphon/lib/models/atlaszero/metric_types.py index 4923ade..a2d547b 100755 --- a/gryphon/lib/models/atlaszero/metric_types.py +++ b/gryphon/lib/models/atlaszero/metric_types.py @@ -1,3 +1,4 @@ +from __future__ import print_function from gryphon.lib.exchange.exchange_factory import ALL_EXCHANGE_KEYS as all_exchanges from gryphon.lib.util.list import distinct @@ -5534,7 +5535,7 @@ def generate_initial_series_name_list(): for st in series_types_orderbook_data: for exchange in all_exchanges: for depth in depths_on_orderbook_data: - print " '%s-%s-%s': %s," % (st, exchange, depth, count) + print(" '%s-%s-%s': %s," % (st, exchange, depth, count)) count += 1 series_types_on_trade_data = ['volume', 'vwap'] @@ -5543,5 +5544,5 @@ def generate_initial_series_name_list(): for st in series_types_on_trade_data: for exchange in all_exchanges: for info in info_on_trade_data: - print " '%s-%s-%s': %s," % (st, exchange, info, count) + print(" '%s-%s-%s': %s," % (st, exchange, info, count)) count += 1 diff --git a/gryphon/lib/models/base.pyx b/gryphon/lib/models/base.pyx index 3d30076..ac67fc5 100755 --- a/gryphon/lib/models/base.pyx +++ b/gryphon/lib/models/base.pyx @@ -1,13 +1,14 @@ # -*- coding: utf-8 -*- +from six import text_type from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() metadata = Base.metadata def unicode_string(self): - return unicode(self).encode('utf-8') + return text_type(self).encode('utf-8') -Base.__str__ == unicode_string +Base.__str__ == unicode_string # How to migrate a database diff --git a/gryphon/lib/models/datum.py b/gryphon/lib/models/datum.py index 34b6c72..6950e0a 100755 --- a/gryphon/lib/models/datum.py +++ b/gryphon/lib/models/datum.py @@ -4,6 +4,7 @@ import uuid from cdecimal import Decimal +from six import text_type from sqlalchemy import ForeignKey, Column, Integer, Unicode, DateTime, UnicodeText, Numeric from gryphon.lib.models.base import Base @@ -31,17 +32,17 @@ def __init__(self, datum_type, numeric_value=None, string_value=None, meta_data= self.datum_type = datum_type self.numeric_value = numeric_value self.string_value = string_value - self.unique_id = u'dat_%s' % unicode(uuid.uuid4().hex) + self.unique_id = u'dat_%s' % text_type(uuid.uuid4().hex) self.meta_data = json.dumps(meta_data) self.order = order def __unicode__(self): - return unicode(repr(self)) + return text_type(repr(self)) def __repr__(self): d = { 'datum_type': self.datum_type, - 'time_created': unicode(self.time_created), + 'time_created': text_type(self.time_created), 'meta_data': json.loads(self.meta_data), } if self.numeric_value: diff --git a/gryphon/lib/models/emeraldhavoc/base.py b/gryphon/lib/models/emeraldhavoc/base.py index 179153b..949c1c6 100755 --- a/gryphon/lib/models/emeraldhavoc/base.py +++ b/gryphon/lib/models/emeraldhavoc/base.py @@ -4,15 +4,16 @@ # names. # Reference: http://stackoverflow.com/questions/8264686/sqlalchemy-multiple-databases-with-same-table-names-not-working +from six import text_type from sqlalchemy.ext.declarative import declarative_base EmeraldHavocBase = declarative_base() metadata = EmeraldHavocBase.metadata def unicode_string(self): - return unicode(self).encode('utf-8') + return text_type(self).encode('utf-8') -EmeraldHavocBase.__str__ == unicode_string +EmeraldHavocBase.__str__ == unicode_string # How to migrate a database diff --git a/gryphon/lib/models/emeraldhavoc/exchange_volume.py b/gryphon/lib/models/emeraldhavoc/exchange_volume.py index 613ffc5..ea14b00 100755 --- a/gryphon/lib/models/emeraldhavoc/exchange_volume.py +++ b/gryphon/lib/models/emeraldhavoc/exchange_volume.py @@ -6,6 +6,7 @@ from gryphon.lib.money import Money from datetime import datetime +from six import text_type from sqlalchemy import Column, Integer, Unicode, DateTime, Numeric from sqlalchemy.ext.declarative import declarative_base @@ -23,7 +24,7 @@ class ExchangeVolume(EmeraldHavocBase): _exchange_volume = Column('exchange_volume', Numeric(precision=20, scale=10)) def __init__(self, exchange_volume, exchange, timestamp): - self.unique_id = unicode(uuid.uuid4().hex) + self.unique_id = text_type(uuid.uuid4().hex) self.time_created = datetime.utcnow() self.timestamp = timestamp self.exchange_volume = exchange_volume @@ -39,7 +40,7 @@ def __repr__(self): def to_json(self): return json.dumps({ 'exchange_volume_id': self.exchange_volume_id, - 'time_created': unicode(self.time_created), + 'time_created': text_type(self.time_created), 'unique_id': self.unique_id, 'exchange': self.exchange, 'exchange_volume': self.exchange_volume diff --git a/gryphon/lib/models/emeraldhavoc/orderbook.pyx b/gryphon/lib/models/emeraldhavoc/orderbook.pyx index 2a2b83d..a24ddb7 100755 --- a/gryphon/lib/models/emeraldhavoc/orderbook.pyx +++ b/gryphon/lib/models/emeraldhavoc/orderbook.pyx @@ -5,6 +5,7 @@ import json import uuid from decimal import * from collections import defaultdict +from six import text_type from gryphon.lib.exchange.consts import Consts from gryphon.lib.exchange.exchange_factory import make_exchange_from_key @@ -18,7 +19,7 @@ metadata = EmeraldHavocBase.metadata class Orderbook(EmeraldHavocBase): __tablename__ = 'orderbook' - + orderbook_id = Column(Integer, primary_key=True) unique_id = Column(Unicode(64), nullable=False) exchange = Column(Unicode(64), nullable=False) @@ -26,15 +27,15 @@ class Orderbook(EmeraldHavocBase): time_created = Column(DateTime, nullable=False) _bids = Column('bids', UnicodeText(length=2**31)) _asks = Column('asks', UnicodeText(length=2**31)) - + def __init__(self, exchange, orderbook, timestamp=None): - self.unique_id = unicode(uuid.uuid4().hex) + self.unique_id = text_type(uuid.uuid4().hex) self.time_created = datetime.utcnow() self.timestamp = timestamp self.bids = orderbook['bids'] self.asks = orderbook['asks'] self.exchange = exchange - + def __unicode__(self): bids = self.bids[:5] asks = self.asks[:5] @@ -48,22 +49,22 @@ class Orderbook(EmeraldHavocBase): for ask in asks: output += u"{0:15} | {1:15}\n".format(ask[0], ask[1]) - + return output - + def __repr__(self): return self.to_json() - + def to_json(self): return json.dumps({ 'trade_id':self.trade_id, - 'time_created':unicode(self.time_created), + 'time_created':text_type(self.time_created), 'unique_id':self.unique_id, 'exchange':self.exchange, 'bids':self.bids, 'asks':self.asks }, ensure_ascii=False) - + @property def bids(self): return json.loads(self._bids) diff --git a/gryphon/lib/models/emeraldhavoc/trade.py b/gryphon/lib/models/emeraldhavoc/trade.py index 2f29947..dfca6c7 100755 --- a/gryphon/lib/models/emeraldhavoc/trade.py +++ b/gryphon/lib/models/emeraldhavoc/trade.py @@ -5,6 +5,7 @@ import uuid from decimal import * from collections import defaultdict +from six import text_type from gryphon.lib.money import Money from gryphon.lib.exchange.consts import Consts @@ -39,7 +40,7 @@ class Trade(EmeraldHavocBase): ) def __init__(self, price, volume, exchange, timestamp, exchange_trade_id, source='EXCHANGE'): - self.unique_id = unicode(uuid.uuid4().hex) + self.unique_id = text_type(uuid.uuid4().hex) self.time_created = datetime.utcnow() self.timestamp = timestamp self.price = price @@ -58,7 +59,7 @@ def __repr__(self): def to_json(self): return json.dumps({ 'trade_id':self.trade_id, - 'timestamp':unicode(self.timestamp), + 'timestamp':text_type(self.timestamp), 'unique_id':self.unique_id, 'exchange':self.exchange, 'price':self.price, @@ -72,7 +73,7 @@ def volume(self): @volume.setter def volume(self, value): self._volume = value.amount - self._volume_currency = unicode(value.currency) + self._volume_currency = text_type(value.currency) @property def price(self): @@ -81,4 +82,4 @@ def price(self): @price.setter def price(self, value): self._price = value.amount - self._price_currency = unicode(value.currency) + self._price_currency = text_type(value.currency) diff --git a/gryphon/lib/models/event.py b/gryphon/lib/models/event.py index 18a30ff..5108a7a 100755 --- a/gryphon/lib/models/event.py +++ b/gryphon/lib/models/event.py @@ -4,6 +4,7 @@ import os import uuid +from six import text_type from sqlalchemy import ForeignKey, Column, Integer, Unicode, DateTime, UnicodeText, BigInteger, Numeric from gryphon.lib.models.base import Base @@ -15,30 +16,30 @@ class Event(Base): __tablename__ = 'event' - + unique_id = Column(Unicode(64), nullable=False) event_id = Column(Integer, primary_key=True) time_created = Column(DateTime, nullable=False) exchange_name = Column(Unicode(256), nullable=False) event_type = Column(Unicode(256), nullable=False) data = Column(UnicodeText(length=2**31)) - + def __init__(self, event_type, exchange_name, data): self.time_created = datetime.utcnow() self.event_type = event_type self.exchange_name = exchange_name - self.unique_id = u'evt_%s' % unicode(uuid.uuid4().hex) + self.unique_id = u'evt_%s' % text_type(uuid.uuid4().hex) self.data = json.dumps(data) - + def __unicode__(self): - return unicode(repr(self)) - + return text_type(repr(self)) + def __repr__(self): return json.dumps({ 'event_type':self.event_type, 'exchange':self.exchange_name, 'data': json.loads(self.data), - 'time_created': unicode(self.time_created), + 'time_created': text_type(self.time_created), }, ensure_ascii=False) @@ -48,14 +49,14 @@ class EventRecorder(object): def create(self, db=None, logger=None): self.db = db self.external_logger = logger - + def record(self, event_type, exchange_name='', data={}): event = Event(event_type, exchange_name, data) - + if not hasattr(self, 'db') and not hasattr(self, 'external_logger'): # we didn't call create. we aren't recording events return - + if self.db: self.db.add(event) commit_mysql_session(self.db) @@ -64,6 +65,6 @@ def record(self, event_type, exchange_name='', data={}): else: # we aren't recording events. pass - - + + diff --git a/gryphon/lib/models/exchange.pyx b/gryphon/lib/models/exchange.pyx index 979c7a3..f2e0014 100755 --- a/gryphon/lib/models/exchange.pyx +++ b/gryphon/lib/models/exchange.pyx @@ -4,6 +4,7 @@ import json import uuid from delorean import parse +from six import text_type from sqlalchemy import Column, Integer, Unicode, Numeric, PickleType from sqlalchemy import or_, and_ from sqlalchemy import func @@ -102,11 +103,11 @@ class Balance(MutableDict): # Make a deep copy of self. copy.deepcopy() is 4x slower than this # because we know the exact structure and don't have to watch for recursions result = self.__class__() - for currency, m in self.iteritems(): + for currency, m in self.items(): result[currency] = Money(m.amount, m.currency) if isinstance(other, Balance): - all_currencies = list(set(self.keys() + other.keys())) + all_currencies = list(set(list(self.keys()) + list(other.keys()))) for c in all_currencies: result[c] += other[c] elif isinstance(other, Money): @@ -117,7 +118,7 @@ class Balance(MutableDict): def __neg__(self): result = self.__class__() - for currency, balance in self.iteritems(): + for currency, balance in self.items(): result[currency] = -balance return result @@ -138,7 +139,7 @@ class Balance(MutableDict): def total_usd_value(self, date=None): total_usd_value = Money(0, 'USD') - for currency, balance in self.iteritems(): + for currency, balance in self.items(): total_usd_value += balance.to('USD', date=date) return total_usd_value @@ -168,7 +169,7 @@ class Exchange(Base): transactions = relationship('Transaction', cascade='all,delete-orphan', backref='exchange', lazy='dynamic') def __init__(self, name): - self.unique_id = unicode(uuid.uuid4().hex) + self.unique_id = text_type(uuid.uuid4().hex) self.name = name self.position = Position() self.target = Target() diff --git a/gryphon/lib/models/liability.py b/gryphon/lib/models/liability.py index 46494cd..6c7c51d 100755 --- a/gryphon/lib/models/liability.py +++ b/gryphon/lib/models/liability.py @@ -17,6 +17,7 @@ from cdecimal import Decimal from delorean import Delorean +from six import text_type from sqlalchemy import Column, Integer, Unicode, DateTime, UnicodeText, Numeric from gryphon.lib.logger import get_logger @@ -55,7 +56,7 @@ class Liability(Base): _details = Column('details', UnicodeText(length=2**31)) def __init__(self, amount, liability_type, entity_name, time_started=None, time_repayed=None, details=None): - self.unique_id = unicode(uuid.uuid4().hex) + self.unique_id = text_type(uuid.uuid4().hex) self.time_created = datetime.utcnow() self.amount = amount @@ -81,12 +82,12 @@ def to_json(self): return json.dumps({ 'liability_id': self.liability_id, 'unique_id': self.unique_id, - 'time_created': unicode(self.time_created), + 'time_created': text_type(self.time_created), 'amount': self.amount, 'liability_type': self.liability_type, 'entity_name': self.entity_name, - 'time_started': unicode(self.time_started), - 'time_repayed': unicode(self.time_repayed), + 'time_started': text_type(self.time_started), + 'time_repayed': text_type(self.time_repayed), 'details': self.details, }, ensure_ascii=False) diff --git a/gryphon/lib/models/market_data.py b/gryphon/lib/models/market_data.py index bde06ab..4674420 100755 --- a/gryphon/lib/models/market_data.py +++ b/gryphon/lib/models/market_data.py @@ -1,10 +1,12 @@ # -*- coding: utf-8 -*- +from __future__ import absolute_import import os -from base import Base +from .base import Base import os import json import uuid from datetime import datetime, timedelta +from six import text_type from sqlalchemy import ForeignKey, Column, Integer, Unicode, DateTime, UnicodeText, Numeric, desc from sqlalchemy.orm import relationship, backref from sqlalchemy.ext.declarative import declarative_base @@ -15,12 +17,12 @@ metadata = Base.metadata class MarketDataRetriever(object): - + BITSTAMP=u'STMP' BTCE=u'BTCE' TRADE = u'TRADE' XBTUSD = u'XBT/USD' - + @staticmethod def trades(exchange=BITSTAMP, ticker_symbol=XBTUSD, start_time=datetime.utcnow()-timedelta(days=30), end_time=datetime.utcnow()): db = session.get_a_gds_db_mysql_session() @@ -31,11 +33,11 @@ def trades(exchange=BITSTAMP, ticker_symbol=XBTUSD, start_time=datetime.utcnow() MarketData.timestamp.between(start_time, end_time)).order_by( desc(MarketData.timestamp)).all() return trades - + def orderbook(self): pass - + class MarketData(Base): @@ -52,7 +54,7 @@ class MarketData(Base): volume = Column('volume', Numeric(precision=20, scale=10)) entry_type = Column(Unicode(32), nullable=True) ticker_symbol = Column(Unicode(256)) - + def __init__(self, timestamp, exchange, price, currency, volume, entry_type, ticker_symbol): self.unique_id = u'mkd_%s' % uuid.uuid4().hex self.time_added = datetime.utcnow() @@ -64,10 +66,10 @@ def __init__(self, timestamp, exchange, price, currency, volume, entry_type, tic self.volume = volume self.entry_type = entry_type self.ticker_symbol = ticker_symbol - + def __str__(self): - return unicode(self) - + return text_type(self) + def __unicode__(self): return '%s,%s,%s,%s,%s,%s,%s' % ( self.timestamp, diff --git a/gryphon/lib/models/order.pyx b/gryphon/lib/models/order.pyx index 6032529..f724456 100755 --- a/gryphon/lib/models/order.pyx +++ b/gryphon/lib/models/order.pyx @@ -7,6 +7,7 @@ import uuid from decimal import * from delorean import epoch +from six import text_type from sqlalchemy import ForeignKey, Column, Integer, Unicode, DateTime, UnicodeText, Numeric, Index from sqlalchemy.orm import relationship, backref from sqlalchemy.ext.declarative import declarative_base @@ -24,7 +25,7 @@ metadata = Base.metadata class Order(Base, BasicOrder): __tablename__ = 'order' - + order_id = Column(Integer, primary_key=True) status = Column(Unicode(32), nullable=False) order_type = Column(Unicode(64)) @@ -32,7 +33,7 @@ class Order(Base, BasicOrder): exchange_order_id = Column(Unicode(64)) actor = Column(Unicode(64)) exchange_rate = Column(Numeric(precision=20, scale=10)) - + time_created = Column(DateTime, nullable=False) time_executed = Column(DateTime) @@ -47,16 +48,16 @@ class Order(Base, BasicOrder): _competitiveness_currency = Column('competitiveness_currency', Unicode(3)) _spread = Column('spread', Numeric(precision=20, scale=10)) _spread_currency = Column('spread_currency', Unicode(3)) - + trades = relationship('Trade', cascade="all,delete-orphan", backref='order') datums = relationship("Datum", backref='order') - + __table_args__ = (Index('idx_exchange_order_id_exchange_name', exchange_order_id, _exchange_name), Index('idx_status', status),) - + def __init__(self, actor, mode, volume, price, exchange, exchange_order_id): self.status = self.OPEN - self.unique_id = unicode(uuid.uuid4().hex) + self.unique_id = text_type(uuid.uuid4().hex) self.time_created = datetime.utcnow() assert actor and price and volume and exchange and mode @@ -71,7 +72,7 @@ class Order(Base, BasicOrder): def __unicode__(self): return u'[ORDER:%s:%s] Status:%s, Price:%s, Volume:%s BTC' % ( self.order_type, self.exchange.name, self.status, self.price, self.volume) - + def __repr__(self): return self.to_json() @@ -80,8 +81,8 @@ class Order(Base, BasicOrder): 'order_id':self.order_id, 'unique_id':self.unique_id, 'exchange_order_id':self.exchange_order_id, - 'time_created':unicode(self.time_created), - 'time_executed':unicode(self.time_executed), + 'time_created':text_type(self.time_created), + 'time_executed':text_type(self.time_executed), 'exchange':self.exchange.name, 'status':self.status, 'order_type': self.order_type, @@ -154,13 +155,13 @@ class Order(Base, BasicOrder): return self._exchange else: return None - + @exchange.setter def exchange(self, value): self._exchange = value self._exchange_name = self._exchange.name - - + + @property def volume(self): if not self._volume: @@ -171,7 +172,7 @@ class Order(Base, BasicOrder): def volume(self, value): self._volume = value.amount self._volume_currency = value.currency - + @property def price(self): if not self._price: @@ -213,7 +214,7 @@ class Order(Base, BasicOrder): def spread(self, value): self._spread = value.amount self._spread_currency = value.currency - + @property def volume_filled(self): return sum([t.volume for t in self.trades], Money("0", self._volume_currency)) diff --git a/gryphon/lib/models/orderbook_snapshot.py b/gryphon/lib/models/orderbook_snapshot.py index 3cf607a..96f2e33 100755 --- a/gryphon/lib/models/orderbook_snapshot.py +++ b/gryphon/lib/models/orderbook_snapshot.py @@ -1,31 +1,33 @@ # -*- coding: utf-8 -*- +from __future__ import absolute_import import os -from base import Base +from .base import Base import json import uuid from datetime import datetime +from six import text_type from sqlalchemy import ForeignKey, Column, Integer, Unicode, DateTime, UnicodeText, BigInteger, Numeric metadata = Base.metadata class OrderbookSnapshot(Base): __tablename__ = 'orderbook_snapshot' - + unique_id = Column(Unicode(64), nullable=False) orderbook_id = Column(Integer, primary_key=True) data = Column(UnicodeText(length=2**31)) time_retrieved = Column(DateTime, nullable=False) - + def __init__(self, data, time_retrieved): - self.unique_id = u'ord_%s' % unicode(uuid.uuid4().hex) + self.unique_id = u'ord_%s' % text_type(uuid.uuid4().hex) self.time_retrieved = time_retrieved self.data = data - + def __unicode__(self): return u'Orderbook_Snapshot' - + def __repr__(self): return json.dumps({ 'data': self.data, - 'time_retrieved': unicode(self.time_retrieved), + 'time_retrieved': text_type(self.time_retrieved), }, ensure_ascii=False) diff --git a/gryphon/lib/models/ticker.py b/gryphon/lib/models/ticker.py index cd303d7..055fe5a 100755 --- a/gryphon/lib/models/ticker.py +++ b/gryphon/lib/models/ticker.py @@ -4,6 +4,7 @@ import os import uuid +from six import text_type from sqlalchemy import ForeignKey, Column, Integer, Unicode, DateTime, UnicodeText, BigInteger, Numeric from gryphon.lib.models.base import Base @@ -13,25 +14,25 @@ class Ticker(Base): __tablename__ = 'ticker' - + unique_id = Column(Unicode(64), nullable=False) ticker_id = Column(Integer, primary_key=True) exchange = Column(Unicode(256)) data = Column(UnicodeText(length=2**31)) time_retrieved = Column(DateTime, nullable=False) - + def __init__(self, exchange, data): self.time_retrieved = datetime.utcnow() self.exchange = exchange - self.unique_id = u'tkr_%s' % unicode(uuid.uuid4().hex) + self.unique_id = u'tkr_%s' % text_type(uuid.uuid4().hex) self.data = json.dumps(data) - + def __unicode__(self): - return unicode(repr(self)) - + return text_type(repr(self)) + def __repr__(self): return json.dumps({ 'exchange':self.exchange, 'data': self.data, - 'time_retrieved': unicode(self.time_retrieved), + 'time_retrieved': text_type(self.time_retrieved), }, ensure_ascii=False) diff --git a/gryphon/lib/models/trade.pyx b/gryphon/lib/models/trade.pyx index 3c29b07..d67d026 100755 --- a/gryphon/lib/models/trade.pyx +++ b/gryphon/lib/models/trade.pyx @@ -6,6 +6,7 @@ import os import uuid from decimal import * +from six import text_type from sqlalchemy import ForeignKey, Column, Integer, Unicode, DateTime, UnicodeText, Numeric from sqlalchemy.orm import relationship, backref from sqlalchemy.ext.declarative import declarative_base @@ -25,17 +26,17 @@ metadata = Base.metadata class Trade(Base): __tablename__ = 'trade' - + #Trade Types BID = Consts.BID ASK = Consts.ASK - + trade_id = Column(Integer, primary_key=True) trade_type = Column(Unicode(64)) unique_id = Column(Unicode(64), nullable=False) exchange_trade_id = Column(Unicode(64)) time_created = Column(DateTime, nullable=False) - + _fee = Column('fee', Numeric(precision=24, scale=14)) _fee_currency = Column('fee_currency', Unicode(3)) _price = Column('price', Numeric(precision=24, scale=14)) @@ -52,9 +53,9 @@ class Trade(Base): fee_buyback_transaction = relationship("Transaction", backref='fee_buyback_trades') order_id = Column(Integer, ForeignKey('order.order_id')) - + def __init__(self, trade_type, price, fee, volume, exchange_trade_id, order, meta_data={}): - self.unique_id = unicode(uuid.uuid4().hex) + self.unique_id = text_type(uuid.uuid4().hex) self.time_created = datetime.utcnow() self.trade_type = trade_type self.price = price @@ -63,19 +64,19 @@ class Trade(Base): self.exchange_trade_id = exchange_trade_id self.order = order self.meta_data = json.dumps(meta_data) - + def __unicode__(self): return u'[TRADE:%s, Order:%s] Price:%s, Volume:%s BTC, Exchange:%s' % ( self.trade_type, self.order_id, self.price, self.volume, self.order.exchange.name) - + def __repr__(self): return self.to_json() - + def to_json(self): return json.dumps({ 'trade_id':self.trade_id, 'trade_type':self.trade_type, - 'time_created':unicode(self.time_created), + 'time_created':text_type(self.time_created), 'unique_id':self.unique_id, 'exchange_trade_id':self.exchange_trade_id, 'order_id':self.order_id, @@ -83,7 +84,7 @@ class Trade(Base): 'price':self.price, 'volume':self.volume }, ensure_ascii=False) - + @property def volume(self): return Money(self._volume, self._volume_currency) diff --git a/gryphon/lib/models/transaction.py b/gryphon/lib/models/transaction.py index c6a5109..099604a 100755 --- a/gryphon/lib/models/transaction.py +++ b/gryphon/lib/models/transaction.py @@ -8,6 +8,7 @@ from decimal import * from delorean import Delorean +from six import text_type from sqlalchemy import ForeignKey, Column, Integer, Unicode, DateTime, UnicodeText, Numeric from sqlalchemy.orm import relationship, backref from sqlalchemy.ext.declarative import declarative_base @@ -29,29 +30,29 @@ class Transaction(Base): __tablename__ = 'transaction' - + #Transaction Types WITHDRAWL = 'WITHDRAWL' DEPOSIT = 'DEPOSIT' - + #Transaction Status' IN_TRANSIT = 'IN_TRANSIT' COMPLETED = 'COMPLETED' CANCELED = 'CANCELED' - + transaction_id = Column(Integer, primary_key=True) transaction_type = Column(Unicode(64)) transaction_status = Column(Unicode(64)) unique_id = Column(Unicode(64), nullable=False) time_created = Column(DateTime, nullable=False) time_completed = Column(DateTime, nullable=True) - + _amount = Column('amount', Numeric(precision=24, scale=14)) _amount_currency = Column('amount_currency', Unicode(3)) _fee = Column('fee', Numeric(precision=24, scale=14)) _fee_currency = Column('fee_currency', Unicode(3)) _transaction_details = Column('transaction_details', UnicodeText(length=2**31)) - + exchange_id = Column(Integer, ForeignKey('exchange.exchange_id')) # Some Transactions have BTC fees, which reduce our total BTC assets. Every once in a while @@ -60,9 +61,9 @@ class Transaction(Base): # This one is a bit complex because it is self-referential fee_buyback_transaction_id = Column(Integer, ForeignKey('transaction.transaction_id')) fee_buyback_transaction = relationship("Transaction", remote_side=[transaction_id], backref='fee_buyback_transactions') - + def __init__(self, transaction_type, transaction_status, amount, exchange, transaction_details, fee=None): - self.unique_id = unicode(uuid.uuid4().hex) + self.unique_id = text_type(uuid.uuid4().hex) self.time_created = datetime.utcnow() self.transaction_type = transaction_type self.transaction_status = transaction_status @@ -71,27 +72,27 @@ def __init__(self, transaction_type, transaction_status, amount, exchange, trans self.transaction_details = transaction_details if fee: self.fee = fee - + def __unicode__(self): return u'[TRANSACTION:%s, EXCHANGE:%s, STATUS:%s] Amount:%s (%s) at %s' % ( self.transaction_type, self.exchange.name, self.transaction_status, self.amount, self.fee, self.time_created) - + def __repr__(self): return self.to_json() - + def to_json(self): return json.dumps({ 'transaction_id':self.transaction_id, 'transaction_type':self.transaction_type, 'transaction_status':self.transaction_status, - 'time_created':unicode(self.time_created), + 'time_created':text_type(self.time_created), 'unique_id':self.unique_id, 'exchange':self.exchange.name, 'amount':self.amount, 'fee': self.fee, 'transaction_details':self.transaction_details }, ensure_ascii=False) - + @property def transaction_details(self): return json.loads(self._transaction_details) @@ -99,7 +100,7 @@ def transaction_details(self): @transaction_details.setter def transaction_details(self, value): self._transaction_details = json.dumps(value, ensure_ascii=False) - + @property def amount(self): return Money(self._amount, self._amount_currency) diff --git a/gryphon/lib/money.py b/gryphon/lib/money.py index 65ff3a8..85fae4d 100755 --- a/gryphon/lib/money.py +++ b/gryphon/lib/money.py @@ -8,6 +8,7 @@ import decimal # need absolute_import from above so that this doesn't load our current file import money as super_money +from six import string_types class Money(super_money.Money): @@ -16,7 +17,7 @@ class Money(super_money.Money): CURRENCIES = FIAT_CURRENCIES + CRYPTO_CURRENCIES def __init__(self, amount="0", currency=None): - if isinstance(amount, basestring): + if isinstance(amount, string_types): amount = amount.replace(",", "") try: diff --git a/gryphon/lib/scrapers/bmo.py b/gryphon/lib/scrapers/bmo.py index a28a9c9..df7a121 100755 --- a/gryphon/lib/scrapers/bmo.py +++ b/gryphon/lib/scrapers/bmo.py @@ -1,3 +1,4 @@ +from __future__ import print_function import logging import os @@ -285,9 +286,9 @@ def __call__(self, driver): def main(): scraper = BMOScraper() - print scraper.load() - print scraper.load_transactions(os.environ['BMO_USD_ACCOUNT_NUMBER']) - print scraper.load_transactions(os.environ['BMO_CAD_ACCOUNT_NUMBER']) + print(scraper.load()) + print(scraper.load_transactions(os.environ['BMO_USD_ACCOUNT_NUMBER'])) + print(scraper.load_transactions(os.environ['BMO_CAD_ACCOUNT_NUMBER'])) scraper.quit() if __name__ == '__main__': diff --git a/gryphon/lib/scrapers/boa.py b/gryphon/lib/scrapers/boa.py index e79dd9e..d819411 100755 --- a/gryphon/lib/scrapers/boa.py +++ b/gryphon/lib/scrapers/boa.py @@ -1,3 +1,4 @@ +from __future__ import print_function import gryphon.lib; gryphon.lib.prepare() import os @@ -82,8 +83,8 @@ def quit(self): def main(): scraper = BoAScraper() - print scraper.load() - print scraper.load_transactions(os.environ['BOA_MAIN_ACCOUNT_NUMBER']) + print(scraper.load()) + print(scraper.load_transactions(os.environ['BOA_MAIN_ACCOUNT_NUMBER'])) scraper.quit() if __name__ == '__main__': diff --git a/gryphon/lib/scripts/bitstamp_auth_test.py b/gryphon/lib/scripts/bitstamp_auth_test.py index 90dfb84..18f8ae7 100755 --- a/gryphon/lib/scripts/bitstamp_auth_test.py +++ b/gryphon/lib/scripts/bitstamp_auth_test.py @@ -2,6 +2,7 @@ This script demonstrates the bitstamp authenticated requests bug that showed up in the week of 26 March. """ +from __future__ import print_function import requests import hmac @@ -12,6 +13,7 @@ import dotenv import os import os.path +from six import text_type dotenv_path = os.path.join(os.path.dirname(__file__), '.env') dotenv.load_dotenv(dotenv_path) @@ -24,7 +26,7 @@ def construct_payload(): - nonce = unicode(int(round(time.time() * 1000))) + nonce = text_type(int(round(time.time() * 1000))) message = nonce + CLIENT_ID + API_KEY sig = hmac.new(SECRET, msg=message, digestmod=hashlib.sha256).hexdigest().upper() @@ -38,13 +40,13 @@ def construct_payload(): def test_response(response, test_name): - print 'Response: %s' % str(response)[:50] + print('Response: %s' % str(response)[:50]) try: assert('btc_available' in response) - print '%s succeeded!' % test_name + print('%s succeeded!' % test_name) except Exception as e: - print '%s: %s' % (test_name, str(e)) + print('%s: %s' % (test_name, str(e))) def requests_dot_post(): @@ -52,7 +54,7 @@ def requests_dot_post(): This just makes a single request.post call to see if it works. """ - print "Trying requests.post" + print("Trying requests.post") payload = construct_payload() @@ -68,7 +70,7 @@ def session_post(session=None, clear_cookies=None, adaptor=None, cookie_jar=None types. """ if session is None: - print "Trying with a new session" + print("Trying with a new session") session = requests.Session() if adaptor is not None: @@ -77,10 +79,10 @@ def session_post(session=None, clear_cookies=None, adaptor=None, cookie_jar=None if cookie_jar is not None: session.cookies = cookie_jar else: - print "Trying with an extant session" + print("Trying with an extant session") if clear_cookies is True: - print "Clearing the session's cookies" + print("Clearing the session's cookies") session.cookies.clear() payload = construct_payload() @@ -107,15 +109,15 @@ def try_different_adaptors(): tls1 = SSLAdapter(ssl.PROTOCOL_TLSv1) tls11 = SSLAdapter(ssl.PROTOCOL_TLSv1_1) - print 'TLSv1' + print('TLSv1') session = session_post(adaptor=tls1) session_post(session=session) - print 'TLSv1' + print('TLSv1') session = session_post(adaptor=tls11) session_post(session=session) - print 'SSLv3' + print('SSLv3') session = session_post(adaptor=ssl3) session_post(session=session) diff --git a/gryphon/lib/scripts/test_fast_revenue_fees_profit.py b/gryphon/lib/scripts/test_fast_revenue_fees_profit.py index 5308c41..ce0d035 100755 --- a/gryphon/lib/scripts/test_fast_revenue_fees_profit.py +++ b/gryphon/lib/scripts/test_fast_revenue_fees_profit.py @@ -2,8 +2,9 @@ Test script for the new fast revenue function. Runs both revenue functions on a random period and checks their results are the same. """ +from __future__ import print_function -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from cdecimal import * from datetime import datetime, timedelta @@ -39,7 +40,7 @@ def test_fast_revenue(): for i in range(1, 30): start, end = get_random_period() - print '%s, %s' % (start, end) + print('%s, %s' % (start, end)) slow_revenue = gryphon_profit.revenue_in_period(db, start, end) fast_revenue = gryphon_profit.fast_revenue_in_period(db, start, end) @@ -51,9 +52,9 @@ def test_fast_revenue(): == fast_revenue.round_to_decimal_places(4)) if not result: - print 'BAD: %s, != %s' % (slow_revenue, fast_revenue) + print('BAD: %s, != %s' % (slow_revenue, fast_revenue)) else: - print 'GOOD: %s, == %s' % (slow_revenue, fast_revenue) + print('GOOD: %s, == %s' % (slow_revenue, fast_revenue)) db.remove() @@ -64,7 +65,7 @@ def test_fast_profit(): for i in range(1, 30): start, end = get_random_period() - print '%s, %s' % (start, end) + print('%s, %s' % (start, end)) slow_profit = gryphon_profit.profit_in_period(db, start, end) fast_profit = gryphon_profit.fast_profit_in_period(db, start, end) @@ -73,9 +74,9 @@ def test_fast_profit(): == fast_profit.round_to_decimal_places(4)) if not result: - print 'BAD: %s, != %s' % (slow_profit, fast_profit) + print('BAD: %s, != %s' % (slow_profit, fast_profit)) else: - print 'GOOD: %s, == %s' % (slow_profit, fast_profit) + print('GOOD: %s, == %s' % (slow_profit, fast_profit)) db.remove() @@ -86,7 +87,7 @@ def test_fast_revenue_fees_profit(): for i in range(1, 30): start, end = get_random_period() - print '%s, %s' % (start, end) + print('%s, %s' % (start, end)) slow_revenue, slow_fees, slow_profit = gryphon_profit.revenue_fees_profit_in_period(db, start, end) fast_revenue, fast_fees, fast_profit = gryphon_profit.fast_revenue_fees_profit_in_period(db, start, end) @@ -99,9 +100,9 @@ def test_fast_revenue_fees_profit(): == fast_fees.round_to_decimal_places(4)) if not result: - print 'BAD' + print('BAD') else: - print 'GOOD' + print('GOOD') db.remove() diff --git a/gryphon/lib/util/profile.py b/gryphon/lib/util/profile.py index dac81d1..c948e1f 100755 --- a/gryphon/lib/util/profile.py +++ b/gryphon/lib/util/profile.py @@ -8,11 +8,12 @@ the outputs of each can be different levels of usable for different cases, so I included both here. """ +from __future__ import absolute_import from collections import defaultdict import functools import timeit -import monkeypatch_timeit; monkeypatch_timeit.monkeypatch_timeit() +from . import monkeypatch_timeit; monkeypatch_timeit.monkeypatch_timeit() from line_profiler import LineProfiler def do_profile(follow=[]): diff --git a/gryphon/tests/environment/exchange_coordinator/auth_methods.py b/gryphon/tests/environment/exchange_coordinator/auth_methods.py index d638ed2..85e0558 100644 --- a/gryphon/tests/environment/exchange_coordinator/auth_methods.py +++ b/gryphon/tests/environment/exchange_coordinator/auth_methods.py @@ -2,7 +2,7 @@ Test an exchange's authenticated endpoints that don't make any modifying calls. """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import gryphon.lib; gryphon.lib.prepare() import logging @@ -19,7 +19,7 @@ class ExchangeAuthMethodsTests(object): def test_balance(self): balance = self.exchange.get_balance() - assert self.exchange.currency in balance + assert self.exchange.currency in balance assert self.exchange.volume_currency in balance def test_open_orders(self): diff --git a/gryphon/tests/environment/exchange_coordinator/bitstamp.py b/gryphon/tests/environment/exchange_coordinator/bitstamp.py index c2c2054..ff2a422 100644 --- a/gryphon/tests/environment/exchange_coordinator/bitstamp.py +++ b/gryphon/tests/environment/exchange_coordinator/bitstamp.py @@ -1,6 +1,6 @@ """ """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import os import time import unittest @@ -60,12 +60,12 @@ def test_accounting_cancelled_order(self): result = self._place_simple_order_1() assert result['success'] is True - order1_exchange_order_id = result['order_id'] - + order1_exchange_order_id = result['order_id'] + self.exchange.cancel_order(order1_exchange_order_id) time.sleep(2) - + open_orders = self.exchange.get_open_orders() eaten_order_ids, current_orders = self.exchange._get_current_orders(open_orders) self.exchange._run_accounting(eaten_order_ids, current_orders) @@ -90,10 +90,10 @@ def test_accounting_untouched_open_order(self): result = self._place_simple_order_1() assert result['success'] is True - order1_exchange_order_id = result['order_id'] - + order1_exchange_order_id = result['order_id'] + time.sleep(2) - + open_orders = self.exchange.get_open_orders() eaten_order_ids, current_orders = self.exchange._get_current_orders(open_orders) @@ -156,7 +156,7 @@ def test_handle_unexpected_orders_2(self): result = self._place_simple_order_1() assert result['success'] is True - order1_exchange_order_id = result['order_id'] + order1_exchange_order_id = result['order_id'] # Account the order as 'filled' db_order = self.exchange._get_orders_by_order_ids([order1_exchange_order_id])[0] @@ -193,7 +193,7 @@ def test_handle_unexpected_orders_3(self): result = self._place_simple_order_1() assert result['success'] is True - order1_exchange_order_id = result['order_id'] + order1_exchange_order_id = result['order_id'] db_order = self.exchange._get_orders_by_order_ids([order1_exchange_order_id])[0] db_order.status = Order.CANCELLED @@ -206,7 +206,7 @@ def test_handle_unexpected_orders_3(self): exchange_open_orders = self.exchange.get_open_orders() self.exchange._get_current_orders(exchange_open_orders) self.db.commit() # Have to force commit here since we're not in a tick. - + # Since the order was cancelled in the database, but open on the exchange, # handle_unexpected should have triggered re-cancelling logic, which just # assumes a previous request failed and tries again. @@ -226,12 +226,12 @@ def test_get_current_orders(self): result = self._place_simple_order_1() assert result['success'] is True - order1_exchange_order_id = result['order_id'] + order1_exchange_order_id = result['order_id'] result = self._place_simple_order_2() assert result['success'] is True - order2_exchange_order_id = result['order_id'] + order2_exchange_order_id = result['order_id'] self.exchange.cancel_order(order1_exchange_order_id) @@ -255,7 +255,7 @@ def test_db_open_orders(self): result = self._place_simple_order_1() assert result['success'] is True - order1_exchange_order_id = result['order_id'] + order1_exchange_order_id = result['order_id'] db_open_orders = self.exchange._get_db_open_orders() @@ -271,12 +271,12 @@ def test_get_orders_by_ids(self): result = self._place_simple_order_1() assert result['success'] is True - order1_exchange_order_id = result['order_id'] + order1_exchange_order_id = result['order_id'] result = self._place_simple_order_2() assert result['success'] is True - order2_exchange_order_id = result['order_id'] + order2_exchange_order_id = result['order_id'] orders = self.exchange._get_orders_by_order_ids([ order1_exchange_order_id, @@ -297,7 +297,7 @@ def test_order_placement(self): result = self._place_simple_order_1() assert result['success'] is True - order1_exchange_order_id = result['order_id'] + order1_exchange_order_id = result['order_id'] db_order = self.db.query(Order)\ .filter(Order.exchange_order_id == order1_exchange_order_id)\ diff --git a/gryphon/tests/environment/exchange_coordinator/kraken.py b/gryphon/tests/environment/exchange_coordinator/kraken.py index e5a69d0..28dc86a 100644 --- a/gryphon/tests/environment/exchange_coordinator/kraken.py +++ b/gryphon/tests/environment/exchange_coordinator/kraken.py @@ -1,7 +1,8 @@ """ """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import os +import time from gryphon.lib.exchange.kraken_btc_eur import KrakenBTCEURExchange from gryphon.fury.harness.exchange_coordinator import ExchangeCoordinator @@ -45,7 +46,7 @@ def test_order_placement(self): self.db.commit() assert result['success'] is True - order1_exchange_order_id = result['order_id'] + order1_exchange_order_id = result['order_id'] db_order = self.db.query(Order)\ .filter(Order.exchange_order_id == order1_exchange_order_id)\ diff --git a/gryphon/tests/environment/exchange_coordinator/public_methods.py b/gryphon/tests/environment/exchange_coordinator/public_methods.py index 08e9f78..a281c9e 100644 --- a/gryphon/tests/environment/exchange_coordinator/public_methods.py +++ b/gryphon/tests/environment/exchange_coordinator/public_methods.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import logging import os diff --git a/gryphon/tests/environment/exchange_wrappers/auth_methods.py b/gryphon/tests/environment/exchange_wrappers/auth_methods.py index d638ed2..85e0558 100644 --- a/gryphon/tests/environment/exchange_wrappers/auth_methods.py +++ b/gryphon/tests/environment/exchange_wrappers/auth_methods.py @@ -2,7 +2,7 @@ Test an exchange's authenticated endpoints that don't make any modifying calls. """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import gryphon.lib; gryphon.lib.prepare() import logging @@ -19,7 +19,7 @@ class ExchangeAuthMethodsTests(object): def test_balance(self): balance = self.exchange.get_balance() - assert self.exchange.currency in balance + assert self.exchange.currency in balance assert self.exchange.volume_currency in balance def test_open_orders(self): diff --git a/gryphon/tests/environment/exchange_wrappers/bitstamp_auth.py b/gryphon/tests/environment/exchange_wrappers/bitstamp_auth.py index 9bde17f..03184be 100644 --- a/gryphon/tests/environment/exchange_wrappers/bitstamp_auth.py +++ b/gryphon/tests/environment/exchange_wrappers/bitstamp_auth.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.bitstamp_btc_usd import BitstampBTCUSDExchange from gryphon.tests.exceptional.exchange_wrappers.auth_methods import ExchangeAuthMethodsTests diff --git a/gryphon/tests/environment/exchange_wrappers/bitstamp_live_orders.py b/gryphon/tests/environment/exchange_wrappers/bitstamp_live_orders.py index 66e5b43..091c324 100644 --- a/gryphon/tests/environment/exchange_wrappers/bitstamp_live_orders.py +++ b/gryphon/tests/environment/exchange_wrappers/bitstamp_live_orders.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.bitstamp_btc_usd import BitstampBTCUSDExchange from gryphon.tests.exceptional.exchange_wrappers.live_orders import LiveOrdersTest diff --git a/gryphon/tests/environment/exchange_wrappers/coinbase_auth.py b/gryphon/tests/environment/exchange_wrappers/coinbase_auth.py index 38605ca..b272cf9 100644 --- a/gryphon/tests/environment/exchange_wrappers/coinbase_auth.py +++ b/gryphon/tests/environment/exchange_wrappers/coinbase_auth.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.coinbase_btc_usd import CoinbaseBTCUSDExchange from gryphon.tests.environment.exchange_wrappers.auth_methods import ExchangeAuthMethodsTests diff --git a/gryphon/tests/environment/exchange_wrappers/coinbase_live_orders.py b/gryphon/tests/environment/exchange_wrappers/coinbase_live_orders.py index 320f6aa..d7248a8 100644 --- a/gryphon/tests/environment/exchange_wrappers/coinbase_live_orders.py +++ b/gryphon/tests/environment/exchange_wrappers/coinbase_live_orders.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.coinbase_btc_usd import CoinbaseBTCUSDExchange from gryphon.tests.environment.exchange_wrappers.live_orders import LiveOrdersTest diff --git a/gryphon/tests/environment/exchange_wrappers/gemini_auth.py b/gryphon/tests/environment/exchange_wrappers/gemini_auth.py index b2d95b3..f2b5699 100644 --- a/gryphon/tests/environment/exchange_wrappers/gemini_auth.py +++ b/gryphon/tests/environment/exchange_wrappers/gemini_auth.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.gemini_btc_usd import GeminiBTCUSDExchange from gryphon.tests.exceptional.exchange_wrappers.auth_methods import ExchangeAuthMethodsTests diff --git a/gryphon/tests/environment/exchange_wrappers/gemini_live_orders.py b/gryphon/tests/environment/exchange_wrappers/gemini_live_orders.py index 23d814c..fd2ead3 100644 --- a/gryphon/tests/environment/exchange_wrappers/gemini_live_orders.py +++ b/gryphon/tests/environment/exchange_wrappers/gemini_live_orders.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.gemini_btc_usd import GeminiBTCUSDExchange from gryphon.tests.exceptional.exchange_wrappers.live_orders import LiveOrdersTest diff --git a/gryphon/tests/environment/exchange_wrappers/itbit_auth.py b/gryphon/tests/environment/exchange_wrappers/itbit_auth.py index 1e1a3ee..7b61bc7 100644 --- a/gryphon/tests/environment/exchange_wrappers/itbit_auth.py +++ b/gryphon/tests/environment/exchange_wrappers/itbit_auth.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.itbit_btc_usd import ItbitBTCUSDExchange from gryphon.tests.exceptional.exchange_wrappers.auth_methods import ExchangeAuthMethodsTests diff --git a/gryphon/tests/environment/exchange_wrappers/itbit_live_orders.py b/gryphon/tests/environment/exchange_wrappers/itbit_live_orders.py index 6ef1d3e..e2bef4b 100644 --- a/gryphon/tests/environment/exchange_wrappers/itbit_live_orders.py +++ b/gryphon/tests/environment/exchange_wrappers/itbit_live_orders.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.itbit_btc_usd import ItbitBTCUSDExchange from gryphon.tests.exceptional.exchange_wrappers.live_orders import LiveOrdersTest diff --git a/gryphon/tests/environment/exchange_wrappers/kraken_auth.py b/gryphon/tests/environment/exchange_wrappers/kraken_auth.py index 18424e3..40a64aa 100644 --- a/gryphon/tests/environment/exchange_wrappers/kraken_auth.py +++ b/gryphon/tests/environment/exchange_wrappers/kraken_auth.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.kraken_btc_eur import KrakenBTCEURExchange from gryphon.tests.exceptional.exchange_wrappers.auth_methods import ExchangeAuthMethodsTests diff --git a/gryphon/tests/environment/exchange_wrappers/kraken_live_orders.py b/gryphon/tests/environment/exchange_wrappers/kraken_live_orders.py index 3b77e02..ebb1779 100644 --- a/gryphon/tests/environment/exchange_wrappers/kraken_live_orders.py +++ b/gryphon/tests/environment/exchange_wrappers/kraken_live_orders.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.kraken_btc_eur import KrakenBTCEURExchange from gryphon.tests.exceptional.exchange_wrappers.live_orders import LiveOrdersTest diff --git a/gryphon/tests/environment/exchange_wrappers/live_orders.py b/gryphon/tests/environment/exchange_wrappers/live_orders.py index a2d01b3..1519f0e 100644 --- a/gryphon/tests/environment/exchange_wrappers/live_orders.py +++ b/gryphon/tests/environment/exchange_wrappers/live_orders.py @@ -2,7 +2,7 @@ Tests authenticated and order-placing endpoints. """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import gryphon.lib; gryphon.lib.prepare() import logging @@ -55,7 +55,7 @@ def test_order_placement_status_and_cancel_methods(self): ) assert result['success'] is True - order1_id = result['order_id'] + order1_id = result['order_id'] time.sleep(self.sleep_time) @@ -68,7 +68,7 @@ def test_order_placement_status_and_cancel_methods(self): assert open_orders[0]['id'] == order1_id assert open_orders[0]['price'] == order1_price assert open_orders[0]['volume_remaining'] == order_volume - + time.sleep(self.sleep_time) # Test the get_order_details function. @@ -91,7 +91,7 @@ def test_order_placement_status_and_cancel_methods(self): ) assert result['success'] is True - order2_id = result['order_id'] + order2_id = result['order_id'] time.sleep(self.sleep_time) diff --git a/gryphon/tests/environment/exchange_wrappers/quadriga_auth.py b/gryphon/tests/environment/exchange_wrappers/quadriga_auth.py index c3e5624..546b594 100644 --- a/gryphon/tests/environment/exchange_wrappers/quadriga_auth.py +++ b/gryphon/tests/environment/exchange_wrappers/quadriga_auth.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.quadriga_btc_cad import QuadrigaBTCCADExchange from gryphon.tests.exceptional.exchange_wrappers.auth_methods import ExchangeAuthMethodsTests diff --git a/gryphon/tests/environment/exchange_wrappers/quadriga_live_orders.py b/gryphon/tests/environment/exchange_wrappers/quadriga_live_orders.py index 1a619d5..dc1e8ea 100644 --- a/gryphon/tests/environment/exchange_wrappers/quadriga_live_orders.py +++ b/gryphon/tests/environment/exchange_wrappers/quadriga_live_orders.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.quadriga_btc_cad import QuadrigaBTCCADExchange from gryphon.tests.exceptional.exchange_wrappers.live_orders import LiveOrdersTest diff --git a/gryphon/tests/extra/libraries/sharpe_test.py b/gryphon/tests/extra/libraries/sharpe_test.py index 7ab1232..9ed1a4b 100644 --- a/gryphon/tests/extra/libraries/sharpe_test.py +++ b/gryphon/tests/extra/libraries/sharpe_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import gryphon.lib; gryphon.lib.prepare() import datetime diff --git a/gryphon/tests/logic/auditing/auditing_test.py b/gryphon/tests/logic/auditing/auditing_test.py index 965af64..0de2941 100644 --- a/gryphon/tests/logic/auditing/auditing_test.py +++ b/gryphon/tests/logic/auditing/auditing_test.py @@ -2,7 +2,7 @@ Tests for gryphon.execution.auditing. """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import gryphon.lib; gryphon.lib.prepare() import unittest diff --git a/gryphon/tests/logic/configuration/base_test.py b/gryphon/tests/logic/configuration/base_test.py index 8d41e04..8fd44ff 100644 --- a/gryphon/tests/logic/configuration/base_test.py +++ b/gryphon/tests/logic/configuration/base_test.py @@ -2,7 +2,7 @@ Tests for the gryphon.lib configuration library. """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest import mock import sure @@ -52,7 +52,7 @@ def test_parse_list_simple(self): value = 'bitstamp' output = configuration.parse_configurable_as_list(value) - + len(output).should.equal(1) output[0].should.equal('bitstamp') @@ -60,8 +60,8 @@ def test_parse_list_more(self): value = 'bitstamp,coinbase,kraken' output = configuration.parse_configurable_as_list(value) - - len(output).should.equal(3) + + len(output).should.equal(3) output[0].should.equal('bitstamp') output[1].should.equal('coinbase') output[2].should.equal('kraken') @@ -70,16 +70,16 @@ def test_parse_list_simple_trailing_comma(self): value = 'bitstamp,' output = configuration.parse_configurable_as_list(value) - - len(output).should.equal(1) + + len(output).should.equal(1) output[0].should.equal('bitstamp') def test_parse_list_more_trailing_comma(self): value = 'bitstamp,coinbase,kraken,' output = configuration.parse_configurable_as_list(value) - - len(output).should.equal(3) + + len(output).should.equal(3) output[0].should.equal('bitstamp') output[1].should.equal('coinbase') output[2].should.equal('kraken') @@ -88,8 +88,8 @@ def test_parse_list_many_commas(self): value = ',bitstamp,coinbase,,,kraken,,,,' output = configuration.parse_configurable_as_list(value) - - len(output).should.equal(3) + + len(output).should.equal(3) output[0].should.equal('bitstamp') output[1].should.equal('coinbase') output[2].should.equal('kraken') @@ -169,8 +169,8 @@ def test_parse_sections_trivial(self): parsed = configuration.parse_sections(parser) - len(parsed.keys()).should.equal(1) - parsed.keys().should.equal(['strategy']) + len(list(parsed.keys())).should.equal(1) + list(parsed.keys()).should.equal(['strategy']) parsed['strategy'].should.equal({'midpoint': Decimal('0.001')}) def test_parse_sections_simple(self): @@ -178,8 +178,8 @@ def test_parse_sections_simple(self): parsed = configuration.parse_sections(parser) - len(parsed.keys()).should.equal(1) - parsed.keys().should.equal(['strategy']) + len(list(parsed.keys())).should.equal(1) + list(parsed.keys()).should.equal(['strategy']) parsed['strategy']['midpoint'].should.equal(Decimal('0.001')) parsed['strategy']['quote_depth'].should.equal(Money('20', 'BTC')) parsed['strategy']['use_gds'].should.equal(True) @@ -190,8 +190,8 @@ def test_parse_sections_multi_section(self): parsed = configuration.parse_sections(parser) - len(parsed.keys()).should.equal(2) - parsed.keys().should.equal(['platform', 'strategy']) + len(list(parsed.keys())).should.equal(2) + list(parsed.keys()).should.equal(['platform', 'strategy']) parsed['strategy']['tick_sleep'].should.equal(Decimal('1')) parsed['platform']['audit'].should.equal(False) @@ -200,12 +200,12 @@ def test_parse_sections_subsection(self): parsed = configuration.parse_sections(parser) - len(parsed.keys()).should.equal(2) - parsed.keys().should.equal(['platform', 'strategy']) + len(list(parsed.keys())).should.equal(2) + list(parsed.keys()).should.equal(['platform', 'strategy']) parsed['strategy']['tick_sleep'].should.equal(Decimal('1')) parsed['platform']['audit'].should.equal(False) - parsed['strategy']['midpoint_weights'].keys().should.equal([ + list(parsed['strategy']['midpoint_weights'].keys()).should.equal([ 'coinbase_btc_usd', 'bitstamp_btc_usd', ]) @@ -215,5 +215,3 @@ def test_parse_sections_subsection(self): parsed['strategy']['midpoint_weights']['bitstamp_btc_usd']\ .should.equal(Decimal('0.5')) - - diff --git a/gryphon/tests/logic/configuration/bitstamp_bch_btc_test.py b/gryphon/tests/logic/configuration/bitstamp_bch_btc_test.py index 1663dec..5b68d76 100644 --- a/gryphon/tests/logic/configuration/bitstamp_bch_btc_test.py +++ b/gryphon/tests/logic/configuration/bitstamp_bch_btc_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/bitstamp_bch_eur_test.py b/gryphon/tests/logic/configuration/bitstamp_bch_eur_test.py index 90bf535..0c87d36 100644 --- a/gryphon/tests/logic/configuration/bitstamp_bch_eur_test.py +++ b/gryphon/tests/logic/configuration/bitstamp_bch_eur_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/bitstamp_bch_usd_test.py b/gryphon/tests/logic/configuration/bitstamp_bch_usd_test.py index 246cfa8..7c11c79 100644 --- a/gryphon/tests/logic/configuration/bitstamp_bch_usd_test.py +++ b/gryphon/tests/logic/configuration/bitstamp_bch_usd_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/bitstamp_btc_eur_test.py b/gryphon/tests/logic/configuration/bitstamp_btc_eur_test.py index cb7e991..132db3b 100644 --- a/gryphon/tests/logic/configuration/bitstamp_btc_eur_test.py +++ b/gryphon/tests/logic/configuration/bitstamp_btc_eur_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/bitstamp_eth_btc_test.py b/gryphon/tests/logic/configuration/bitstamp_eth_btc_test.py index 026e439..1ae75aa 100644 --- a/gryphon/tests/logic/configuration/bitstamp_eth_btc_test.py +++ b/gryphon/tests/logic/configuration/bitstamp_eth_btc_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/bitstamp_eth_eur_test.py b/gryphon/tests/logic/configuration/bitstamp_eth_eur_test.py index bb7966a..dde6fda 100644 --- a/gryphon/tests/logic/configuration/bitstamp_eth_eur_test.py +++ b/gryphon/tests/logic/configuration/bitstamp_eth_eur_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/bitstamp_eth_usd_test.py b/gryphon/tests/logic/configuration/bitstamp_eth_usd_test.py index a67d373..3f3afdc 100644 --- a/gryphon/tests/logic/configuration/bitstamp_eth_usd_test.py +++ b/gryphon/tests/logic/configuration/bitstamp_eth_usd_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/bitstamp_test.py b/gryphon/tests/logic/configuration/bitstamp_test.py index 0b61eb3..9ff7011 100644 --- a/gryphon/tests/logic/configuration/bitstamp_test.py +++ b/gryphon/tests/logic/configuration/bitstamp_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/coinbase_test.py b/gryphon/tests/logic/configuration/coinbase_test.py index af44d91..e88190d 100644 --- a/gryphon/tests/logic/configuration/coinbase_test.py +++ b/gryphon/tests/logic/configuration/coinbase_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/exchange.py b/gryphon/tests/logic/configuration/exchange.py index a5ddaec..1cb9b81 100644 --- a/gryphon/tests/logic/configuration/exchange.py +++ b/gryphon/tests/logic/configuration/exchange.py @@ -1,7 +1,7 @@ """ Just a few exercises for our configuration library. """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import os import time @@ -30,7 +30,7 @@ def test_simple(self): }, } } - + exchange = self.exchange_class(configuration=configuration) assert exchange.fiat_balance_tolerance == Money('1', self.price_currency) diff --git a/gryphon/tests/logic/configuration/execution_config_test.py b/gryphon/tests/logic/configuration/execution_config_test.py index 6df4fc1..39d7b67 100644 --- a/gryphon/tests/logic/configuration/execution_config_test.py +++ b/gryphon/tests/logic/configuration/execution_config_test.py @@ -2,7 +2,7 @@ Just a few exercises for the execution configuration helper library. """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import os import time import unittest @@ -80,8 +80,8 @@ def test_parse_extra_args(self): parsed = config_helper.parse_extra_strategy_args(extra_args) - assert len(parsed.keys()) == 1 - assert parsed.keys()[0] == 'spread' + assert len(list(parsed.keys())) == 1 + assert list(parsed.keys())[0] == 'spread' assert parsed['spread'] == Decimal('0.01') def test_parse_extra_args_boolean(self): @@ -89,8 +89,8 @@ def test_parse_extra_args_boolean(self): parsed = config_helper.parse_extra_strategy_args(extra_args) - assert len(parsed.keys()) == 1 - assert parsed.keys()[0] == 'market_order' + assert len(list(parsed.keys())) == 1 + assert list(parsed.keys())[0] == 'market_order' assert parsed['market_order'] == True def test_parse_extra_args_complex(self): @@ -103,7 +103,7 @@ def test_parse_extra_args_complex(self): parsed = config_helper.parse_extra_strategy_args(extra_args) - assert len(parsed.keys()) == 4 + assert len(list(parsed.keys())) == 4 assert parsed['spread'] == Decimal('0.1') assert parsed['market_order'] == True assert parsed['exchange'] == 'bitstamp' @@ -150,6 +150,6 @@ def test_standardization_exchanges(self): new_config = config_helper.format_file_config_to_standard(base_config) len(new_config['exchanges']).should.equal(1) - len(new_config['exchanges']['coinbase_btc_usd'].keys()).should.equal(1) + len(list(new_config['exchanges']['coinbase_btc_usd'].keys())).should.equal(1) new_config['exchanges']['coinbase_btc_usd']['fiat_balance_tolerance']\ .should.equal(Money('0.01', 'USD')) diff --git a/gryphon/tests/logic/configuration/gemini_eth_btc_test.py b/gryphon/tests/logic/configuration/gemini_eth_btc_test.py index 9041dfa..fb30e4e 100644 --- a/gryphon/tests/logic/configuration/gemini_eth_btc_test.py +++ b/gryphon/tests/logic/configuration/gemini_eth_btc_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/gemini_eth_usd_test.py b/gryphon/tests/logic/configuration/gemini_eth_usd_test.py index 53bc15f..7605d49 100644 --- a/gryphon/tests/logic/configuration/gemini_eth_usd_test.py +++ b/gryphon/tests/logic/configuration/gemini_eth_usd_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/gemini_test.py b/gryphon/tests/logic/configuration/gemini_test.py index c14bc89..8d39bec 100644 --- a/gryphon/tests/logic/configuration/gemini_test.py +++ b/gryphon/tests/logic/configuration/gemini_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/itbit_test.py b/gryphon/tests/logic/configuration/itbit_test.py index 210c176..746d52b 100644 --- a/gryphon/tests/logic/configuration/itbit_test.py +++ b/gryphon/tests/logic/configuration/itbit_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/kraken_cad_test.py b/gryphon/tests/logic/configuration/kraken_cad_test.py index a5fa029..4681693 100644 --- a/gryphon/tests/logic/configuration/kraken_cad_test.py +++ b/gryphon/tests/logic/configuration/kraken_cad_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/kraken_test.py b/gryphon/tests/logic/configuration/kraken_test.py index 8f1dc56..1b3cb3e 100644 --- a/gryphon/tests/logic/configuration/kraken_test.py +++ b/gryphon/tests/logic/configuration/kraken_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/kraken_usd_test.py b/gryphon/tests/logic/configuration/kraken_usd_test.py index 5210c66..d194b84 100644 --- a/gryphon/tests/logic/configuration/kraken_usd_test.py +++ b/gryphon/tests/logic/configuration/kraken_usd_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/quadriga_test.py b/gryphon/tests/logic/configuration/quadriga_test.py index c9c4aea..30099c0 100644 --- a/gryphon/tests/logic/configuration/quadriga_test.py +++ b/gryphon/tests/logic/configuration/quadriga_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/logic/configuration/strategy_config_test.py b/gryphon/tests/logic/configuration/strategy_config_test.py index 129ec8f..86a45f1 100644 --- a/gryphon/tests/logic/configuration/strategy_config_test.py +++ b/gryphon/tests/logic/configuration/strategy_config_test.py @@ -1,7 +1,7 @@ """ Just a few exercises for our configuration library. """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest import mock @@ -39,7 +39,7 @@ def test_simple(self): }, 'exchanges': {}, } - + strat = SimpleMarketMaking(None, self.mock_harness, configuration['strategy']) assert strat.spread == Decimal('1') diff --git a/gryphon/tests/logic/exchange_wrappers/bitstamp_test.py b/gryphon/tests/logic/exchange_wrappers/bitstamp_test.py index 360bcd1..d9b61ef 100644 --- a/gryphon/tests/logic/exchange_wrappers/bitstamp_test.py +++ b/gryphon/tests/logic/exchange_wrappers/bitstamp_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.bitstamp_btc_usd import BitstampBTCUSDExchange from gryphon.tests.logic.exchange_wrappers.public_methods import ExchangePublicMethodsTests diff --git a/gryphon/tests/logic/exchange_wrappers/coinbase.py b/gryphon/tests/logic/exchange_wrappers/coinbase.py index 6eba85d..353a456 100644 --- a/gryphon/tests/logic/exchange_wrappers/coinbase.py +++ b/gryphon/tests/logic/exchange_wrappers/coinbase.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.coinbase_btc_usd import CoinbaseBTCUSDExchange from gryphon.tests.logic.exchange_wrappers.public_methods import ExchangePublicMethodsTests diff --git a/gryphon/tests/logic/exchange_wrappers/gemini_test.py b/gryphon/tests/logic/exchange_wrappers/gemini_test.py index b5a5206..8d754dc 100644 --- a/gryphon/tests/logic/exchange_wrappers/gemini_test.py +++ b/gryphon/tests/logic/exchange_wrappers/gemini_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.gemini_btc_usd import GeminiBTCUSDExchange from gryphon.tests.logic.exchange_wrappers.public_methods import ExchangePublicMethodsTests diff --git a/gryphon/tests/logic/exchange_wrappers/itbit.py b/gryphon/tests/logic/exchange_wrappers/itbit.py index 6eb8f1f..bdc6548 100644 --- a/gryphon/tests/logic/exchange_wrappers/itbit.py +++ b/gryphon/tests/logic/exchange_wrappers/itbit.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.itbit_btc_usd import ItbitBTCUSDExchange from gryphon.tests.logic.exchange_wrappers.public_methods import ExchangePublicMethodsTests diff --git a/gryphon/tests/logic/exchange_wrappers/kraken.py b/gryphon/tests/logic/exchange_wrappers/kraken.py index 5c39057..f9e1985 100644 --- a/gryphon/tests/logic/exchange_wrappers/kraken.py +++ b/gryphon/tests/logic/exchange_wrappers/kraken.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.kraken_btc_eur import KrakenBTCEURExchange from gryphon.tests.logic.exchange_wrappers.public_methods import ExchangePublicMethodsTests diff --git a/gryphon/tests/logic/exchange_wrappers/public_methods.py b/gryphon/tests/logic/exchange_wrappers/public_methods.py index 08e9f78..a281c9e 100644 --- a/gryphon/tests/logic/exchange_wrappers/public_methods.py +++ b/gryphon/tests/logic/exchange_wrappers/public_methods.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import logging import os diff --git a/gryphon/tests/logic/exchange_wrappers/quadriga.py b/gryphon/tests/logic/exchange_wrappers/quadriga.py index b0a6bd7..7a5545d 100644 --- a/gryphon/tests/logic/exchange_wrappers/quadriga.py +++ b/gryphon/tests/logic/exchange_wrappers/quadriga.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) from gryphon.lib.exchange.quadriga_btc_cad import QuadrigaBTCCADExchange from gryphon.tests.logic.exchange_wrappers.public_methods import ExchangePublicMethodsTests diff --git a/gryphon/tests/logic/libraries/arbitrage_test.py b/gryphon/tests/logic/libraries/arbitrage_test.py index f4835bb..f13f38c 100644 --- a/gryphon/tests/logic/libraries/arbitrage_test.py +++ b/gryphon/tests/logic/libraries/arbitrage_test.py @@ -8,7 +8,7 @@ we can test e.g. detecting arbitrage between USD and CAD priced orderbooks. """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import gryphon.lib; gryphon.lib.prepare() import unittest diff --git a/gryphon/tests/logic/libraries/close_options_test.py b/gryphon/tests/logic/libraries/close_options_test.py index 3941d3b..e5798c3 100644 --- a/gryphon/tests/logic/libraries/close_options_test.py +++ b/gryphon/tests/logic/libraries/close_options_test.py @@ -2,7 +2,7 @@ Unit tests for gryphon.lib.gryphonfury.close_options """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import gryphon.lib; gryphon.lib.prepare() import mock diff --git a/gryphon/tests/logic/libraries/market_making_test.py b/gryphon/tests/logic/libraries/market_making_test.py index 4c6312e..9b80280 100644 --- a/gryphon/tests/logic/libraries/market_making_test.py +++ b/gryphon/tests/logic/libraries/market_making_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import os import unittest diff --git a/gryphon/tests/logic/libraries/midpoint_test.py b/gryphon/tests/logic/libraries/midpoint_test.py index 5320e11..eda6bd1 100644 --- a/gryphon/tests/logic/libraries/midpoint_test.py +++ b/gryphon/tests/logic/libraries/midpoint_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import os import unittest diff --git a/gryphon/tests/logic/libraries/money_test.py b/gryphon/tests/logic/libraries/money_test.py index c5a11b2..78cba1d 100644 --- a/gryphon/tests/logic/libraries/money_test.py +++ b/gryphon/tests/logic/libraries/money_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import gryphon.lib; gryphon.lib.prepare() import os diff --git a/gryphon/tests/logic/libraries/order_sliding_test.py b/gryphon/tests/logic/libraries/order_sliding_test.py index b1ba817..1b00565 100644 --- a/gryphon/tests/logic/libraries/order_sliding_test.py +++ b/gryphon/tests/logic/libraries/order_sliding_test.py @@ -6,7 +6,7 @@ not guaranteed that our fee levels on a given exchange won't change. """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import gryphon.lib; gryphon.lib.prepare() import unittest @@ -51,7 +51,7 @@ def setUp(self): def tearDown(self): pass - + def test_trivial_bid(self): mode = Consts.BID initial_price = Money('999', 'USD') diff --git a/gryphon/tests/logic/libraries/orderbook_strength_test.py b/gryphon/tests/logic/libraries/orderbook_strength_test.py index af5d3e0..61992bd 100644 --- a/gryphon/tests/logic/libraries/orderbook_strength_test.py +++ b/gryphon/tests/logic/libraries/orderbook_strength_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import os import unittest @@ -21,14 +21,14 @@ def setUp(self): self.exchange = None bid = ExchangeOrder( - Money('249', 'USD'), + Money('249', 'USD'), Money('10', 'BTC'), self.exchange, Order.BID, ) - + ask = ExchangeOrder( - Money('251', 'USD'), + Money('251', 'USD'), Money('10', 'BTC'), self.exchange, Order.ASK, diff --git a/gryphon/tests/logic/libraries/revenue_test.py b/gryphon/tests/logic/libraries/revenue_test.py index d2f48f4..07fa06e 100644 --- a/gryphon/tests/logic/libraries/revenue_test.py +++ b/gryphon/tests/logic/libraries/revenue_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import gryphon.lib; gryphon.lib.prepare() from decimal import Decimal @@ -155,14 +155,14 @@ def test_profit_units_with_btc_and_fiat_fees_and_cad(self): self.ask.volume = Money('1', 'BTC') self.ask.price = Money('101', 'CAD') self.ask.fee = Money('1', 'CAD') - + self.order.fundamental_value = Money(250, 'CAD') - + matched_trades, position_trades = revenue_lib.split_trades(self.trades) profit_units = revenue_lib.profit_units(matched_trades) profit_units.should.have.length_of(1) profit_units[0]['profit'].should.equal(Money('-2.50', 'CAD')) - + def test_profit_with_btc_and_fiat_fees_and_cad(self): self.bid.volume = Money('1', 'BTC') self.bid.price = Money('100', 'CAD') @@ -171,9 +171,9 @@ def test_profit_with_btc_and_fiat_fees_and_cad(self): self.ask.volume = Money('1', 'BTC') self.ask.price = Money('101', 'CAD') self.ask.fee = Money('1', 'CAD') - + self.order.fundamental_value = Money(250, 'CAD') - + matched_trades, position_trades = revenue_lib.split_trades(self.trades) p = revenue_lib.realized_pl(matched_trades) diff --git a/gryphon/tests/logic/libraries/volume_available_test.py b/gryphon/tests/logic/libraries/volume_available_test.py index af7d418..c58a7d6 100644 --- a/gryphon/tests/logic/libraries/volume_available_test.py +++ b/gryphon/tests/logic/libraries/volume_available_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest @@ -18,14 +18,14 @@ def setUp(self): self.exchange = None bid = ExchangeOrder( - Money('249', 'USD'), + Money('249', 'USD'), Money('10', 'BTC'), self.exchange, Order.BID, ) - + ask = ExchangeOrder( - Money('251', 'USD'), + Money('251', 'USD'), Money('10', 'BTC'), self.exchange, Order.ASK, @@ -65,7 +65,7 @@ def test_empty(self): self.empty_book, ) except Exception: - did_throw_exception = True + did_throw_exception = True did_throw_exception.should.equal(True) diff --git a/gryphon/tests/logic/models/balance_test.py b/gryphon/tests/logic/models/balance_test.py index ec11cb9..0f55011 100644 --- a/gryphon/tests/logic/models/balance_test.py +++ b/gryphon/tests/logic/models/balance_test.py @@ -2,7 +2,7 @@ This file tests the Balance class, which also tests for us the Position and Target classes, since they are just clones of Balance. """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest import sure diff --git a/gryphon/tests/logic/models/liability_test.py b/gryphon/tests/logic/models/liability_test.py index 5c66b37..9f283db 100644 --- a/gryphon/tests/logic/models/liability_test.py +++ b/gryphon/tests/logic/models/liability_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import gryphon.lib; gryphon.lib.prepare() import os diff --git a/gryphon/tests/logic/models/order_test.py b/gryphon/tests/logic/models/order_test.py index ead2182..0fd22c6 100644 --- a/gryphon/tests/logic/models/order_test.py +++ b/gryphon/tests/logic/models/order_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import os import unittest diff --git a/gryphon/tests/logic/models/trade_test.py b/gryphon/tests/logic/models/trade_test.py index f76e8d4..3004730 100644 --- a/gryphon/tests/logic/models/trade_test.py +++ b/gryphon/tests/logic/models/trade_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import gryphon.lib; gryphon.lib.prepare() import os diff --git a/gryphon/tests/logic/models/transaction_test.py b/gryphon/tests/logic/models/transaction_test.py index 4e5e2e7..f48a469 100644 --- a/gryphon/tests/logic/models/transaction_test.py +++ b/gryphon/tests/logic/models/transaction_test.py @@ -1,4 +1,4 @@ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import os import unittest diff --git a/gryphon/tests/logic/strategies/multi_test.py b/gryphon/tests/logic/strategies/multi_test.py index b715cc3..ddf46ec 100644 --- a/gryphon/tests/logic/strategies/multi_test.py +++ b/gryphon/tests/logic/strategies/multi_test.py @@ -2,7 +2,7 @@ Some simple tests for the Multiexchange Linear Market Making strategy. """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import unittest diff --git a/gryphon/tests/runtests.py b/gryphon/tests/runtests.py index 7d0c0aa..1b89b1e 100755 --- a/gryphon/tests/runtests.py +++ b/gryphon/tests/runtests.py @@ -3,7 +3,7 @@ point. """ -import pyximport; pyximport.install() +import pyximport; pyximport.install(language_level=2 if bytes == str else 3) import logging import os diff --git a/setup.py b/setup.py index f17aadc..757c3af 100755 --- a/setup.py +++ b/setup.py @@ -37,6 +37,7 @@ def run(self): url='http://www.gryphonframework.org', classifiers=( 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.6', 'Operating System :: OS Independent', 'License :: Other/Proprietary License', ), @@ -58,11 +59,11 @@ def run(self): 'chardet==3.0.4', 'coinbase==1.0.4', 'contextlib2==0.5.5', - 'Cython==0.20.1', + 'Cython==0.29.12', 'decorator==4.3.0', 'Delorean>=1.0.0,<2', 'enum34==1.1.6', - 'futures==3.2.0', + 'futures==3.2.0 ; python_version<"3.0"', 'gryphon-cdecimal==2.3', 'gryphon-money', # Our fork of Python Money. 'gryphon-pusherclient', # Our duplicate of PythonPusherClient. @@ -74,7 +75,8 @@ def run(self): 'MarkupSafe==1.0', 'mock==1.0.1', 'more-itertools>=4.2.0,<5', - 'MySQL-python==1.2.5', + 'MySQL-python==1.2.5 ; python_version<"3.0"', + 'mysql-connector-python ; python_version>="3.0"', 'nose==1.3.7', 'pathlib2==2.3.2', 'pexpect==4.6.0', @@ -94,7 +96,7 @@ def run(self): 'retrying==1.3.3', 'scandir==1.7', 'simplegeneric==0.8.1', - 'six==1.11.0', + 'six==1.12.0', 'sure==1.2.9', 'SQLAlchemy>=1.2.10,<1.3', 'termcolor==1.1.0',