def to_python(self, value): if value is None: return value try: return Currency(value) except InvalidOperation as e: raise InvalidOperation(_("This value must be a decimal number."))
def decimal(data): try: return dec_con.create_decimal(data).quantize(convert_to._quantizer) except TypeError: if isinstance(data, np.ndarray): return convert_to._quantize_array(data.astype(str)) else: return Decimal.from_float(np.float64(data)).quantize(convert_to._quantizer) except InvalidOperation: if abs(data) > Decimal('1e20'): raise InvalidOperation("Numeric overflow in convert_to.decimal") elif data == np.nan or math.nan: raise InvalidOperation("NaN encountered in convert_to.decimal") except Exception as e: print(data) print(e) raise e
def __sqrt__(self): # if self.num._sign == 1: # raise InvalidOperation('sqrt(-x), x > 0') # return sqrt(self.num) if self.num >= 0: return sqrt(self.num) else: raise InvalidOperation('sqrt(-x), x > 0')
def convert_forecast_amount(amount_string): if amount_string.strip() == "": return None try: return Decimal(amount_string.replace(",", "")) * 100 except InvalidOperation as ex: logger.fatal(f"Unable to convert value '{amount_string}' to decimal") raise InvalidOperation(ex)
def parse_latlong(value): """ Given a string with a decimal value, or a float, parse to a Decimal and truncate to the number of places we're keeping for lat/long values. Return the result. """ val = Decimal(value).quantize(LATLONG_QUANTIZE_PLACES) if val > MAX_LATLONG: raise InvalidOperation("Lat or long too large") return val
def positive_decimal_validate(number): """ """ try: value = Decimal(number) if value < 0: raise InvalidOperation( '{val} should be a positive number'.format(val=value), code='negative number' ) except (ValueError, TypeError): raise ValidationError('Enter a valid decimal or integer value', code='invalid number')
def decimal(data): try: return Decimal(data).quantize(convert_to._quantizer) except TypeError: if isinstance(data, np.ndarray): # shape = data.shape # output = np.empty(data.flatten().shape, dtype=np.dtype(Decimal)) # for i, item in enumerate(data.flatten()): # output[i] = Decimal(np.float64(item)).quantize(convert_to._quantizer) # return output.reshape(shape) return convert_to._quantize_array(data.astype(str)) else: return Decimal.from_float(np.float64(data)).quantize( convert_to._quantizer) except InvalidOperation: if abs(data) > Decimal('1e15'): raise InvalidOperation( "Numeric overflow in convert_to.decimal") elif data == np.nan or math.nan: raise InvalidOperation("NaN encountered in convert_to.decimal") except Exception as e: print(data) print(e) raise e
def rebalance_portfolio(portfolio, band=Decimal(0.05)): """ Rebalance the portfolio by finding the qty of each asset which falls into the given band that minimizes the unallocated size of the portfolio. This approach has a couple drawbacks. For one it enumerates the space. Further, it does not optimize for minimizing the tracking error -- it could, I just ran out of time. :param portfolio: Valid Portfolio :param band: the tracking band for each asset. :return: Rebalanced portfolio :raises: InvalidOperation("Portfolio cannot be rebalanced") >>> json_str = '{"assets": [{"alloc": "0.6", "symbol": "GOOG", "price": "98.0", "qty": 52}, {"alloc": "0.3", "symbol": "AAPL", "price": "22.0", "qty": 136}, {"alloc": "0.1", "symbol": "TSLA", "price": "8.0", "qty": 239}], "size": "10000.0"}' >>> port = portfolio_from_json(json_str) >>> rebalance_portfolio(port) Portfolio(size=Decimal('10000.0'), assets=(Asset(price=Decimal('98.0'), qty=60, alloc=Decimal('0.588'), symbol=u'GOOG'), Asset(price=Decimal('22.0'), qty=140, alloc=Decimal('0.308'), symbol=u'AAPL'), Asset(price=Decimal('8.0'), qty=130, alloc=Decimal('0.104'), symbol=u'TSLA'))) """ # makes a list of lists of all asset rebalances that fall within the band asset_options = [ asset_rebalance_options(asset, portfolio.size, band=band) for asset in portfolio.assets ] # makes the cartesian product of the possible rebalances -- yes this can be optimized port_universe = product(*asset_options) best_port = None for port in port_universe: total_alloc = sum(map(lambda x: x.alloc, port)) total_size = sum(map(lambda x: x.qty * x.price, port)) if total_alloc > 1: # We've allocated over 100% continue if best_port is not None: if best_port.size < total_size: # means this port is the new max best_port = mk_portfolio(total_size, port) else: continue else: # NB: we don't need to check that total_size is <= size as checking allocation handles this best_port = mk_portfolio(total_size, port) if best_port is None: raise InvalidOperation("This portfolio cannot be rebalanced!") else: return best_port
def extract_number(val: Union[int, float, Decimal, str]) -> Decimal: if isinstance(val, (int, float, Decimal)): return Decimal(val) val = str(val) val = re.sub(r'([$,%]|\s)', "", val) if val == "-": val = "0" if re.search(r'^\(\d+(\.\d+)?\)$', val): val = "-" + re.sub(r'[()]', "", val) try: return Decimal(val) except InvalidOperation: raise InvalidOperation(val)
def save(self, commit=True): """ Make sure to parse the geolocation """ # TODO: remove redundnacy, have this rely solely on cleaning method to # get the pieces geolocation = self.cleaned_data.get('geolocation') if not geolocation: pieces = (None, None) else: try: pieces = [float(x) for x in geolocation.split(",")] except ValueError: raise ValueError( "Latitude and longitude must be numeric values") except InvalidOperation: raise InvalidOperation( "Latitude or longitude have too many digits") self.instance.latitude = pieces[0] self.instance.longitude = pieces[1] return super(LocationAdminForm, self).save(commit)
def convert_decimal_str(value): result = str(value) if result == "sNaN": raise InvalidOperation("Won't save signalling NaN") return result
def parse_decimal_value(value: str) -> Decimal: if not isinstance(value, str): raise InvalidOperation("Decimal must be a string") return Decimal(sanitize_separators(value))