def build_equities(equities):
    log.info("building equities")
    session = Session()

    gateway = session\
                .query(Gateway)\
                .filter(Gateway.name=="Options City Live")\
                .options(subqueryload(Gateway.gateway_assets))\
                .first()

    ac = None
    for equity in equities:
        # cooperative yield to allow gevent to service other greenlets
        gevent.sleep()
        # check to see if there's a corresponding gateway asset for current equity
        if equity.instrument_id in gateway.gateway_assets:
            #already exists
            pass
        # if not found, create new gateway asset
        else:
            ga = OCAsset()
            ga.oc_id = equity.instrument_id
            ga.oc_class_id = equity.class_id
            ga.oc_group_id = equity.group_id
            gateway.gateway_assets[ga.gateway_index] = ga

            if ac is None or ac.symbol != equity.parent_symbol:
                ac = session\
                        .query(AssetClass)\
                        .filter(AssetClass.symbol==equity.parent_symbol)\
                        .options(subqueryload(AssetClass.assets.of_type(Equity)))\
                        .first()
            # if asset class not found, create new one
            if ac is None:
                log.info("creating AssetClass: {}".format(equity.parent_symbol))
                ac = AssetClass()
                ac.symbol = equity.parent_symbol

            # lookup equity asset
            if equity.symbol in ac.assets:
                e = ac.assets[equity.symbol]
            # if equity asset not found, create new one
            else:
                log.info("creating EquityAsset: {}".format(equity.symbol))
                e = Equity()
                e.symbol = equity.symbol
                e.min_price_increment = equity.min_price_increment
                ac.assets[e.asset_class_index] = e

            # link new gateway asset to equity asset
            e.gateway_assets.append(ga)

    session.commit()
    session.close()
def build_options(options):
    log.info('building options')
    session = Session()
    gateway = session\
                .query(Gateway)\
                .options(subqueryload(Gateway.gateway_assets.of_type(OCAsset)))\
                .filter(Gateway.name=="Options City Live")\
                .first()

    sort_key = attrgetter('parent_symbol', 'expiration')
    sorted_options = sorted(options, key=sort_key)

    asset_class = None
    for group_key, option_group in groupby(sorted_options, key=sort_key):
        # cooperative yield to allow gevent to service other greenlets
        gevent.sleep()
        parent_symbol = group_key[0]
        expiration_date = group_key[1]

        # lookup asset class, checking first to see if previous asset_class matches
        if asset_class is None or asset_class.symbol != parent_symbol:
            asset_class = session\
                            .query(AssetClass)\
                            .filter(AssetClass.symbol==parent_symbol)\
                            .options(subqueryload(AssetClass.expiries))\
                            .options(subqueryload(AssetClass.assets.of_type(Option)))\
                            .first()
        # if asset class not found, create new asset class
        if asset_class is None:
            log.info('creating AssetClass: {}'.format(parent_symbol))
            asset_class = AssetClass()
            asset_class.symbol = parent_symbol

        # lookup expiry in asset class' expiries
        if expiration_date in asset_class.expiries:
            exp = asset_class.expiries[expiration_date]
        # if expiry not found, create new one
        else:
            log.info('creating Expiration: {} {}'.format(parent_symbol, expiration_date))
            exp = Expiry()
            exp.expiration_date = expiration_date
            asset_class.expiries[exp.expiration_date] = exp

        for option in option_group:
            # cooperative yield to allow gevent to service other greenlets
            gevent.sleep()
            # check to see if gateway asset corresponding to current option exists
            if option.instrument_id in gateway.gateway_assets:
                pass
            # if it doesn't, create new gateway asset
            else:
                new_gateway_asset = OCAsset()
                new_gateway_asset.oc_id = option.instrument_id
                new_gateway_asset.oc_class_id = option.class_id
                new_gateway_asset.oc_group_id = option.group_id
                gateway.gateway_assets[new_gateway_asset.gateway_index] = new_gateway_asset

                # lookup option instrument corresponding to Options City Option
                ac_index = create_asset_class_option_index(expiration_date, option.strike, option.instrument_type)
                exp_index = create_expiry_option_index(option.strike, option.instrument_type)
                if ac_index in asset_class.assets:
                    option_inst = asset_class.assets[ac_index]
                else:
                    log.debug('creating OptionAsset: {} {} {}'.format(option.expiration, option.strike, option.instrument_type))
                    option_inst = Option()
                    option_inst.put_call = option.instrument_type
                    option_inst.strike = option.strike
                    option_inst.min_price_increment = option.min_price_increment
                    asset_class.assets[ac_index] = option_inst
                    exp.derivatives[exp_index] = option_inst
                option_inst.gateway_assets.append(new_gateway_asset)
    session.commit()
    session.close()
