Exemplo n.º 1
0
def fetch_historical(symbol, db_name=None):
    """Fetches historical (EOD) quotes from CBOE and saves them to database.

    Args:
        symbol (str): Symbol to fetch.
        db_name (str): Optional database name.

    Returns:
        int: Number of quotes fetched.
    """
    logger = logging.getLogger(__name__)
    logger.info('Fetching historical futures quotes from CBOE for %s...', \
                symbol)

    lines = 0
    today = datetime.today()
    expirations = dates.get_expirations(symbol)
    for expiration_year in xrange(2015, today.year + 2):
        for expiration_month in xrange(1, 13):
            expiration = dates.find_date(
                expirations, expiration_month, expiration_year)
            if expiration is None:
                continue
            try:
                data = _fetch_historical_data(symbol, expiration)
                if data is None:
                    continue
                lines += _parse_historical_data(
                    symbol, expiration, data, db_name)
            except ValueError:
                break
    logger.info('... quotes retrieved: %d', lines)
    return lines
Exemplo n.º 2
0
def _parse_data(symbol, data, is_eod, db_name=None, timestamp=None):
    """Parses realtime (delayed) options quotes from CBOE and saves to
    database.

    Args:
        symbol (str): Symbol.
        data (str): Raw quotes for the symbol.
        is_eod (bool): If True: mark received quotes as EOD (time=None),
            if False: store actual time.
        db_name (str): Optional database name.
        timestamp (datetime): Optional datetime for the data.

    Returns:
        list: List of OptionQuote objects.
    """
    logger = logging.getLogger(__name__)
    if timestamp is None:
        timestamp = dates.get_database_timestamp()
    date = timestamp.date()
    time = None if is_eod else timestamp.time()

    quotes = []
    stock_price = None
    expirations = dates.get_expirations(symbol)
    with database.connect_db(db_name) as db:
        for line in data.splitlines():
            values = line.strip().split(',')
            if (len(values) == 4) and (stock_price is None):
                stock_price = utils.to_float(values[1])
                continue
            if len(values) != 15:
                continue
            if values[0] == 'Calls' or values[0].find('-') >= 0:
                continue

            code_values = values[0].split(' ')
            if len(code_values) != 4:
                continue
            position = code_values[3].find(code_values[0])
            if code_values[3][1:position] in SKIP_SYMBOLS:
                continue
            expiration_year = 2000 + int(code_values[0])
            expiration_month = MONTHS[code_values[1]]
            expiration_day = int(code_values[3][position + 2:position + 4])
            expiration = datetime(expiration_year, expiration_month,
                                  expiration_day).date()
            if expiration not in expirations:
                continue
            strike = utils.to_float(code_values[2])

            for type_, bid, ask in [
                (consts.CALL, values[3], values[4]),
                (consts.PUT, values[10], values[11]),
            ]:
                bid = utils.to_float(bid)
                ask = utils.to_float(ask)
                quote = OptionQuote(
                    symbol, type_, expiration, strike, date, time,
                    bid, ask, stock_price, None, None)
                iv_bid = math.calc_iv(quote, bid) * 100
                iv_ask = math.calc_iv(quote, ask) * 100
                quote = OptionQuote(
                    symbol, type_, expiration, strike, date, time,
                    bid, ask, stock_price, iv_bid, iv_ask)
                save_quote(db, quote)
                quotes.append(quote)
    logger.info('... quotes parsed: %d', len(quotes))
    return quotes