Ejemplo n.º 1
0
    def compute_margin_quantity(self, trader, price):
        quantity = 0.0

        if not trader.has_margin(self.instrument.market_id,
                                 self.instrument.trade_quantity, price):
            msg = "Not enought free margin %s, has %s but need %s" % (
                self.instrument.quote,
                self.instrument.format_quantity(trader.account.margin_balance),
                self.instrument.format_quantity(
                    self.instrument.trade_quantity))

            logger.warning(msg)
            Terminal.inst().notice(msg, view='status')
        else:
            quantity = self.instrument.adjust_quantity(
                self.instrument.trade_quantity)

        return quantity
Ejemplo n.º 2
0
    def execute(self, args):
        if not args:
            Terminal.inst().action("Missing parameters", view='status')
            return False

        if args[0] == 'traders':
            if len(args) == 1:
                self._trader_service.command(Trader.COMMAND_INFO, {})
                return True
            elif len(args) == 2:
                self._trader_service.command(Trader.COMMAND_INFO,
                                             {'trader': args[1]})
                return False
            elif len(args) == 3:
                self._trader_service.command(Trader.COMMAND_INFO, {
                    'trader': args[1],
                    'market-id': args[2]
                })
                return False
        elif args[0] == 'apps':
            if len(args) == 1:
                self._strategy_service.command(Strategy.COMMAND_INFO, {})
                return True
            elif len(args) == 2:
                self._strategy_service.command(Strategy.COMMAND_INFO,
                                               {'appliance': args[1]})
                return True
            elif len(args) == 3:
                self._strategy_service.command(Strategy.COMMAND_INFO, {
                    'appliance': args[1],
                    'market-id': args[2]
                })
                return True
        elif args[0] == 'notifiers':
            if len(args) == 1:
                self._notifier_service.command(Notifier.COMMAND_INFO, {})
                return True
            elif len(args) == 2:
                self._notifier_service.command(Notifier.COMMAND_INFO,
                                               {'notifier': args[1]})
                return True

        return False
Ejemplo n.º 3
0
    def has_max_trades(self, max_trades):
        result = False

        if self.trades:
            self.lock()

            if len(self.trades) >= max_trades:
                # no more than max simultaneous trades
                result = True

            self.unlock()

        if result:
            msg = "Max trade reached for %s with %s" % (self.instrument.symbol, max_trades)

            logger.warning(msg)
            Terminal.inst().notice(msg, view='status')

        return result
Ejemplo n.º 4
0
    def format(self, record):
        colors = self.colors(
            Terminal.inst().style() if Terminal.inst() else "")

        if record.levelno in (logging.ERROR,
                              logging.CRITICAL) and self.use_color:
            record.name = colors['ERROR'] + '- ' + copy.copy(
                record.name) + colors["DEFAULT"] + ' '
            record.levelname = colors['ERROR'] + copy.copy(
                record.levelname) + colors["DEFAULT"] + ' '
            record.msg = colors['ERROR'] + copy.copy(str(
                record.msg)) + colors["DEFAULT"]
            return logging.Formatter.format(self, record)

        elif record.levelno == logging.WARNING and self.use_color:
            record.name = colors["WARNING"] + '- ' + copy.copy(
                record.name) + colors["DEFAULT"] + ' '
            record.levelname = colors["WARNING"] + '- ' + copy.copy(
                record.levelname) + colors["DEFAULT"] + ' '
            record.msg = colors["WARNING"] + copy.copy(str(
                record.msg)) + colors["DEFAULT"]
            return logging.Formatter.format(self, record)

        elif record.levelno == logging.INFO and self.use_color:
            record.name = '- '
            record.levelname = colors["DEFAULT"] + '- ' + copy.copy(
                record.levelname) + colors["DEFAULT"] + ' '
            record.msg = colors["DEFAULT"] + copy.copy(str(
                record.msg)) + colors["DEFAULT"]
            return logging.Formatter.format(self, record)

        elif record.levelno == logging.DEBUG and self.use_color:
            record.name = colors["NOTICE"] + '- ' + copy.copy(
                record.name) + colors["DEFAULT"] + ' '
            record.levelname = colors["NOTICE"] + '- ' + copy.copy(
                record.levelname) + colors["DEFAULT"] + ' '
            record.msg = colors["NOTICE"] + copy.copy(str(
                record.msg)) + colors["DEFAULT"]
            return logging.Formatter.format(self, record)

        else:
            return logging.Formatter.format(self, record)
Ejemplo n.º 5
0
    def execute(self, args):
        if not args:
            return False

        appliance = None
        market_id = None
        trade_id = None

        action = 'stop-loss'
        stop_loss = 0.0
        force = False

        # ie ":SL _ EURUSD 1 1.10"
        if len(args) < 4:
            Terminal.inst().action("Missing parameters", view='status')
            return False

        try:
            appliance, market_id = args[0], args[1]

            trade_id = int(args[2])
            stop_loss = float(args[3])

            if len(args) > 4:
                # create an order or modify the position, else use default
                force = str(args[4]) == "force"

        except Exception:
            Terminal.inst().action("Invalid parameters", view='status')
            return False

        self._strategy_service.command(
            Strategy.COMMAND_TRADE_MODIFY, {
                'appliance': appliance,
                'market-id': market_id,
                'trade-id': trade_id,
                'action': action,
                'stop-loss': stop_loss,
                'force': force
            })

        return True
Ejemplo n.º 6
0
    def execute(self, args):
        if not args:
            Terminal.inst().action("Missing parameters", view='status')
            return False

        appliance = None
        market_id = None
        trade_id = None
        action = "clean"

        # ie ":clean _ XRPUSDT 5"
        if len(args) != 3:
            Terminal.inst().action("Missing parameters", view='status')
            return False

        try:
            appliance, market_id = args[0], args[1]
            trade_id = int(args[2])

        except Exception:
            Terminal.inst().action("Invalid parameters", view='status')
            return False

        self._strategy_service.command(
            Strategy.COMMAND_TRADE_CLEAN, {
                'appliance': appliance,
                'market-id': market_id,
                'trade-id': trade_id,
                'action': action
            })

        return True
Ejemplo n.º 7
0
    def execute(self, args):
        if not args:
            Terminal.inst().action("Missing parameters", view='status')
            return False

        # ie: ":chart altbtc BTCUSDT"
        appliance = None
        market_id = None

        # optionnal timeframe (could depend of the strategy)
        timeframe = None

        if len(args) < 2:
            Terminal.inst().action("Missing parameters", view='status')
            return False

        try:
            appliance, market_id = args[0], args[1]

            if len(args) == 3:
                timeframe = timeframe_from_str(args[2])

        except Exception:
            Terminal.inst().action("Invalid parameters", view='status')
            return False

        self._strategy_service.command(
            Strategy.COMMAND_TRADER_CHART, {
                'appliance': appliance,
                'market-id': market_id,
                'timeframe': timeframe,
                'monitor-url': self._monitor_service.url()
            })
Ejemplo n.º 8
0
    def execute(self, args):
        if not args:
            Terminal.inst().action("Missing parameters", view='status')
            return False

        appliance = None
        market_id = None

        action = 'del-region'
        operation_id = None

        # ie ":rmregion _ EURUSD 1"
        if len(args) < 3:
            Terminal.inst().action("Missing parameters", view='status')
            return False

        try:
            appliance, market_id = args[0], args[1]

            region_id = int(args[2])
        except Exception:
            Terminal.inst().action("Invalid parameters", view='status')
            return False

        self._strategy_service.command(
            Strategy.COMMAND_TRADER_MODIFY, {
                'appliance': appliance,
                'market-id': market_id,
                'action': action,
                'region-id': region_id
            })

        return True
Ejemplo n.º 9
0
    def setup_live(self):
        super().setup_live()

        # pre-feed in live mode only
        Terminal.inst().info("In appliance %s retrieves last data history..." %
                             self.name,
                             view='status')

        now = datetime.now()

        # retrieve recent data history
        for market_id, instrument in self._instruments.items():
            try:
                watcher = instrument.watcher(Watcher.WATCHER_PRICE_AND_VOLUME)
                if watcher:
                    tfs = [(tf['timeframe'], tf['history'])
                           for tf in self.timeframes_config.values()
                           if tf['timeframe'] > 0]
                    watcher.subscribe(instrument.symbol, tfs)

                    # query for most recent candles
                    for k, timeframe in self.timeframes_config.items():
                        if timeframe['timeframe'] > 0:
                            l_from = now - timedelta(
                                seconds=timeframe['history'] *
                                timeframe['timeframe'])
                            l_to = now
                            watcher.historical_data(instrument.symbol,
                                                    timeframe['timeframe'],
                                                    from_date=l_from,
                                                    to_date=l_to)

                            # wait for this timeframe before processing
                            instrument.want_timeframe(timeframe['timeframe'])

            except Exception as e:
                logger.error(repr(e))
                logger.debug(traceback.format_exc())

        Terminal.inst().info("Appliance data retrieved", view='status')
Ejemplo n.º 10
0
    def execute(self, args):
        if not args:
            Terminal.inst().action("Missing parameters", view='status')
            return False

        if args[0] == 'traders':
            if len(args) == 1:
                self._trader_service.set_activity(True)
                Terminal.inst().action("Activated all traders", view='status')
                return True
            elif len(args) == 2:
                # @todo specific trader
                return False

        elif args[0] == 'apps':
            if len(args) == 1:
                self._strategy_service.set_activity(True)
                Terminal.inst().action(
                    "Activated any markets for all appliances", view='status')
                return True
            elif len(args) == 2:
                appliance = self._strategy_service.appliance(args[1])
                if appliance:
                    appliance.set_activity(True)
                    Terminal.inst().action(
                        "Activated any markets for appliances %s" % args[1],
                        view='status')
                return True
            elif len(args) == 3:
                appliance = self._strategy_service.appliance(args[1])
                if appliance:
                    appliance.set_activity(True, args[2])
                    Terminal.inst().action(
                        "Activated instrument %s for appliances %s" %
                        (args[2], args[1]),
                        view='status')
                return True

        return False
Ejemplo n.º 11
0
    def compute_asset_quantity(self, trader, price):
        quantity = 0.0

        if trader.has_asset(self.instrument.quote):
            # quantity = min(quantity, trader.asset(self.instrument.quote).free) / self.instrument.market_ofr
            if trader.has_quantity(self.instrument.quote, self.instrument.trade_quantity):
                quantity = self.instrument.adjust_quantity(self.instrument.trade_quantity / price)  # and adjusted to 0/max/step
            else:
                msg = "Not enought free quote asset %s, has %s but need %s" % (
                    self.instrument.quote,
                    self.instrument.format_quantity(trader.asset(self.instrument.quote).free),
                    self.instrument.format_quantity(self.instrument.trade_quantity))

                logger.warning(msg)
                Terminal.inst().notice(msg, view='status')
        else:
            msg = "Quote asset %s not found" % self.instrument.quote

            logger.warning(msg)
            Terminal.inst().notice(msg, view='status')

        return quantity
Ejemplo n.º 12
0
def display_command_help(commands_handler, command_name):
    name, alias, details = commands_handler.get_command_help(command_name)

    if not name:
        Terminal.inst().message("Command %s not found" % command_name,
                                view='content')
        return

    Terminal.inst().message("Details of the command %s" % name, view='content')
    if alias:
        Terminal.inst().message(" - Alias %s" % alias, view='content')

    if details:
        for entry in details:
            Terminal.inst().message(entry, view='content')
Ejemplo n.º 13
0
def display_welcome():
    Terminal.inst().info("Console", view='content-head')

    Terminal.inst().action(
        "To type a command line, start with a ':', finally validate by <ENTER> or cancel with <ESC>.",
        view='content')
    Terminal.inst().action(
        "Enter command :help or :h for command details, and :quit :q to exit",
        view='content')
Ejemplo n.º 14
0
    def checkout(self):
        var = {
            'pretty': 'false',
            'token': self.__apitoken,
            'limit': 20,
            'offset': 0
        }

        # checkout social traders details and instantiates authors models
        watcher_config = self.service.watcher_config(self._name)

        for trader in watcher_config.get('authors'):
            trader_id = trader['id']
            var['user_id'] = trader_id

            url = self._base_url + 'social/profile_trades.php?' + urllib.parse.urlencode(
                var)

            self._conn.request("GET", url)

            response = self._conn.getresponse()
            data = response.read()

            if response.status != 200:
                Terminal.inst().error(
                    "Http error getting %s user %s trades !" %
                    (self.name, trader_id))
                continue

            data = json.loads(data)

            if data['error'] or data['warning']:
                Terminal.inst().error("API error getting %s user %s trades !" %
                                      (self.name, trader_id))
                continue

            server_date = datetime.strptime(data['server_time'],
                                            "%Y-%m-%dT%H:%M:%S.%fZ")

            user_id = data['response']['user_id']
            user_name = data['response']['username']
            risk_score = int(data['response']['risk_score'])

            # author id stored as string but used as integer into queries
            author = Author(self, str(user_id), user_name)
            self._authors[str(user_id)] = author

            author.risk_score = risk_score
            author.success_rate = risk_score

            Terminal.inst().info("Found user %s id %s (risk:%i)" %
                                 (user_name, user_id, risk_score))
            # @todo logger

            self.service.notify(Signal.SIGNAL_AUTHOR_ADDED, self.name, author)

        self._checkout = True
Ejemplo n.º 15
0
    def table(self, columns, data):
        """
        Draw a table in this view.
        """
        if not columns or data is None:
            return

        self._table = (len(columns), len(data))

        table = tabulate(data, headers=columns, tablefmt='psql', showindex=False, floatfmt=".2f", disable_numparse=True)

        # draw the table
        vt = Terminal.inst().view(self._id)
        if vt:
            vt.draw('', table, True)
Ejemplo n.º 16
0
    def setup_live(self):
        super().setup_live()

        # pre-feed en live mode only
        Terminal.inst().info("> In appliance %s retrieves last data history..." % self.name, True)
        max_retry = 30

        # retrieve recent data history
        for market_id, instrument in self._instruments.items():
            try:
                price_and_vol_watcher = instrument.watcher(Watcher.WATCHER_PRICE_AND_VOLUME)
                if price_and_vol_watcher:
                    # query for most recent candles
                    price_and_vol_watcher.historical_data(market_id, Instrument.TF_MIN, n_last=720)
                    # price_and_vol_watcher.historical_data(market_id, Instrument.TF_5MIN, n_last=120)
                    # price_and_vol_watcher.historical_data(market_id, Instrument.TF_HOUR, n_last=4*24)

                    # buy/sells signals
                    # @todo
            except Exception as e:
                logger.error(repr(e))
                logger.error(traceback.format_exc())

        Terminal.inst().info("> Appliance data retrieved")
Ejemplo n.º 17
0
    def on_key_pressed(self, key):
        super().on_key_pressed(key)

        if Terminal.inst().mode == Terminal.MODE_DEFAULT:
            if key == 'KEY_PPAGE':
                self.scroll_row(-(self.height()-4))   
            elif key == 'KEY_NPAGE':
                self.scroll_row(self.height()-4)
            elif (c == 'KEY_SR' or c == 'j'):
                self.scroll_row(-1)
            elif (c == 'KEY_SF' or c == 'k'):
                self.scroll_row(1)
            elif (c == 'KEY_SLEFT' or c == 'h'):
                self.scroll_col(-1)
            elif (c == 'KEY_SRIGHT' or c == 'l'):
                self.scroll_col(1)
Ejemplo n.º 18
0
def display_welcome():
    Terminal.inst().info("Console", view='content-head')

    Terminal.inst().action(
        "To type a command line, start with a ':', finally validate by <ENTER> or cancel with <ESC>.",
        view='content')
    Terminal.inst().action(
        "Enter command :help or :h for command details, and :quit :q to exit",
        view='content')

    LOGO1 = """
   SSSSSSSSSSSSSSS IIIIIIIIIIIIIIIIIIII   SSSSSSSSSSSSSSS 
 SS:::::::::::::::SI::::::::II::::::::I SS:::::::::::::::S
S:::::SSSSSS::::::SI::::::::II::::::::IS:::::SSSSSS::::::S
S:::::S     SSSSSSSII::::::IIII::::::IIS:::::S     SSSSSSS
S:::::S              I::::I    I::::I  S:::::S            
S:::::S              I::::I    I::::I  S:::::S            
 S::::SSSS           I::::I    I::::I   S::::SSSS         
  SS::::::SSSSS      I::::I    I::::I    SS::::::SSSSS    
    SSS::::::::SS    I::::I    I::::I      SSS::::::::SS  
       SSSSSS::::S   I::::I    I::::I         SSSSSS::::S 
            S:::::S  I::::I    I::::I              S:::::S
            S:::::S  I::::I    I::::I              S:::::S
SSSSSSS     S:::::SII::::::IIII::::::IISSSSSSS     S:::::S
S::::::SSSSSS:::::SI::::::::II::::::::IS::::::SSSSSS:::::S
S:::::::::::::::SS I::::::::II::::::::IS:::::::::::::::SS 
 SSSSSSSSSSSSSSS   IIIIIIIIIIIIIIIIIIII SSSSSSSSSSSSSSS"""

    LOGO2 = """
   ▄████████  ▄█   ▄█     ▄████████ 
  ███    ███ ███  ███    ███    ███ 
  ███    █▀  ███▌ ███▌   ███    █▀  
  ███        ███▌ ███▌   ███        
▀███████████ ███▌ ███▌ ▀███████████ 
         ███ ███  ███           ███ 
   ▄█    ███ ███  ███     ▄█    ███ 
 ▄████████▀  █▀   █▀    ▄████████▀"""

    # ASCII art centered SIIS title
    logo = LOGO1 if randint(0, 10) < 5 else LOGO2
    Terminal.inst().message(logo, view="content")
Ejemplo n.º 19
0
    def table(self, columns, table, total_size=None):
        """
        Draw a table in this view.
        """
        if not columns or table is None:
            return

        self._table = total_size if total_size else (len(columns), len(table))

        table_data = tabulate(table, headers=columns, tablefmt='psql', showindex=False, floatfmt=".2f", disable_numparse=True)

        # replace color espace code before drawing
        for k, v in Color.UTERM_COLORS_MAP.items():
            table_data = table_data.replace(k, v)

        # draw the table
        vt = Terminal.inst().view(self._id)
        if vt:
            vt.draw('', table_data, True)
Ejemplo n.º 20
0
    def execute(self, args):
        if not args:
            Terminal.inst().action("Missing parameters", view='status')
            return False

        appliance = None
        market_id = None
        trade_id = None

        action = "add-op"
        op = "dynamic-stop-loss"

        trigger = 0.0
        stop_loss = 0.0

        # ie ":DSL _ EURUSD 4 1.12 1.15"
        if len(args) != 5:
            Terminal.inst().action("Missing parameters", view='status')
            return False

        try:
            appliance, market_id = args[0], args[1]

            trade_id = int(args[2])

            trigger = float(args[3])
            stop_loss = float(args[4])
        except Exception:
            Terminal.inst().action("Invalid parameters", view='status')
            return False

        self._strategy_service.command(
            Strategy.COMMAND_TRADE_MODIFY, {
                'appliance': appliance,
                'market-id': market_id,
                'trade-id': trade_id,
                'action': action,
                'operation': op,
                'trigger': trigger,
                'stop-loss': stop_loss
            })

        return True
