def update_historical_prices_with_checks_for_instrument(
    instrument_code, data, log=logger("")):
    """
    Do a daily update for futures contract prices, using IB historical data

    Any 'spikes' are manually checked

    :param instrument_code: str
    :param data: dataBlob
    :param log: logger
    :return: None
    """
    diag_contracts = diagContracts(data)
    all_contracts_list = diag_contracts.get_all_contract_objects_for_instrument_code(
        instrument_code)
    contract_list = all_contracts_list.currently_sampling()

    if len(contract_list) == 0:
        log.warn("No contracts marked for sampling for %s" % instrument_code)
        return failure

    for contract_object in contract_list:
        update_historical_prices_with_checks_for_instrument_and_contract(
            contract_object,
            data,
            log=log.setup(contract_date=contract_object.date))

    return success
Example #2
0
def create_force_roll_orders(data, instrument_code):
    """

    :param data:
    :param instrument_code:
    :return: tuple; instrument_order (or missing_order), contract_orders
    """
    diag_positions = diagPositions(data)
    roll_state = diag_positions.get_roll_state(instrument_code)
    if roll_state not in ['Force', 'Force_Outright']:
        return missing_order, []

    strategy = ROLL_PSEUDO_STRATEGY
    trade = 0
    instrument_order = instrumentOrder(strategy, instrument_code, trade, roll_order=True, order_type="Zero-roll-order")

    diag_contracts = diagContracts(data)
    priced_contract_id = diag_contracts.get_priced_contract_id(instrument_code)
    forward_contract_id = diag_contracts.get_forward_contract_id(instrument_code)
    position_in_priced = diag_positions.get_position_for_instrument_and_contract_date(instrument_code, priced_contract_id)

    if roll_state=='Force_Outright':
        contract_orders = create_contract_orders_outright(data,  instrument_code, priced_contract_id, forward_contract_id, position_in_priced)
    elif roll_state=='Force':
        contract_orders = create_contract_orders_spread(data,  instrument_code, priced_contract_id, forward_contract_id, position_in_priced)
    else:
        raise  Exception("Roll state %s not recognised" % roll_state)

    return instrument_order, contract_orders
def passive_roll_child_order(
    data: dataBlob,
    trade: int,
    instrument_order: instrumentOrder,
) -> list:

    log = instrument_order.log_with_attributes(data.log)
    diag_positions = diagPositions(data)
    instrument_code = instrument_order.instrument_code

    diag_contracts = diagContracts(data)
    current_contract = diag_contracts.get_priced_contract_id(instrument_code)
    next_contract = diag_contracts.get_forward_contract_id(instrument_code)

    position_current_contract = (
        diag_positions.get_position_for_instrument_and_contract_date(
            instrument_code, current_contract))

    # Break out because so darn complicated
    if position_current_contract == 0:
        # Passive roll and no position in the current contract, start trading
        # the next contract
        log.msg(
            "Passive roll handling order %s, no position in current contract, entire trade in next contract %s"
            % (str(instrument_order), next_contract))
        return [contractIdAndTrade(next_contract, trade)]

    # ok still have a position in the current contract
    increasing_trade = sign(trade) == sign(position_current_contract)
    if increasing_trade:
        # Passive roll and increasing trade
        # Do it all in next contract
        log.msg(
            "Passive roll handling order %s, increasing trade, entire trade in next contract %s"
            % (str(instrument_order), next_contract))
        return [contractIdAndTrade(next_contract, trade)]

    # ok a reducing trade
    new_position = position_current_contract + trade
    sign_of_position_is_unchanged = sign(position_current_contract) == sign(
        new_position)
    if new_position == 0 or sign_of_position_is_unchanged:
        # A reducing trade that we can do entirely in the current contract
        log.msg(
            "Passive roll handling order %s, reducing trade, entire trade in next contract %s"
            % (str(instrument_order), next_contract))
        return [contractIdAndTrade(current_contract, trade)]

    # OKAY to recap: it's a passive roll, but the trade will be split between
    # current and next
    list_of_child_contract_dates_and_trades = \
        passive_trade_split_over_two_contracts(trade=trade,
                                               current_contract=current_contract,
                                               next_contract=next_contract,
                                               position_current_contract=position_current_contract)
    log.msg(
        "Passive roll handling order %s, reducing trade, split trade between contract %s and %s"
        % (str(instrument_order), current_contract, next_contract))

    return list_of_child_contract_dates_and_trades
def update_contract_database_with_contract_chain( instrument_code, required_contract_chain, data, log=logtoscreen("")):
    """

    :param required_contract_chain: list of contract dates 'yyyymm'
    :param instrument_code: str
    :param data: dataBlob
    :return: None
    """
    diag_contracts = diagContracts(data)

    # Get list of contracts in the database
    all_contracts_in_db = diag_contracts.get_all_contract_objects_for_instrument_code(instrument_code)
    current_contract_chain = all_contracts_in_db.currently_sampling()

    #Is something in required_contract_chain, but not in the database?
    missing_from_db = required_contract_chain.difference(current_contract_chain)

    #They have probably been added as the result of a recent roll
    # Let's add them
    add_missing_contracts_to_database(instrument_code, missing_from_db, data, log=log)

    #Is something in the database, but not in required_contract_chain?
    #Then it's eithier expired or weirdly very far in the future (maybe we changed the roll parameters)
    #Eithier way, we stop sampling it (if it hasn't expired, will be added in the future)
    contracts_not_sampling = current_contract_chain.difference(required_contract_chain)
    mark_contracts_as_stopped_sampling(instrument_code, contracts_not_sampling, data, log=log)

    return None
def add_missing_contracts_to_database(instrument_code,
                                      missing_from_db,
                                      data,
                                      log=logtoscreen("")):
    """

    :param instrument_code: str
    :param missing_from_db: list of contract_date objects
    :param data: dataBlob
    :return: None
    """
    diag_contracts = diagContracts(data)
    update_contracts = updateContracts(data)

    for contract_to_add in missing_from_db:
        contract_date = contract_to_add.date
        if diag_contracts.is_contract_in_data(instrument_code, contract_date):
            contract_to_add = diag_contracts.get_contract_data(
                instrument_code, contract_date)

        # Mark it as sampling
        contract_to_add.sampling_on()

        # Add it to the database
        # We are happy to overwrite
        update_contracts.add_contract_data(contract_to_add,
                                           ignore_duplication=True)

        log.msg("Contract %s now added to database and sampling" %
                str(contract_to_add))

    return None
Example #6
0
def get_roll_spread_information(data: dataBlob,
                                instrument_code: str) -> rollSpreadInformation:
    diag_positions = diagPositions(data)
    diag_contracts = diagContracts(data)
    diag_prices = diagPrices(data)

    priced_contract_id = diag_contracts.get_priced_contract_id(instrument_code)
    forward_contract_id = diag_contracts.get_forward_contract_id(
        instrument_code)

    position_in_priced = diag_positions.get_position_for_instrument_and_contract_date(
        instrument_code, priced_contract_id)

    reference_date, last_matched_prices = tuple(
        diag_prices.get_last_matched_date_and_prices_for_contract_list(
            instrument_code, [priced_contract_id, forward_contract_id]))
    reference_price_priced_contract, reference_price_forward_contract = last_matched_prices

    return rollSpreadInformation(
        priced_contract_id=priced_contract_id,
        forward_contract_id=forward_contract_id,
        reference_price_forward_contract=reference_price_forward_contract,
        reference_price_priced_contract=reference_price_priced_contract,
        position_in_priced=int(position_in_priced),
        reference_date=reference_date,
        instrument_code=instrument_code)
def get_contract_chain(instrument_code, data):
    diag_contracts = diagContracts(data)
    diag_prices = diagPrices(data)

    roll_parameters = diag_contracts.get_roll_parameters(instrument_code)

    # Get the last contract currently being used
    multiple_prices = diag_prices.get_multiple_prices(instrument_code)
    current_contract_dict = multiple_prices.current_contract_dict()
    current_contract_list = list(current_contract_dict.values())
    furthest_out_contract_date = max(current_contract_list)
    furthest_out_contract = contractDateWithRollParameters(
        roll_parameters, furthest_out_contract_date)

    # To give us wiggle room, and ensure we start collecting the new forward a
    # little in advance
    final_contract = furthest_out_contract.next_priced_contract()

    contract_date_chain = (
        final_contract.get_unexpired_contracts_from_now_to_contract_date())

    # We have a list of contract_date objects, need futureContracts
    # create a 'bare' instrument object
    instrument_object = futuresInstrument(instrument_code)

    contract_object_chain_as_list = [
        futuresContract(instrument_object, contract_date_object)
        for contract_date_object in contract_date_chain
    ]

    contract_object_chain = listOfFuturesContracts(
        contract_object_chain_as_list)

    return contract_object_chain
