class Wallet:
pass # Placeholder definition because python is bad at types
class Valuation(np.ndarray):
def __new__(cls, input_array):
obj = np.asarray(input_array, dtype=np.float64).view(cls)
return obj
class Wallet(np.ndarray):
def __new__(cls, input_array):
obj = np.asarray(input_array, dtype=np.float64).view(cls)
return obj
def value(s, valuation: Valuation):
return np.sum(s * np.array(valuation))
def index(s, valuation: Valuation, quantity: float):
value = s.value(valuation)
if value == 0:
return Index(np.zeros_like(s))
return Index(s * (quantity / value))
def conciliation(s, source: Wallet, target: Wallet, quantity: float):
return s.index(target, quantity).value(source) - quantity
def payment(s, source: Wallet, target: Wallet, quantity: float):
return s.index(source, s.conciliation(source, target, quantity) + quantity)
def send(s, payer: Wallet, recipient: Wallet):
raise TypeError(
"The send method should be called on an Index object, not a Wallet. "
"You can create an Index object with the `index` or `payment` method. "
"Example: `index = wallet.index(valuation, quantity)`, then call "
"`index.send(wallet, recipient)`."
)
class Index(Wallet):
def __new__(cls, input_array):
return super().__new__(cls, input_array)
def send(s, payer: Wallet, recipient: Wallet):
if np.any(payer - s < 0):
raise ValueError(
"Insufficient funds: Attempting to send more than available in the wallet."
)
payer -= s
recipient += s
return payer, recipient