Ejemplo n.º 21
0
def display_help_tools():
    tools = Tool.find_tools()

    for tool in tools:
        try:
            alias, msgs = Tool.tool_help(tool)

            if alias:
                Terminal.inst().message(
                    "  --tool=%s, --%s %s" %
                    (tool, alias, msgs[0] if len(msgs) > 0 else ""))
            else:
                Terminal.inst().message(
                    "  --tool=%s %s" %
                    (tool, msgs[0] if len(msgs) > 0 else ""))

            for msg in msgs[1:]:
                Terminal.inst().message("    " + msg)
        except:
            pass
Ejemplo n.º 22
0
 def command(self, command_type, data):
     if command_type == self.COMMAND_TOGGLE and data and data.get(
             "value", "") == "popup":
         self._popups = not self._popups
         Terminal.inst().action(
             "desktop notifier popups are now %s" %
             ("actives" if self._popups else "disabled", ),
             view='status')
     elif command_type == self.COMMAND_TOGGLE and data and data.get(
             "value", "") == "audible":
         self._audible = not self._audible
         Terminal.inst().action(
             "desktop notifier audio alertes are now %s" %
             ("actives" if self._audible else "disabled", ),
             view='status')
     elif command_type == self.COMMAND_INFO:
         Terminal.inst().info(
             "desktop notifier is %s" %
             ("active" if self._playpause else "disabled", ),
             view='content')
Ejemplo n.º 23
0
    def execute(self, args):
        if not args:
            Terminal.inst().action("Missing parameters", view='status')
            return False

        appliance = None
        market_id = None
        region_id = None

        if len(args) >= 2:
            try:
                appliance, market_id = args[0], args[1]

                if len(args) >= 3:
                    region_id = int(args[2])
                else:
                    region_id = -1

            except Exception:
                Terminal.inst().action("Invalid parameters", view='status')
                return False

            self._strategy_service.command(
                Strategy.COMMAND_TRADER_INFO, {
                    'appliance': appliance,
                    'market-id': market_id,
                    'detail': 'region',
                    'region-id': region_id
                })

            return True
        else:
            Terminal.inst().action("Missing or invalid parameters",
                                   view='status')
            return False

        return False
Ejemplo n.º 24
0
    def execute(self, args):
        if not args:
            Terminal.inst().action("Missing parameters", view='status')
            return False

        appliance = None
        market_id = None
        trade_id = None

        action = 'take-profit'
        take_profit = 0.0

        # ie ":TP _ EURUSD 1 1.15"
        if len(args) < 4:
            Terminal.inst().action("Missing parameters", view='status')
            return False

        try:
            appliance, market_id = args[0], args[1]

            trade_id = int(args[2])
            take_profit = float(args[3])
        except Exception:
            Terminal.inst().action("Invalid parameters", view='status')
            return False

        self._strategy_service.command(
            Strategy.COMMAND_TRADE_MODIFY, {
                'appliance': appliance,
                'market-id': market_id,
                'trade-id': trade_id,
                'action': action,
                'take-profit': take_profit
            })

        return True
Ejemplo n.º 25
0
def do_fetcher(options):
    Terminal.inst().info("Starting SIIS fetcher using %s identity..." %
                         options['identity'])
    Terminal.inst().flush()

    # database manager
    Database.create(options)
    Database.inst().setup(options)

    watcher_service = WatcherService(options)
    fetcher = watcher_service.create_fetcher(options, options['broker'])

    timeframe = -1
    cascaded = None

    if not options.get('timeframe'):
        timeframe = 60  # default to 1min
    else:
        if options['timeframe'] in TIMEFRAME_FROM_STR_MAP:
            timeframe = TIMEFRAME_FROM_STR_MAP[options['timeframe']]
        else:
            try:
                timeframe = int(options['timeframe'])
            except:
                pass

    if not options.get('cascaded'):
        cascaded = None
    else:
        if options['cascaded'] in TIMEFRAME_FROM_STR_MAP:
            cascaded = TIMEFRAME_FROM_STR_MAP[options['cascaded']]
        else:
            try:
                cascaded = int(options['cascaded'])
            except:
                pass

    if timeframe < 0:
        logger.error("Invalid timeframe")
        sys.exit(-1)

    try:
        fetcher.connect()
    except:
        sys.exit(-1)

    if fetcher.connected:
        logger.info("Fetcher authentified to %s, trying to collect data..." %
                    fetcher.name)

        markets = fetcher.matching_symbols_set(options['market'].split(','),
                                               fetcher.available_instruments())

        try:
            for market_id in markets:
                if not fetcher.has_instrument(market_id, options.get('spec')):
                    logger.error("Market %s not found !" % (market_id, ))
                else:
                    if options.get('install-market', False):
                        fetcher.install_market(market_id)
                    else:
                        fetcher.fetch_and_generate(market_id, timeframe,
                                                   options.get('from'),
                                                   options.get('to'),
                                                   options.get('last'),
                                                   options.get('spec'),
                                                   cascaded)

        except KeyboardInterrupt:
            pass
        finally:
            fetcher.disconnect()

    fetcher = None

    Terminal.inst().info("Flushing database...")
    Terminal.inst().flush()

    Database.terminate()

    Terminal.inst().info("Fetch done!")
    Terminal.inst().flush()

    Terminal.terminate()
    sys.exit(0)