Example #8
0
def add_missing_contract_to_database(data: dataBlob, contract_to_add: futuresContract):
    diag_contracts = diagContracts(data)
    update_contracts = updateContracts(data)
    instrument_code = contract_to_add.instrument_code

    contract_date_str = contract_to_add.date_str

    if diag_contracts.is_contract_in_data(instrument_code, contract_date_str):
        contract_to_add = diag_contracts.get_contract_object(
            instrument_code, contract_date_str
        )

    # Mark it as sampling
    contract_to_add.sampling_on()

    # Add it to the database
    # We are happy to overwrite
    update_contracts.add_contract_data(
        contract_to_add, ignore_duplication=True)

    log = data.log.setup(instrument_code=instrument_code)

    log.msg(
        "Contract %s now added to database and sampling" %
        str(contract_to_add))
Example #9
0
def update_historical_prices_for_instrument(instrument_code: str,
                                            data: dataBlob):
    """
    Do a daily update for futures contract prices, using IB historical data

    :param instrument_code: str
    :param data: dataBlob
    :return: None
    """
    diag_contracts = diagContracts(data)
    all_contracts_list = diag_contracts.get_all_contract_objects_for_instrument_code(
        instrument_code)
    contract_list = all_contracts_list.currently_sampling()

    if len(contract_list) == 0:
        data.log.warn("No contracts marked for sampling for %s" %
                      instrument_code)
        return failure

    for contract_object in contract_list:
        data.log.label(contract_date=contract_object.date_str)
        update_historical_prices_for_instrument_and_contract(
            contract_object, data)

    return success
def mark_contracts_as_stopped_sampling(instrument_code,
                                       contracts_not_sampling,
                                       data,
                                       log=logtoscreen("")):
    """

    :param instrument_code: str
    :param contracts_not_sampling: list of contractDate objects
    :param data: dataBlobg
    :return: None
    """
    diag_contracts = diagContracts(data)
    update_contracts = updateContracts(data)

    for contract_date_object in contracts_not_sampling:
        contract_date = contract_date_object.date

        # Mark it as stop sampling in the database
        contract = diag_contracts.get_contract_data(instrument_code,
                                                    contract_date)
        if contract.currently_sampling:
            contract.sampling_off()
            update_contracts.add_contract_data(contract,
                                               ignore_duplication=True)

            log.msg(
                "Contract %s has now stopped sampling" % str(contract),
                contract_date=contract.date,
            )
        else:
            # nothing to do
            pass

    return None
def update_expiry_for_contract(contract_object, data):
    """
    Get an expiry from IB, check if same as database, otherwise update the database

    :param contract_object: contract object
    :param data: dataBlob
    :param log: log
    :return: None
    """
    log = data.log
    diag_contracts = diagContracts(data)
    data_broker = dataBroker(data)
    update_contracts = updateContracts(data)

    contract_date = contract_object.date
    instrument_code = contract_object.instrument_code

    log = log.setup(
        instrument_code=instrument_code,
        contract_date=contract_date)
    db_contract = diag_contracts.get_contract_data(
        instrument_code, contract_date)

    # Both should be in format expiryDate(yyyy,mm,dd)
    db_expiry_date = db_contract.date.expiry_date
    try:
        ib_expiry_date = (
            data_broker.get_actual_expiry_date_for_instrument_code_and_contract_date(
                instrument_code, contract_date))

        if ib_expiry_date is missing_contract:
            raise Exception()

    except Exception as e:
        # We can do nothing with that...
        log.warn(
            "%s so couldn't get expiry date for %s" %
            (e, str(contract_object)))
        return None

    # Will they be same format?
    if ib_expiry_date == db_expiry_date:
        log.msg(
            "No change to contract expiry %s to %s"
            % (str(contract_object), str(ib_expiry_date))
        )
        return None

    # Different!
    contract_object.date.update_expiry_date(ib_expiry_date)
    update_contracts.add_contract_data(
        contract_object, ignore_duplication=True)

    log.msg(
        "Updated expiry of contract %s to %s"
        % (str(contract_object), str(ib_expiry_date))
    )

    return None
