Ejemplo n.º 1
0
def configure_worker(whiptail, worker_config):
    # By default always editing
    editing = True

    if not worker_config:
        editing = False

    default_strategy = worker_config.get('module',
                                         'dexbot.strategies.relative_orders')
    strategy_list = []

    for strategy in STRATEGIES:
        if default_strategy == strategy['class']:
            default_strategy = strategy['tag']

        # Add strategy tag and name pairs to a list
        strategy_list.append([strategy['tag'], strategy['name']])

    # Strategy selection
    worker_config['module'] = whiptail.radiolist(
        "Choose a worker strategy",
        select_choice(default_strategy, strategy_list))

    for strategy in STRATEGIES:
        if strategy['tag'] == worker_config['module']:
            worker_config['module'] = strategy['class']

    # Import the strategy class but we don't __init__ it here
    strategy_class = getattr(importlib.import_module(worker_config["module"]),
                             'Strategy')

    # Check if strategy has changed and editing existing worker
    if editing and default_strategy != get_strategy_tag(
            worker_config['module']):
        new_worker_config = {}

        # If strategy has changed, create new config where base elements stay the same
        for config_item in StrategyBase.configure():
            key = config_item[0]
            new_worker_config[key] = worker_config[key]

        # Add module separately to the config
        new_worker_config['module'] = worker_config['module']
        worker_config = new_worker_config

    # Use class metadata for per-worker configuration
    config_elems = strategy_class.configure()
    if config_elems:
        # Strategy options
        for elem in config_elems:
            process_config_element(elem, whiptail, worker_config)
    else:
        whiptail.alert(
            "This worker type does not have configuration information. "
            "You will have to check the worker code and add configuration values to config.yml if required"
        )
    return worker_config
Ejemplo n.º 2
0
 def configure(cls, return_base_config=True):
     return StrategyBase.configure(return_base_config) + [
         ConfigElement(
             'amount', 'float', 1, 'Amount',
             'Fixed order size, expressed in quote asset, unless "relative order size" selected',
             (0, None, 8, '')),
         ConfigElement(
             'relative_order_size', 'bool', False, 'Relative order size',
             'Amount is expressed as a percentage of the account balance of quote/base asset',
             None),
         ConfigElement('spread', 'float', 5, 'Spread',
                       'The percentage difference between buy and sell',
                       (0, 100, 2, '%')),
         ConfigElement(
             'center_price', 'float', 0, 'Center price',
             'Fixed center price expressed in base asset: base/quote',
             (0, None, 8, '')),
         ConfigElement(
             'center_price_dynamic', 'bool', True,
             'Update center price from closest market orders',
             'Always calculate the middle from the closest market orders',
             None),
         ConfigElement(
             'center_price_offset', 'bool', False,
             'Center price offset based on asset balances',
             'Automatically adjust orders up or down based on the imbalance of your assets',
             None),
         ConfigElement(
             'manual_offset', 'float', 0, 'Manual center price offset',
             "Manually adjust orders up or down. "
             "Works independently of other offsets and doesn't override them",
             (-50, 100, 2, '%')),
         ConfigElement(
             'reset_on_partial_fill', 'bool', True,
             'Reset orders on partial fill',
             'Reset orders when buy or sell order is partially filled',
             None),
         ConfigElement(
             'partial_fill_threshold', 'float', 30, 'Fill threshold',
             'Order fill threshold to reset orders', (0, 100, 2, '%')),
         ConfigElement(
             'reset_on_price_change', 'bool', False,
             'Reset orders on center price change',
             'Reset orders when center price is changed more than threshold',
             None),
         ConfigElement(
             'price_change_threshold', 'float', 2, 'Price change threshold',
             'Define center price threshold to react on', (0, 100, 2, '%')),
         ConfigElement(
             'custom_expiration', 'bool', False, 'Custom expiration',
             'Override order expiration time to trigger a reset', None),
         ConfigElement(
             'expiration_time', 'int', 157680000, 'Order expiration time',
             'Define custom order expiration time to force orders reset more often, seconds',
             (30, 157680000, ''))
     ]
