def enter_manual_instrument_order(data): strategy_name = get_valid_strategy_name_from_user(data=data, source="positions") instrument_code = get_valid_instrument_code_from_user(data) qty = get_and_convert("Quantity (-ve for sell, +ve for buy?)", type_expected=int, allow_default=False) order_type = input("Order type (one of %s)?" % str(possible_order_types)) limit_price = get_and_convert( "Limit price? (if you put None you can still add one to the contract order)", type_expected=float, default_value=None, default_str="None", ) if limit_price is None: limit_contract = None else: print("Enter contractid that limit price is referenced to") _, contract_date = get_valid_instrument_code_and_contractid_from_user( data, instrument_code=instrument_code) limit_contract = contract_date instrument_order = instrumentOrder( strategy_name, instrument_code, qty, order_type=order_type, limit_price=limit_price, limit_contract=limit_contract, manual_trade=True, roll_order=False, ) return instrument_order
def create_instrument_balance_trade(data): data_broker = dataBroker(data) default_account = data_broker.get_broker_account() print( "Use to fix breaks between instrument strategy and contract level positions" ) strategy_name = get_valid_strategy_name_from_user(data=data) instrument_code = get_valid_instrument_code_from_user(data) fill_qty = get_and_convert("Quantity ", type_expected=int, allow_default=False) filled_price = get_and_convert("Filled price", type_expected=float, allow_default=False) fill_datetime = get_datetime_input("Fill datetime", allow_default=True) instrument_order = instrumentOrder( strategy_name, instrument_code, fill_qty, fill=fill_qty, order_type="balance_trade", filled_price=filled_price, fill_datetime=fill_datetime, ) print(instrument_order) ans = input("Are you sure? (Y/other)") if ans != "Y": return None stack_handler = stackHandlerCreateBalanceTrades(data) stack_handler.create_balance_instrument_trade(instrument_order)
def trade_given_optimal_and_actual_positions(data, strategy_name, instrument_code, optimal_positions, actual_positions): log = data.log.setup(strategy_name=strategy_name, instrument_code=instrument_code) ( upper_positions, lower_positions, reference_prices, reference_contracts, ref_dates, ) = optimal_positions upper_for_instrument = upper_positions[instrument_code] lower_for_instrument = lower_positions[instrument_code] actual_for_instrument = actual_positions.get(instrument_code, 0.0) if actual_for_instrument < lower_for_instrument: required_position = round(lower_for_instrument) elif actual_for_instrument > upper_for_instrument: required_position = round(upper_for_instrument) else: required_position = actual_for_instrument # Might seem weird to have a zero order, but since orders can be updated # it makes sense trade_required = required_position - actual_for_instrument reference_contract = reference_contracts[instrument_code] reference_price = reference_prices[instrument_code] log.msg( "Upper %.2f Lower %.2f Current %d Required position %d Required trade %d Reference price %f for contract %s" % ( upper_for_instrument, lower_for_instrument, actual_for_instrument, required_position, trade_required, reference_price, reference_contract, )) ref_date = ref_dates[instrument_code] # No limit orders, just best execution order_required = instrumentOrder( strategy_name, instrument_code, trade_required, order_type="best", reference_price=reference_price, reference_contract=reference_contract, reference_datetime=ref_date, ) return order_required
def trade_given_optimal_and_actual_positions(strategy_name, instrument_code, optimal_positions, actual_positions): upper_positions, lower_positions = optimal_positions upper_for_instrument = upper_positions.get(instrument_code, 0.0) lower_for_instrument = lower_positions.get(instrument_code, 0.0) actual_for_instrument = actual_positions.get(instrument_code, 0.0) if actual_for_instrument < lower_for_instrument: required_position = round(lower_for_instrument) elif actual_for_instrument > upper_for_instrument: required_position = round(upper_for_instrument) else: required_position = actual_for_instrument # Might seem weird to have a zero order, but since orders can be updated it makes sense trade_required = required_position - actual_for_instrument order_required = instrumentOrder(strategy_name, instrument_code, trade_required, type="best") return order_required
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 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
def create_balance_instrument_order_from_contract_order(contract_order): instrument_order = instrumentOrder( contract_order.strategy_name, contract_order.instrument_code, contract_order.trade[0], fill=contract_order.fill[0], filled_price=contract_order.filled_price, fill_datetime=contract_order.fill_datetime, manual_trade=True, active=False) return instrument_order