def build_futures(futures):
    log.info('building futures')
    session = Session()
    gateway = session\
                .query(Gateway)\
                .filter(Gateway.name=="Options City Live")\
                .options(subqueryload(Gateway.gateway_assets.of_type(OCAsset)))\
                .first()

    sort_key = attrgetter('parent_symbol', 'expiration')
    sorted_futures = sorted(futures, key=sort_key)

    asset_class = None
    for group_key, future_group in groupby(sorted_futures, key=sort_key):
        # cooperative yield to allow gevent to service other greenlets
        gevent.sleep()
        parent_symbol = group_key[0]
        expiration_date = group_key[1]

        # lookup asset class corresponding to parent_symbol
        if asset_class is None or asset_class.symbol != parent_symbol:
            asset_class = session\
                            .query(AssetClass)\
                            .filter(AssetClass.symbol==parent_symbol)\
                            .options(subqueryload(AssetClass.expiries))\
                            .options(subqueryload(AssetClass.assets.of_type(Future)))\
                            .first()
        # if not found, create new asset class
        if asset_class is None:
            log.info("creating AssetClass: {}".format(parent_symbol))
            asset_class = AssetClass()
            asset_class.symbol = parent_symbol

        # lookup expiry in asset class
        if expiration_date in asset_class.expiries:
            exp = asset_class.expiries[expiration_date]
        # if not found, create a new expiry
        else:
            log.info("creating Expiry: {} {}".format(parent_symbol, expiration_date))
            exp = Expiry()
            exp.expiration_date = expiration_date
            asset_class.expiries[exp.expiration_date] = exp

        # loop through futures in (parent_symbol, expiration) group
        for oc_future in future_group:
            # cooperative yield to allow gevent to service other greenlets
            gevent.sleep()
            # check to see if corresponding gateway asset already exists
            if oc_future.instrument_id in gateway.gateway_assets:
                pass
            # if not found, create new gateway asset for future
            else:
                new_gateway_asset = OCAsset()
                new_gateway_asset.oc_id = oc_future.instrument_id
                new_gateway_asset.oc_class_id = oc_future.class_id
                new_gateway_asset.oc_group_id = oc_future.group_id
                gateway.gateway_assets[new_gateway_asset.gateway_index] = new_gateway_asset

                #exp.derivatives indexed by tuple of ('F', future_expiration_date) for future contracts
                ac_index = create_asset_class_future_index(expiration_date)
                exp_index = create_expiry_future_index(expiration_date)
                # search for future instrument in exp.derivatives
                if ac_index in asset_class.assets:
                    future_inst = asset_class.assets[ac_index]
                # if not found, create new future instrument and link to new gateway asset
                else:
                    log.debug('creating FutureAsset: {} {}'.format(oc_future.parent_symbol, oc_future.expiration))
                    future_inst = Future()
                    future_inst.min_price_increment = oc_future.min_price_increment
                    asset_class.assets[ac_index] = future_inst
                    exp.derivatives[exp_index] = future_inst
                future_inst.gateway_assets.append(new_gateway_asset)
    session.commit()
    session.close()