def test_target_collateral_ratio(self): self.op = operations.Call_order_update( **{ "fee": { "amount": 100, "asset_id": "1.3.0" }, "delta_debt": { "amount": 10000, "asset_id": "1.3.22" }, "delta_collateral": { "amount": 100000000, "asset_id": "1.3.0" }, "funding_account": "1.2.29", "extensions": { "target_collateral_ratio": 12345 }, }) self.cm = ("f68585abf4dce7c8045701036400000000000000001d00e1f5" "05000000000010270000000000001601003930000120767cf8d8402b" "cffa3fbaf774feb128c5a34c7a25b21d64c2285a99bf254c66" "57158b0eeb2fb674b0aed6a31b0ec9e20b903d6b15b6bcb1cd" "9dd6ac22b8c5456b") self.doit()
def close_debt_position(self, symbol, account=None): """ Close a debt position and reclaim the collateral. :param str symbol: Symbol to close debt position for :raises ValueError: if symbol has no open call position """ if not account: if "default_account" in self.blockchain.config: account = self.blockchain.config["default_account"] if not account: raise ValueError("You need to provide an account") account = Account(account, full=True, blockchain_instance=self.blockchain) debts = self.list_debt_positions(account) if symbol not in debts: raise ValueError("No call position open for %s" % symbol) debt = debts[symbol] asset = debt["debt"]["asset"] collateral_asset = debt["collateral"]["asset"] op = operations.Call_order_update( **{ "fee": { "amount": 0, "asset_id": "1.3.0" }, "delta_debt": { "amount": int(-float(debt["debt"]) * 10**asset["precision"]), "asset_id": asset["id"], }, "delta_collateral": { "amount": int(-float(debt["collateral"]) * 10**collateral_asset["precision"]), "asset_id": collateral_asset["id"], }, "funding_account": account["id"], "extensions": [], }) return self.blockchain.finalizeOp(op, account["name"], "active")
def compareConstructedTX(self): self.maxDiff = None self.op = operations.Call_order_update( **{ "fee": { "amount": 100, "asset_id": "1.3.0" }, "delta_debt": { "amount": 10000, "asset_id": "1.3.22" }, "delta_collateral": { "amount": 100000000, "asset_id": "1.3.0" }, "funding_account": "1.2.29", "extensions": { "target_collateral_ratio": 12345 }, }) ops = [Operation(self.op)] tx = Signed_Transaction( ref_block_num=ref_block_num, ref_block_prefix=ref_block_prefix, expiration=expiration, operations=ops, ) tx = tx.sign([wif], chain=prefix) tx.verify([PrivateKey(wif).pubkey], prefix) txWire = hexlify(bytes(tx)).decode("ascii") print("=" * 80) pprint(tx.json()) print("=" * 80) # Test against Deex backened self.cm = deex.rpc.get_transaction_hex(tx.json()) print("soll: %s" % self.cm[:-130]) print("ist: %s" % txWire[:-130]) print(txWire[:-130] == self.cm[:-130]) self.assertEqual(self.cm[:-130], txWire[:-130])
def test_call_update(self): self.op = operations.Call_order_update( **{ "fee": { "amount": 100, "asset_id": "1.3.0" }, "delta_debt": { "amount": 10000, "asset_id": "1.3.22" }, "delta_collateral": { "amount": 100000000, "asset_id": "1.3.0" }, "funding_account": "1.2.29", "extensions": {}, }) self.cm = ("f68585abf4dce7c8045701036400000000000000001d00e1f" "50500000000001027000000000000160000011f2627efb5c5" "144440e06ff567f1a09928d699ac6f5122653cd7173362a1a" "e20205952c874ed14ccec050be1c86c1a300811763ef3b481" "e562e0933c09b40e31fb") self.doit()
def adjust_debt( self, delta, new_collateral_ratio=None, account=None, target_collateral_ratio=None, ): """ Adjust the amount of debt for an asset. :param Amount delta: Delta amount of the debt (-10 means reduce debt by 10, +10 means borrow another 10) :param float new_collateral_ratio: collateral ratio to maintain (optional, by default tries to maintain old ratio) :param float target_collateral_ratio: Tag the call order so that in case of margin call, only enough debt is covered to get back to this ratio :raises ValueError: if symbol is not a bitasset :raises ValueError: if collateral ratio is smaller than maintenance collateral ratio :raises ValueError: if required amounts of collateral are not available """ if not account: if "default_account" in self.blockchain.config: account = self.blockchain.config["default_account"] if not account: raise ValueError("You need to provide an account") account = Account(account, full=True, blockchain_instance=self.blockchain) # We sell quote and pay with base symbol = delta["symbol"] asset = Asset(symbol, full=True, blockchain_instance=self.blockchain) if not asset.is_bitasset: raise ValueError("%s is not a bitasset!" % symbol) bitasset = asset["bitasset_data"] # Check minimum collateral ratio backing_asset_id = bitasset["options"]["short_backing_asset"] current_debts = self.list_debt_positions(account) if not new_collateral_ratio and symbol not in current_debts: new_collateral_ratio = ( bitasset["current_feed"]["maintenance_collateral_ratio"] / 1000) elif not new_collateral_ratio and symbol in current_debts: new_collateral_ratio = current_debts[symbol]["ratio"] # Derive Amount of Collateral collateral_asset = Asset(backing_asset_id, blockchain_instance=self.blockchain) settlement_price = Price( bitasset["current_feed"]["settlement_price"], blockchain_instance=self.blockchain, ) if symbol in current_debts: amount_of_collateral = ((float(current_debts[symbol]["debt"]) + float(delta["amount"])) * new_collateral_ratio / float(settlement_price)) amount_of_collateral -= float(current_debts[symbol]["collateral"]) else: amount_of_collateral = (float(delta["amount"]) * new_collateral_ratio / float(settlement_price)) # Verify that enough funds are available fundsNeeded = amount_of_collateral + float( self.returnFees()["call_order_update"]["fee"]) fundsHave = account.balance(collateral_asset["symbol"]) or 0 if fundsHave <= fundsNeeded: raise ValueError( "Not enough funds available. Need %f %s, but only %f %s are available" % ( fundsNeeded, collateral_asset["symbol"], fundsHave, collateral_asset["symbol"], )) payload = { "fee": { "amount": 0, "asset_id": "1.3.0" }, "delta_debt": { "amount": int(float(delta) * 10**asset["precision"]), "asset_id": asset["id"], }, "delta_collateral": { "amount": int( float(amount_of_collateral) * 10**collateral_asset["precision"]), "asset_id": collateral_asset["id"], }, "funding_account": account["id"], "extensions": {}, } # Extension if target_collateral_ratio: payload["extensions"].update({ "target_collateral_ratio": int(target_collateral_ratio * 100) }) op = operations.Call_order_update(**payload) return self.blockchain.finalizeOp(op, account["name"], "active")