Skip to content

Instantly share code, notes, and snippets.

@whardier
Last active July 29, 2017 19:02
Show Gist options
  • Save whardier/aabaaf1564e5a8009b0d07007211a3a3 to your computer and use it in GitHub Desktop.
Save whardier/aabaaf1564e5a8009b0d07007211a3a3 to your computer and use it in GitHub Desktop.
Multiple Order Spread Bot GDAX (Sits at the margin, has a minimum, spreads out orders using the minimum increment for quote currency)
declare -x GDAX_KEY="..."
declare -x GDAX_PASSPHRASE="..."
declare -x GDAX_SECRET="..."
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
# ┏┳┓╻ ╻╻ ╺┳╸╻┏━┓┏━┓┏━┓┏━╸┏━┓╺┳┓┏┓ ┏━┓╺┳╸
# ┃┃┃┃ ┃┃ ┃ ┃┗━┓┣━┛┣┳┛┣╸ ┣━┫ ┃┃┣┻┓┃ ┃ ┃
# ╹ ╹┗━┛┗━╸ ╹ ╹┗━┛╹ ╹┗╸┗━╸╹ ╹╺┻┛┗━┛┗━┛ ╹
# https://gist.github.com/whardier/aabaaf1564e5a8009b0d07007211a3a3
# donations: btc: 1CGkAzqwvCc47316QoyrfDZHNuUNsRCsxj
# donations: eth: 0x49f40801D4041B8E76C8c3DBa3C24cE62BF8Ebf5
# donations: ltc: LbwwqKFE9qnm3LjEWCRVHqF4F7Th6sNjYz
# status: research (not in use)
from __future__ import print_function, unicode_literals
import os
import sys
import time
import argparse
import logging
import decimal
import json
try:
import gdax
import requests
except:
pass
try:
import telepot
except:
telepot = None
__version__ = "0.00"
__useful__ = "not currently useful"
def lazy_format(s, *args, **kwargs):
for key, val in globals().items():
kwargs.setdefault(key, val)
return s.format(*args, **kwargs)
def environ_or_required(key, required_if_present=None):
if os.environ.get(key):
return {'default': os.environ.get(key)}
else:
return {'required': required_if_present in sys.argv if required_if_present else True}
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--version', action='version', version=lazy_format('%(prog)s {__version__} ({__useful__})'))
parser.add_argument('-v', '--verbose', action='count', default=0, help='Verbosity (can be used multiple times)')
gdax_parser = parser.add_argument_group('GDAX', description='Always use latest GDAX module from git')
gdax_parser.add_argument('--gdax-key', **environ_or_required('GDAX_KEY'))
gdax_parser.add_argument('--gdax-secret', **environ_or_required('GDAX_SECRET'))
gdax_parser.add_argument('--gdax-passphrase', **environ_or_required('GDAX_PASSPHRASE'))
if telepot:
teleport_parser = parser.add_argument_group('Teleport', description='See: http://telepot.readthedocs.io/')
teleport_parser.add_argument('--teleport', action='store_true', help='Send bot updates over Teleport')
teleport_parser.add_argument('--teleport-token', **environ_or_required('TELEPORT_TOKEN', '--teleport'))
teleport_parser.add_argument('--teleport-user-id', **environ_or_required('TELEPORT_USER_ID', '--teleport'))
bot_parser = parser.add_argument_group('Bot Parameters')
bot_parser.add_argument('--base-currency', required=True, help='Base Currency (LTC, BTC, ETH, ...)')
bot_parser.add_argument('--quote-currency', required=True, help='Quote Currency (USD, EUR, BTC, ...)')
bot_parser.add_argument('--chunk-size', type=decimal.Decimal, default=decimal.Decimal(0.25), help='Base Currency Chunk Size')
bot_parser.add_argument('--increment-multiplier', type=decimal.Decimal, default=decimal.Decimal(1.0), help='Increment Multiplier')
bot_parser.add_argument('--lowest-quote-price', type=decimal.Decimal, default=decimal.Decimal(0.0), help='Lowest Quote Price (safety)')
args = parser.parse_args()
args.base_currency = args.base_currency.upper()
args.quote_currency = args.quote_currency.upper()
levels = [logging.WARNING, logging.INFO, logging.DEBUG]
level = levels[min(len(levels)-1, args.verbose)]
logging.basicConfig(level=level,
format='%(asctime)s %(levelname)s %(message)s')
logging.debug(repr(args))
# ┏┳┓┏━┓╻┏┓╻
# ┃┃┃┣━┫┃┃┗┫
# ╹ ╹╹ ╹╹╹ ╹
gdax_public_api = gdax.PublicClient()
class GDAXAuthenticatedClient(gdax.AuthenticatedClient):
def get_product_orders(self, product_id):
r = requests.get(self.url + '/orders?product_id=' + product_id, auth=self.auth)
# r.raise_for_status()
return r.json()
gdax_auth_api = GDAXAuthenticatedClient(args.gdax_key, args.gdax_secret, args.gdax_passphrase)
gdax_auth_api
# ┏━╸┏━╸╺┳╸ ┏━┓┏━┓┏━┓╺┳┓╻ ╻┏━╸╺┳╸┏━┓
# ┃╺┓┣╸ ┃ ┣━┛┣┳┛┃ ┃ ┃┃┃ ┃┃ ┃ ┗━┓
# ┗━┛┗━╸ ╹ ╹ ╹┗╸┗━┛╺┻┛┗━┛┗━╸ ╹ ┗━┛
# Set up currencies, decimal precision, and market product information
for product in gdax_public_api.get_products():
if product.get('base_currency') == args.base_currency and \
product.get('quote_currency') == args.quote_currency:
product_base_currency = product['base_currency']
product_base_max_size = decimal.Decimal(product['base_max_size'])
product_base_min_size = decimal.Decimal(product['base_min_size'])
product_quote_currency = product['quote_currency']
product_quote_increment = decimal.Decimal(product['quote_increment'])
product_display_name = product['display_name']
product_id = product['id']
break
logging.info('Setting product to: %s' % product_display_name)
# Order book list to use for a set() intersection filter
while True:
# Check to see if we have orders in the works
orders = gdax_auth_api.get_product_orders(product_id)
ticker = gdax_public_api.get_product_ticker(product_id)
logging.info(json.dumps(ticker, sort_keys=True))
#full second "don't upset gdax" sleep to stay under limits .. this will change as code goes on
time.sleep(1)
-e git+https://github.com/danpaquin/gdax-python.git#egg=gdax
-e git+https://github.com/nickoala/telepot.git#egg=telepot
# Authentication goes to our environment (or command line.. see --help)
source ./gdax-environment.sh
python2.7 ./multi-spread-bot-gdax.py --base-currency LTC --quote-currency USD -vvv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment