From bf36c672c0ba9aacd2e806ff8c8b062eb488549d Mon Sep 17 00:00:00 2001 From: Geoff Taylor Date: Thu, 9 Sep 2021 09:51:41 +0100 Subject: [PATCH] Updated notebooks. Fixed ones that could be fixed, removed ones that require functionality not in V3. --- Liquidation.ipynb | 254 --------------- Pandas.ipynb | 308 ------------------ ShowAccount.ipynb | 58 ++-- ShowAllMarginAccounts.ipynb | 135 -------- ShowGroup.ipynb | 40 ++- ...ginAccount.ipynb => ShowMangoAccount.ipynb | 48 +-- ShowRipeMarginAccounts.ipynb | 125 ------- 7 files changed, 80 insertions(+), 888 deletions(-) delete mode 100644 Liquidation.ipynb delete mode 100644 Pandas.ipynb delete mode 100644 ShowAllMarginAccounts.ipynb rename ShowMarginAccount.ipynb => ShowMangoAccount.ipynb (83%) delete mode 100644 ShowRipeMarginAccounts.ipynb diff --git a/Liquidation.ipynb b/Liquidation.ipynb deleted file mode 100644 index 3ee38ee..0000000 --- a/Liquidation.ipynb +++ /dev/null @@ -1,254 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "", - "metadata": {}, - "source": [ - "# ⚠ Warning\n", - "\n", - "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", - "\n", - "[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gl/OpinionatedGeek%2Fmango-explorer/HEAD?filepath=Liquidation.ipynb) _πŸƒβ€β™€οΈ To run this notebook press the ⏩ icon in the toolbar above._\n", - "\n", - "[πŸ₯­ Mango Markets](https://mango.markets/) support is available at: [Docs](https://docs.mango.markets/) | [Discord](https://discord.gg/67jySBhxrg) | [Twitter](https://twitter.com/mangomarkets) | [Github](https://github.com/blockworks-foundation) | [Email](mailto:hello@blockworks.foundation)" - ] - }, - { - "cell_type": "markdown", - "id": "", - "metadata": {}, - "source": [ - "# πŸ₯­ Liquidation\n", - "\n", - "Mango Markets margin accounts must hold more assets than liabilities.\n", - "\n", - "If a margin account doesn't hold assets worth more than the _maintenance collateral ratio_ (currently 110%) of its liabilities, anyone can 'pay off' some of the liabilities in that account. In return, that payer receives 105% of their tokens back.\n", - "\n", - "This process - called '_liquidation_' - continues until the remaining assets are worth more than the _initial collateral ratio_ (currently 120%) of the remaining liabilities, or until there are no more collateral tokens to return to liquidators.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "", - "metadata": { - "jupyter": { - "source_hidden": true - } - }, - "outputs": [], - "source": [ - "import logging\n", - "import mango\n", - "\n", - "from solana.publickey import PublicKey\n" - ] - }, - { - "cell_type": "markdown", - "id": "", - "metadata": {}, - "source": [ - "## 🦺 Safety\n", - "\n", - "Liquidation is how Mango Markets protects accounts from systemic losses.\n", - "\n", - "If the collateralisation ratio were allowed to fall below 100%, that would represent a systemic risk to Mango Markets. Funds would have to be taken from the lending pools, affecting all lenders, which may in turn affect their collateralisation ratio and expose them to liquidation, possibly leading to a cascade of liquidations until the system stabilises.\n", - "\n", - "Liquidators promptly stepping in to 'buy' liquidatable accounts before they fall to less than 100% collateralisation prevent this instability.\n" - ] - }, - { - "cell_type": "markdown", - "id": "", - "metadata": {}, - "source": [ - "## πŸ“‡ Collateralisation Ratios Details\n", - "\n", - "When trading with leverage on Mango Markets, you start by adding assets to your margin account. Your margin account must hold assets worth more than 120% of the liabilities. This ratio of assets to liabilities is called your '_collateralisation ratio_'.\n", - "\n", - "If a new trade would mean your assets would be worth less 120% of the libilities - that your collateralisation ratio would be less than 120% - you will not be allowed to place the trade. No existing trades are closed, you just can't place any new orders.\n", - "\n", - "The value of assets and liabilities is derived from the prices from on-chain oracles.\n", - "\n", - "Prices change, so even if no new trades are made the value of assets can fall and the liabilities can increase, changing the collateralisation ratio.\n", - "\n", - "**If the collateralisation ratio falls below 110%, your margin account can be '_liquidated_', resulting in the loss of some or a all assets in the account.**\n" - ] - }, - { - "cell_type": "markdown", - "id": "", - "metadata": {}, - "source": [ - "# πŸ’§ Liquidation Process" - ] - }, - { - "cell_type": "markdown", - "id": "", - "metadata": {}, - "source": [ - "## πŸ“‡ Steps\n", - "\n", - "The liquidation process involves paying off some or all of one of the liabilities in the under-collateralised margin account. Margin accounts can have liabilities in multiple tokens, but liquidation can only be performed on one token at a time.\n", - "\n", - "These are the basic steps to liquidate an account:\n", - "1. (Optional) Force cancellation of all outstanding orders for the margin account in that market.\n", - "2. Build and send the `PartialLiquidate` instruction.\n", - "3. Repeat step 2 (if necessary) with fresh tokens.\n", - "\n", - "Step 1 is optional. Open orders can lock funds in an account, preventing liquidation, but it may be desirable for liquidators to optimise their liquidation process by only force-cancelling orders on that margin account's first partial-liquidation. The margin account is unlikely to have been able to open new orders between partial-liquidations if they happen quickly enough.\n", - "\n", - "To actually run a liquidator, however, there are probably some additional steps:\n", - "1. Find all liquidatable margin accounts.\n", - "2. Pick the most appropriate of these margin accounts, based on that account's collatoralisation and the liquidator's token balances.\n", - "3. Pick the market with the most value in the margin account's openorders accounts.\n", - "4. Force cancellation of all outstanding orders for the margin account in that market.\n", - "5. Build and send the `PartialLiquidate` instruction.\n", - "6. Convert the received tokens to your desired tokens.\n", - "7. Repeat from step 2 (if necessary) with fresh tokens.\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "", - "metadata": {}, - "source": [ - "# πŸƒ Running\n", - "\n", - "This section allows you to perform a liquidation on a specific `MarginAccount`.\n", - "\n", - "To do this you will need:\n", - "* The `PublicKey` of the margin account - put this in the `MARGIN_ACCOUNT_TO_LIQUIDATE` variable below, and\n", - "* A wallet with appropriate funds and accounts for Mango Markets liquidation (see [AccountScout](AccountScout.ipynb) for details). The private key for this wallet should be placed in the `id.json` file.\n", - "\n", - "You can then πŸƒβ€β™€οΈ run this notebook by pressing the ⏩ icon in the toolbar at the top of the page." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "", - "metadata": {}, - "outputs": [], - "source": [ - "MARGIN_ACCOUNT_TO_LIQUIDATE = \"\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "", - "metadata": {}, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " logging.getLogger().setLevel(logging.INFO)\n", - "\n", - " if MARGIN_ACCOUNT_TO_LIQUIDATE == \"\":\n", - " raise Exception(\"No margin account to liquidate - try setting the variable MARGIN_ACCOUNT_TO_LIQUIDATE to a margin account public key.\")\n", - "\n", - " context = mango.Context.default()\n", - "\n", - " # You'll need to load the wallet properly here to be able to liquidate.\n", - " wallet = mango.Wallet([])\n", - "\n", - " print(\"Wallet Balances Before:\")\n", - " group = mango.Group.load(context)\n", - " balances_before = group.fetch_balances(context, wallet.address)\n", - " mango.TokenValue.report(balances_before)\n", - "\n", - " prices = group.fetch_token_prices(context)\n", - " margin_account = mango.MarginAccount.load(context, PublicKey(MARGIN_ACCOUNT_TO_LIQUIDATE), group)\n", - " intrinsic_balance_sheets_before = margin_account.get_intrinsic_balance_sheets(group)\n", - " print(\"Margin Account Before:\", intrinsic_balance_sheets_before)\n", - " liquidator = mango.ForceCancelOrdersAccountLiquidator(context, wallet)\n", - " transaction_id = liquidator.liquidate(group, margin_account, prices)\n", - " if transaction_id is None:\n", - " print(\"No transaction sent.\")\n", - " else:\n", - " print(\"Transaction ID:\", transaction_id)\n", - " print(\"Waiting for confirmation...\")\n", - "\n", - " context.client.wait_for_confirmation(transaction_id)\n", - "\n", - " group_after = mango.Group.load(context)\n", - " margin_account_after_liquidation = mango.MarginAccount.load(context, PublicKey(MARGIN_ACCOUNT_TO_LIQUIDATE), group_after)\n", - " intrinsic_balance_sheets_after = margin_account_after_liquidation.get_intrinsic_balance_sheets(group_after)\n", - " print(\"Margin Account After:\", intrinsic_balance_sheets_after)\n", - " print(\"Wallet Balances After:\")\n", - " balances_after = group_after.fetch_balances(context, wallet.address)\n", - " mango.TokenValue.report(balances_after)\n", - "\n", - " print(\"Wallet Balances Changes:\")\n", - " changes = mango.TokenValue.changes(balances_before, balances_after)\n", - " mango.TokenValue.report(changes)\n" - ] - } - ], - "metadata": { - "interpreter": { - "hash": "ac2eaa0ea0ebeafcc7822e65e46aa9d4f966f30b695406963e145ea4a91cd4fc" - }, - "kernelspec": { - "display_name": "Python 3.9.4 64-bit", - "name": "python3" - }, - "language_info": { - "name": "python", - "version": "" - }, - "metadata": { - "interpreter": { - "hash": "ac2eaa0ea0ebeafcc7822e65e46aa9d4f966f30b695406963e145ea4a91cd4fc" - } - }, - "toc": { - "base_numbering": 1, - "nav_menu": {}, - "number_sections": true, - "sideBar": true, - "skip_h1_title": false, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": true, - "toc_window_display": true - }, - "varInspector": { - "cols": { - "lenName": 16, - "lenType": 16, - "lenVar": 40 - }, - "kernels_config": { - "python": { - "delete_cmd_postfix": "", - "delete_cmd_prefix": "del ", - "library": "var_list.py", - "varRefreshCmd": "print(var_dic_list())" - }, - "r": { - "delete_cmd_postfix": ") ", - "delete_cmd_prefix": "rm(", - "library": "var_list.r", - "varRefreshCmd": "cat(var_dic_list()) " - } - }, - "types_to_exclude": [ - "module", - "function", - "builtin_function_or_method", - "instance", - "_Feature" - ], - "window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/Pandas.ipynb b/Pandas.ipynb deleted file mode 100644 index 1760cf9..0000000 --- a/Pandas.ipynb +++ /dev/null @@ -1,308 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "source": [ - "# ⚠ Warning\n", - "\n", - "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", - "\n", - "[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gl/OpinionatedGeek%2Fmango-explorer/HEAD?filepath=Pandas.ipynb) _πŸƒβ€β™€οΈ To run this notebook press the ⏩ icon in the toolbar above._\n", - "\n", - "[πŸ₯­ Mango Markets](https://mango.markets/) support is available at: [Docs](https://docs.mango.markets/) | [Discord](https://discord.gg/67jySBhxrg) | [Twitter](https://twitter.com/mangomarkets) | [Github](https://github.com/blockworks-foundation) | [Email](mailto:hello@blockworks.foundation)" - ], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "# πŸ₯­ Mango + Pandas 🐼🐼\n", - "\n", - "This notebook loads margin account data into a Pandas `DataFrame`.\n", - "\n", - "The `DataFrame` is then queried for the total assets and liabilities, the Top 10 margin accounts with the most assets and the most liabilities, and then the Top 10 margin accounts closest to liquidation.\n", - "\n", - "The data remains in the `DataFrame` called `df` so you can easily add your own queries and analyses." - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "import logging\n", - "import mango\n", - "import pandas as pd\n", - "import time\n" - ], - "outputs": [], - "metadata": { - "jupyter": { - "source_hidden": true - } - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "start_time = time.time()\n", - "context = mango.Context.default()\n", - "\n", - "print(\"Loading group...\")\n", - "group = mango.Group.load(context)\n", - "print(f\"Done. Time taken: {time.time() - start_time}\")\n", - "\n", - "print(\"Loading prices...\")\n", - "prices = group.fetch_token_prices(context)\n", - "print(f\"Done. Time taken: {time.time() - start_time}\")\n", - "\n", - "print(\"Loading margin accounts...\")\n", - "margin_accounts = mango.MarginAccount.load_all_for_group_with_open_orders(context, context.mango_program_address, group)\n", - "print(f\"Done. {len(margin_accounts)} accounts. Time taken: {time.time() - start_time}\")\n", - "\n", - "print(\"Loading pandas dataframe...\")\n", - "data = []\n", - "df_index = []\n", - "sheet_formats = {}\n", - "for index, margin_account in enumerate(margin_accounts):\n", - " balance_sheet = margin_account.get_balance_sheet_totals(group, prices)\n", - " df_index += [str(margin_account.address)]\n", - " row = {\n", - " \"Collateral Ratio\": balance_sheet.collateral_ratio,\n", - " \"Available Collateral\": balance_sheet.assets - balance_sheet.liabilities,\n", - " \"Liabilities\": balance_sheet.liabilities,\n", - " \"Assets\": balance_sheet.assets,\n", - " \"Settled Assets\": balance_sheet.settled_assets,\n", - " \"Unsettled Assets\": balance_sheet.unsettled_assets,\n", - " \"Owner\": margin_account.owner\n", - " }\n", - " intrinsic_balance_sheets = margin_account.get_intrinsic_balance_sheets(group)\n", - " priced_balance_sheets = margin_account.get_priced_balance_sheets(group, prices)\n", - " for index, sheet in enumerate(intrinsic_balance_sheets):\n", - " if sheet is None:\n", - " continue\n", - " row[f\"{sheet.token.name} Liabilities (Intrinsic)\"] = sheet.liabilities\n", - " row[f\"{sheet.token.name} Assets (Intrinsic)\"] = sheet.assets\n", - " sheet_formats[f\"{sheet.token.name} Liabilities (Intrinsic)\"] = \"{:,.8f}\"\n", - " sheet_formats[f\"{sheet.token.name} Assets (Intrinsic)\"] = \"{:,.8f}\"\n", - " priced_sheet = priced_balance_sheets[index]\n", - " row[f\"{priced_sheet.token.name} Liabilities (Priced)\"] = priced_sheet.liabilities\n", - " row[f\"{priced_sheet.token.name} Assets (Priced)\"] = priced_sheet.assets\n", - " sheet_formats[f\"{sheet.token.name} Liabilities (Priced)\"] = \"${:,.2f}\"\n", - " sheet_formats[f\"{sheet.token.name} Assets (Priced)\"] = \"${:,.2f}\"\n", - " data += [row]\n", - "\n", - "\n", - "df = pd.DataFrame(data, index=df_index)\n", - "\n", - "print(f\"Done. Time taken: {time.time() - start_time}\")\n", - "\n", - "def render_styled(df: pd.DataFrame):\n", - " all_formats = {\n", - " \"Collateral Ratio\": \"{:,.2%}\",\n", - " \"Available Collateral\": \"${:,.2f}\",\n", - " \"Liabilities\": \"${:,.2f}\",\n", - " \"Assets\": \"${:,.2f}\",\n", - " \"Settled Assets\": \"${:,.2f}\",\n", - " \"Unsettled Assets\": \"${:,.2f}\"\n", - " }\n", - " all_formats.update(sheet_formats)\n", - " return df.style.format(all_formats)\n" - ], - "outputs": [], - "metadata": { - "tags": [] - } - }, - { - "cell_type": "markdown", - "source": [ - "# πŸ”₯ Total Assets + Liabilities" - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "print(f\"\"\"\n", - "Total Assets: ${df['Assets'].sum():>15,.2f}\n", - "Total Liabilities: ${df['Liabilities'].sum():>15,.2f}\n", - "Empty Accounts: {len(df[df[\"Collateral Ratio\"] == 0]):>15,}\n", - "Liquidatable: {len(df[(df[\"Collateral Ratio\"] != 0) & (df[\"Collateral Ratio\"] <= 1.1)]):>15,}\n", - "πŸ₯­ Ripe Mangoes: {len(df[(df[\"Collateral Ratio\"] > 1.1) & (df[\"Collateral Ratio\"] < 1.2)]):>15,}\n", - "\"\"\")" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "# πŸ” Top 10 Greatest Assets\n", - "\n", - "The top 10 margin accounts with most assets" - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "render_styled(df.sort_values(\"Assets\", ascending=False).head(10))" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "# πŸ” Top 10 Greatest Liabilities\n", - "\n", - "The top 10 margin accounts with most liabilities" - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "render_styled(df.sort_values(\"Liabilities\", ascending=False).head(10))" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "# πŸ” Top 10 Least Collateralised\n", - "\n", - "The top 10 least collateralised margin accounts\n", - "\n", - "Collect all margin accounts that have a non-zero Collateral Ratio (so have some liabilities). Then sort them from least-collateralised to most-collateralised." - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "nonzero = df[df[\"Collateral Ratio\"] != 0]\n", - "render_styled(nonzero.sort_values(\"Collateral Ratio\", ascending=True).head(10))" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "# πŸ’§ Liquidatable\n", - "\n", - "An account is 'liquidatable' when its available collateral falls below the group's maintenance collataeral threshold.\n", - "\n", - "This code shows all liquidatable margin accounts, sorted by the available collateral (_not_ the collateral ratio)." - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "simplified = nonzero.drop([\"Settled Assets\", \"Unsettled Assets\"], axis=1)\n", - "liquidatable = simplified[simplified[\"Collateral Ratio\"] < group.maint_coll_ratio].copy()\n", - "\n", - "print(f\"There are {len(liquidatable)} liquidatable accounts.\")\n", - "render_styled(liquidatable.sort_values(\"Available Collateral\", ascending=False).head(len(liquidatable)))" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "# πŸ₯­ Ripe Mangoes\n", - "\n", - "'Ripe mangoes' are margin accounts that are below the group's initial margin requirements but have not yet fallen below the liquidation threshold.\n", - "\n", - "This code shows all ripe mangoes, sorted by the available collateral (_not_ the collateral ratio)." - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "ripe = simplified[simplified[\"Collateral Ratio\"] < group.init_coll_ratio]\n", - "only_ripe = ripe[ripe[\"Collateral Ratio\"] >= group.maint_coll_ratio].copy()\n", - "\n", - "print(f\"There are {len(only_ripe)} πŸ₯­ ripe mangoes.\")\n", - "render_styled(only_ripe.sort_values(\"Available Collateral\", ascending=False).head(len(only_ripe)))" - ], - "outputs": [], - "metadata": {} - } - ], - "metadata": { - "interpreter": { - "hash": "ac2eaa0ea0ebeafcc7822e65e46aa9d4f966f30b695406963e145ea4a91cd4fc" - }, - "kernelspec": { - "display_name": "Python 3.9.4 64-bit", - "name": "python3" - }, - "language_info": { - "name": "python", - "version": "" - }, - "metadata": { - "interpreter": { - "hash": "ac2eaa0ea0ebeafcc7822e65e46aa9d4f966f30b695406963e145ea4a91cd4fc" - } - }, - "toc": { - "base_numbering": 1, - "nav_menu": {}, - "number_sections": true, - "sideBar": true, - "skip_h1_title": false, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": true, - "toc_window_display": true - }, - "varInspector": { - "cols": { - "lenName": 16, - "lenType": 16, - "lenVar": 40 - }, - "kernels_config": { - "python": { - "delete_cmd_postfix": "", - "delete_cmd_prefix": "del ", - "library": "var_list.py", - "varRefreshCmd": "print(var_dic_list())" - }, - "r": { - "delete_cmd_postfix": ") ", - "delete_cmd_prefix": "rm(", - "library": "var_list.r", - "varRefreshCmd": "cat(var_dic_list()) " - } - }, - "types_to_exclude": [ - "module", - "function", - "builtin_function_or_method", - "instance", - "_Feature" - ], - "window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/ShowAccount.ipynb b/ShowAccount.ipynb index e87632e..a992dd3 100644 --- a/ShowAccount.ipynb +++ b/ShowAccount.ipynb @@ -2,7 +2,6 @@ "cells": [ { "cell_type": "markdown", - "metadata": {}, "source": [ "# ⚠ Warning\n", "\n", @@ -11,42 +10,41 @@ "[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gl/OpinionatedGeek%2Fmango-explorer/HEAD?filepath=ShowAccount.ipynb) _πŸƒβ€β™€οΈ To run this notebook press the ⏩ icon in the toolbar above._\n", "\n", "[πŸ₯­ Mango Markets](https://mango.markets/) support is available at: [Docs](https://docs.mango.markets/) | [Discord](https://discord.gg/67jySBhxrg) | [Twitter](https://twitter.com/mangomarkets) | [Github](https://github.com/blockworks-foundation) | [Email](mailto:hello@blockworks.foundation)" - ] + ], + "metadata": {} }, { "cell_type": "markdown", - "metadata": {}, "source": [ "# πŸ₯­ Show My Accounts\n", "\n", "This notebook tries to display information about all Mango margin accounts that belong to a specified account.\n", "\n", "It fetches the data from Solana, parses it, and then prints it.\n" - ] + ], + "metadata": {} }, { "cell_type": "markdown", - "metadata": {}, "source": [ "## How To Use This Page\n", "\n", "Enter the public key of the account you want to check in the value for `ACCOUNT_TO_LOOK_UP` in the box below, between the double-quote marks. Then run the notebook by choosing 'Run > Run All Cells' from the notebook menu at the top of the page." - ] + ], + "metadata": {} }, { "cell_type": "code", "execution_count": null, - "metadata": {}, - "outputs": [], "source": [ "ACCOUNT_TO_LOOK_UP = \"\"" - ] + ], + "outputs": [], + "metadata": {} }, { "cell_type": "code", "execution_count": null, - "metadata": {}, - "outputs": [], "source": [ "if __name__ == \"__main__\":\n", " import mango\n", @@ -55,7 +53,7 @@ " if ACCOUNT_TO_LOOK_UP == \"\":\n", " raise Exception(\"No account to look up - try setting the variable ACCOUNT_TO_LOOK_UP to an account public key.\")\n", "\n", - " context = mango.Context.default()\n", + " context = mango.ContextBuilder.default()\n", " # print(\"Context:\", context)\n", "\n", " root_account_key = publickey.PublicKey(ACCOUNT_TO_LOOK_UP)\n", @@ -67,22 +65,14 @@ " if root_account.owner != mango.SYSTEM_PROGRAM_ADDRESS:\n", " raise Exception(f\"Account '{root_account_key}' is not a root user account.\")\n", "\n", - " scout = mango.AccountScout()\n", " group = mango.Group.load(context)\n", - " scout_report = scout.verify_account_prepared_for_group(context, group, root_account_key)\n", - " print(scout_report)\n", - "\n", - " print(\"Balances:\")\n", - " mango.TokenValue.report(group.fetch_balances(context, root_account_key))\n", - "\n", - " prices = group.fetch_token_prices(context)\n", - "\n", - " margin_accounts = mango.MarginAccount.load_all_for_owner(context, root_account_key, group)\n", - " print(f\"Account has {len(margin_accounts)} margin account(s).\")\n", - " for margin_account in margin_accounts:\n", - " print(\"Margin account:\", margin_account)\n", - " print(\"Balance sheet totals\", margin_account.get_balance_sheet_totals(group, prices))\n" - ] + " accounts = mango.Account.load_all_for_owner(context, root_account_key, group)\n", + " print(f\"Account has {len(accounts)} Mango account(s).\")\n", + " for account in accounts:\n", + " print(\"Margin account:\", account)\n" + ], + "outputs": [], + "metadata": {} } ], "metadata": { @@ -90,12 +80,20 @@ "hash": "ac2eaa0ea0ebeafcc7822e65e46aa9d4f966f30b695406963e145ea4a91cd4fc" }, "kernelspec": { - "display_name": "Python 3.9.4 64-bit", - "name": "python3" + "name": "python3", + "display_name": "Python 3.9.6 64-bit" }, "language_info": { "name": "python", - "version": "" + "version": "3.9.6", + "mimetype": "text/x-python", + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "pygments_lexer": "ipython3", + "nbconvert_exporter": "python", + "file_extension": ".py" }, "metadata": { "interpreter": { diff --git a/ShowAllMarginAccounts.ipynb b/ShowAllMarginAccounts.ipynb deleted file mode 100644 index 28b4bec..0000000 --- a/ShowAllMarginAccounts.ipynb +++ /dev/null @@ -1,135 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "source": [ - "# ⚠ Warning\n", - "\n", - "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", - "\n", - "[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gl/OpinionatedGeek%2Fmango-explorer/HEAD?filepath=ShowAllMarginAccounts.ipynb) _πŸƒβ€β™€οΈ To run this notebook press the ⏩ icon in the toolbar above._\n", - "\n", - "[πŸ₯­ Mango Markets](https://mango.markets/) support is available at: [Docs](https://docs.mango.markets/) | [Discord](https://discord.gg/67jySBhxrg) | [Twitter](https://twitter.com/mangomarkets) | [Github](https://github.com/blockworks-foundation) | [Email](mailto:hello@blockworks.foundation)" - ], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "# πŸ₯­ Show All Margin Accounts\n", - "\n", - "This notebook tries to display information about all Mango Markets margin accounts.\n", - "\n", - "It fetches the data from Solana, parses it, and then prints it.\n", - "\n", - "Note: this can take a long time to run." - ], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "## How To Use This Page\n", - "\n", - "Theo code should be runnable as-is. Just click the >> button in the toolbar above, and you should see output appear below the code." - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "if __name__ == \"__main__\":\n", - " import mango\n", - " import time\n", - "\n", - " def show_all_margin_accounts(context: mango.Context):\n", - " start_time = time.time()\n", - "\n", - " print(\"Loading group...\")\n", - " group = mango.Group.load(context)\n", - " print(f\"Done loading group. Time taken: {time.time() - start_time}\")\n", - "\n", - " print(\"Loading margin accounts...\")\n", - " margin_accounts = mango.MarginAccount.load_all_for_group_with_open_orders(context, context.mango_program_address, group)\n", - " print(f\"Done loading {len(margin_accounts)} account(s). Total time taken: {time.time() - start_time}\")\n", - "\n", - " print(*margin_accounts, sep=\"\\n\")\n", - "\n", - "\n", - " show_all_margin_accounts(mango.Context.default())\n", - " # import cProfile\n", - " # import pstats\n", - " # cProfile.run(\"show_all_accounts()\", sort=pstats.SortKey.TIME)\n" - ], - "outputs": [], - "metadata": { - "tags": [ - "outputPrepend" - ] - } - } - ], - "metadata": { - "interpreter": { - "hash": "ac2eaa0ea0ebeafcc7822e65e46aa9d4f966f30b695406963e145ea4a91cd4fc" - }, - "kernelspec": { - "display_name": "Python 3.9.4 64-bit", - "name": "python3" - }, - "language_info": { - "name": "python", - "version": "" - }, - "metadata": { - "interpreter": { - "hash": "ac2eaa0ea0ebeafcc7822e65e46aa9d4f966f30b695406963e145ea4a91cd4fc" - } - }, - "toc": { - "base_numbering": 1, - "nav_menu": {}, - "number_sections": true, - "sideBar": true, - "skip_h1_title": false, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": true, - "toc_window_display": true - }, - "varInspector": { - "cols": { - "lenName": 16, - "lenType": 16, - "lenVar": 40 - }, - "kernels_config": { - "python": { - "delete_cmd_postfix": "", - "delete_cmd_prefix": "del ", - "library": "var_list.py", - "varRefreshCmd": "print(var_dic_list())" - }, - "r": { - "delete_cmd_postfix": ") ", - "delete_cmd_prefix": "rm(", - "library": "var_list.r", - "varRefreshCmd": "cat(var_dic_list()) " - } - }, - "types_to_exclude": [ - "module", - "function", - "builtin_function_or_method", - "instance", - "_Feature" - ], - "window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/ShowGroup.ipynb b/ShowGroup.ipynb index df22f49..8f06e55 100644 --- a/ShowGroup.ipynb +++ b/ShowGroup.ipynb @@ -2,7 +2,6 @@ "cells": [ { "cell_type": "markdown", - "metadata": {}, "source": [ "# ⚠ Warning\n", "\n", @@ -11,42 +10,41 @@ "[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gl/OpinionatedGeek%2Fmango-explorer/HEAD?filepath=ShowGroup.ipynb) _πŸƒβ€β™€οΈ To run this notebook press the ⏩ icon in the toolbar above._\n", "\n", "[πŸ₯­ Mango Markets](https://mango.markets/) support is available at: [Docs](https://docs.mango.markets/) | [Discord](https://discord.gg/67jySBhxrg) | [Twitter](https://twitter.com/mangomarkets) | [Github](https://github.com/blockworks-foundation) | [Email](mailto:hello@blockworks.foundation)" - ] + ], + "metadata": {} }, { "cell_type": "markdown", - "metadata": {}, "source": [ "# πŸ₯­ Show Group\n", "\n", "This notebook tries to display information about a specific Mango Markets group.\n", "\n", "It fetches the data from Solana, parses it, and then prints it.\n" - ] + ], + "metadata": {} }, { "cell_type": "markdown", - "metadata": {}, "source": [ "## How To Use This Page\n", "\n", "Enter the name of the group you want to check in the value for `GROUP_TO_LOOK_UP` in the box below, between the double-quote marks. Then run the notebook by choosing 'Run > Run All Cells' from the notebook menu at the top of the page." - ] + ], + "metadata": {} }, { "cell_type": "code", "execution_count": null, - "metadata": {}, - "outputs": [], "source": [ "GROUP_TO_LOOK_UP = \"\"" - ] + ], + "outputs": [], + "metadata": {} }, { "cell_type": "code", "execution_count": null, - "metadata": {}, - "outputs": [], "source": [ "if __name__ == \"__main__\":\n", " import mango\n", @@ -54,10 +52,12 @@ " if GROUP_TO_LOOK_UP == \"\":\n", " raise Exception(\"No group to look up - try setting the variable GROUP_TO_LOOK_UP to an group's public key.\")\n", "\n", - " context = mango.Context.default().new_from_group_name(GROUP_TO_LOOK_UP)\n", + " context = mango.ContextBuilder.from_group_name(mango.ContextBuilder.default(), GROUP_TO_LOOK_UP)\n", " group = mango.Group.load(context)\n", " print(group)\n" - ] + ], + "outputs": [], + "metadata": {} } ], "metadata": { @@ -65,12 +65,20 @@ "hash": "ac2eaa0ea0ebeafcc7822e65e46aa9d4f966f30b695406963e145ea4a91cd4fc" }, "kernelspec": { - "display_name": "Python 3.9.4 64-bit", - "name": "python3" + "name": "python3", + "display_name": "Python 3.9.6 64-bit" }, "language_info": { "name": "python", - "version": "" + "version": "3.9.6", + "mimetype": "text/x-python", + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "pygments_lexer": "ipython3", + "nbconvert_exporter": "python", + "file_extension": ".py" }, "metadata": { "interpreter": { diff --git a/ShowMarginAccount.ipynb b/ShowMangoAccount.ipynb similarity index 83% rename from ShowMarginAccount.ipynb rename to ShowMangoAccount.ipynb index 2c10cd4..629a4ba 100644 --- a/ShowMarginAccount.ipynb +++ b/ShowMangoAccount.ipynb @@ -2,7 +2,6 @@ "cells": [ { "cell_type": "markdown", - "metadata": {}, "source": [ "# ⚠ Warning\n", "\n", @@ -11,55 +10,56 @@ "[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gl/OpinionatedGeek%2Fmango-explorer/HEAD?filepath=ShowMarginAccount.ipynb) _πŸƒβ€β™€οΈ To run this notebook press the ⏩ icon in the toolbar above._\n", "\n", "[πŸ₯­ Mango Markets](https://mango.markets/) support is available at: [Docs](https://docs.mango.markets/) | [Discord](https://discord.gg/67jySBhxrg) | [Twitter](https://twitter.com/mangomarkets) | [Github](https://github.com/blockworks-foundation) | [Email](mailto:hello@blockworks.foundation)" - ] + ], + "metadata": {} }, { "cell_type": "markdown", - "metadata": {}, "source": [ "# πŸ₯­ Show Margin Account\n", "\n", "This notebook tries to display information about a specific Mango Markets margin account.\n", "\n", "It fetches the data from Solana, parses it, and then prints it.\n" - ] + ], + "metadata": {} }, { "cell_type": "markdown", - "metadata": {}, "source": [ "## How To Use This Page\n", "\n", "Enter the public key of the margin account you want to check in the value for `MARGIN_ACCOUNT_TO_LOOK_UP` in the box below, between the double-quote marks. Then run the notebook by choosing 'Run > Run All Cells' from the notebook menu at the top of the page." - ] + ], + "metadata": {} }, { "cell_type": "code", "execution_count": null, - "metadata": {}, - "outputs": [], "source": [ - "MARGIN_ACCOUNT_TO_LOOK_UP = \"\"" - ] + "MANGO_ACCOUNT_TO_LOOK_UP = \"\"" + ], + "outputs": [], + "metadata": {} }, { "cell_type": "code", "execution_count": null, - "metadata": {}, - "outputs": [], "source": [ "if __name__ == \"__main__\":\n", " import mango\n", " import solana.publickey as publickey\n", "\n", - " if MARGIN_ACCOUNT_TO_LOOK_UP == \"\":\n", + " if MANGO_ACCOUNT_TO_LOOK_UP == \"\":\n", " raise Exception(\"No account to look up - try setting the variable ACCOUNT_TO_LOOK_UP to an account public key.\")\n", "\n", - " context = mango.Context.default()\n", + " context = mango.ContextBuilder.default()\n", " group = mango.Group.load(context)\n", - " margin_account = mango.MarginAccount.load(context, publickey.PublicKey(MARGIN_ACCOUNT_TO_LOOK_UP), group)\n", - " print(margin_account)\n" - ] + " account = mango.Account.load(context, publickey.PublicKey(MANGO_ACCOUNT_TO_LOOK_UP), group)\n", + " print(account)\n" + ], + "outputs": [], + "metadata": {} } ], "metadata": { @@ -67,12 +67,20 @@ "hash": "ac2eaa0ea0ebeafcc7822e65e46aa9d4f966f30b695406963e145ea4a91cd4fc" }, "kernelspec": { - "display_name": "Python 3.9.4 64-bit", - "name": "python3" + "name": "python3", + "display_name": "Python 3.9.6 64-bit" }, "language_info": { "name": "python", - "version": "" + "version": "3.9.6", + "mimetype": "text/x-python", + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "pygments_lexer": "ipython3", + "nbconvert_exporter": "python", + "file_extension": ".py" }, "metadata": { "interpreter": { diff --git a/ShowRipeMarginAccounts.ipynb b/ShowRipeMarginAccounts.ipynb deleted file mode 100644 index ce3b081..0000000 --- a/ShowRipeMarginAccounts.ipynb +++ /dev/null @@ -1,125 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# ⚠ Warning\n", - "\n", - "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", - "\n", - "[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gl/OpinionatedGeek%2Fmango-explorer/HEAD?filepath=ShowRipeMarginAccounts.ipynb) _πŸƒβ€β™€οΈ To run this notebook press the ⏩ icon in the toolbar above._\n", - "\n", - "[πŸ₯­ Mango Markets](https://mango.markets/) support is available at: [Docs](https://docs.mango.markets/) | [Discord](https://discord.gg/67jySBhxrg) | [Twitter](https://twitter.com/mangomarkets) | [Github](https://github.com/blockworks-foundation) | [Email](mailto:hello@blockworks.foundation)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# πŸ₯­ Show Ripe Margin Accounts\n", - "\n", - "This notebook tries to display information about all 'ripe' Mango Markets margin accounts. A 'ripe' margin account is one where the collateral ratio is less than the Initial Collateral Ratio but more than the Maintenance Collateral Ratio.\n", - "\n", - "It fetches the data from Solana, parses it, and then prints it.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## How To Use This Page\n", - "\n", - "Configure the `Context` for the `Group` you want to load, or just use as-is for the default `Group`.\n", - "\n", - "For example, to change to the _BTC_ETH_USDT_ `Group`, use:\n", - "```\n", - "context = Context.default().new_from_group_name(\"BTC_ETH_USDT\")\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "outputPrepend" - ] - }, - "outputs": [], - "source": [ - "if __name__ == \"__main__\":\n", - " import mango\n", - "\n", - " context = mango.Context.default()\n", - " group = mango.Group.load(context)\n", - "\n", - " ripe_margin_accounts = mango.MarginAccount.load_ripe(context, group)\n", - " print(f\"Fetched {len(ripe_margin_accounts)} ripe margin account(s).\")\n", - " print(*ripe_margin_accounts, sep=\"\\n\")\n" - ] - } - ], - "metadata": { - "interpreter": { - "hash": "ac2eaa0ea0ebeafcc7822e65e46aa9d4f966f30b695406963e145ea4a91cd4fc" - }, - "kernelspec": { - "display_name": "Python 3.9.4 64-bit", - "name": "python3" - }, - "language_info": { - "name": "python", - "version": "" - }, - "metadata": { - "interpreter": { - "hash": "ac2eaa0ea0ebeafcc7822e65e46aa9d4f966f30b695406963e145ea4a91cd4fc" - } - }, - "toc": { - "base_numbering": 1, - "nav_menu": {}, - "number_sections": true, - "sideBar": true, - "skip_h1_title": false, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": true, - "toc_window_display": true - }, - "varInspector": { - "cols": { - "lenName": 16, - "lenType": 16, - "lenVar": 40 - }, - "kernels_config": { - "python": { - "delete_cmd_postfix": "", - "delete_cmd_prefix": "del ", - "library": "var_list.py", - "varRefreshCmd": "print(var_dic_list())" - }, - "r": { - "delete_cmd_postfix": ") ", - "delete_cmd_prefix": "rm(", - "library": "var_list.r", - "varRefreshCmd": "cat(var_dic_list()) " - } - }, - "types_to_exclude": [ - "module", - "function", - "builtin_function_or_method", - "instance", - "_Feature" - ], - "window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file