Exemple #1
0
    def __init__(self):
        self.logger = logging.getLogger('root')

        setup_custom_logger('order', log_level=settings.LOG_LEVEL)
        self.exe_logger = logging.getLogger('order')

        self.__reset()
Exemple #2
0
    def __connect(self, wsURL):
        '''Connect to the websocket in a thread.'''
        self.logger.debug("Starting thread")

        ssl_defaults = ssl.get_default_verify_paths()
        sslopt_ca_certs = {'ca_certs': ssl_defaults.cafile}
        self.ws = websocket.WebSocketApp(wsURL,
                                         on_message=self.__on_message,
                                         on_close=self.__on_close,
                                         on_open=self.__on_open,
                                         on_error=self.__on_error,
                                         header=self.__get_auth())

        setup_custom_logger('websocket', log_level=settings.LOG_LEVEL)
        self.wst = threading.Thread(
            target=lambda: self.ws.run_forever(sslopt=sslopt_ca_certs))
        self.wst.daemon = True
        self.wst.start()
        self.logger.info("Started thread")

        # Wait for connect before continuing
        conn_timeout = 5
        while (not self.ws.sock or not self.ws.sock.connected
               ) and conn_timeout and not self._error:
            sleep(1)
            conn_timeout -= 1

        if not conn_timeout or self._error:
            self.logger.error("Couldn't connect to WS! Exiting.")
            self.exit()
            sys.exit(1)
Exemple #3
0
    def __connect(self, wsURL):
        '''Connect to the websocket in a thread.'''
        self.logger.debug("Starting thread")

        ssl_defaults = ssl.get_default_verify_paths()
        sslopt_ca_certs = {'ca_certs': ssl_defaults.cafile}
        self.ws = websocket.WebSocketApp(wsURL,
                                         on_message=self.__on_message,
                                         on_close=self.__on_close,
                                         on_open=self.__on_open,
                                         on_error=self.__on_error,
                                         header=self.__get_auth()
                                         )

        setup_custom_logger('websocket', log_level=settings.LOG_LEVEL)
        self.wst = threading.Thread(target=lambda: self.ws.run_forever(sslopt=sslopt_ca_certs))
        self.wst.daemon = True
        self.wst.start()
        self.logger.info("Started thread")

        # Wait for connect before continuing
        conn_timeout = 5
        while (not self.ws.sock or not self.ws.sock.connected) and conn_timeout and not self._error:
            sleep(1)
            conn_timeout -= 1

        if not conn_timeout or self._error:
            self.logger.error("Couldn't connect to WS! Exiting.")
            self.exit()
            sys.exit(1)
Exemple #4
0
    def __init__(self) -> None:
        self.logger = log.setup_custom_logger('fundingbot')

        self.exchange = ExchangeInterface()

        self.start_balance = self.exchange.get_margin(
        )['marginBalance'] / 100000000

        self.tick_size = self.exchange.get_instrument()['tickSize']

        self.loop_count = 1

        self.start_time = datetime.utcnow().isoformat(timespec='seconds') + 'Z'

        self.last_request = datetime.utcnow()

        self.limits_exist = False

        position = self.exchange.get_position()['currentQty']

        self.hedge_exists = position != 0 and (abs(position) not in [
            settings.POSITION_SIZE_BUY, settings.POSITION_SIZE_SELL
        ])

        self.could_hedge = position == 0

        self.cancel_open_orders()
Exemple #5
0
    def __connect(self, wsURL):
        '''Connect to the websocket in a thread.'''
        self.logger.debug("Starting thread")

        ssl_defaults = ssl.get_default_verify_paths()
        sslopt_ca_certs = {'ca_certs': ssl_defaults.cafile}
        self.ws = websocket.WebSocketApp(wsURL,
                                         on_message=self.__on_message,
                                         on_close=self.__on_close,
                                         on_open=self.__on_open,
                                         on_error=self.__on_error,
                                         header=self.__get_auth())

        setup_custom_logger('websocket', log_level=settings.LOG_LEVEL)
        self.wst = threading.Thread(
            target=lambda: self.ws.run_forever(sslopt=sslopt_ca_certs))
        self.wst.daemon = True
        self.wst.start()
        self.logger.info("Started thread")
        self.__wait_ws(lambda: self.ws.sock and self.ws.sock.connected)
