"""Explicit Decimal instrument units; research calculations, never an order route."""
from decimal import Decimal
from infinbot_common import number,Rejected

MES_SPEC_URL='https://www.cmegroup.com/markets/equities/sp/micro-e-mini-sandp-500.contractSpecs.html'
MES_POINT_MULTIPLIER=Decimal('5')
MES_TICK_SIZE=Decimal('0.25')

def displayed_price(clearing_price,display_factor):
    """Caller must supply the actual security-reference display factor."""
    return number(clearing_price)*number(display_factor,positive=True)

def mes_contract_values(price,change_points,contracts):
    price=number(price,positive=True);change=number(change_points)
    if type(contracts) is not int or contracts<=0:raise Rejected('Positive whole contract count required')
    if price%MES_TICK_SIZE or change%MES_TICK_SIZE:raise Rejected('MES prices and changes must align to the declared tick')
    return {'product':'MES','contracts':contracts,'display_price':str(price),
            'point_multiplier_usd':'5','tick_size_points':'0.25','tick_value_per_contract_usd':'1.25',
            'notional_usd':str(price*MES_POINT_MULTIPLIER*contracts),
            'price_change_value_usd':str(change*MES_POINT_MULTIPLIER*contracts),
            'orders_submitted':0,'actual_position_allocation_verified':False}

def option_contract_value(premium,contracts,contract_multiplier):
    """Multiplier is explicit; adjusted equity options must not default to 100."""
    if type(contracts) is not int or contracts<=0:raise Rejected('Positive whole contract count required')
    premium=number(premium);multiplier=number(contract_multiplier,positive=True)
    if premium<0:raise Rejected('Standalone option premium must be nonnegative; strategy pricing requires its own definition')
    return premium*contracts*multiplier
