def adjust_capital_for_delta(data: dataBlob): data_capital = dataCapital(data) capital_delta = get_and_convert( "What change have you made to brokerage account that will not change capital +ve deposit, -ve withdrawal", type_expected=float, ) old_capital = data_capital.get_series_of_broker_capital()[-1] new_capital = old_capital + capital_delta user_wants_adjustment = true_if_answer_is_yes( "New brokerage capital will be %f, are you sure? " % new_capital) if user_wants_adjustment: data_capital.total_capital_calculator.adjust_broker_account_for_delta( capital_delta)
def change_limit_for_instrument_strategy(data): trade_limits = dataTradeLimits(data) instrument_code = get_valid_instrument_code_from_user(data) period_days = get_and_convert("Period of days?", type_expected=int, allow_default=True, default_value=1) strategy_name = get_valid_strategy_name_from_user(data=data, source="positions") new_limit = get_and_convert("Limit (in contracts?)", type_expected=int, allow_default=False) instrument_strategy = instrumentStrategy(instrument_code=instrument_code, strategy_name=strategy_name) ans = input( "Update will change number of trades allowed in periods, but won't reset 'clock'. Are you sure? (y/other)" ) if ans == "y": trade_limits.update_instrument_strategy_limit_with_new_limit( instrument_strategy=instrument_strategy, period_days=period_days, new_limit=new_limit)
def email_or_print(report_config): ans = get_and_convert( "1: Email or 2: print?", type_expected=int, allow_default=True, default_str="Print", default_value=2, ) if ans == 1: report_config = report_config.new_config_with_modified_output("email") else: report_config = report_config.new_config_with_modified_output( "console") return report_config
def auto_populate_limits(data: dataBlob): instrument_list = get_list_of_instruments(data) auto_parameters = get_auto_population_parameters() trade_multiplier = get_and_convert( "Higgest proportion of standard position expected to trade daily?", type_expected=float, default_value=MAX_POSITION_TRADED_DAILY, ) period_days = get_and_convert( "What period in days to set limit for?", type_expected=int, default_value=1 ) _ = [ set_trade_limit_for_instrument( data, instrument_code=instrument_code, auto_parameters = auto_parameters, trade_multiplier=trade_multiplier, period_days=period_days, ) for instrument_code in instrument_list ] return None
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) possible_order_types = market_order_type.allowed_types() 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=instrumentOrderType(order_type), limit_price=limit_price, limit_contract=limit_contract, manual_trade=True, roll_order=False, ) return instrument_order
def adjust_capital_for_delta(data: dataBlob): data_capital = dataCapital(data) capital_delta = get_and_convert( "What change have you made to brokerage account that will not change capital +ve deposit, -ve withdrawal", type_expected=float, ) old_capital = data_capital.get_current_total_capital() new_capital = old_capital + capital_delta ans = input( "New brokerage capital will be %f, are you sure? Yes/<anything else for no>" % new_capital) if ans == "Yes": data_capital.total_capital_calculator.adjust_broker_account_for_delta( capital_delta)
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, source="positions") 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=instrument_balance_order_type, 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 get_risk_multiplier_and_max_leverage() -> (float, float): print("Enter parameters to estimate typical position sizes") notional_risk_target = get_and_convert("Notional risk target (% per year)", type_expected=float, default_value=0.25) approx_IDM = get_and_convert("Approximate IDM", type_expected=float, default_value=2.5) notional_instrument_weight = get_and_convert( "Notional instrument weight (go large for safety!)", type_expected=float, default_value=0.1, ) raw_max_leverage = get_and_convert( "Maximum Leverage per instrument (notional exposure*# contracts / capital)", type_expected=float, default_value=1.0, ) # because we multiply by eg 2, need to half this max_leverage = raw_max_leverage / MAX_VS_AVERAGE_FORECAST risk_multiplier = notional_risk_target * approx_IDM * notional_instrument_weight return risk_multiplier, max_leverage
def reset_limit_for_instrument_strategy(data): trade_limits = dataTradeLimits(data) instrument_code = get_valid_instrument_code_from_user(data) period_days = get_and_convert( "Period of days?", type_expected=int, allow_default=True, default_value=1 ) strategy_name = get_valid_strategy_name_from_user(data=data, source="positions") ans = input("Reset means trade 'clock' will restart. Are you sure? (y/other)") if ans == "y": instrument_strategy = instrumentStrategy( instrument_code=instrument_code, strategy_name=strategy_name ) trade_limits.reset_instrument_strategy_limit( instrument_strategy=instrument_strategy, period_days=period_days )
def cancel_broker_order(data): view_broker_order_list(data) view_broker_stack(data) stack_handler = stackHandler(data) broker_order_id = get_and_convert( "Which order ID?", default_value="ALL", default_str="for all", type_expected=int) ans = input("Are you sure? (Y/other)") if ans != "Y": return None if broker_order_id == "ALL": stack_handler.try_and_cancel_all_broker_orders_and_return_list_of_orders() else: stack_handler.cancel_broker_order_with_id_and_return_order(broker_order_id)
def change_position_limit_for_instrument(data): view_position_limit(data) data_position_limits = dataPositionLimits(data) instrument_code = get_valid_instrument_code_from_user(data, allow_all=False) new_position_limit = get_and_convert("New position limit?", type_expected=int, allow_default=True, default_str="No limit", default_value=-1) if new_position_limit == -1: data_position_limits.delete_position_limit_for_instrument( instrument_code) else: new_position_limit = abs(new_position_limit) data_position_limits.set_abs_position_limit_for_instrument( instrument_code, new_position_limit)
def email_or_print_or_file(report_config): ans = get_and_convert( "1: Print or 2: email or 3: file or 4: email and file?", type_expected=int, allow_default=True, default_str="Print", default_value=1, ) if ans == 1: report_config = report_config.new_config_with_modified_output("console") elif ans == 2: report_config = report_config.new_config_with_modified_output("email") elif ans ==3: report_config = report_config.new_config_with_modified_output("file") else: report_config = report_config.new_config_with_modified_output("emailfile") return report_config
def delete_specific_order(data): stack = resolve_stack(data) if stack is None: return None view_generic_stack(stack) order_id = get_and_convert("Order ID ", type_expected=int, allow_default=False) order = stack.get_order_with_id_from_stack(order_id) print(order) print("This will delete the order from the stack!") print("Make sure parents and children are also deleted or weird stuff will happen") ans = input("This will delete the order from the stack! Are you sure? (Y/other)") if ans == "Y": stack._remove_order_with_id_from_stack_no_checking(order_id) print( "Make sure parents and children are also deleted or weird stuff will happen" ) return None
def handle_completed_orders(data): stack_handler = stackHandler(data) print("This will process any completed orders (all fills present)") view_instrument_stack(data) instrument_order_id = get_and_convert( "Which instrument order ID?", default_str="All", default_value="ALL", type_expected=int, ) ans = input("Are you sure? (Y/other)") if ans != "Y": return None if instrument_order_id == "ALL": stack_handler.handle_completed_orders() else: stack_handler.handle_completed_instrument_order(instrument_order_id)
def resolve_stack(data, exclude_instrument_stack=False): stack_handler = stackHandler(data) if exclude_instrument_stack: request_str = "Broker stack [1], or Contract stack [2]?" else: request_str = "Broker stack [1], Contract stack [2] or instrument stack [3]?" ans = get_and_convert( request_str, type_expected=int, default_str="Exit", default_value=0 ) if ans == 1: stack = stack_handler.broker_stack elif ans == 2: stack = stack_handler.contract_stack elif ans == 3 and not exclude_instrument_stack: stack = stack_handler.instrument_stack else: return None return stack
def get_report_dates(data): end_date = get_datetime_input("End date for report?\n", allow_default=True) start_date = get_datetime_input( "Start date for report? (SPACE to use an offset from end date)\n", allow_no_arg=True, ) if start_date is None: start_date = arg_not_supplied calendar_days = get_and_convert( "Calendar days back from %s?" % str(end_date), type_expected=int, allow_default=True, default_value=1, ) else: calendar_days = arg_not_supplied return start_date, end_date, calendar_days
def pass_fills_upwards_from_contracts(data): stack_handler = stackHandler(data) print( "This will process any fills applied to contract orders and pass them up to instrument orders" ) view_contract_stack(data) contract_order_id = get_and_convert( "Which order ID?", default_value="ALL", default_str="for all", type_expected=int ) ans = input("Are you sure? (Y/other)") if ans != "Y": return None if contract_order_id == "ALL": stack_handler.pass_fills_from_contract_up_to_instrument() else: stack_handler.apply_contract_fill_to_instrument_order(contract_order_id) print( "If stack process not running, your next job will be to handle completed orders" )
def get_auto_roll_parameters() -> autoRollParameters: min_volume = get_and_convert( "Minimum relative volume before rolling", type_expected=float, allow_default=True, default_value=0.1, ) manual_prompt_for_position = true_if_answer_is_yes( "Manually prompt for state if have position? (y/n)") if manual_prompt_for_position: state_when_position_held = no_change_required else: state_when_position_held = get_state_to_use_for_held_position() auto_parameters = autoRollParameters( min_volume=min_volume, manual_prompt_for_position=manual_prompt_for_position, state_when_position_held=state_when_position_held, ) return auto_parameters
def get_fills_from_broker(data): stack_handler = stackHandler(data) print("This will get any fills from the broker, and write them to the broker stack") print("Broker orders: (in database)") view_broker_stack(data) broker_order_id = get_and_convert( "Which broker order ID?", default_value="ALL", default_str="for all", type_expected=int, ) ans = input("Are you sure? (Y/other)") if ans != "Y": return None if broker_order_id == "ALL": stack_handler.pass_fills_from_broker_to_broker_stack() else: stack_handler.apply_broker_fill_from_broker_to_broker_database(broker_order_id) print( "If stack process not running, your next job will be to pass fills from broker to contract stack" )
def change_position_limit_for_instrument_strategy(data): view_position_limit(data) data_position_limits = dataPositionLimits(data) strategy_name = get_valid_strategy_name_from_user(data, allow_all=False, source="positions") instrument_code = get_valid_instrument_code_from_user(data, allow_all=False) new_position_limit = get_and_convert("New position limit?", type_expected=int, allow_default=True, default_value=-1, default_str="No limit") instrument_strategy = instrumentStrategy(instrument_code=instrument_code, strategy_name=strategy_name) if new_position_limit == -1: data_position_limits.delete_position_limit_for_instrument_strategy( instrument_strategy) else: new_position_limit = abs(new_position_limit) data_position_limits.set_position_limit_for_instrument_strategy( instrument_strategy, new_position_limit)
def generate_ib_orders(data): stack_handler = stackHandler(data) print("This will create broker orders and submit to IB") print("Contract orders:") view_contract_stack(data) contract_order_id = get_and_convert( "Which contract order ID?", default_value="ALL", default_str="for all", type_expected=int, ) ans = input("Are you sure? (Y/other)") if ans != "Y": return None if contract_order_id == "ALL": stack_handler.create_broker_orders_from_contract_orders() else: stack_handler.create_broker_order_for_contract_order(contract_order_id) print( "If stack process not running, your next job will be to get the fills from IB" )
def order_locking(data): stack = resolve_stack(data) if stack is None: return None view_generic_stack(stack) order_id = get_and_convert("Order ID ", type_expected=int, allow_default=False) order = stack.get_order_with_id_from_stack(order_id) print(order) if order.is_order_locked(): ans = input("Unlock order? <y/other>") if ans == "y": stack._unlock_order_on_stack(order_id) else: return None else: ans = input("Lock order? <y/other>") if ans == "y": stack._lock_order_on_stack(order_id) else: return None return None
def get_auto_population_parameters() -> parametersForAutoPopulation: print("Enter parameters to estimate typical position sizes") notional_risk_target = get_and_convert( "Notional risk target (% per year, 0.25 = 25%%)", type_expected=float, default_value=RISK_TARGET_ASSUMED/100.0 ) approx_IDM = get_and_convert( "Approximate IDM", type_expected=float, default_value=IDM_ASSUMED ) notional_instrument_weight = get_and_convert( "Notional instrument weight (go large for safety!)", type_expected=float, default_value=INSTRUMENT_WEIGHT_ASSUMED, ) raw_max_leverage = get_and_convert( "Maximum Leverage per instrument (notional exposure*# contracts / capital)", type_expected=float, default_value=RAW_MAX_LEVERAGE, ) max_proportion_risk_one_contract = get_and_convert( "Maximum proportion of risk in a single instrument (0.1 = 10%%)", type_expected=float, default_value=MAX_RISK_EXPOSURE_ONE_INSTRUMENT ) max_proportion_of_volume = get_and_convert( "Maximum proportion of volume for expiry with largest volume (0.1 = 10%)", type_expected=float, default_value=MAX_PROPORTION_OF_VOLUME ) auto_parameters = parametersForAutoPopulation(raw_max_leverage = raw_max_leverage, max_vs_average_forecast = MAX_VS_AVERAGE_FORECAST, notional_risk_target =notional_risk_target, approx_IDM = approx_IDM, max_proportion_risk_one_contract=max_proportion_risk_one_contract, notional_instrument_weight = notional_instrument_weight, max_proportion_of_volume = max_proportion_of_volume ) return auto_parameters