Exemple #1
0
def lookup_sid(sid):
    """Lookup a security by id.

    >>> lookup_sid(45149)
    {u'symbol': u'HTBX', u'name': u'HEAT BIOLOGICS INC', u'sid': 45149}
    >>> lookup_sid(1111111)  # Returns None of no security is found

    :param sid: Security id.
    :type sid: int
    :return: A dictionary containing the security's name, sid, and symbol or ``None`` if no security is found.
    :rtype: dict
    :raises quantopian_tools.exceptions.RequestError: If the request to the quantopian_tools server failed.
    :raises quantopian_tools.exceptions.ResponseValidationError: If the response from the quantopian_tools server is not
     of the format expected.
    """
    url = build_url('securities/', q=sid)
    headers = {
        'x-csrf-token':
        session.browser.get_csrf_token(build_url('algorithms')),
        'x-requested-with': 'XMLHttpRequest'
    }
    response = session.browser.get(url, headers=headers)
    if not response.ok:
        raise RequestError('failed to lookup sid %d' % sid, response)

    valid, data_or_errors = schema.validate(response.json(), {
        "data":
        schema.dictionary(
            required=True,
            nullable=False,
            schema={
                "matches":
                schema.list_(
                    required=True,
                    nullable=True,
                    coerce='falsey_to_none',
                    schema=schema.dictionary(
                        schema={
                            'name':
                            schema.string(
                                required=True, nullable=False, empty=False),
                            'sid':
                            schema.integer(
                                required=True, nullable=False, min=1),
                            'symbol':
                            schema.string(
                                required=True, nullable=False, empty=False)
                        }))
            })
    },
                                            allow_unknown=True)
    if not valid:
        raise ResponseValidationError('GET', url, None, data_or_errors)
    for security in data_or_errors['data']['matches'] or []:
        if security['sid'] == sid:
            return security
    return None
def daily_result_schema():
    return {
        'o':
        schema.list_(required=True, nullable=True,
                     default=None),  # , rename='o'),  # TODO: Find actual name
        'rv':
        schema.dictionary(required=True,
                          nullable=True,
                          default=None,
                          rename='custom_data'),
        'd':
        schema.date_(required=True,
                     nullable=True,
                     min=0,
                     default=None,
                     rename='date',
                     coerce=('millis_timestamp', 'datetime_to_date')),
        'c':
        schema.dictionary(required=True,
                          nullable=True,
                          default=None,
                          rename='performance',
                          schema=performance_schema()),
        'l':
        schema.number(required=True,
                      nullable=True,
                      default=None,
                      rename='leverage'),
        'ec':
        schema.number(required=True,
                      nullable=True,
                      default=None,
                      rename='equity_with_loan'),
        'p':
        schema.list_(required=True,
                     nullable=True,
                     default=None,
                     rename='positions',
                     schema=schema.dictionary(schema=position_schema())),
        'pnl':
        schema.number(required=True, nullable=True, default=None),
        't':
        schema.list_(required=True, nullable=True,
                     default=None),  # , rename='t'),  # TODO: Find actual name
        'cb':
        schema.number(
            required=True, nullable=True,
            default=None),  # , rename='t'),  # TODO: Find actual name
        'bm':
        schema.number(required=True, nullable=True,
                      default=None)  # , rename='t')  # TODO: Find actual name
    }
def validate_algorithm(algorithm,
                       start_date=None,
                       end_date=None,
                       data_frequency='minute'):
    assert session.browser.is_authenticated, "You must be authenticated to validate algorithms"
    url = build_url('algorithms', algorithm['id'], 'validate')
    data = {
        'code': algorithm['code'],
        'algo_id': algorithm['id'],
        'data_frequency': data_frequency,
        'start_date_str': start_date.strftime('%m/%d/%Y'),
        'end_date_str': end_date.strftime('%m/%d/%Y')
    }
    headers = {
        'x-csrf-token':
        session.browser.get_csrf_token(build_url('algorithms',
                                                 algorithm['id'])),
        'x-requested-with':
        'XMLHttpRequest'
    }
    response = session.browser.post(url, data=data, headers=headers)
    if not response.ok:
        raise RequestError('validate algorithm request failed', response)

    valid, data_or_errors = schema.validate(response.json(), {
        "data":
        schema.dictionary(
            required=True,
            schema={
                "test_results":
                schema.list_(
                    required=True,
                    schema=schema.dictionary(schema={
                        "passed":
                        schema.boolean(required=True, nullable=False)
                    }))
            })
    },
                                            allow_unknown=True)
    if not valid:
        raise ResponseValidationError('POST', url, data, data_or_errors)

    test_results = data_or_errors['data']['test_results']

    return all(result['passed'] for result in test_results), test_results