Ejemplo n.º 26
0
def exec_indmargin_order(trader, order, market, open_exec_price,
                         close_exec_price):
    """
    Execute the order for indivisible margin position.
    @todo update to support only indivisible margin order
    """
    current_position = None
    positions = []

    trader.lock()

    if order.symbol:
        # in that case position is identifier by its market
        current_position = trader._positions.get(order.symbol)

    if current_position and current_position.is_opened():
        # increase or reduce the current position
        org_quantity = current_position.quantity
        exec_price = 0.0

        #
        # and adjust the position quantity (no possible hedging)
        #

        # price difference depending of the direction
        delta_price = 0
        if current_position.direction == Position.LONG:
            delta_price = close_exec_price - current_position.entry_price
            # logger.debug("cl", delta_price, " use ", close_exec_price, " other ", open_exec_price, close_exec_price < open_exec_price)
        elif current_position.direction == Position.SHORT:
            delta_price = current_position.entry_price - close_exec_price
            # logger.debug("cs", delta_price, " use ", close_exec_price, " other ", open_exec_price, close_exec_price < open_exec_price)

        # keep for percent calculation
        prev_entry_price = current_position.entry_price or close_exec_price
        leverage = order.leverage

        # most of thoose data rarely change except the base_exchange_rate
        value_per_pip = market.value_per_pip
        contract_size = market.contract_size
        lot_size = market.lot_size
        one_pip_means = market.one_pip_means
        base_exchange_rate = market.base_exchange_rate
        margin_factor = market.margin_factor

        # logger.debug(order.symbol, bid_price, ofr_price, open_exec_price, close_exec_price, delta_price, current_position.entry_price, order.price)
        realized_position_cost = 0.0  # realized cost of the position in base currency

        # effective meaning of delta price in base currency
        effective_price = (delta_price / one_pip_means) * value_per_pip

        # in base currency
        position_gain_loss = 0.0

        if order.direction == current_position.direction:
            # first, same direction, increase the position
            # it's what we have really buy
            realized_position_cost = order.quantity * (lot_size * contract_size
                                                       )  # in base currency

            # check available margin
            margin_cost = realized_position_cost * margin_factor / base_exchange_rate

            if not trader.has_margin(margin_cost):
                # and then rejected order
                trader.unlock()

                trader.service.watcher_service.notify(
                    Signal.SIGNAL_ORDER_REJECTED, trader.name,
                    (order.symbol, order.ref_order_id))

                logger.error(
                    "Not enought free margin for %s need %s but have %s!" %
                    (order.symbol, margin_cost, trader.account.margin_balance))
                return False

            # still in long, position size increase and adjust the entry price
            entry_price = (
                (current_position.entry_price * current_position.quantity) +
                (open_exec_price * order.quantity)) / 2
            current_position.entry_price = entry_price
            current_position.quantity += order.quantity

            # directly executed quantity
            order.executed = order.quantity
            exec_price = open_exec_price

            # increase used margin
            trader.account.add_used_margin(margin_cost)
        else:
            # different direction
            if current_position.quantity > order.quantity:
                # first case the direction still the same, reduce the position and the margin
                # take the profit/loss from the difference by order.quantity and adjust the entry price and quantity
                position_gain_loss = effective_price * order.quantity

                # it's what we have really closed
                realized_position_cost = order.quantity * (
                    lot_size * contract_size)  # in base currency

                # and decrease used margin
                trader.account.add_used_margin(-realized_position_cost *
                                               margin_factor /
                                               base_exchange_rate)

                # entry price might not move...
                # current_position.entry_price = ((current_position.entry_price * current_position.quantity) - (close_exec_price * order.quantity)) / 2
                current_position.quantity -= order.quantity
                exec_price = close_exec_price

                # directly executed quantity
                order.executed = order.quantity

            elif current_position.quantity == order.quantity:
                # second case the position is closed, exact quantity in the opposite direction

                position_gain_loss = effective_price * current_position.quantity
                current_position.quantity = 0.0

                # it's what we have really closed
                realized_position_cost = order.quantity * (
                    lot_size * contract_size)  # in base currency

                # directly executed quantity
                order.executed = order.quantity
                exec_price = close_exec_price

                # and decrease used margin
                trader.account.add_used_margin(-realized_position_cost *
                                               margin_factor /
                                               base_exchange_rate)
            else:
                # third case the position is reversed
                # 1) get the profit loss
                position_gain_loss = effective_price * current_position.quantity

                # it's what we have really closed
                realized_position_cost = order.quantity * (
                    lot_size * contract_size)  # in base currency

                # first decrease of released margin
                trader.account.add_used_margin(-realized_position_cost *
                                               margin_factor /
                                               base_exchange_rate)

                # 2) adjust the position entry
                current_position.quantity = order.quantity - current_position.quantity
                current_position.entry_price = open_exec_price

                # 3) the direction is now at opposite
                current_position.direction = order.direction

                # directly executed quantity
                order.executed = order.quantity
                exec_price = open_exec_price

                # next increase margin of the new volume
                trader.account.add_used_margin(
                    (order.quantity * lot_size * contract_size * margin_factor)
                    / base_exchange_rate)

        # transaction time is current timestamp
        order.transact_time = trader.timestamp

        #order.set_position_id(current_position.position_id)

        if position_gain_loss != 0.0 and realized_position_cost > 0.0:
            # ratio
            gain_loss_rate = position_gain_loss / realized_position_cost
            relative_gain_loss_rate = delta_price / prev_entry_price

            # if maker close (limit+post-order) (for now same as market)
            current_position.profit_loss = position_gain_loss
            current_position.profit_loss_rate = gain_loss_rate

            # if taker close (market)
            current_position.profit_loss_market = position_gain_loss
            current_position.profit_loss_market_rate = gain_loss_rate

            trader.account.add_realized_profit_loss(position_gain_loss /
                                                    base_exchange_rate)

            # display only for debug
            if position_gain_loss > 0.0:
                Terminal.inst().high(
                    "Close profitable position with %.2f on %s (%.2fpips) (%.2f%%) at %s"
                    % (position_gain_loss, order.symbol,
                       delta_price / one_pip_means, gain_loss_rate * 100.0,
                       market.format_price(close_exec_price)),
                    view='debug')
            elif position_gain_loss < 0.0:
                Terminal.inst().low(
                    "Close loosing position with %.2f on %s (%.2fpips) (%.2f%%) at %s"
                    % (position_gain_loss, order.symbol,
                       delta_price / one_pip_means, gain_loss_rate * 100.0,
                       market.format_price(close_exec_price)),
                    view='debug')

            logger.debug(
                "Account balance %.2f / Margin balance %.2f" %
                (trader.account.balance, trader.account.margin_balance))
        else:
            gain_loss_rate = 0.0

        #
        # history
        #

        # and keep for history (backtesting reporting)
        history = PaperTraderHistoryEntry(
            order, trader.account.balance, trader.account.margin_balance,
            delta_price / one_pip_means, gain_loss_rate, position_gain_loss,
            position_gain_loss / base_exchange_rate)

        trader._history.add(history)

        # unlock before notify signals
        trader.unlock()

        result = True

        #
        # order signal (SIGNAL_ORDER_OPENED+DELETED because we assume fully completed)
        #

        order_data = {
            'id': order.order_id,
            'symbol': order.symbol,
            'type': order.order_type,
            'direction': order.direction,
            'timestamp': order.created_time,
            'quantity': order.quantity,
            'price': order.price,
            'stop-price': order.stop_price,
            'stop-loss': order.stop_loss,
            'take-profit': order.take_profit,
            'time-in-force': order.time_in_force
        }

        # signal as watcher service (opened + fully traded qty)
        trader.service.watcher_service.notify(
            Signal.SIGNAL_ORDER_OPENED, trader.name,
            (order.symbol, order_data, order.ref_order_id))

        order_data = {
            'id': order.order_id,
            'symbol': order.symbol,
            'type': order.order_type,
            'trade-id': 0,
            'direction': order.direction,
            'timestamp': order.transact_time,
            'quantity': order.quantity,
            'price': order.price,
            'stop-price': order.stop_price,
            'exec-price': exec_price,
            'avg-price': exec_price,  # current_position.entry_price,
            'filled': order.executed,
            'cumulative-filled': order.executed,
            'quote-transacted': realized_position_cost,  # its margin
            'stop-loss': order.stop_loss,
            'take-profit': order.take_profit,
            'time-in-force': order.time_in_force,
            'commission-amount': 0,  # @todo
            'commission-asset': trader.account.currency
        }

        trader.service.watcher_service.notify(
            Signal.SIGNAL_ORDER_TRADED, trader.name,
            (order.symbol, order_data, order.ref_order_id))

        #
        # position signal
        #

        # signal as watcher service
        if current_position.quantity <= 0:
            # closed position
            position_data = {
                'id': current_position.position_id,
                'symbol': current_position.symbol,
                'direction': current_position.direction,
                'timestamp': order.transact_time,
                'quantity': 0,
                'exec-price': exec_price,
                'stop-loss': None,
                'take-profit': None
            }

            trader.service.watcher_service.notify(
                Signal.SIGNAL_POSITION_DELETED, trader.name,
                (order.symbol, position_data, order.ref_order_id))
        else:
            # updated position
            position_data = {
                'id': current_position.position_id,
                'symbol': current_position.symbol,
                'direction': current_position.direction,
                'timestamp': order.transact_time,
                'quantity': current_position.quantity,
                # 'avg-price': current_position.entry_price,
                'exec-price': exec_price,
                'stop-loss': current_position.stop_loss,
                'take-profit': current_position.take_profit,
                # 'profit-loss': @todo here
            }

            trader.service.watcher_service.notify(
                Signal.SIGNAL_POSITION_UPDATED, trader.name,
                (order.symbol, position_data, order.ref_order_id))

        # and then deleted order
        trader.service.watcher_service.notify(
            Signal.SIGNAL_ORDER_DELETED, trader.name,
            (order.symbol, order.order_id, ""))

        # if position is empty -> closed -> delete it
        if current_position.quantity <= 0.0:
            # take care this does not make an issue
            current_position.exit(None)

            # dont a next update
            # trader.lock()

            # if current_position.symbol in trader._positions:
            #     del trader._positions[current_position.symbol]

            # trader.unlock()
    else:
        # unique position per market
        position_id = market.market_id

        # it's what we have really buy
        realized_position_cost = order.quantity * (
            market.lot_size * market.contract_size)  # in base currency

        # check available margin
        margin_cost = realized_position_cost * market.margin_factor / market.base_exchange_rate

        if not trader.has_margin(margin_cost):
            # and then rejected order
            trader.unlock()

            trader.service.watcher_service.notify(
                Signal.SIGNAL_ORDER_REJECTED, trader.name,
                (order.symbol, order.ref_order_id))

            logger.error(
                "Not enought free margin for %s need %s but have %s!" %
                (order.symbol, margin_cost, trader.account.margin_balance))
            return False

        # create a new position at market
        position = Position(trader)
        position.symbol = order.symbol

        position.set_position_id(position_id)
        position.set_key(trader.service.gen_key())

        position.entry(order.direction, order.symbol, order.quantity)
        position.leverage = order.leverage

        position.created_time = trader.timestamp

        account_currency = trader.account.currency

        # long are open on ofr and short on bid
        exec_price = open_exec_price
        position.entry_price = exec_price
        # logger.debug("%s %f %f %f %i" % ("el" if position.direction>0 else "es", position.entry_price, market.bid, market.ofr, market.bid < market.ofr))

        # transaction time is creation position date time
        order.transact_time = position.created_time
        order.set_position_id(position_id)

        # directly executed quantity
        order.executed = order.quantity

        trader._positions[position_id] = position

        # increase used margin
        trader.account.add_used_margin(margin_cost)

        #
        # history
        #

        history = PaperTraderHistoryEntry(order, trader.account.balance,
                                          trader.account.margin_balance)
        trader._history.add(history)

        # unlock before notify signals
        trader.unlock()

        result = True

        #
        # order signal (SIGNAL_ORDER_OPENED+TRADED+DELETED, fully completed)
        #

        order_data = {
            'id': order.order_id,
            'symbol': order.symbol,
            'type': order.order_type,
            'direction': order.direction,
            'timestamp': order.created_time,
            'quantity': order.quantity,
            'price': order.price,
            'stop-price': order.stop_price,
            'stop-loss': order.stop_loss,
            'take-profit': order.take_profit,
            'time-in-force': order.time_in_force
        }

        # signal as watcher service (opened + fully traded qty)
        trader.service.watcher_service.notify(
            Signal.SIGNAL_ORDER_OPENED, trader.name,
            (order.symbol, order_data, order.ref_order_id))

        order_data = {
            'id': order.order_id,
            'symbol': order.symbol,
            'type': order.order_type,
            'trade-id': 0,
            'direction': order.direction,
            'timestamp': order.transact_time,
            'quantity': order.quantity,
            'price': order.price,
            'stop-price': order.stop_price,
            'exec-price': position.entry_price,
            'avg-price': position.entry_price,
            'filled': order.executed,
            'cumulative-filled': order.executed,
            'quote-transacted': realized_position_cost,  # its margin
            'stop-loss': order.stop_loss,
            'take-profit': order.take_profit,
            'time-in-force': order.time_in_force,
            'commission-amount': 0,  # @todo
            'commission-asset': trader.account.currency
        }

        #logger.info("%s %s %s" % (position.entry_price, position.quantity, order.direction))
        trader.service.watcher_service.notify(
            Signal.SIGNAL_ORDER_TRADED, trader.name,
            (order.symbol, order_data, order.ref_order_id))

        #
        # position signal
        #

        position_data = {
            'id': position.position_id,
            'symbol': position.symbol,
            'direction': position.direction,
            'timestamp': order.transact_time,
            'quantity': position.quantity,
            'exec-price': position.entry_price,
            'stop-loss': position.stop_loss,
            'take-profit': position.take_profit
        }

        # signal as watcher service (position opened fully completed)
        trader.service.watcher_service.notify(
            Signal.SIGNAL_POSITION_OPENED, trader.name,
            (order.symbol, position_data, order.ref_order_id))

        # and then deleted order
        trader.service.watcher_service.notify(
            Signal.SIGNAL_ORDER_DELETED, trader.name,
            (order.symbol, order.order_id, ""))

    return result
