def main():
    # Setup parse options, imitate global constants and logs.
    args = [SUPPRESS_TRADES, EXPORT_CSV]
    Constants.parse_arguments(Constants.APP_NAME, custom_args=args)

    # Setup database.
    db = Database()
    db.log()

    # Initiate Job
    job = Job(log_path=Constants.log_path)
    job.log()

    # Parse strategy xml.
    strategy = parse_strategy_from_xml(Constants.xml.path,
                                       return_object=True,
                                       db=db)
    Constants.log.info("Strategy portfolio: {0}".format(strategy.portfolio.id))
    db.update_value(Strategy.TABLE, 'updated_by', job.id,
                    'name="{}"'.format(strategy.name.lower()))

    # Initiate strategy executor
    strategy_executor = StrategyExecutor(
        strategy,
        job_object=job,
        suppress_trades=Constants.configs[SUPPRESS_TRADES])

    # Run strategy.
    strategy_executor.run()

    # Generate report.
    if Constants.configs[EXPORT_CSV]:
        strategy_executor.generate_strategy_report()

    # Check for any warnings.
    status = Job.SUCCESSFUL
    if strategy.data_loader.warnings:
        status = Job.WARNINGS

    # Finish job.
    job.finished(status=status, condition=strategy_executor.finish_condition)
    return status
Exemplo n.º 2
0
def main():
    # Setup parse options, imitate global constants and logs.
    Constants.parse_arguments(Constants.APP_NAME)

    # Initiate Job.
    job = Job(log_path=Constants.log_path)
    job.log()

    # Setup connection to market data database, using the data loader's db name constant.
    db = Database(name=MarketDataLoader.DB_NAME)
    db.log()

    # Parse subscriptions file.
    job.update_phase('parsing subscriptions')
    subscriptions = []
    for tick_requirement in get_xml_root(Constants.xml.path):
        symbol = get_xml_element_attribute(tick_requirement, 'symbol', required=True)
        stale_tick_limit = get_xml_element_attribute(tick_requirement, 'stale_tick_limit')
        if stale_tick_limit:
            subscriptions.append({'symbol': symbol.upper(), 'stale_tick_limit': int(stale_tick_limit)})
        else:
            subscriptions.append({'symbol': symbol.upper()})
    Constants.log.info('Loaded {0} required tickers.'.format(len(subscriptions)))

    # Load data.
    job.update_phase('requesting data')
    ticker_data_source = TickerDataSource()
    warnings = 0
    for ticker in subscriptions:
        data_source_data = ticker_data_source.request_quote(ticker[TickerDataSource.SYMBOL])
        if data_source_data:
            # Add data to ticker dictionary.
            ticker['price'] = data_source_data[TickerDataSource.PRICE]
            ticker['volume'] = data_source_data[TickerDataSource.VOLUME]

            # Carry out checks on ticker.
            ticker_warnings = ticker_checks(ticker)

            # Save tick to database.
            run_time_string = Constants.run_time.strftime(Constants.DATETIME_FORMAT)
            db.insert_row('ticks', [generate_unique_id(ticker['symbol'] + run_time_string),
                                    run_time_string,
                                    ticker['symbol'],
                                    ticker['price'],
                                    ticker['volume']
                                    ]
                          )

            # Log ticks.
            Constants.log.info('symbol: {0}, price: {1}, volume: {2}'.format(ticker['symbol'], ticker['price'], ticker['volume']))
        else:
            ticker_warnings = ['no_data']

        for warning_type in ticker_warnings:
            warning_id = generate_unique_id(ticker['symbol'] + Constants.run_time.strftime(Constants.DATETIME_FORMAT))
            db.insert_row('data_warnings', [warning_id, 'tick', warning_type, ticker['symbol']])
            Constants.log.info('Could not get data for ticker {0}'.format(ticker['symbol']))
            warnings += 1

    if warnings:
        job.finished(status=Job.WARNINGS, condition='data warnings')
        return Job.WARNINGS
    else:
        job.finished()
        return Job.SUCCESSFUL