Exemple #1
0
 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()
Exemple #2
0
    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")
Exemple #3
0
    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])
Exemple #4
0
 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()
Exemple #5
0
    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")