Ejemplo n.º 27
0
    def emit(self, record):
        msg = self.format(record)

        if record.levelno == logging.ERROR:
            Terminal.inst().error(str(msg), view='default')
            Terminal.inst().error(str(msg), view='debug')
        elif record.levelno == logging.WARNING:
            Terminal.inst().warning(str(msg), view='default')
            Terminal.inst().error(str(msg), view='debug')
        elif record.levelno == logging.INFO:
            Terminal.inst().info(str(msg), view='default')
            Terminal.inst().info(str(msg), view='content')
        elif record.levelno == logging.DEBUG:
            Terminal.inst().message(str(msg), view='debug')
        else:
            Terminal.inst().message(str(msg), view='default')
Ejemplo n.º 28
0
    def update(self):
        if not super().update():
            return

        if not self._connected:
            # try reconnect
            time.sleep(10)
            self.connect()
            return

        if not self._checkout:
            # need checkout performed before update
            self.checkout()
            if not self._checkout:
                return

        self.lock()

        # update position of followed authors/traders
        for author_id, author in self._authors.items():
            var = {
                'pretty': 'false',
                'token': self.__apitoken,
                'limit': 20,
                'offset': 0,
                'user_id': int(author_id)
            }

            # https://1broker.com/api/v2/social/profile_trades.php?token=Aa508b7a7a5ffba14908bded38a88ee8&pretty=true&user_id=71368&limit=10&offset=0
            url = self._base_url + 'social/profile_trades.php?' + urllib.parse.urlencode(
                var)

            self._conn.request("GET", url)

            response = self._conn.getresponse()
            data = response.read()

            if response.status != 200:
                Terminal.inst().error(
                    "Http error getting %s user %s trades !" %
                    (self.name, author_id))
                continue

            data = json.loads(data)

            if data['error'] or data['warning']:
                Terminal.inst().error("API Error getting %s user %s trades !" %
                                      (self.name, author_id))
                continue

            try:
                server_date = datetime.strptime(data['server_time'],
                                                "%Y-%m-%dT%H:%M:%S.%fZ")
            except:
                server_date = datetime.strptime(data['server_time'],
                                                "%Y-%m-%dT%H:%M:%SZ")

            open_trades = data['response']['trading_ideas_open']
            closed_trades = data['response']['trading_ideas_closed']

            for t in open_trades:
                position_id = t['position_id']
                position = Position(self, position_id, author)

                direction = Position.LONG if t[
                    'direction'] == 'long' else Position.SHORT
                date_created = datetime.strptime(
                    t['date_created'], "%Y-%m-%dT%H:%M:%SZ")  # .%fZ")
                is_open = t['is_open']

                if not is_open:
                    # should be open...
                    continue

                symbol = t['symbol']
                profit_loss_percent = float(t['profit_loss_percent'])
                comment_count = t['comment_count']  # @todo use as indicateur
                leverage = float(t['leverage'])

                if self._positions.get(position_id):
                    # already exists, just update the profit_loss_percent value

                    # retrieve the position
                    position = self._positions.get(position_id)
                    position.profit_loss_rate = profit_loss_percent * 0.01

                    continue

                #
                # get position details
                #

                var = {
                    'pretty': 'false',
                    'token': self.__apitoken,
                    'position_id': position_id
                }

                # https://1broker.com/api/v2/position/shared/get.php?token=Aa508b7a7a5ffba14908bded38a88ee8&pretty=true&position_id=4459904
                url = self._base_url + 'position/shared/get.php?' + urllib.parse.urlencode(
                    var)

                self._conn.request("GET", url)

                response = self._conn.getresponse()
                data = response.read()

                if response.status != 200:
                    Terminal.inst().error(
                        "Http error getting %s open position %s !" %
                        (self.name, position_id))
                    continue

                data = json.loads(data)

                if data['error'] or data['warning']:
                    Terminal.inst().error(
                        "API Error getting %s open position %s !" %
                        (self.name, position_id))
                    continue

                p = data['response']

                entry_price = float(p['entry_price'])
                stop_loss = float(
                    p['stop_loss']) if p['stop_loss'] is not None else None
                take_profit = float(
                    p['take_profit']) if p['take_profit'] is not None else None
                trailing_stop_loss = p['trailing_stop_loss']
                comments = p['comments']

                # @todo comments +/- 'upvotes' 'downvotes' 'deleted' 'content' 'comment_id' 'username' 'user_id' 'date_created'
                # => make a confidence score + alert at threshold

                # quantity is not known from the copier, let it to 0
                position.symbol = symbol
                position.entry(direction,
                               0.0,
                               entry_price,
                               stop_loss,
                               take_profit,
                               date_created,
                               leverage=leverage,
                               trailing_stop_loss=trailing_stop_loss)

                # add position
                self._positions[position_id] = position

                self.service.notify(Signal.SIGNAL_SOCIAL_ENTER, self.name,
                                    position)

            for t in closed_trades:
                position_id = t['position_id']

                # retrieve the position
                position = self._positions.get(position_id)

                if position is None:
                    # Terminal.inst().error("Closed position %s cannot be found !" % (position_id,))
                    continue

                if position.status == Position.POSITION_CLOSED:
                    # already closed
                    continue

                #
                # get position details
                #

                var = {
                    'pretty': 'false',
                    'token': self.__apitoken,
                    'position_id': position_id
                }

                # https://1broker.com/api/v2/position/shared/get.php?token=Aa508b7a7a5ffba14908bded38a88ee8&pretty=true&position_id=4459904
                url = self._base_url + 'position/shared/get.php?' + urllib.parse.urlencode(
                    var)

                self._conn.request("GET", url)

                response = self._conn.getresponse()
                data = response.read()

                if response.status != 200:
                    Terminal.inst().error(
                        "Http error getting %s closed position %s !" %
                        (self.name, position_id))
                    continue

                data = json.loads(data)

                if data['error'] or data['warning']:
                    Terminal.inst().error(
                        "API Error getting %s closed position %s !" %
                        (self.name, position_id))
                    continue

                p = data['response']

                profit_loss_percent = float(t['profit_loss_percent'])
                exit_price = float(
                    p['exit_price']) if p['exit_price'] is not None else None
                date_closed = datetime.strptime(t['date_closed'],
                                                "%Y-%m-%dT%H:%M:%SZ")  # .%fZ")

                position.exit(exit_price, date_closed)
                position.profit_loss_rate = profit_loss_percent * 0.01

                # Terminal.inst().info("Exited position %s found !" % (position_id,), view='status')

                self.service.notify(Signal.SIGNAL_SOCIAL_EXIT, self.name,
                                    position)

        self.unlock()