Example #12
0
def get_current_contract_chain_in_db(data: dataBlob, instrument_code:str) -> listOfFuturesContracts:
    diag_contracts = diagContracts(data)

    # Get list of contracts in the database
    all_contracts_in_db = diag_contracts.get_all_contract_objects_for_instrument_code(
        instrument_code)
    current_contract_chain = all_contracts_in_db.currently_sampling()

    return current_contract_chain
def get_trading_hours_for_instrument(data, instrument_code):

    diag_contracts = diagContracts(data)
    contract_id = diag_contracts.get_priced_contract_id(instrument_code)

    data_broker = dataBroker(data)
    trading_hours = data_broker.get_trading_hours_for_instrument_code_and_contract_date(instrument_code, contract_id)

    return trading_hours
Example #14
0
def view_contract_config(data):
    instrument_code, contract_id = get_valid_instrument_code_and_contractid_from_user(data)
    diag_contracts = diagContracts(data)
    contract_object = diag_contracts.get_contract_object(instrument_code, contract_id)
    contract_date = diag_contracts.get_contract_date_object_with_roll_parameters(instrument_code, contract_id)
    print(contract_object.as_dict())
    print(contract_date.roll_parameters)

    return None
def get_required_contract_trade_for_instrument(
        data: dataBlob, instrument_order: instrumentOrder) -> list:
    """
    Return the contract to trade for a given instrument

    Depends on roll status and trade vs position:
     - roll_states = ['No_Roll', 'Passive', 'Force', 'Force_Outright', 'Roll_Adjusted']

    If 'No Roll' then trade current contract
    If 'Passive', and no position in current contract: trade next contract
    If 'Passive', and reducing trade which leaves zero or something in current contract: trade current contract
    If 'Passive', and reducing trade which is larger than current contract position: trade current and next contract
    If 'Passive', and increasing trade: trade next contract
    If 'Force' or 'Force Outright' or 'Roll_Adjusted': don't trade

    :param instrument_order:
    :param data: dataBlog
    :return: tuple: list of child orders: each is a tuple: contract str or missing_contract, trade int
    """
    instrument_code = instrument_order.instrument_code
    log = instrument_order.log_with_attributes(data.log)
    trade = instrument_order.as_single_trade_qty_or_error()
    if trade is missing_order:
        log.critical("Instrument order can't be a spread order")
        return []

    diag_positions = diagPositions(data)

    if diag_positions.is_roll_state_no_roll(instrument_code):
        diag_contracts = diagContracts(data)
        current_contract = diag_contracts.get_priced_contract_id(
            instrument_code)

        log.msg("No roll, allocating entire order %s to current contract %s" %
                (str(instrument_order), current_contract))
        return [contractIdAndTrade(current_contract, trade)]

    elif diag_positions.is_roll_state_passive(instrument_code):
        # no log as function does it
        list_of_child_contract_dates_and_trades = passive_roll_child_order(
            data=data, instrument_order=instrument_order, trade=trade)

        return list_of_child_contract_dates_and_trades

    elif diag_positions.is_type_of_active_rolling_roll_state(instrument_code):
        log.msg(
            "Roll state is active rolling, not going to generate trade for order %s"
            % (str(instrument_order)))
        return []

    else:
        log.critical(
            "Roll state %s not understood: can't generate trade for %s" %
            (diag_positions.get_name_of_roll_state(instrument_code),
             str(instrument_order)))
        return []
Example #16
0
def get_roll_data_for_instrument(instrument_code, data):
    """
    Get roll data for an individual instrument

    :param instrument_code: str
    :param data: dataBlob
    :return:
    """
    c_data = diagContracts(data)
    relevant_contract_dict = c_data.get_labelled_list_of_relevant_contracts(
        instrument_code)
    relevant_contracts = relevant_contract_dict['contracts']
    contract_labels = relevant_contract_dict['labels']
    current_contracts = relevant_contract_dict['current_contracts']

    v_data = diagVolumes(data)
    volumes = v_data.get_normalised_smoothed_volumes_of_contract_list(
        instrument_code, relevant_contracts)

    # price curve
    p_data = diagPrices(data)
    contracts_to_match = [current_contracts[k] for k in ('PRICE', 'FORWARD')]
    last_matched_prices = p_data.get_last_matched_prices_for_contract_list(
        instrument_code,
        relevant_contracts,
        contracts_to_match=contracts_to_match)

    # length to expiries / length to suggested roll
    price_expiry = c_data.get_priced_expiry(instrument_code)
    carry_expiry = c_data.get_carry_expiry(instrument_code)
    when_to_roll = c_data.when_to_roll_priced_contract(instrument_code)

    now = datetime.datetime.now()
    price_expiry_days = (price_expiry - now).days
    carry_expiry_days = (carry_expiry - now).days
    when_to_roll_days = (when_to_roll - now).days

    # roll status
    s_data = diagPositions(data)
    roll_status = s_data.get_roll_state(instrument_code)

    # Positions
    positions = s_data.get_positions_for_instrument_and_contract_list(
        instrument_code, relevant_contracts)

    results_dict_code = dict(code=instrument_code,
                             status=roll_status,
                             roll_expiry=when_to_roll_days,
                             price_expiry=price_expiry_days,
                             carry_expiry=carry_expiry_days,
                             contract_labels=contract_labels,
                             volumes=volumes,
                             curve=last_matched_prices,
                             positions=positions)

    return results_dict_code
