Exemplo n.º 1
0
def strategies():
    # Authenticate.
    client_ip = request.environ.get('HTTP_X_REAL_IP', request.remote_addr)
    if client_ip not in Constants.configs['authorised_ip_address']:
        return response(401, 'Client is not authorised.')

    # Initiate database connection.
    db = Database()

    # Extract any parameters from url.
    params = {x: request.args[x] for x in request.args if x is not None}

    if 'id' in params:
        strategies_rows = db.query_table('strategies',
                                         'name="{}"'.format(params['id']))
    else:
        strategies_rows = db.query_table('strategies')

    crumb_timestamp = BreadCrumbsDataLoader.TIMESTAMP
    crumb_type = BreadCrumbsDataLoader.TYPE
    crumb_data = BreadCrumbsDataLoader.DATA

    strategy_table_schema = Constants.configs['tables'][
        Constants.DB_NAME]['strategies']
    strategies_as_dict = query_result_to_dict(strategies_rows,
                                              strategy_table_schema)
    for strategy in strategies_as_dict:
        # Get historical valuations from way points.
        bread_crumbs_data_loader = BreadCrumbsDataLoader()
        bread_crumbs_data_loader.load_bread_crumbs_time_series(
            strategy['name'])
        bread_crumbs = bread_crumbs_data_loader.data[
            BreadCrumbsDataLoader.BREAD_CRUMBS_TIME_SERIES][strategy['name']]
        valuation_type = BreadCrumbs.VALUATION
        valuations = [(b[crumb_timestamp], float(b[crumb_data]))
                      for b in bread_crumbs if b[crumb_type] == valuation_type]

        strategy['historical_valuations'] = [[format_datetime_str(v[0]), v[1]]
                                             for v in valuations]
        strategy['pnl'] = float_to_str(
            float(valuations[-1][1] - valuations[0][1]))

    return response(200, strategies_as_dict)
Exemplo n.º 2
0
class Job:
    DB_NAME = 'job_data'

    SUCCESSFUL = 0
    WARNINGS = 2
    FAILED = 1
    STATUS_MAP = {
        SUCCESSFUL: 'finished successfully',
        WARNINGS: 'finished with warnings',
        FAILED: 'failed'
    }
    FIRST_PHASE = 'INITIATED'

    def __init__(self, log_path=None, job_id=None):
        self._db = Database(name=self.DB_NAME)
        self.phase_name = None

        if job_id:
            # Load in an existing job from database.
            job_row = self._db.get_one_row('jobs', 'id="{0}"'.format(job_id))
            job_dict = query_result_to_dict([job_row], Constants.configs['tables'][self.DB_NAME]['jobs'])[0]

            # Read in job phase.
            phase_row = self._db.query_table('phases', 'job_id="{0}"'.format(job_dict['id']))
            phase_dict = query_result_to_dict(phase_row, Constants.configs['tables'][self.DB_NAME]['phases'])[-1]
            job_dict['phase_name'] = phase_dict['name']

        else:
            # Create new job and add it to the database.
            job_dict = self._create_job_dict(log_path)
            self._db.insert_row_from_dict('jobs', job_dict)

        # Set instance variables.
        self.id = job_dict['id']
        self.name = job_dict['name']
        self.script = job_dict['script']
        self.version = job_dict['version']
        self.log_path = job_dict['log_path']
        self.elapsed_time = job_dict['elapsed_time']
        self.finish_state = job_dict['finish_state']
        self.start_time = job_dict['start_time']
        self.phase_name = job_dict['phase_name']

        # Initiate the job is no phase.
        if self.phase_name is None:
            self.update_phase(Job.FIRST_PHASE)

    @staticmethod
    def _create_job_dict(log_path):
        if Constants.job_name:
            name = Constants.job_name
        else:
            name = '{0}_manual_run'.format(Constants.script)
        return {
            'id': str(abs(hash(name + datetime.datetime.now().strftime(Constants.DATETIME_FORMAT)))),
            'name': name.lower(),
            'script': Constants.script,
            'version': Constants.configs['version'],
            'log_path': log_path,
            'elapsed_time': None,
            'finish_state': None,
            'start_time': datetime.datetime.now().strftime(Constants.DATETIME_FORMAT),
            'phase_name': None
        }

    def _add_phase(self, name):
        phase_id = str(abs(hash(name + self.id)))
        date_time = datetime.datetime.now().strftime(Constants.DATETIME_FORMAT)
        self._db.insert_row('phases', [phase_id, self.id, date_time, name])
        return phase_id

    def log(self, logger=None):
        if logger is None:
            logger = Constants.log
        logger.info('Starting job: {0}'.format(self.id))
        log_hr()

    def update_phase(self, phase):
        self.phase_name = phase.replace(' ', '_').upper()
        phase_id = self._add_phase(self.phase_name)
        # self._db.update_value('jobs', 'phase_id', phase_id, 'id="{0}"'.format(self.id))

    def finished(self, status=SUCCESSFUL, condition=None):
        log_hr()

        # Update job phase.
        if condition is None:
            self.update_phase('TERMINATED_SUCCESSFULLY')
        else:
            Constants.log.warning('Job finished early with condition: "{0}"'.format(condition))
            self.update_phase('TERMINATED_{0}'.format(condition))

        # Update job.
        start_time = self._db.get_one_row('phases', 'job_id="{}" AND name="{}"'.format(self.id, Job.FIRST_PHASE))[2]
        start_time = datetime.datetime.strptime(start_time, Constants.DATETIME_FORMAT)
        run_time = round((datetime.datetime.now() - start_time).total_seconds(), 3)
        self._db.update_value('jobs', 'elapsed_time', run_time, 'id="{0}"'.format(self.id))
        self._db.update_value('jobs', 'finish_state', status, 'id="{0}"'.format(self.id))

        # Log final status.
        if status == Job.SUCCESSFUL or status == Job.WARNINGS:
            Constants.log.info('Job "{0}" {1} in {2} seconds.'.format(self.name, Job.STATUS_MAP[status], run_time))
        elif status == Job.FAILED:
            Constants.log.error('Job "{0}" {1} after {2} seconds.'.format(self.name, Job.STATUS_MAP[status], run_time))
        else:
            Constants.log.info('Job "{0}" finished in {1} seconds.'.format(self.name, run_time))