Ejemplo n.º 29
0
def check_ohlcs(broker_id, market_id, timeframe, from_date, to_date):
    last_ohlcs = {}

    ohlc_streamer = Database.inst().create_ohlc_streamer(broker_id, market_id, timeframe, from_date=from_date, to_date=to_date, buffer_size=100)
    timestamp = from_date.timestamp()
    to_timestamp = to_date.timestamp()
    progression = 0.0
    prev_update = timestamp
    count = 0
    total_count = 0

    progression_incr = (to_timestamp - timestamp) * 0.01

    tts = 0.0
    prev_tts = 0.0

    while not ohlc_streamer.finished():
        ohlcs = ohlc_streamer.next(timestamp + timeframe * 100)  # per 100

        count = len(ohlcs)
        total_count += len(ohlcs)

        for ohlc in ohlcs:
            tts = ohlc.timestamp

            if not prev_tts:
                prev_tts = tts

            gap_duration = tts - prev_tts
            if gap_duration > timeframe:
                date = format_datetime(timestamp)
                Terminal.inst().warning("Ohlc gap of %s on %s !" % (format_delta(gap_duration), date))

            if ohlc.bid_open <= 0.0:
                Terminal.inst().warning("Bid open price is lesser than 0 %s on %s !" % (ohlc.bid_open, date))
            if ohlc.bid_high <= 0.0:
                Terminal.inst().warning("Bid high price is lesser than 0 %s on %s !" % (ohlc.bid_high, date))
            if ohlc.bid_low <= 0.0:
                Terminal.inst().warning("Bid close price is lesser than 0 %s on %s !" % (ohlc.bid_low, date))
            if ohlc.bid_close <= 0.0:
                Terminal.inst().warning("Bid close price is lesser than 0 %s on %s !" % (ohlc.bid_close, date))

            if ohlc.ofr_open <= 0.0:
                Terminal.inst().warning("Ofr open price is lesser than 0 %s on %s !" % (ohlc.ofr_open, date))
            if ohlc.ofr_high <= 0.0:
                Terminal.inst().warning("Ofr high price is lesser than 0 %s on %s !" % (ohlc.ofr_high, date))
            if ohlc.ofr_low <= 0.0:
                Terminal.inst().warning("Ofr low price is lesser than 0 %s on %s !" % (ohlc.ofr_low, date))
            if ohlc.ofr_close <= 0.0:
                Terminal.inst().warning("Ofr close price is lesser than 0 %s on %s !" % (ohlc.ofr_close, date))

            if ohlc.volume < 0.0:
                Terminal.inst().warning("Volume quantity is lesser than 0 %s on %s !" % (ohlc.volume, date))

            prev_tts = tts
            timestamp = tts

            if timestamp > to_timestamp:
                break

        if timestamp - prev_update >= progression_incr:
            progression += 1

            Terminal.inst().info("%i%% on %s, %s for last 100 candles, current total of %s..." % (progression, format_datetime(timestamp), count, total_count))

            prev_update = timestamp
            count = 0

        if timestamp > to_timestamp:
            break

        if total_count == 0:
            timestamp += timeframe * 100

    if progression < 100:
        Terminal.inst().info("100%% on %s, %s for last 100 candles, current total of %s..." % (format_datetime(timestamp), count, total_count))
    
    Terminal.inst().info("Last candle datetime is %s" % (format_datetime(tts),))