import traceback
import ssl
from time import sleep
import json
import decimal
import logging
from market_maker.settings import settings
from market_maker.auth.APIKeyAuth import generate_expires, generate_signature
from market_maker.utils import log
from market_maker.utils.math import toNearest
from future.utils import iteritems
from future.standard_library import hooks
with hooks():  # Python 2/3 compat
    from urllib.parse import urlparse, urlunparse

logger = log.setup_custom_logger('root')


# Connects to BitMEX websocket for streaming realtime data.
# The Marketmaker still interacts with this as if it were a REST Endpoint, but now it can get
# much more realtime data without heavily polling the API.
#
# The Websocket offers a bunch of data as raw properties right on the object.
# On connect, it synchronously asks for a push of all this data then returns.
# Right after, the MM can start using its data. It will be updated in realtime, so the MM can
# poll as often as it wants.
class BitMEXWebsocket():

    # Don't grow a table larger than this amount. Helps cap memory usage.
    MAX_TABLE_LEN = 200
Exemple #7
0
import uuid

from market_maker.settings import settings
from market_maker.states import *
from market_maker.utils import log

logger = log.setup_custom_logger(f'{uuid.uuid4()}')


class MockExchangeInterface:
    ticker = {'last': 3786.0, 'buy': 3785, 'sell': 3787.0, 'mid': 3787.0}
    position = {
        'avgEntryPrice': 0,
        'avgCostPrice': 0,
        'currentQty': 0,
    }
    orders = []

    def remove_filled_orders(self):
        MockExchangeInterface.orders = list(
            filter(lambda o: o['ordStatus'] != OrderStates.filled,
                   MockExchangeInterface.orders))
        # print(MockExchangeInterface.orders)x
        return MockExchangeInterface.orders

    def set_ticker(self, key, valye):
        MockExchangeInterface.ticker[key] = valye
        MockExchangeInterface.ticker['buy'] = valye - 1
        MockExchangeInterface.ticker['sell'] = valye - 1
        MockExchangeInterface.ticker['mid'] = key
from copy import deepcopy
import linecache
import sys
import threading
from time import sleep

import settings
from market_maker.utils.singleton import singleton_data
from market_maker.utils import log

logger = log.setup_custom_logger('root')
execept_logger = log.setup_custom_logger('exception')
execute_logger = log.setup_custom_logger('order')


class BuyThread(threading.Thread):
    def __init__(self, custom_strategy):
        logger.info("[BuyThread][run] __init__")
        threading.Thread.__init__(self)
        self.custom_strategy = custom_strategy
        singleton_data.instance().setAllowSell(False)
        singleton_data.instance().setBuyThread(True)

        # default(20.0) * (current_quantity / max_order_quantity)
        # The maximum value is the default even if the quantity you have now is greater than max_order.
        # MAX = default(20.0)
        # The more bulk_net_buy orders, the higher the price.
        currentQty = self.custom_strategy.exchange.get_currentQty()
        logger.info("[BuyThread][run] MAX_ORDER_QUENTITY : " +
                    str(settings.MAX_ORDER_QUENTITY))
import atexit
import signal

from market_maker import bitmex
from market_maker.settings import settings
from market_maker.utils import log, constants, errors, math

# Used for reloading the bot - saves modified times of key files
import os

watched_files_mtimes = [(f, getmtime(f)) for f in settings.WATCHED_FILES]

#
# Helpers
#
logger = log.setup_custom_logger("root")


