Exemplo n.º 1
0
 def _decimal_places_for_asset(self, asset, reference_date):
     if isinstance(asset, Future) and asset.tick_size:
         return number_of_decimal_places(asset.tick_size)
     elif isinstance(asset, ContinuousFuture):
         # Tick size should be the same for all contracts of a continuous
         # future, so arbitrarily get the contract with next upcoming auto
         # close date.
         oc = self._asset_finder.get_ordered_contracts(asset.root_symbol)
         contract_sid = oc.contract_before_auto_close(reference_date.value)
         if contract_sid is not None:
             contract = self._asset_finder.retrieve_asset(contract_sid)
             if contract.tick_size:
                 return number_of_decimal_places(contract.tick_size)
     return DEFAULT_ASSET_PRICE_DECIMALS
Exemplo n.º 2
0
 def _decimal_places_for_asset(self, asset, reference_date):
     if isinstance(asset, Future) and asset.tick_size:
         return number_of_decimal_places(asset.tick_size)
     elif isinstance(asset, ContinuousFuture):
         # Tick size should be the same for all contracts of a continuous
         # future, so arbitrarily get the contract with next upcoming auto
         # close date.
         oc = self._asset_finder.get_ordered_contracts(asset.root_symbol)
         contract_sid = oc.contract_before_auto_close(reference_date.value)
         if contract_sid is not None:
             contract = self._asset_finder.retrieve_asset(contract_sid)
             if contract.tick_size:
                 return number_of_decimal_places(contract.tick_size)
     return DEFAULT_ASSET_PRICE_DECIMALS
Exemplo n.º 3
0
def asymmetric_round_price(price, prefer_round_down, tick_size, diff=0.95):
    """
    Asymmetric rounding function for adjusting prices to the specified number
    of places in a way that "improves" the price. For limit prices, this means
    preferring to round down on buys and preferring to round up on sells.
    For stop prices, it means the reverse.

    If prefer_round_down == True:
        When .05 below to .95 above a specified decimal place, use it.
    If prefer_round_down == False:
        When .95 below to .05 above a specified decimal place, use it.

    In math-speak:
    If prefer_round_down: [<X-1>.0095, X.0195) -> round to X.01.
    If not prefer_round_down: (<X-1>.0005, X.0105] -> round to X.01.
    """
    precision = zp_math.number_of_decimal_places(tick_size)
    multiplier = int(tick_size * (10**precision))
    diff -= 0.5  # shift the difference down
    diff *= (10**-precision)  # adjust diff to precision of tick size
    diff *= multiplier  # adjust diff to value of tick_size

    # Subtracting an epsilon from diff to enforce the open-ness of the upper
    # bound on buys and the lower bound on sells.  Using the actual system
    # epsilon doesn't quite get there, so use a slightly less epsilon-ey value.
    epsilon = float_info.epsilon * 10
    diff = diff - epsilon

    # relies on rounding half away from zero, unlike numpy's bankers' rounding
    rounded = tick_size * consistent_round(
        (price - (diff if prefer_round_down else -diff)) / tick_size)
    if zp_math.tolerant_equals(rounded, 0.0):
        return 0.0
    return rounded
Exemplo n.º 4
0
def asymmetric_round_price(price, prefer_round_down, tick_size, diff=0.95):
    """
    Asymmetric rounding function for adjusting prices to the specified number
    of places in a way that "improves" the price. For limit prices, this means
    preferring to round down on buys and preferring to round up on sells.
    For stop prices, it means the reverse.

    If prefer_round_down == True:
        When .05 below to .95 above a specified decimal place, use it.
    If prefer_round_down == False:
        When .95 below to .05 above a specified decimal place, use it.

    In math-speak:
    If prefer_round_down: [<X-1>.0095, X.0195) -> round to X.01.
    If not prefer_round_down: (<X-1>.0005, X.0105] -> round to X.01.
    """
    precision = zp_math.number_of_decimal_places(tick_size)
    multiplier = int(tick_size * (10 ** precision))
    diff -= 0.5  # shift the difference down
    diff *= (10 ** -precision)  # adjust diff to precision of tick size
    diff *= multiplier  # adjust diff to value of tick_size

    # Subtracting an epsilon from diff to enforce the open-ness of the upper
    # bound on buys and the lower bound on sells.  Using the actual system
    # epsilon doesn't quite get there, so use a slightly less epsilon-ey value.
    epsilon = float_info.epsilon * 10
    diff = diff - epsilon

    # relies on rounding half away from zero, unlike numpy's bankers' rounding
    rounded = tick_size * consistent_round(
        (price - (diff if prefer_round_down else -diff)) / tick_size
    )
    if zp_math.tolerant_equals(rounded, 0.0):
        return 0.0
    return rounded
Exemplo n.º 5
0
 def test_number_of_decimal_places(self):
     self.assertEqual(number_of_decimal_places(1), 0)
     self.assertEqual(number_of_decimal_places(3.14), 2)
     self.assertEqual(number_of_decimal_places('3.14'), 2)
     self.assertEqual(number_of_decimal_places(-3.14), 2)
Exemplo n.º 6
0
def test_number_of_decimal_places(value, expected):
    assert number_of_decimal_places(value) == expected
 def test_number_of_decimal_places(self):
     self.assertEqual(number_of_decimal_places(1), 0)
     self.assertEqual(number_of_decimal_places(3.14), 2)
     self.assertEqual(number_of_decimal_places('3.14'), 2)
     self.assertEqual(number_of_decimal_places(-3.14), 2)