def create_furthest_out_contract_with_roll_parameters_from_contract_date(
        data: dataBlob, instrument_code: str, furthest_out_contract_date: str):

    diag_contracts = diagContracts(data)
    roll_parameters = diag_contracts.get_roll_parameters(instrument_code)

    furthest_out_contract = contractDateWithRollParameters(
        contractDate(furthest_out_contract_date), roll_parameters)

    return furthest_out_contract
Example #18
0
def construct_position_entry(data, system, instrument_code, lower_buffer,
                             upper_buffer):
    diag_contracts = diagContracts(data)
    reference_price = system.rawdata.get_daily_prices(instrument_code).iloc[-1]
    reference_contract = diag_contracts.get_priced_contract_id(instrument_code)
    position_entry = bufferedOptimalPositions(lower_buffer, upper_buffer,
                                              reference_price,
                                              reference_contract)

    return position_entry
Example #19
0
def create_force_roll_orders(data, instrument_code):
    """

    :param data:
    :param instrument_code:
    :return: tuple; instrument_order (or missing_order), contract_orders
    """
    diag_positions = diagPositions(data)

    strategy = ROLL_PSEUDO_STRATEGY
    trade = 0
    instrument_order = instrumentOrder(
        strategy,
        instrument_code,
        trade,
        roll_order=True,
        order_type="Zero-roll-order")


    diag_contracts = diagContracts(data)
    priced_contract_id = diag_contracts.get_priced_contract_id(instrument_code)
    forward_contract_id = diag_contracts.get_forward_contract_id(
        instrument_code)
    position_in_priced = diag_positions.get_position_for_instrument_and_contract_date(
        instrument_code, priced_contract_id)

    if position_in_priced == 0:
        return missing_order, []

    if diag_positions.is_roll_state_force(instrument_code):
        contract_orders = create_contract_orders_outright(
            data,
            instrument_code,
            priced_contract_id,
            forward_contract_id,
            position_in_priced,
        )
    elif diag_positions.is_roll_state_force_outright(instrument_code):
        contract_orders = create_contract_orders_spread(
            data,
            instrument_code,
            priced_contract_id,
            forward_contract_id,
            position_in_priced,
        )
    else:
        log = instrument_order.log_with_attributes(data.log)
        log.warn("Roll state %s is unexpected, might have changed" % str(roll_state))
        return missing_order, []

    contract_orders = allocate_algo_to_list_of_contract_orders(
        data, contract_orders, instrument_order=instrument_order
    )

    return instrument_order, contract_orders