class ExchangeInterface:
    def __init__(self, dry_run=False):
        self.dry_run = dry_run
        if len(sys.argv) > 1:
            self.symbol = sys.argv[1]
        else:
            self.symbol = settings.SYMBOL
        self.bitmex = bitmex.BitMEX(
            base_url=settings.BASE_URL,
            symbol=self.symbol,
            api_key=settings.API_KEY,
            api_secret=settings.API_SECRET,
            order_id_prefix=settings.ORDERID_PREFIX,
Exemple #10
0
import sys
from copy import deepcopy

from market_maker.market_maker import OrderManager, ExchangeInterface
from market_maker.settings import settings
from market_maker.utils import log
from market_maker.states import *

#
# Helpers
#
logger = log.setup_custom_logger('customer')


class CustomOrderManager(OrderManager):
    def __init__(self):
        self.history_orders = []
        self.history_log_message = []
        self.log_message = []
        self.orders = {}
        self.orders[OrderSide.sell] = []
        self.orders[OrderSide.buy] = []
        super().__init__()

    def order_is_filled(self, order):
        cl_ord_id = order.get('clOrdID', False)
        execution = self.exchange.order_by_clOrdID(cl_ord_id)
        if cl_ord_id and len(execution) > 0:
            return execution[-1].get('ordStatus') == OrderStates.filled
        else:
            return False
import linecache
import os
import pathlib
import sys
import threading
import settings

from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
from market_maker.utils import log
from market_maker.utils.singleton import singleton_data

execept_logger = log.setup_custom_logger('exception')
logger = log.setup_custom_logger('root')


class Telegram(threading.Thread):
    def __init__(self, custom_strategy):
        logger.info("[Telegram] __init__")
        threading.Thread.__init__(self)

        self.custom_strategy = custom_strategy
        self.setApiKey()
        #self.chat_id = '1653838244'

    def run(self):
        """Start the bot."""
        logger.info("[telegram][run]")
        # Create the Updater and pass it your bot's token.
        # Make sure to set use_context=True to use the new context based callbacks
        # Post version 12 this will no longer be necessary
import signal
import os
import math

from market_maker import bitmex
from market_maker.settings import settings
from market_maker.utils import log, constants, errors, botmath

# Used for reloading the bot - saves modified times of key files
import os
watched_files_mtimes = [(f, getmtime(f)) for f in settings.WATCHED_FILES]

#
# Helpers
#
logger = log.setup_custom_logger('root')


class ExchangeInterface:
    def __init__(self, dry_run=False):
        self.dry_run = dry_run
        if len(sys.argv) > 1:
            self.symbol = sys.argv[1]
        else:
            self.symbol = settings.SYMBOL
        self.bitmex = bitmex.BitMEX(base_url=settings.BASE_URL, symbol=self.symbol,
                                    apiKey=settings.API_KEY, apiSecret=settings.API_SECRET,
                                    orderIDPrefix=settings.ORDERID_PREFIX, postOnly=settings.POST_ONLY)

    def cancel_order(self, order):
        tickLog = self.get_instrument()['tickLog']
import string
import atexit

from market_maker import bitmex
from market_maker.settings import settings
from market_maker.utils import log, constants, errors

# Used for reloading the bot - saves modified times of key files
import os
watched_files_mtimes = [(f, getmtime(f)) for f in settings.WATCHED_FILES]


#
# Helpers
#
logger = log.setup_custom_logger('root')


class ExchangeInterface:
    def __init__(self, dry_run=False):
        self.dry_run = dry_run
        if len(sys.argv) > 1:
            self.symbol = sys.argv[1]
        else:
            self.symbol = settings.SYMBOL
        self.bitmex = bitmex.BitMEX(base_url=settings.BASE_URL, symbol=self.symbol, login=settings.LOGIN,
                                    password=settings.PASSWORD, otpToken=settings.OTPTOKEN, apiKey=settings.API_KEY,
                                    apiSecret=settings.API_SECRET, orderIDPrefix=settings.ORDERID_PREFIX)

    def authenticate(self):
        if not self.dry_run:
Exemple #14
0
from datetime import datetime
from dateutil import tz
import signal
import schedule
import threading
from time import sleep

from market_maker.utils import log

from bot import FundingBot
import settings

logger = log.setup_custom_logger('strat')


def half_funding(bot: FundingBot) -> None:
    """4 hours until funding: enter a position
    if funding is negative, go long
    if funding is positive, go short
    """

    bot.could_hedge = False

    bot.exit_position(market=False, wait_for_fill=True)

    bot.cancel_open_orders()

    funding_rate = bot.get_funding_rate()

    logger.info('funding rate: %.4f%%' % (funding_rate * 100))
Exemple #15
0
from market_maker.utils import log, constants, errors, math
import time
import math as math_lib

import threading
import numpy as np
from decimal import *
import pandas as pd
import ccxt

# Chosing the correct settings file based on the parameter
if len(sys.argv) == 1:
    settings = SettingsDict.OPTIONS['XBTUSD']
else:
    settings = SettingsDict.OPTIONS[str(sys.argv[1])]
    logger = log.setup_custom_logger(str(sys.argv[1]))

# Used symbols
SYMBOLS = ['XBTUSD', 'ETHUSD']

print(settings)

from influxdb import InfluxDBClient

# Used for reloading the bot - saves modified times of key files
import os
watched_files_mtimes = [(f, getmtime(f)) for f in settings.WATCHED_FILES]

#
# Helpers
#
from subprocess import run, PIPE, DEVNULL
from time import sleep

import numpy as np
import pytz
import pywt
from dateutil import parser
import talib.stream as ta

import get_history_bitmex
import globalvar
from market_maker import bitmex
from market_maker.utils import log
import api_keys

logger = log.setup_custom_logger('root', log_level='INFO')
if not testing:
    HOST = "https://www.bitmex.com"
    SPEC_URI = HOST + "/api/explorer/swagger.json"

    # See full config options at http://bravado.readthedocs.io/en/latest/configuration.html
    config = {
        # Don't use models (Python classes) instead of dicts for #/definitions/{models}
        'use_models': True,
        # This library has some issues with nullable fields
        'validate_responses': False,
        # Returns response in 2-tuple of (body, response); if False, will only return body
        'also_return_response': False,
    }

    API_KEY = api_keys.bmx_api_key
from market_maker.utils import log, errors, constants
from market_maker.settings import settings
from market_maker.utils.math import toNearest
from future.utils import iteritems
import atexit
import signal
from market_maker.exchange_interface import ExchangeInterface
from market_maker.tape_interface import Tape
import pytz
import random
import uuid  # to generate unique id for linked orders
import stockstats
import math
from market_maker.strategies import funding_rates

logger = log.setup_custom_logger(__name__)
VERSION = 'v0.2'
pd.options.display.width = 300  # for pandas


class OrderManager:
    def __init__(self):
        self.exchange = ExchangeInterface(settings.DRY_RUN)
        # Once exchange is created, register exit handler that will always cancel orders on any error.
        atexit.register(self.exit)
        signal.signal(signal.SIGTERM, self.exit)
        logger.info("Using symbol %s." % self.exchange.symbol)
        # self.start_time = datetime.utcnow()
        self.instrument = self.exchange.get_instrument()
        self.starting_qty = self.exchange.get_currentQty()
        self.running_qty = self.starting_qty
Exemple #18
0
import sys

from market_maker.market_maker import OrderManager

from market_maker.utils import log, constants, errors, math
from market_maker.settings import settings
import requests
from time import sleep

#
# Helpers
#
logger = log.setup_custom_logger('xxx')


class CustomOrderManager(OrderManager):
    def reset(self):
        # self.exchange.cancel_all_orders()
        self.sanity_check()
        self.print_status()

        # Create orders and converge.
        self.place_orders()

    def exit(self):
        try:
            # self.exchange.cancel_all_orders()
            self.exchange.bitmex.exit()
        except errors.AuthenticationError as e:
            logger.info("Was not authenticated; could not cancel orders.")
        except Exception as e:
Exemple #19
0
import signal

from market_maker import bitmex
from market_maker.settings import settings
from market_maker.utils import log, constants, errors

# Used for reloading the bot - saves modified times of key files
import os

watched_files_mtimes = [(f, getmtime(f)) for f in settings.WATCHED_FILES]


#
# Helpers
#
logger = log.setup_custom_logger("root")


class ExchangeInterface:
    def __init__(self, dry_run=False):
        self.dry_run = dry_run
        if len(sys.argv) > 1:
            self.symbol = sys.argv[1]
        else:
            self.symbol = settings.SYMBOL
        self.bitmex = bitmex.BitMEX(
            base_url=settings.BASE_URL,
            symbol=self.symbol,
            login=settings.LOGIN,
            password=settings.PASSWORD,
            otpToken=settings.OTPTOKEN,