Updated notebooks. Fixed ones that could be fixed, removed ones that require functionality not in V3.

This commit is contained in:
Geoff Taylor 2021-09-09 09:51:41 +01:00
parent 70a038ffd9
commit bf36c672c0
7 changed files with 80 additions and 888 deletions

View File

@ -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
}

View File

@ -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
}

View File

@ -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": {

View File

@ -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
}

View File

@ -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": {

View File

@ -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": {

View File

@ -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
}