Ejemplo n.º 3
0
 def configure(cls, return_base_config=True):
     return StrategyBase.configure(return_base_config) + [
         ConfigElement('external_price_source', 'choice', EXCHANGES[0], 'External price source',
                       'The bot will try to get price information from this source', EXCHANGES),
         ConfigElement('external_feed', 'bool', False, 'External price feed',
                       'Use external reference price instead of center price acquired from the market', None),
         ConfigElement('amount', 'float', 1, 'Amount',
                       'Fixed order size, expressed in quote asset, unless "relative order size" selected',
                       (0, None, 8, '')),
         ConfigElement('relative_order_size', 'bool', False, 'Relative order size',
                       'Amount is expressed as a percentage of the account balance of quote/base asset', None),
         ConfigElement('spread', 'float', 5, 'Spread',
                       'The percentage difference between buy and sell', (0, 100, 2, '%')),
         ConfigElement('dynamic_spread', 'bool', False, 'Dynamic spread',
                       'Enable dynamic spread which overrides the spread field', None),
         ConfigElement('market_depth_amount', 'float', 0, 'Market depth',
                       'From which depth will market spread be measured? (QUOTE amount)',
                       (0.00000001, 1000000000, 8, '')),
         ConfigElement('dynamic_spread_factor', 'float', 1, 'Dynamic spread factor',
                       'How many percent will own spread be compared to market spread?',
                       (0.01, 1000, 2, '%')),
         ConfigElement('center_price', 'float', 0, 'Center price',
                       'Fixed center price expressed in base asset: base/quote', (0, None, 8, '')),
         ConfigElement('center_price_dynamic', 'bool', True, 'Measure center price from market orders',
                       'Estimate the center from closest opposite orders or from a depth', None),
         ConfigElement('center_price_depth', 'float', 0, 'Measurement depth',
                       'Cumulative quote amount from which depth center price will be measured',
                       (0.00000001, 1000000000, 8, '')),
         ConfigElement('center_price_offset', 'bool', False, 'Center price offset based on asset balances',
                       'Automatically adjust orders up or down based on the imbalance of your assets', None),
         ConfigElement('manual_offset', 'float', 0, 'Manual center price offset',
                       "Manually adjust orders up or down. "
                       "Works independently of other offsets and doesn't override them", (-50, 100, 2, '%')),
         ConfigElement('reset_on_partial_fill', 'bool', True, 'Reset orders on partial fill',
                       'Reset orders when buy or sell order is partially filled', None),
         ConfigElement('partial_fill_threshold', 'float', 30, 'Fill threshold',
                       'Order fill threshold to reset orders', (0, 100, 2, '%')),
         ConfigElement('reset_on_price_change', 'bool', False, 'Reset orders on center price change',
                       'Reset orders when center price is changed more than threshold '
                       '(set False for external feeds)', None),
         ConfigElement('price_change_threshold', 'float', 2, 'Price change threshold',
                       'Define center price threshold to react on', (0, 100, 2, '%')),
         ConfigElement('custom_expiration', 'bool', False, 'Custom expiration',
                       'Override order expiration time to trigger a reset', None),
         ConfigElement('expiration_time', 'int', 157680000, 'Order expiration time',
                       'Define custom order expiration time to force orders reset more often, seconds',
                       (30, 157680000, ''))
     ]
Ejemplo n.º 4
0
    def configure(cls, return_base_config=True):
        """ This function is used to auto generate fields for GUI

            :param return_base_config: If base config is used in addition to this configuration.
            :return: List of ConfigElement(s)
        """
        """ As a demonstration this template has two fields in the worker configuration. Upper and lower bound. 
            Documentation of ConfigElements can be found from base.py.
        """
        return StrategyBase.configure(return_base_config) + [
            ConfigElement('lower_bound', 'float', 1, 'Lower bound',
                          'The bottom price in the range',
                          (0, 10000000, 8, '')),
            ConfigElement('upper_bound', 'float', 10, 'Upper bound',
                          'The top price in the range', (0, 10000000, 8, '')),
        ]
Ejemplo n.º 5
0
def configure_worker(whiptail, worker_config, bitshares_instance):
    """ Single worker configurator

        :param whiptail.Whiptail whiptail: instance of Whiptail or NoWhiptail
        :param collections.OrderedDict worker_config: the config dictionary for this worker
        :param bitshares.BitShares bitshares_instance: an instance of BitShares class
    """
    # By default always editing
    editing = True

    if not worker_config:
        editing = False

    default_strategy = worker_config.get('module',
                                         'dexbot.strategies.relative_orders')
    strategy_list = []

    for strategy in STRATEGIES:
        if default_strategy == strategy['class']:
            default_strategy = strategy['tag']

        # Add strategy tag and name pairs to a list
        strategy_list.append([strategy['tag'], strategy['name']])

    # Strategy selection
    worker_config['module'] = whiptail.radiolist(
        "Choose a worker strategy",
        select_choice(default_strategy, strategy_list))

    for strategy in STRATEGIES:
        if strategy['tag'] == worker_config['module']:
            worker_config['module'] = strategy['class']

    # Import the strategy class but we don't __init__ it here
    strategy_class = getattr(importlib.import_module(worker_config["module"]),
                             'Strategy')

    # Check if strategy has changed and editing existing worker
    if editing and default_strategy != get_strategy_tag(
            worker_config['module']):
        new_worker_config = {}
        # If strategy has changed, create new config where base elements stay the same
        for config_item in StrategyBase.configure():
            try:
                key = config_item[0]
                new_worker_config[key] = worker_config[key]
            except KeyError:
                # In case using old configuration file and there are new fields, this passes missing key
                pass

        # Add module separately to the config
        new_worker_config['module'] = worker_config['module']
        worker_config = new_worker_config

    # Use class metadata for per-worker configuration
    config_elems = strategy_class.configure()

    if config_elems:
        # Strategy options
        for elem in config_elems:
            if not editing and (elem.key == "account"):
                # only allow WIF addition for new workers
                account_name = None
                # Query user until correct account and key provided
                while not account_name:
                    account_name = add_account(whiptail, bitshares_instance)
                worker_config[elem.key] = account_name
            else:  # account name only for edit worker
                process_config_element(elem, whiptail, worker_config)
    else:
        whiptail.alert(
            "This worker type does not have configuration information. "
            "You will have to check the worker code and add configuration values to config.yml if required"
        )

    return worker_config