Example #20
0
def get_required_contract_trade_for_instrument(data, instrument_order):
    """
    Return the contract to trade for a given instrument

    Depends on roll status and trade vs position:
     - roll_states = ['No_Roll', 'Passive', 'Force', 'Force_Outright', 'Roll_Adjusted']

    If 'No Roll' then trade current contract
    If 'Passive', and no position in current contract: trade next contract
    If 'Passive', and reducing trade which leaves zero or something in current contract: trade current contract
    If 'Passive', and reducing trade which is larger than current contract position: trade current and next contract
    If 'Passive', and increasing trade: trade next contract
    If 'Force' or 'Force Outright' or 'Roll_Adjusted': don't trade

    :param instrument_order:
    :param data: dataBlog
    :return: tuple: list of child orders: each is a tuple: contract str or missing_contract, trade int
    """
    instrument_code = instrument_order.instrument_code
    log = instrument_order.log_with_attributes(data.log)
    trade = instrument_order.trade.as_int()
    if trade is missing_order:
        log.critical("Instrument order can't be a spread order")
        return missing_contract

    diag_contracts = diagContracts(data)
    current_contract = diag_contracts.get_priced_contract_id(instrument_code)
    next_contract = diag_contracts.get_forward_contract_id(instrument_code)

    diag_positions = diagPositions(data)
    roll_state = diag_positions.get_roll_state(instrument_code)

    position_current_contract = diag_positions.get_position_for_instrument_and_contract_date(
        instrument_code, current_contract)
    if roll_state == 'No_Roll':
        log.msg("No roll, allocating entire order %s to current contract %s" %
                (str(instrument_order), current_contract))
        return [(current_contract, trade)]

    elif roll_state in ['Force', 'Force_Outright', 'Roll_Adjusted']:
        log.msg(
            "Roll state %s is rolling, not going to generate trade for order %s"
            % (roll_state, str(instrument_order)))
        return rolling_cant_trade

    elif roll_state == "Passive":
        return passive_roll_child_order(position_current_contract,
                                        current_contract, next_contract, trade,
                                        log, instrument_order)
    else:
        log.critical(
            "Roll state %s not understood: can't generate trade for %s" %
            (roll_state, str(instrument_order)))
        return missing_contract
def get_required_roll_state(data: dataBlob, instrument_code: str):
    diag_positions = diagPositions(data)
    diag_contracts = diagContracts(data)

    current_roll_status = diag_positions.get_roll_state(instrument_code)
    priced_contract_date = diag_contracts.get_priced_contract_id(
        instrument_code)
    position_priced_contract = (
        diag_positions.get_position_for_instrument_and_contract_date(
            instrument_code, priced_contract_date))

    allowable_roll_states = allowable_roll_state_from_current_and_position(
        current_roll_status, position_priced_contract)
    max_possible_states = len(allowable_roll_states) - 1

    roll_state_required = no_state_available
    while roll_state_required is no_state_available:
        display_roll_query_banner(current_roll_status,
                                  position_priced_contract,
                                  allowable_roll_states)
        number_of_state_required = input("Which state do you want? [0-%d] " %
                                         max_possible_states)
        try:
            number_of_state_required = int(number_of_state_required)
            assert number_of_state_required >= 0  # avoid weird behaviour
            roll_state_required = allowable_roll_states[
                number_of_state_required]
        except BaseException:
            print(
                "State %s is not an integer specifying a possible roll state\n"
                % number_of_state_required)
            roll_state_required = no_state_available
            # will try again
            continue

        # Update roll state
        if roll_state_required != current_roll_status:
            # check if changing
            print("")
            check = input(
                "Changing roll state for %s from %s to %s, are you sure y/n: "
                % (instrument_code, current_roll_status, roll_state_required))
            print("")
            if check == "y":
                # happy
                break
            else:
                print("OK. Choose again.")
                roll_state_required = no_state_available
                # back to top of loop
                continue

    return current_roll_status, roll_state_required
Example #22
0
def get_roll_data_for_instrument(instrument_code, data):
    """
    Get roll data for an individual instrument

    :param instrument_code: str
    :param data: dataBlob
    :return:
    """
    c_data = diagContracts(data)
    relevant_contract_dict = c_data.get_labelled_list_of_relevant_contracts(
        instrument_code)
    list_of_relevant_contract_date_str = relevant_contract_dict["contracts"]
    contract_labels = relevant_contract_dict["labels"]
    current_contracts = relevant_contract_dict["current_contracts"]

    v_data = diagVolumes(data)
    volumes = v_data.get_normalised_smoothed_volumes_of_contract_list(
        instrument_code, list_of_relevant_contract_date_str)

    # length to expiries / length to suggested roll
    price_expiry = c_data.get_priced_expiry(instrument_code)
    carry_expiry = c_data.get_carry_expiry(instrument_code)
    when_to_roll = c_data.when_to_roll_priced_contract(instrument_code)

    now = datetime.datetime.now()
    price_expiry_days = (price_expiry - now).days
    carry_expiry_days = (carry_expiry - now).days
    when_to_roll_days = (when_to_roll - now).days

    # roll status
    diag_positions = diagPositions(data)
    roll_status = diag_positions.get_name_of_roll_state(instrument_code)

    # Positions
    positions = diag_positions.get_positions_for_instrument_and_contract_list(
        instrument_code, list_of_relevant_contract_date_str)

    results_dict_code = dict(
        code=instrument_code,
        status=roll_status,
        roll_expiry=when_to_roll_days,
        price_expiry=price_expiry_days,
        carry_expiry=carry_expiry_days,
        contract_labels=contract_labels,
        volumes=volumes,
        positions=positions,
    )

    return results_dict_code