Ejemplo n.º 30
0
def do_optimizer(options):
    Terminal.inst().info("Starting SIIS optimizer...")
    Terminal.inst().flush()

    # database manager
    Database.create(options)
    Database.inst().setup(options)

    broker_id = options['broker']
    market_id = options['market']

    timeframe = None

    from_date = options.get('from')
    to_date = options.get('to')

    if not to_date:
        today = datetime.now().astimezone(UTC())

        if timeframe == Instrument.TF_MONTH:
            to_date = today + timedelta(months=1)
        else:
            to_date = today + timedelta(seconds=timeframe)

        to_date = to_date.replace(microsecond=0)

    if not options.get('timeframe'):
        timeframe = None
    else:
        if options['timeframe'] in TIMEFRAME_FROM_STR_MAP:
            timeframe = TIMEFRAME_FROM_STR_MAP[options['timeframe']]
        else:
            try:
                timeframe = int(options['timeframe'])
            except:
                pass

    try:
        # checking data integrity, gap...
        if timeframe is None:
            for market in options['market'].split(','):
                if market.startswith('!') or market.startswith('*'):
                    continue

                for tf in GENERATED_TF:
                    Terminal.inst().info("Verifying %s OHLC %s..." % (market, timeframe_to_str(tf)))

                    check_ohlcs(options['broker'], market, tf, from_date, to_date)

        elif timeframe == Instrument.TF_TICK:
            for market in options['market'].split(','):
                if market.startswith('!') or market.startswith('*'):
                    continue

                Terminal.inst().info("Verifying %s ticks/trades..." % (market,))

                check_ticks(options['broker'], market, from_date, to_date)

        elif timeframe > 0:
            # particular ohlc
            for market in options['market'].split(','):
                if market.startswith('!') or market.startswith('*'):
                    continue

                Terminal.inst().info("Verifying %s OHLC %s..." % (market, timeframe_to_str(timeframe)))

                check_ohlcs(options['broker'], market, timeframe, from_date, to_date)
    except KeyboardInterrupt:
        pass
    finally:
        pass

    Terminal.inst().info("Flushing database...")
    Terminal.inst().flush() 

    Database.terminate()

    Terminal.inst().info("Optimization done!")
    Terminal.inst().flush()

    Terminal.terminate()
    sys.exit(0)