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 Bitshares backened
        self.cm = bitshares.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 #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 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 #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(
                dict(target_collateral_ratio=int(target_collateral_ratio *
                                                 100)))

        op = operations.Call_order_update(**payload)
        return self.blockchain.finalizeOp(op, account["name"], "active")
Exemple #6
0
    def adjust_debt(self, delta, new_collateral_ratio=None, account=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)
            :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.bitshares.config:
                account = self.bitshares.config["default_account"]
        if not account:
            raise ValueError("You need to provide an account")
        account = Account(account, full=True, bitshares_instance=self.bitshares)

        # We sell quote and pay with base
        symbol = delta["symbol"]
        asset = Asset(symbol)
        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"]
        maintenance_col_ratio = bitasset["current_feed"]["maintenance_collateral_ratio"] / 1000
        current_debts = self.list_debt_positions(account)
        if not new_collateral_ratio and symbol not in current_debts:
            new_collateral_ratio = maintenance_col_ratio
        elif not new_collateral_ratio and symbol in current_debts:
            new_collateral_ratio = current_debts[symbol]["ratio"]
        if maintenance_col_ratio > new_collateral_ratio:
            raise ValueError("Collateral Ratio has to be higher than %5.2f" % maintenance_col_ratio)

        # Derive Amount of Collateral
        collateral_asset = Asset(backing_asset_id)
        settlement_price = Price(bitasset["current_feed"]["settlement_price"])

        if symbol not in current_debts:
            raise ValueError("No Call position available to adjust! Please borrow first!")

        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"])

        # Verify that enough funds are available
        fundsNeeded = amount_of_collateral + float(self.returnFees()["call_order_update"]["fee"])
        fundsHave = account.balance(collateral_asset["symbol"])
        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"]))

        op = operations.Call_order_update(**{
            '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': []
        })
        return self.bitshares.finalizeOp(op, account["name"], "active")