def performance_payload_schema():
    return {
        'cursor':
        schema.integer(required=True, nullable=False),
        'pc':
        schema.number(required=True, nullable=False,
                      rename='percent_complete'),
        'sa':
        schema.datetime_(required=True,
                         nullable=False,
                         min=0,
                         rename='timestamp',
                         coerce='millis_timestamp'),
        'daily':
        schema.dictionary(required=True,
                          nullable=True,
                          default=None,
                          rename='daily_performance',
                          coerce='first_item',
                          schema=daily_result_schema())
    }
def run_backtest(algorithm,
                 start_date,
                 end_date,
                 capital_base,
                 data_frequency='minute'):
    url = build_url('backtests', 'start_ide_backtest')
    headers = {
        'x-csrf-token':
        session.browser.get_csrf_token(build_url('algorithms',
                                                 algorithm['id'])),
        'x-requested-with':
        'XMLHttpRequest'
    }
    data = {
        'algo_id': algorithm['id'],
        'code': algorithm['code'],
        'backtest_start_date_year': start_date.year,
        'backtest_start_date_month': start_date.month,
        'backtest_start_date_day': start_date.day,
        'backtest_end_date_year': end_date.year,
        'backtest_end_date_month': end_date.month,
        'backtest_end_date_day': end_date.day,
        'backtest_capital_base': capital_base,
        'backtest_data_frequency_value': data_frequency
    }
    response = session.browser.post(url, data=data, headers=headers)
    if not response.ok:
        raise RequestError('failed to start backtest', response)

    valid, data_or_errors = schema.validate(response.json(), {
        "data":
        schema.dictionary(
            required=True,
            schema={
                "ws_open_msg":
                schema.string(required=True, nullable=False, empty=False),
                "ws_url":
                schema.string(required=True, nullable=False, empty=False)
            })
    },
                                            allow_unknown=True)
    if not valid:
        raise ResponseValidationError('POST', url, algorithm, data_or_errors)

    with closing(websocket.create_connection(
            data_or_errors['data']['ws_url'])) as ws:
        ws.send(
            json.dumps({
                'e': 'open',
                'p': {
                    'a': data_or_errors['data']['ws_open_msg'],
                    'cursor': 0,
                    'include_txn': True
                }
            }))
        while True:
            msg = json.loads(ws.recv())
            if msg['e'] == 'log':
                yield schema.validate(msg['p'],
                                      log_payload_schema(),
                                      raise_exc=True)

            elif msg['e'] == 'performance':
                yield schema.validate(msg['p'],
                                      performance_payload_schema(),
                                      raise_exc=True)

            elif msg['e'] == 'risk_report':
                yield schema.validate(msg['p'],
                                      risk_report_payload_schema(),
                                      raise_exc=True)

            elif msg['e'] == 'done':
                yield schema.validate(msg['p'],
                                      done_payload_schema(),
                                      raise_exc=True)
                break

            elif msg['e'] == 'exception':
                exc = schema.validate(msg['p'],
                                      exception_payload_schema(),
                                      raise_exc=True)
                trace = '\n'.join("  File \"{}\", line {}, in {}\n    {}"
                                  "".format(s['filename'], s['lineno'],
                                            s['method'], s['line'])
                                  for s in exc['stack'])
                raise RuntimeError(
                    "Traceback (most recent call last):\n{}\n{}: {}"
                    "".format(trace, exc['name'], exc['message']))
            else:
                raise QuantopianException("unknown backtest event '{}'".format(
                    msg['e']))
def risk_report_payload_schema():
    return {
        'metrics':
        schema.dictionary(required=True,
                          nullable=False,
                          schema={
                              'information':
                              schema.dictionary(required=True, nullable=False),
                              'algorithm_period_return':
                              schema.dictionary(required=True, nullable=False),
                              'max_drawdown':
                              schema.dictionary(required=True, nullable=False),
                              'sortino':
                              schema.dictionary(required=True, nullable=False),
                              'algo_volatility':
                              schema.dictionary(required=True, nullable=False),
                              'trading_days':
                              schema.dictionary(required=True, nullable=False),
                              'max_leverage':
                              schema.dictionary(required=True, nullable=False),
                              'benchmark_volatility':
                              schema.dictionary(required=True, nullable=False),
                              'beta':
                              schema.dictionary(required=True, nullable=False),
                              'excess_return':
                              schema.dictionary(required=True, nullable=False),
                              'treasury_period_return':
                              schema.dictionary(required=True, nullable=False),
                              'sharpe':
                              schema.dictionary(required=True, nullable=False),
                              'alpha':
                              schema.dictionary(required=True, nullable=False),
                              'benchmark_period_return':
                              schema.dictionary(required=True, nullable=False)
                          })
    }