def mark_existing_contract_as_sampling(contract_to_add: futuresContract,
                                       data: dataBlob):
    data_contracts = dataContracts(data)
    data_contracts.mark_contract_as_sampling(contract_to_add)
    log = contract_to_add.specific_log(data.log)

    log.msg("Contract %s now sampling" % str(contract_to_add))
Esempio n. 2
0
def get_roll_spread_information(data: dataBlob, instrument_code: str) -> rollSpreadInformation:
    diag_positions = diagPositions(data)
    diag_contracts = dataContracts(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)

    contract = futuresContract(instrument_code, priced_contract_id)

    position_in_priced = diag_positions.get_position_for_contract(contract)

    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)
Esempio n. 3
0
def update_historical_prices_for_instrument(
        instrument_code: str,
        data: dataBlob,
        cleaning_config: priceFilterConfig = arg_not_supplied,
        interactive_mode: bool = False):
    """
    Do a daily update for futures contract prices, using IB historical data

    :param instrument_code: str
    :param data: dataBlob
    :return: None
    """
    diag_contracts = dataContracts(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.update_log(contract_object.specific_log(data.log))
        update_historical_prices_for_instrument_and_contract(
            contract_object,
            data,
            cleaning_config=cleaning_config,
            interactive_mode=interactive_mode)

    return success
def get_contract_expiry_from_db(contract: futuresContract,
                                data: dataBlob) -> expiryDate:
    data_contracts = dataContracts(data)
    db_contract = data_contracts.get_contract_from_db(contract)
    db_expiry_date = db_contract.expiry_date

    return db_expiry_date
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 = dataContracts(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
Esempio n. 6
0
    def data_contracts(self) -> dataContracts:
        data_contracts = getattr(self, "_data_contracts", None)
        if data_contracts is None:
            data_contracts = dataContracts(self.data)
            self._data_contracts = data_contracts

        return data_contracts
def setup_roll_data_with_state_reporting(
    data: dataBlob, instrument_code: str
) -> RollDataWithStateReporting:
    diag_positions = diagPositions(data)
    diag_contracts = dataContracts(data)

    original_roll_status = diag_positions.get_roll_state(instrument_code)
    priced_contract_date = diag_contracts.get_priced_contract_id(instrument_code)

    contract = futuresContract(instrument_code, priced_contract_date)

    position_priced_contract = int(diag_positions.get_position_for_contract(contract))

    allowable_roll_states = allowable_roll_state_from_current_and_position(
        original_roll_status, position_priced_contract
    )

    days_until_roll = diag_contracts.days_until_roll(instrument_code)

    relative_volume = relative_volume_in_forward_contract_versus_price(
        data=data, instrument_code=instrument_code
    )
    if np.isnan(relative_volume):
        relative_volume = 0.0

    roll_data_with_state = RollDataWithStateReporting(
        instrument_code=instrument_code,
        original_roll_status=original_roll_status,
        position_priced_contract=position_priced_contract,
        allowable_roll_states_as_list_of_str=allowable_roll_states,
        days_until_roll=days_until_roll,
        relative_volume=relative_volume,
    )

    return roll_data_with_state
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 = dataContracts(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 []
def get_list_of_currently_sampling_contracts_in_db(
        data: dataBlob, instrument_code: str) -> listOfFuturesContracts:
    data_contracts = dataContracts(data)

    currently_sampling_contracts = data_contracts.get_all_sampled_contracts(
        instrument_code)

    return currently_sampling_contracts
def days_until_earliest_expiry(data: dataBlob, instrument_code: str) -> int:

    data_contracts = dataContracts(data)
    carry_days = data_contracts.days_until_carry_expiry(instrument_code)
    roll_days = data_contracts.days_until_roll(instrument_code)
    price_days = data_contracts.days_until_price_expiry(instrument_code)

    return min([carry_days, roll_days, price_days])
def create_furthest_out_contract_with_roll_parameters_from_contract_date(
        data: dataBlob, instrument_code: str, furthest_out_contract_date: str):

    diag_contracts = dataContracts(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
Esempio n. 12
0
def get_trading_hours_for_instrument(data, instrument_code):

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

    contract = futuresContract(instrument_code, contract_id)

    data_broker = dataBroker(data)
    trading_hours = data_broker.get_trading_hours_for_contract(contract)

    return trading_hours
Esempio n. 13
0
def relative_volume_in_forward_contract_and_price(
        data: dataBlob, instrument_code: str) -> list:

    c_data = dataContracts(data)
    forward_contract_id = c_data.get_forward_contract_id(instrument_code)
    current_contract = c_data.get_priced_contract_id(instrument_code)
    v_data = diagVolumes(data)
    volumes = v_data.get_normalised_smoothed_volumes_of_contract_list(
        instrument_code, [current_contract, forward_contract_id])

    return volumes
def update_contract_object_with_new_expiry_date(
        data: dataBlob, broker_expiry_date: expiryDate,
        contract_object: futuresContract):
    data_contracts = dataContracts(data)
    data_contracts.update_expiry_date(contract_object,
                                      new_expiry_date=broker_expiry_date)

    log = contract_object.specific_log(data.log)

    log.msg("Updated expiry of contract %s to %s" %
            (str(contract_object), str(broker_expiry_date)))
def get_trading_hours_for_instrument(data: dataBlob,
                                     instrument_code: str) -> listOfOpeningTimes:

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

    contract = futuresContract(instrument_code, contract_id)

    data_broker = dataBroker(data)
    trading_hours = data_broker.get_trading_hours_for_contract(contract)

    return trading_hours
def view_contract_config(data):
    instrument_code, contract_id = get_valid_instrument_code_and_contractid_from_user(
        data)
    diag_contracts = dataContracts(data)
    contract_object = diag_contracts.get_contract_from_db_given_code_and_id(
        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
Esempio n. 17
0
def construct_position_entry(data: dataBlob, system: System,
                             instrument_code: str, lower_buffer: float,
                             upper_buffer: float) -> bufferedOptimalPositions:

    diag_contracts = dataContracts(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
Esempio n. 18
0
def add_new_contract_with_sampling_on(contract_to_add: futuresContract, data: dataBlob):
    data_contracts = dataContracts(data)

    # Mark it as sampling
    contract_to_add.sampling_on()

    # Add it to the database
    # Should not be any duplication to ignore
    data_contracts.add_contract_data(contract_to_add, ignore_duplication=False)

    log = contract_to_add.specific_log(data.log)

    log.msg("Contract %s now added to database and sampling" % str(contract_to_add))
def add_missing_or_not_sampling_contract_to_database(
        data: dataBlob, contract_to_add: futuresContract):
    ## A 'missing' contract may be genuinely missing, or just not sampling

    data_contracts = dataContracts(data)

    is_contract_already_in_database = data_contracts.is_contract_in_data(
        contract_to_add)

    if is_contract_already_in_database:
        mark_existing_contract_as_sampling(contract_to_add, data=data)
    else:
        add_new_contract_with_sampling_on(contract_to_add, data=data)
Esempio n. 20
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 = dataContracts(data)
    relevant_contract_dict = c_data.get_labelled_dict_of_current_contracts(
        instrument_code)
    list_of_relevant_contract_date_str = relevant_contract_dict["contracts"]
    contract_labels = relevant_contract_dict["labels"]

    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
Esempio n. 21
0
def check_and_stop_expired_contract_sampling(contract: futuresContract, data: dataBlob):

    data_contracts = dataContracts(data)
    db_contract = data_contracts.get_contract_from_db(contract)
    contract_expired = db_contract.expired()
    contract_sampling = db_contract.currently_sampling

    if contract_expired and contract_sampling:
        # Mark it as stop sampling in the database

        data_contracts.mark_contract_as_not_sampling(contract)
        log = contract.specific_log(data.log)
        log.msg(
            "Contract %s has expired so now stopped sampling" % str(contract),
            contract_date=contract.date_str,
        )
Esempio n. 22
0
def get_best_average_daily_volume_for_instrument(data, instrument_code: str):

    data_contracts = dataContracts(data)
    contract_dates = data_contracts.get_all_sampled_contracts(instrument_code)

    volumes = [
        get_average_daily_volume_for_contract_object(data, contract_object)
        for contract_object in contract_dates
    ]

    if len(volumes) == 0:
        ## can happen with brand new instruments not properly added
        return np.nan

    best_volume = max(volumes)

    return best_volume
def setup_roll_data(data: dataBlob, instrument_code: str) -> RollData:
    diag_positions = diagPositions(data)
    diag_contracts = dataContracts(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
Esempio n. 24
0
def construct_optimal_position_entry(
        data: dataBlob, system: System,
        instrument_code: str) -> optimalPositionWithReference:

    diag_contracts = dataContracts(data)

    optimal_position = get_optimal_position_from_system(
        system, instrument_code)

    reference_price = system.rawdata.get_daily_prices(instrument_code).iloc[-1]
    reference_date = system.rawdata.get_daily_prices(instrument_code).index[-1]
    reference_contract = diag_contracts.get_priced_contract_id(instrument_code)
    position_entry = optimalPositionWithReference(optimal_position,
                                                  reference_price,
                                                  reference_contract,
                                                  reference_date)

    return position_entry
Esempio n. 25
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 = dataContracts(data)
    contract_priced = c_data.get_priced_contract_id(instrument_code)
    contract_fwd = c_data.get_forward_contract_id(instrument_code)

    volumes = relative_volume_in_forward_contract_and_price(
        data, instrument_code)
    volume_priced = volumes[0]
    volume_fwd = volumes[1]

    # length to expiries / length to suggested roll

    price_expiry_days = c_data.days_until_price_expiry(instrument_code)
    carry_expiry_days = c_data.days_until_carry_expiry(instrument_code)
    when_to_roll_days = c_data.days_until_roll(instrument_code)

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

    # Positions
    position_priced = diag_positions.get_position_for_contract(
        futuresContract(instrument_code, contract_priced))

    results_dict_code = dict(
        status=roll_status,
        roll_expiry=when_to_roll_days,
        price_expiry=price_expiry_days,
        carry_expiry=carry_expiry_days,
        contract_priced=contract_priced,
        contract_fwd=contract_fwd,
        position_priced=position_priced,
        volume_priced=volume_priced,
        volume_fwd=volume_fwd,
    )

    return results_dict_code
def update_expiries_of_sampled_contracts(instrument_code: str, data: dataBlob):
    """
    # 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 = dataContracts(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)
Esempio n. 27
0
def check_and_update_sampling_status(contract: futuresContract, data: dataBlob,
                                     contract_chain: listOfFuturesContracts):

    unsample = False
    reason = ""
    data_contracts = dataContracts(data)
    db_contract = data_contracts.get_contract_from_db(contract)

    if db_contract.expired():
        unsample = True
        reason = "has expired"
    elif db_contract not in contract_chain:
        unsample = True
        reason = "not in chain"

    if unsample:
        # Mark it as stop sampling in the database
        data_contracts.mark_contract_as_not_sampling(contract)
        log = contract.specific_log(data.log)
        log.msg(
            "Contract %s %s so now stopped sampling" % (str(contract), reason),
            contract_date=contract.date_str,
        )
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 = dataContracts(data)
    current_contract = diag_contracts.get_priced_contract_id(instrument_code)
    next_contract = diag_contracts.get_forward_contract_id(instrument_code)

    contract = futuresContract(instrument_code, current_contract)

    position_current_contract = diag_positions.get_position_for_contract(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
Esempio n. 29
0
def update_multiple_prices_on_roll(
        data: dataBlob,
        current_multiple_prices: futuresMultiplePrices,
        instrument_code: str,
        allow_forward_fill: bool = False) -> futuresMultiplePrices:
    """
    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 allow_forward_fill:
        new_multiple_prices = new_multiple_prices.ffill()

    # 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.forward

    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 = dataContracts(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_forward_contract_date = new_price_contract_date_object.next_held_contract(
    )
    new_carry_contract_date = new_price_contract_date_object.carry_contract()

    new_price_contract_object = futuresContract(
        instrument_object, new_price_contract_date_object.contract_date)
    new_forward_contract_object = futuresContract(
        instrument_object, new_forward_contract_date.contract_date)
    new_carry_contract_object = futuresContract(
        instrument_object, new_carry_contract_date.contract_date)

    new_price_price = old_forward_contract_last_price
    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_str
    new_forward_contractid = new_forward_contract_object.date_str
    new_carry_contractid = new_carry_contract_object.date_str

    # 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_single_row = singleRowMultiplePrices(
            price=old_priced_contract_last_price,
            forward=old_forward_contract_last_price,
        )
        new_multiple_prices = new_multiple_prices.add_one_row_with_time_delta(
            new_single_row)
    # SOME KIND OF WARNING HERE...?

    # Now we add a row with the new rolled contracts
    newer_single_row = singleRowMultiplePrices(
        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,
    )
    newer_multiple_prices = new_multiple_prices.add_one_row_with_time_delta(
        newer_single_row)

    return newer_multiple_prices