Example #23
0
def setup_roll_data(data: dataBlob, instrument_code: str) -> RollData:
    diag_positions = diagPositions(data)
    diag_contracts = diagContracts(data)

    original_roll_status = diag_positions.get_roll_state(instrument_code)
    priced_contract_date = diag_contracts.get_priced_contract_id(
        instrument_code)
    position_priced_contract = (
        diag_positions.get_position_for_instrument_and_contract_date(
            instrument_code, priced_contract_date))

    allowable_roll_states = allowable_roll_state_from_current_and_position(
        original_roll_status, position_priced_contract)

    roll_data = RollData(instrument_code, original_roll_status,
                         position_priced_contract, allowable_roll_states)

    return roll_data
Example #24
0
def update_expiry_for_contract(contract_object: futuresContract, data: dataBlob):
    """
    Get an expiry from IB, check if same as database, otherwise update the database

    :param contract_object: contract object
    :param data: dataBlob
    :param log: log
    :return: None
    """
    log = data.log
    diag_contracts = diagContracts(data)
    data_broker = dataBroker(data)

    contract_date = contract_object.date_str
    instrument_code = contract_object.instrument_code

    log = log.setup(
        instrument_code=instrument_code,
        contract_date=contract_date)
    db_contract = diag_contracts.get_contract_object(
        instrument_code, contract_date)

    db_expiry_date = db_contract.expiry_date
    broker_expiry_date = \
        data_broker.get_actual_expiry_date_for_single_contract(db_contract)

    if broker_expiry_date is missing_contract:
        log.msg(
            "Can't find expiry for %s, could be a connection problem but could be because contract has already expired"
            % (str(contract_object))
        )

        ## don't warn as probably expired we'll remove it from the sampling list
        return None

    if broker_expiry_date == db_expiry_date:
        log.msg(
            "No change to contract expiry %s to %s"
            % (str(contract_object), str(broker_expiry_date))
        )
        return None

    # Different!
    update_contract_object_with_new_expiry_date(data, broker_expiry_date, contract_object)
def update_expiries_of_sampled_contracts(instrument_code, data, log=logtoscreen("")):
    """
    # Now to check if expiry dates are resolved
    # For everything in the database which is sampling
    #   - if it hasn't got an IB expiry recorded, then check for the expiry in IB (can fail)
    #    - if expiry found, add expiry to database, and flag in lookup table as found

    :param instrument_code:
    :param data: dataBlob
    :return: None
    """

    diag_contracts = diagContracts(data)

    all_contracts_in_db = diag_contracts.get_all_contract_objects_for_instrument_code(instrument_code)
    currently_sampling_contracts = all_contracts_in_db.currently_sampling()

    for contract_object in currently_sampling_contracts:
        update_expiry_for_contract(contract_object, data)

    return None
def update_expiry_for_contract(contract_object: futuresContract,
                               data: dataBlob):
    """
    Get an expiry from IB, check if same as database, otherwise update the database

    :param contract_object: contract object
    :param data: dataBlob
    :param log: log
    :return: None
    """
    log = data.log
    diag_contracts = diagContracts(data)
    data_broker = dataBroker(data)

    contract_date = contract_object.date_str
    instrument_code = contract_object.instrument_code

    log = log.setup(instrument_code=instrument_code,
                    contract_date=contract_date)
    db_contract = diag_contracts.get_contract_object(instrument_code,
                                                     contract_date)

    db_expiry_date = db_contract.expiry_date
    broker_expiry_date = \
        data_broker.get_actual_expiry_date_for_contract(db_contract)

    if broker_expiry_date is missing_contract:
        log.warn("Couldn't get expiry date for %s" % (str(contract_object)))
        return None

    if broker_expiry_date == db_expiry_date:
        log.msg("No change to contract expiry %s to %s" %
                (str(contract_object), str(broker_expiry_date)))
        return None

    # Different!
    update_contract_object_with_new_expiry_date(data, broker_expiry_date,
                                                contract_object)
Example #27
0
def stop_expired_contracts_sampling(instrument_code: str, data: dataBlob):
    ## expiry dates will have been updated and are correct
    current_contract_chain_in_db = get_current_contract_chain_in_db(data, instrument_code)

    diag_contracts = diagContracts(data)
    update_contracts = updateContracts(data)
    log = data.log.setup(instrument_code=instrument_code)

    for contract_date_object in current_contract_chain_in_db:
        contract_date = contract_date_object.date_str

        # Mark it as stop sampling in the database
        contract = diag_contracts.get_contract_object(
            instrument_code, contract_date)
        if contract.expired() and contract.currently_sampling:
            contract.sampling_off()
            update_contracts.add_contract_data(
                contract, ignore_duplication=True)

            log.msg(
                "Contract %s has now stopped sampling" % str(contract),
                contract_date=contract.date_str,
            )
Example #28
0
def update_multiple_prices_on_roll(data, current_multiple_prices,
                                   instrument_code):
    """
    Roll multiple prices

    Adds rows to multiple prices

    First row: (optionally) Inferred price and forward prices
    If there is no (old) forward contract price, one needs to be inferred
    If there is no (old) price contract price, one needs to be inferred

    Time index = Last time index + 1 second

    Second row:
    Time index:  Last time index + 1 second

    PRICE = last price of the forward contract
    PRICE_CONTRACT = previous forward contract

    FORWARD_CONTRACT = the new forward contract
    FORWARD_PRICE = the new forward price, this can be Nan; it will get filled in

    CARRY_CONTRACT = the new carry contract
    CARRY_PRICE = the new carry price: if possible infer from price, this can be Nan

    :param data: dataBlob
    :param current_multiple_prices: futuresMultiplePrices
    :return: new futuresMultiplePrices
    """

    new_multiple_prices = futuresMultiplePrices(copy(current_multiple_prices))

    ## If the last row is all Nans, we can't do this
    new_multiple_prices = new_multiple_prices.sort_index()
    new_multiple_prices = new_multiple_prices.drop_trailing_nan()

    price_column = price_column_names['PRICE']
    fwd_column = price_column_names['FORWARD']

    current_contract_dict = new_multiple_prices.current_contract_dict()
    old_forward_contract = current_contract_dict[fwd_column]

    old_priced_contract_last_price, price_inferred = get_or_infer_latest_price(
        new_multiple_prices, price_col=price_column)
    old_forward_contract_last_price, forward_inferred = get_or_infer_latest_price(
        new_multiple_prices, price_col=fwd_column)

    diag_contracts = diagContracts(data)

    instrument_object = futuresInstrument(instrument_code)
    ## Old forward contract -> New price contract
    new_price_contract_date_object = diag_contracts.get_contract_date_object_with_roll_parameters(
        instrument_code, old_forward_contract)
    new_price_contract_object = futuresContract(
        instrument_object, new_price_contract_date_object)
    new_forward_contract_object = new_price_contract_object.next_held_contract(
    )
    new_carry_contract_object = new_price_contract_object.carry_contract()

    new_price_price = get_final_matched_price_from_contract_object(
        data, new_price_contract_object, new_multiple_prices)
    new_forward_price = get_final_matched_price_from_contract_object(
        data, new_forward_contract_object, new_multiple_prices)
    new_carry_price = get_final_matched_price_from_contract_object(
        data, new_carry_contract_object, new_multiple_prices)

    new_price_contractid = new_price_contract_object.date
    new_forward_contractid = new_forward_contract_object.date
    new_carry_contractid = new_carry_contract_object.date

    # If any prices had to be inferred, then add row with both current priced and forward prices
    # Otherwise adjusted prices will break
    if price_inferred or forward_inferred:
        new_multiple_prices = new_multiple_prices.add_one_row_with_time_delta(
            dict(price=old_priced_contract_last_price,
                 forward=old_forward_contract_last_price))

    ## SOME KIND OF WARNING HERE...?

    # Now we add a row with the new rolled contracts
    new_multiple_prices = new_multiple_prices.add_one_row_with_time_delta(
        dict(price=new_price_price,
             forward=new_forward_price,
             carry=new_carry_price,
             price_contract=new_price_contractid,
             forward_contract=new_forward_contractid,
             carry_contract=new_carry_contractid))

    return new_multiple_prices