Now use solana.tokenlist.json for token lookups.
This commit is contained in:
parent
cbd42d24ae
commit
f73ee9ca19
464
BaseModel.ipynb
464
BaseModel.ipynb
|
@ -2,7 +2,7 @@
|
||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "successful-traveler",
|
"id": "satellite-attachment",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# ⚠ Warning\n",
|
"# ⚠ Warning\n",
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "adequate-accreditation",
|
"id": "antique-studio",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🥭 BaseModel\n",
|
"# 🥭 BaseModel\n",
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "functional-porcelain",
|
"id": "crucial-norwegian",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"jupyter": {
|
"jupyter": {
|
||||||
"source_hidden": true
|
"source_hidden": true
|
||||||
|
@ -45,6 +45,7 @@
|
||||||
"import construct\n",
|
"import construct\n",
|
||||||
"import datetime\n",
|
"import datetime\n",
|
||||||
"import enum\n",
|
"import enum\n",
|
||||||
|
"import json\n",
|
||||||
"import logging\n",
|
"import logging\n",
|
||||||
"import time\n",
|
"import time\n",
|
||||||
"import typing\n",
|
"import typing\n",
|
||||||
|
@ -68,7 +69,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "alternate-choir",
|
"id": "mediterranean-cream",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Version enum\n",
|
"## Version enum\n",
|
||||||
|
@ -79,7 +80,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "blank-salad",
|
"id": "bibliographic-thong",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -94,7 +95,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "arranged-fiber",
|
"id": "previous-standard",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## InstructionType enum\n",
|
"## InstructionType enum\n",
|
||||||
|
@ -105,7 +106,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "liberal-director",
|
"id": "tight-indication",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -134,7 +135,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "aggregate-philippines",
|
"id": "foreign-performer",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Internal functions\n",
|
"## Internal functions\n",
|
||||||
|
@ -145,7 +146,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "digital-diabetes",
|
"id": "violent-separate",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -161,7 +162,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "marked-collector",
|
"id": "pacific-stuff",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## AccountInfo class\n"
|
"## AccountInfo class\n"
|
||||||
|
@ -170,7 +171,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "controlled-bandwidth",
|
"id": "answering-catholic",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -242,7 +243,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "developing-passage",
|
"id": "requested-craps",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## AddressableAccount class\n",
|
"## AddressableAccount class\n",
|
||||||
|
@ -255,7 +256,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "unexpected-choir",
|
"id": "sublime-broad",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -274,7 +275,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "arbitrary-variable",
|
"id": "infrared-religion",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## SerumAccountFlags class\n",
|
"## SerumAccountFlags class\n",
|
||||||
|
@ -285,7 +286,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "technical-chosen",
|
"id": "comparable-applicant",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -328,7 +329,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "rental-annual",
|
"id": "fabulous-copper",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## MangoAccountFlags class\n",
|
"## MangoAccountFlags class\n",
|
||||||
|
@ -339,7 +340,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "alternative-november",
|
"id": "adolescent-provincial",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -372,7 +373,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "thermal-behavior",
|
"id": "excellent-edmonton",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Index class"
|
"## Index class"
|
||||||
|
@ -381,7 +382,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "effective-kentucky",
|
"id": "knowing-discipline",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -408,7 +409,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "speaking-introduction",
|
"id": "regular-repeat",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## AggregatorConfig class"
|
"## AggregatorConfig class"
|
||||||
|
@ -417,7 +418,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "current-stone",
|
"id": "convinced-african",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -450,7 +451,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "agreed-louisville",
|
"id": "afraid-addiction",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Round class"
|
"## Round class"
|
||||||
|
@ -459,7 +460,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "uniform-hollywood",
|
"id": "manual-malaysia",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -484,7 +485,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "purple-deficit",
|
"id": "chemical-functionality",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Answer class"
|
"## Answer class"
|
||||||
|
@ -493,7 +494,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "possible-position",
|
"id": "flying-blame",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -519,7 +520,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "focal-minute",
|
"id": "collective-float",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Aggregator class"
|
"## Aggregator class"
|
||||||
|
@ -528,7 +529,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "unlikely-surprise",
|
"id": "chinese-green",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -594,7 +595,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "caroline-hospital",
|
"id": "acting-protection",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Token class\n",
|
"## Token class\n",
|
||||||
|
@ -605,31 +606,32 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "critical-hamburg",
|
"id": "raised-sender",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"class Token:\n",
|
"class Token:\n",
|
||||||
" def __init__(self, name: str, mint: PublicKey, decimals: Decimal):\n",
|
" def __init__(self, symbol: str, name: str, mint: PublicKey, decimals: Decimal):\n",
|
||||||
" self.logger: logging.Logger = logging.getLogger(self.__class__.__name__)\n",
|
" self.logger: logging.Logger = logging.getLogger(self.__class__.__name__)\n",
|
||||||
" self.name: str = name.upper()\n",
|
" self.symbol: str = symbol.upper()\n",
|
||||||
|
" self.name: str = name\n",
|
||||||
" self.mint: PublicKey = mint\n",
|
" self.mint: PublicKey = mint\n",
|
||||||
" self.decimals: Decimal = decimals\n",
|
" self.decimals: Decimal = decimals\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def round(self, value: Decimal) -> Decimal:\n",
|
" def round(self, value: Decimal) -> Decimal:\n",
|
||||||
" return round(value, int(self.decimals))\n",
|
" return round(value, int(self.decimals))\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def name_matches(self, name: str) -> bool:\n",
|
" def symbol_matches(self, symbol: str) -> bool:\n",
|
||||||
" return self.name.upper() == name.upper()\n",
|
" return self.symbol.upper() == symbol.upper()\n",
|
||||||
"\n",
|
"\n",
|
||||||
" @staticmethod\n",
|
" @staticmethod\n",
|
||||||
" def find_by_name(values: typing.List[\"Token\"], name: str) -> \"Token\":\n",
|
" def find_by_symbol(values: typing.List[\"Token\"], symbol: str) -> \"Token\":\n",
|
||||||
" found = [value for value in values if value.name_matches(name)]\n",
|
" found = [value for value in values if value.symbol_matches(symbol)]\n",
|
||||||
" if len(found) == 0:\n",
|
" if len(found) == 0:\n",
|
||||||
" raise Exception(f\"Token '{name}' not found in token values: {values}\")\n",
|
" raise Exception(f\"Token '{symbol}' not found in token values: {values}\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
" if len(found) > 1:\n",
|
" if len(found) > 1:\n",
|
||||||
" raise Exception(f\"Token '{name}' matched multiple tokens in values: {values}\")\n",
|
" raise Exception(f\"Token '{symbol}' matched multiple tokens in values: {values}\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
" return found[0]\n",
|
" return found[0]\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
@ -659,71 +661,229 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "surface-astrology",
|
"id": "mental-advertising",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## SolToken object\n",
|
"## SolToken object\n",
|
||||||
"\n",
|
"\n",
|
||||||
"It's sometimes handy to have a `Token` for SOL, but SOL isn't actually a token and can't appear in baskets. This object defines a special case for SOL."
|
"It's sometimes handy to have a `Token` for SOL, but SOL isn't actually a token and can't appear in baskets. This object defines a special case for SOL.\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "centered-respect",
|
"id": "signed-emphasis",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"SolToken = Token(\"SOL\", SOL_MINT_ADDRESS, SOL_DECIMALS)"
|
"SolToken = Token(\"SOL\", \"Pure SOL\", SOL_MINT_ADDRESS, SOL_DECIMALS)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "ready-projection",
|
"id": "capital-input",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## TokenLookup class\n",
|
"## TokenLookup class\n",
|
||||||
"\n",
|
"\n",
|
||||||
"The sole reason for this class is for us to be able to look up a token by name or mint address, and return a `Token` instances.\n",
|
"This class allows us to look up token symbols, names, mint addresses and decimals, all from our Solana static data.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"It's complicated because:\n",
|
"The `_find_data_by_symbol()` is used here and later in the `SpotMarketLookup` class.\n",
|
||||||
"* Our static token data is in `MangoConstants`\n",
|
"\n",
|
||||||
"* Our `Token` class is defined in `BaseModel`\n",
|
"The static data is the [Solana token list](https://raw.githubusercontent.com/solana-labs/token-list/main/src/tokens/solana.tokenlist.json) provided by Serum.\n",
|
||||||
"* Our `context` is the only part that knows which cluster we're in\n",
|
"\n",
|
||||||
"* `Context` can't use anything from `BaseModel` (it would cause a dependency cycle)\n",
|
"You can load a `TokenLookup` class by something like:\n",
|
||||||
"* SOL isn't mentioned in our `MangoConstants` data\n"
|
"```\n",
|
||||||
|
"with open(\"solana.tokenlist.json\") as json_file:\n",
|
||||||
|
" token_data = json.load(json_file)\n",
|
||||||
|
" token_lookup = TokenLookup(token_data)\n",
|
||||||
|
"```"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "frequent-worth",
|
"id": "formed-table",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
"def _find_data_by_symbol(symbol: str, token_data: typing.Dict) -> typing.Optional[typing.Dict]:\n",
|
||||||
|
" for token in token_data[\"tokens\"]:\n",
|
||||||
|
" if token[\"symbol\"] == symbol:\n",
|
||||||
|
" return token\n",
|
||||||
|
" return None\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
"class TokenLookup:\n",
|
"class TokenLookup:\n",
|
||||||
" @staticmethod\n",
|
" def __init__(self, token_data: typing.Dict) -> None:\n",
|
||||||
" def find_by_name(context: Context, name: str) -> Token:\n",
|
" self.logger: logging.Logger = logging.getLogger(self.__class__.__name__)\n",
|
||||||
" if SolToken.name_matches(name):\n",
|
" self.token_data = token_data\n",
|
||||||
" return SolToken\n",
|
"\n",
|
||||||
" mint = context.lookup_token_address(name)\n",
|
" def find_by_symbol(self, symbol: str):\n",
|
||||||
" if mint is None:\n",
|
" found = _find_data_by_symbol(symbol, self.token_data)\n",
|
||||||
" raise Exception(f\"Could not find token with name '{name}'.\")\n",
|
" if found is not None:\n",
|
||||||
" return Token(name, mint, Decimal(6))\n",
|
" return Token(found[\"symbol\"], found[\"name\"], PublicKey(found[\"address\"]), Decimal(found[\"decimals\"]))\n",
|
||||||
|
"\n",
|
||||||
|
" return None\n",
|
||||||
|
"\n",
|
||||||
|
" def find_by_mint(self, mint: PublicKey):\n",
|
||||||
|
" mint_string: str = str(mint)\n",
|
||||||
|
" for token in self.token_data[\"tokens\"]:\n",
|
||||||
|
" if token[\"address\"] == mint_string:\n",
|
||||||
|
" return Token(token[\"symbol\"], token[\"name\"], PublicKey(token[\"address\"]), Decimal(token[\"decimals\"]))\n",
|
||||||
|
"\n",
|
||||||
|
" return None\n",
|
||||||
"\n",
|
"\n",
|
||||||
" @staticmethod\n",
|
" @staticmethod\n",
|
||||||
" def find_by_mint(context: Context, mint: PublicKey) -> Token:\n",
|
" def default_lookups() -> \"TokenLookup\":\n",
|
||||||
" if SolToken.mint == mint:\n",
|
" with open(\"solana.tokenlist.json\") as json_file:\n",
|
||||||
" return SolToken\n",
|
" token_data = json.load(json_file)\n",
|
||||||
" name = context.lookup_token_name(mint)\n",
|
" return TokenLookup(token_data)"
|
||||||
" if name is None:\n",
|
|
||||||
" raise Exception(f\"Could not find token with mint '{mint}'.\")\n",
|
|
||||||
" return Token(name, mint, Decimal(6))\n"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "plastic-cambridge",
|
"id": "southern-gather",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## SpotMarket class"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "automatic-vegetation",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"class SpotMarket:\n",
|
||||||
|
" def __init__(self, address: PublicKey, base: Token, quote: Token):\n",
|
||||||
|
" self.logger: logging.Logger = logging.getLogger(self.__class__.__name__)\n",
|
||||||
|
" self.address: PublicKey = address\n",
|
||||||
|
" self.base: Token = base\n",
|
||||||
|
" self.quote: Token = quote\n",
|
||||||
|
"\n",
|
||||||
|
" @property\n",
|
||||||
|
" def name(self) -> str:\n",
|
||||||
|
" return f\"{self.base.symbol}/{self.quote.symbol}\"\n",
|
||||||
|
"\n",
|
||||||
|
" def __str__(self) -> str:\n",
|
||||||
|
" return f\"« Market {self.name}: {self.address} »\"\n",
|
||||||
|
"\n",
|
||||||
|
" def __repr__(self) -> str:\n",
|
||||||
|
" return f\"{self}\"\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "handy-batch",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## SpotMarketLookup class\n",
|
||||||
|
"\n",
|
||||||
|
"This class allows us to look up Serum market addresses and tokens, all from our Solana static data.\n",
|
||||||
|
"\n",
|
||||||
|
"The static data is the [Solana token list](https://raw.githubusercontent.com/solana-labs/token-list/main/src/tokens/solana.tokenlist.json) provided by Serum.\n",
|
||||||
|
"\n",
|
||||||
|
"You can load a `SpotMarketLookup` class by something like:\n",
|
||||||
|
"```\n",
|
||||||
|
"with open(\"solana.tokenlist.json\") as json_file:\n",
|
||||||
|
" token_data = json.load(json_file)\n",
|
||||||
|
" token_lookup = SpotMarketLookup(token_data)\n",
|
||||||
|
"```\n",
|
||||||
|
"This uses the same data file as `TokenLookup` but it looks a lot more complicated. The main reason for this is that tokens are described in a list, whereas markets are optional child attributes of tokens.\n",
|
||||||
|
"\n",
|
||||||
|
"To find a token, we can just go through the list.\n",
|
||||||
|
"\n",
|
||||||
|
"To find a market, we need to split the market symbol into the two token symbols, go through the list, check if the item has the optional `extensions` attribute, and in there see if there is a name-value pair for the particular market we're interested in. Also, the current file only lists USDC and USDT markets, so that's all we can support this way."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "arctic-portsmouth",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"class SpotMarketLookup:\n",
|
||||||
|
" def __init__(self, token_data: typing.Dict) -> None:\n",
|
||||||
|
" self.logger: logging.Logger = logging.getLogger(self.__class__.__name__)\n",
|
||||||
|
" self.token_data: typing.Dict = token_data\n",
|
||||||
|
"\n",
|
||||||
|
" def find_by_symbol(self, symbol: str) -> typing.Optional[SpotMarket]:\n",
|
||||||
|
" base_symbol, quote_symbol = symbol.split(\"/\")\n",
|
||||||
|
" base_data = _find_data_by_symbol(base_symbol, self.token_data)\n",
|
||||||
|
" if base_data is None:\n",
|
||||||
|
" self.logger.warning(f\"Could not find data for base token '{base_symbol}'\")\n",
|
||||||
|
" return None\n",
|
||||||
|
" base = Token(base_data[\"symbol\"], base_data[\"name\"], PublicKey(base_data[\"address\"]), Decimal(base_data[\"decimals\"]))\n",
|
||||||
|
"\n",
|
||||||
|
" quote_data = _find_data_by_symbol(quote_symbol, self.token_data)\n",
|
||||||
|
" if quote_data is None:\n",
|
||||||
|
" self.logger.warning(f\"Could not find data for quote token '{quote_symbol}'\")\n",
|
||||||
|
" return None\n",
|
||||||
|
" quote = Token(quote_data[\"symbol\"], quote_data[\"name\"], PublicKey(quote_data[\"address\"]), Decimal(quote_data[\"decimals\"]))\n",
|
||||||
|
"\n",
|
||||||
|
" if \"extensions\" not in base_data:\n",
|
||||||
|
" self.logger.warning(f\"No markets found for base token '{base.symbol}'.\")\n",
|
||||||
|
" return None\n",
|
||||||
|
"\n",
|
||||||
|
" if quote.symbol == \"USDC\":\n",
|
||||||
|
" if \"serumV3Usdc\" not in base_data[\"extensions\"]:\n",
|
||||||
|
" self.logger.warning(f\"No USDC market found for base token '{base.symbol}'.\")\n",
|
||||||
|
" return None\n",
|
||||||
|
"\n",
|
||||||
|
" market_address_string = base_data[\"extensions\"][\"serumV3Usdc\"]\n",
|
||||||
|
" market_address = PublicKey(market_address_string)\n",
|
||||||
|
" elif quote.symbol == \"USDT\":\n",
|
||||||
|
" if \"serumV3Usdt\" not in base_data[\"extensions\"]:\n",
|
||||||
|
" self.logger.warning(f\"No USDT market found for base token '{base.symbol}'.\")\n",
|
||||||
|
" return None\n",
|
||||||
|
"\n",
|
||||||
|
" market_address_string = base_data[\"extensions\"][\"serumV3Usdt\"]\n",
|
||||||
|
" market_address = PublicKey(market_address_string)\n",
|
||||||
|
" else:\n",
|
||||||
|
" self.logger.warning(f\"Could not find market with quote token '{quote.symbol}'. Only markets based on USDC or USDT are supported.\")\n",
|
||||||
|
" return None\n",
|
||||||
|
"\n",
|
||||||
|
" return SpotMarket(market_address, base, quote)\n",
|
||||||
|
"\n",
|
||||||
|
" def find_by_address(self, address: PublicKey) -> typing.Optional[SpotMarket]:\n",
|
||||||
|
" address_string: str = str(address)\n",
|
||||||
|
" for token_data in self.token_data[\"tokens\"]:\n",
|
||||||
|
" if \"extensions\" in token_data:\n",
|
||||||
|
" if \"serumV3Usdc\" in token_data[\"extensions\"]:\n",
|
||||||
|
" if token_data[\"extensions\"][\"serumV3Usdc\"] == address_string:\n",
|
||||||
|
" market_address_string = token_data[\"extensions\"][\"serumV3Usdc\"]\n",
|
||||||
|
" market_address = PublicKey(market_address_string)\n",
|
||||||
|
" base = Token(token_data[\"symbol\"], token_data[\"name\"], PublicKey(token_data[\"address\"]), Decimal(token_data[\"decimals\"]))\n",
|
||||||
|
" quote_data = _find_data_by_symbol(\"USDC\", self.token_data)\n",
|
||||||
|
" if quote_data is None:\n",
|
||||||
|
" raise Exception(\"Could not load token data for USDC (which should always be present).\")\n",
|
||||||
|
" quote = Token(quote_data[\"symbol\"], quote_data[\"name\"], PublicKey(quote_data[\"address\"]), Decimal(quote_data[\"decimals\"]))\n",
|
||||||
|
" return SpotMarket(market_address, base, quote)\n",
|
||||||
|
" if \"serumV3Usdt\" in token_data[\"extensions\"]:\n",
|
||||||
|
" if token_data[\"extensions\"][\"serumV3Usdt\"] == address_string:\n",
|
||||||
|
" market_address_string = token_data[\"extensions\"][\"serumV3Usdt\"]\n",
|
||||||
|
" market_address = PublicKey(market_address_string)\n",
|
||||||
|
" base = Token(token_data[\"symbol\"], token_data[\"name\"], PublicKey(token_data[\"address\"]), Decimal(token_data[\"decimals\"]))\n",
|
||||||
|
" quote_data = _find_data_by_symbol(\"USDT\", self.token_data)\n",
|
||||||
|
" if quote_data is None:\n",
|
||||||
|
" raise Exception(\"Could not load token data for USDT (which should always be present).\")\n",
|
||||||
|
" quote = Token(quote_data[\"symbol\"], quote_data[\"name\"], PublicKey(quote_data[\"address\"]), Decimal(quote_data[\"decimals\"]))\n",
|
||||||
|
" return SpotMarket(market_address, base, quote)\n",
|
||||||
|
" return None\n",
|
||||||
|
"\n",
|
||||||
|
" @staticmethod\n",
|
||||||
|
" def default_lookups() -> \"SpotMarketLookup\":\n",
|
||||||
|
" with open(\"solana.tokenlist.json\") as json_file:\n",
|
||||||
|
" token_data = json.load(json_file)\n",
|
||||||
|
" return SpotMarketLookup(token_data)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "moderate-taxation",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## BasketToken class\n",
|
"## BasketToken class\n",
|
||||||
|
@ -734,7 +894,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "pretty-baghdad",
|
"id": "protective-travel",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -746,13 +906,13 @@
|
||||||
" self.index: Index = index\n",
|
" self.index: Index = index\n",
|
||||||
"\n",
|
"\n",
|
||||||
" @staticmethod\n",
|
" @staticmethod\n",
|
||||||
" def find_by_name(values: typing.List[\"BasketToken\"], name: str) -> \"BasketToken\":\n",
|
" def find_by_symbol(values: typing.List[\"BasketToken\"], symbol: str) -> \"BasketToken\":\n",
|
||||||
" found = [value for value in values if value.token.name_matches(name)]\n",
|
" found = [value for value in values if value.token.symbol_matches(symbol)]\n",
|
||||||
" if len(found) == 0:\n",
|
" if len(found) == 0:\n",
|
||||||
" raise Exception(f\"Token '{name}' not found in token values: {values}\")\n",
|
" raise Exception(f\"Token '{symbol}' not found in token values: {values}\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
" if len(found) > 1:\n",
|
" if len(found) > 1:\n",
|
||||||
" raise Exception(f\"Token '{name}' matched multiple tokens in values: {values}\")\n",
|
" raise Exception(f\"Token '{symbol}' matched multiple tokens in values: {values}\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
" return found[0]\n",
|
" return found[0]\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
@ -790,7 +950,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "suburban-teaching",
|
"id": "enclosed-morocco",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## TokenValue class\n",
|
"## TokenValue class\n",
|
||||||
|
@ -801,7 +961,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "indirect-image",
|
"id": "provincial-submission",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -842,13 +1002,13 @@
|
||||||
" reporter(f\"{value.value:>18,.8f} {value.token.name}\")\n",
|
" reporter(f\"{value.value:>18,.8f} {value.token.name}\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
" @staticmethod\n",
|
" @staticmethod\n",
|
||||||
" def find_by_name(values: typing.List[\"TokenValue\"], name: str) -> \"TokenValue\":\n",
|
" def find_by_symbol(values: typing.List[\"TokenValue\"], symbol: str) -> \"TokenValue\":\n",
|
||||||
" found = [value for value in values if value.token.name_matches(name)]\n",
|
" found = [value for value in values if value.token.symbol_matches(symbol)]\n",
|
||||||
" if len(found) == 0:\n",
|
" if len(found) == 0:\n",
|
||||||
" raise Exception(f\"Token '{name}' not found in token values: {values}\")\n",
|
" raise Exception(f\"Token '{symbol}' not found in token values: {values}\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
" if len(found) > 1:\n",
|
" if len(found) > 1:\n",
|
||||||
" raise Exception(f\"Token '{name}' matched multiple tokens in values: {values}\")\n",
|
" raise Exception(f\"Token '{symbol}' matched multiple tokens in values: {values}\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
" return found[0]\n",
|
" return found[0]\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
@ -886,7 +1046,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "specialized-dominican",
|
"id": "exterior-petersburg",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## OwnedTokenValue class\n",
|
"## OwnedTokenValue class\n",
|
||||||
|
@ -897,7 +1057,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "charged-steering",
|
"id": "earned-patio",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -937,7 +1097,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "responsible-missile",
|
"id": "spanish-wagner",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## MarketMetadata class"
|
"## MarketMetadata class"
|
||||||
|
@ -946,33 +1106,33 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "humanitarian-emperor",
|
"id": "through-bruce",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"class MarketMetadata:\n",
|
"class MarketMetadata:\n",
|
||||||
" def __init__(self, name: str, address: PublicKey, base: BasketToken, quote: BasketToken,\n",
|
" def __init__(self, name: str, address: PublicKey, base: BasketToken, quote: BasketToken,\n",
|
||||||
" spot: PublicKey, oracle: PublicKey, decimals: Decimal):\n",
|
" spot: SpotMarket, oracle: PublicKey, decimals: Decimal):\n",
|
||||||
" self.logger: logging.Logger = logging.getLogger(self.__class__.__name__)\n",
|
" self.logger: logging.Logger = logging.getLogger(self.__class__.__name__)\n",
|
||||||
" self.name: str = name\n",
|
" self.name: str = name\n",
|
||||||
" self.address: PublicKey = address\n",
|
" self.address: PublicKey = address\n",
|
||||||
" self.base: BasketToken = base\n",
|
" self.base: BasketToken = base\n",
|
||||||
" self.quote: BasketToken = quote\n",
|
" self.quote: BasketToken = quote\n",
|
||||||
" self.spot: PublicKey = spot\n",
|
" self.spot: SpotMarket = spot\n",
|
||||||
" self.oracle: PublicKey = oracle\n",
|
" self.oracle: PublicKey = oracle\n",
|
||||||
" self.decimals: Decimal = decimals\n",
|
" self.decimals: Decimal = decimals\n",
|
||||||
" self._market = None\n",
|
" self._market = None\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def fetch_market(self, context: Context) -> Market:\n",
|
" def fetch_market(self, context: Context) -> Market:\n",
|
||||||
" if self._market is None:\n",
|
" if self._market is None:\n",
|
||||||
" self._market = Market.load(context.client, self.spot)\n",
|
" self._market = Market.load(context.client, self.spot.address)\n",
|
||||||
"\n",
|
"\n",
|
||||||
" return self._market\n",
|
" return self._market\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __str__(self) -> str:\n",
|
" def __str__(self) -> str:\n",
|
||||||
" base = f\"{self.base}\".replace(\"\\n\", \"\\n \")\n",
|
" base = f\"{self.base}\".replace(\"\\n\", \"\\n \")\n",
|
||||||
" quote = f\"{self.quote}\".replace(\"\\n\", \"\\n \")\n",
|
" quote = f\"{self.quote}\".replace(\"\\n\", \"\\n \")\n",
|
||||||
" return f\"\"\"« Market '{self.name}' [{self.spot}]:\n",
|
" return f\"\"\"« Market '{self.name}' [{self.address}/{self.spot.address}]:\n",
|
||||||
" Base: {base}\n",
|
" Base: {base}\n",
|
||||||
" Quote: {quote}\n",
|
" Quote: {quote}\n",
|
||||||
" Oracle: {self.oracle} ({self.decimals} decimals)\n",
|
" Oracle: {self.oracle} ({self.decimals} decimals)\n",
|
||||||
|
@ -984,7 +1144,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "floppy-glasgow",
|
"id": "collected-capitol",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Group class\n",
|
"## Group class\n",
|
||||||
|
@ -995,7 +1155,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "threaded-lebanon",
|
"id": "domestic-discovery",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -1033,29 +1193,32 @@
|
||||||
" return self.basket_tokens[:-1]\n",
|
" return self.basket_tokens[:-1]\n",
|
||||||
"\n",
|
"\n",
|
||||||
" @staticmethod\n",
|
" @staticmethod\n",
|
||||||
" def from_layout(layout: construct.Struct, context: Context, account_info: AccountInfo, version: Version) -> \"Group\":\n",
|
" def from_layout(layout: construct.Struct, context: Context, account_info: AccountInfo, version: Version, token_lookup: TokenLookup = TokenLookup.default_lookups(), spot_market_lookup: SpotMarketLookup = SpotMarketLookup.default_lookups()) -> \"Group\":\n",
|
||||||
" account_flags: MangoAccountFlags = MangoAccountFlags.from_layout(layout.account_flags)\n",
|
" account_flags: MangoAccountFlags = MangoAccountFlags.from_layout(layout.account_flags)\n",
|
||||||
" indexes = list(map(lambda pair: Index.from_layout(pair[0], pair[1]), zip(layout.indexes, layout.mint_decimals)))\n",
|
" indexes = list(map(lambda pair: Index.from_layout(pair[0], pair[1]), zip(layout.indexes, layout.mint_decimals)))\n",
|
||||||
"\n",
|
"\n",
|
||||||
" basket_tokens: typing.List[BasketToken] = []\n",
|
" basket_tokens: typing.List[BasketToken] = []\n",
|
||||||
" for index, token_address in enumerate(layout.tokens):\n",
|
" for index, token_address in enumerate(layout.tokens):\n",
|
||||||
" token_name = context.lookup_token_name(token_address)\n",
|
" static_token_data = token_lookup.find_by_mint(token_address)\n",
|
||||||
" if token_name is None:\n",
|
" if static_token_data is None:\n",
|
||||||
" raise Exception(f\"Could not find token with mint '{token_address}' in Group ['{account_info.address}'].\")\n",
|
" raise Exception(f\"Could not find token with mint '{token_address}'.\")\n",
|
||||||
" token = Token(token_name, token_address, layout.mint_decimals[index])\n",
|
"\n",
|
||||||
|
" # We create a new Token object here specifically to force the use of our own decimals\n",
|
||||||
|
" token = Token(static_token_data.symbol, static_token_data.name, token_address, layout.mint_decimals[index])\n",
|
||||||
" basket_token = BasketToken(token, layout.vaults[index], indexes[index])\n",
|
" basket_token = BasketToken(token, layout.vaults[index], indexes[index])\n",
|
||||||
" basket_tokens += [basket_token]\n",
|
" basket_tokens += [basket_token]\n",
|
||||||
"\n",
|
"\n",
|
||||||
" markets: typing.List[MarketMetadata] = []\n",
|
" markets: typing.List[MarketMetadata] = []\n",
|
||||||
" for index, market_address in enumerate(layout.spot_markets):\n",
|
" for index, market_address in enumerate(layout.spot_markets):\n",
|
||||||
" market_name = context.lookup_market_name(market_address)\n",
|
" spot_market = spot_market_lookup.find_by_address(market_address)\n",
|
||||||
" base_name, quote_name = market_name.split(\"/\")\n",
|
" if spot_market is None:\n",
|
||||||
" base_token = BasketToken.find_by_name(basket_tokens, base_name)\n",
|
" raise Exception(f\"Could not find spot market with address '{market_address}'.\")\n",
|
||||||
" quote_token = BasketToken.find_by_name(basket_tokens, quote_name)\n",
|
"\n",
|
||||||
" market = MarketMetadata(market_name, market_address, base_token, quote_token,\n",
|
" base_token = BasketToken.find_by_mint(basket_tokens, spot_market.base.mint)\n",
|
||||||
" layout.spot_markets[index],\n",
|
" quote_token = BasketToken.find_by_mint(basket_tokens, spot_market.quote.mint)\n",
|
||||||
" layout.oracles[index],\n",
|
"\n",
|
||||||
" layout.oracle_decimals[index])\n",
|
" market = MarketMetadata(spot_market.name, market_address, base_token, quote_token,\n",
|
||||||
|
" spot_market, layout.oracles[index], layout.oracle_decimals[index])\n",
|
||||||
" markets += [market]\n",
|
" markets += [market]\n",
|
||||||
"\n",
|
"\n",
|
||||||
" maint_coll_ratio = layout.maint_coll_ratio.quantize(Decimal('.01'))\n",
|
" maint_coll_ratio = layout.maint_coll_ratio.quantize(Decimal('.01'))\n",
|
||||||
|
@ -1126,7 +1289,6 @@
|
||||||
" balances += [TokenValue(SolToken, sol_balance)]\n",
|
" balances += [TokenValue(SolToken, sol_balance)]\n",
|
||||||
"\n",
|
"\n",
|
||||||
" for basket_token in self.basket_tokens:\n",
|
" for basket_token in self.basket_tokens:\n",
|
||||||
" if basket_token.token != SolToken:\n",
|
|
||||||
" balance = TokenValue.fetch_total_value(self.context, root_address, basket_token.token)\n",
|
" balance = TokenValue.fetch_total_value(self.context, root_address, basket_token.token)\n",
|
||||||
" balances += [balance]\n",
|
" balances += [balance]\n",
|
||||||
" return balances\n",
|
" return balances\n",
|
||||||
|
@ -1252,7 +1414,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "statistical-dominant",
|
"id": "motivated-chorus",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## TokenAccount class"
|
"## TokenAccount class"
|
||||||
|
@ -1261,7 +1423,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "blessed-usage",
|
"id": "fewer-pilot",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -1345,7 +1507,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "romance-funds",
|
"id": "hispanic-difficulty",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## OpenOrders class\n"
|
"## OpenOrders class\n"
|
||||||
|
@ -1354,7 +1516,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "homeless-palmer",
|
"id": "annual-brain",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -1474,7 +1636,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "downtown-facing",
|
"id": "dependent-proposition",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## BalanceSheet class"
|
"## BalanceSheet class"
|
||||||
|
@ -1483,7 +1645,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "renewable-redhead",
|
"id": "compound-commitment",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -1530,7 +1692,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "atmospheric-arbitration",
|
"id": "located-linux",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## MarginAccount class\n"
|
"## MarginAccount class\n"
|
||||||
|
@ -1539,7 +1701,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "aquatic-republican",
|
"id": "aerial-weight",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -1755,7 +1917,7 @@
|
||||||
" # If this becomes more painful than typing.Optional[Token], we can go with making\n",
|
" # If this becomes more painful than typing.Optional[Token], we can go with making\n",
|
||||||
" # Token optional.\n",
|
" # Token optional.\n",
|
||||||
" summary_name = \"-\".join([bal.token.name for bal in balance_sheets])\n",
|
" summary_name = \"-\".join([bal.token.name for bal in balance_sheets])\n",
|
||||||
" summary_token = Token(summary_name, SYSTEM_PROGRAM_ADDRESS, Decimal(0))\n",
|
" summary_token = Token(summary_name, f\"{summary_name} Summary\", SYSTEM_PROGRAM_ADDRESS, Decimal(0))\n",
|
||||||
" return BalanceSheet(summary_token, liabilities, settled_assets, unsettled_assets)\n",
|
" return BalanceSheet(summary_token, liabilities, settled_assets, unsettled_assets)\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def get_intrinsic_balances(self, group: Group) -> typing.List[TokenValue]:\n",
|
" def get_intrinsic_balances(self, group: Group) -> typing.List[TokenValue]:\n",
|
||||||
|
@ -1789,7 +1951,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "common-albania",
|
"id": "geological-winner",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## MarginAccountMetadata class"
|
"## MarginAccountMetadata class"
|
||||||
|
@ -1798,7 +1960,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "assumed-giant",
|
"id": "natural-semester",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -1824,7 +1986,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "impressed-tender",
|
"id": "introductory-premises",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# Events"
|
"# Events"
|
||||||
|
@ -1832,7 +1994,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "quick-finland",
|
"id": "varied-spokesman",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## LiquidationEvent"
|
"## LiquidationEvent"
|
||||||
|
@ -1841,7 +2003,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "narrative-reason",
|
"id": "faced-death",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -1860,7 +2022,7 @@
|
||||||
"\n",
|
"\n",
|
||||||
" def __str__(self) -> str:\n",
|
" def __str__(self) -> str:\n",
|
||||||
" result = \"✅\" if self.succeeded else \"❌\"\n",
|
" result = \"✅\" if self.succeeded else \"❌\"\n",
|
||||||
" changes_text = \"\\n \".join([f\"{change.value:>15,.8f} {change.token.name}\" for change in self.changes])\n",
|
" changes_text = \"\\n \".join([f\"{change.value:>15,.8f} {change.token.symbol}\" for change in self.changes])\n",
|
||||||
" return f\"\"\"« 🥭 Liqudation Event {result} at {self.timestamp}\n",
|
" return f\"\"\"« 🥭 Liqudation Event {result} at {self.timestamp}\n",
|
||||||
" 💧 Liquidator: {self.liquidator_name}\n",
|
" 💧 Liquidator: {self.liquidator_name}\n",
|
||||||
" 🗃️ Group: {self.group_name}\n",
|
" 🗃️ Group: {self.group_name}\n",
|
||||||
|
@ -1877,7 +2039,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "positive-twist",
|
"id": "appreciated-citation",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# ✅ Testing"
|
"# ✅ Testing"
|
||||||
|
@ -1886,7 +2048,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "breeding-nirvana",
|
"id": "average-rapid",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -1895,8 +2057,6 @@
|
||||||
" try:\n",
|
" try:\n",
|
||||||
" logging.getLogger().setLevel(logging.CRITICAL)\n",
|
" logging.getLogger().setLevel(logging.CRITICAL)\n",
|
||||||
"\n",
|
"\n",
|
||||||
" from Context import default_context\n",
|
|
||||||
"\n",
|
|
||||||
" list_to_split = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\"]\n",
|
" list_to_split = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\"]\n",
|
||||||
" split_3 = _split_list_into_chunks(list_to_split, 3)\n",
|
" split_3 = _split_list_into_chunks(list_to_split, 3)\n",
|
||||||
" assert(len(split_3) == 4)\n",
|
" assert(len(split_3) == 4)\n",
|
||||||
|
@ -1915,15 +2075,32 @@
|
||||||
" assert(len(split_20) == 1)\n",
|
" assert(len(split_20) == 1)\n",
|
||||||
" assert(split_20[0] == [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\"])\n",
|
" assert(split_20[0] == [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\"])\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
" token_lookup = TokenLookup.default_lookups()\n",
|
||||||
|
"\n",
|
||||||
|
" assert(token_lookup.find_by_symbol(\"ETH\").mint == PublicKey(\"2FPyTwcZLUg1MDrwsyoP4D6s1tM7hAkHYRjkNb5w6Pxk\"))\n",
|
||||||
|
" assert(token_lookup.find_by_mint(\"AKJHspCwDhABucCxNLXUSfEzb7Ny62RqFtC9uNjJi4fq\").symbol == \"SRM-SOL\")\n",
|
||||||
|
"\n",
|
||||||
|
" market_lookup = SpotMarketLookup.default_lookups()\n",
|
||||||
|
" assert(market_lookup.find_by_symbol(\"ETH/USDT\").base.symbol == \"ETH\")\n",
|
||||||
|
" assert(market_lookup.find_by_symbol(\"ETH/USDT\").quote.symbol == \"USDT\")\n",
|
||||||
|
" assert(market_lookup.find_by_symbol(\"ETH/USDT\").address == PublicKey(\"7dLVkUfBVfCGkFhSXDCq1ukM9usathSgS716t643iFGF\"))\n",
|
||||||
|
" assert(market_lookup.find_by_symbol(\"BTC/USDC\").base.symbol == \"BTC\")\n",
|
||||||
|
" assert(market_lookup.find_by_symbol(\"BTC/USDC\").quote.symbol == \"USDC\")\n",
|
||||||
|
" assert(market_lookup.find_by_symbol(\"BTC/USDC\").address == PublicKey(\"A8YFbxQYFVqKZaoYJLLUVcQiWP7G2MeEgW5wsAQgMvFw\"))\n",
|
||||||
|
" assert(market_lookup.find_by_symbol(\"ETH/BTC\") is None) # No such market\n",
|
||||||
|
" assert(market_lookup.find_by_address(\"ByRys5tuUWDgL73G8JBAEfkdFf8JWBzPBDHsBVQ5vbQA\").base.symbol == \"SRM\")\n",
|
||||||
|
" assert(market_lookup.find_by_address(\"ByRys5tuUWDgL73G8JBAEfkdFf8JWBzPBDHsBVQ5vbQA\").quote.symbol == \"USDC\")\n",
|
||||||
|
" assert(market_lookup.find_by_address(\"ByRys5tuUWDgL73G8JBAEfkdFf8JWBzPBDHsBVQ5vbQA\").address == PublicKey(\"ByRys5tuUWDgL73G8JBAEfkdFf8JWBzPBDHsBVQ5vbQA\"))\n",
|
||||||
|
"\n",
|
||||||
" balances_before = [\n",
|
" balances_before = [\n",
|
||||||
" TokenValue(TokenLookup.find_by_name(default_context, \"ETH\"), Decimal(1)),\n",
|
" TokenValue(token_lookup.find_by_symbol(\"ETH\"), Decimal(1)),\n",
|
||||||
" TokenValue(TokenLookup.find_by_name(default_context, \"BTC\"), Decimal(\"0.1\")),\n",
|
" TokenValue(token_lookup.find_by_symbol(\"BTC\"), Decimal(\"0.1\")),\n",
|
||||||
" TokenValue(TokenLookup.find_by_name(default_context, \"USDT\"), Decimal(1000))\n",
|
" TokenValue(token_lookup.find_by_symbol(\"USDT\"), Decimal(1000))\n",
|
||||||
" ]\n",
|
" ]\n",
|
||||||
" balances_after = [\n",
|
" balances_after = [\n",
|
||||||
" TokenValue(TokenLookup.find_by_name(default_context, \"ETH\"), Decimal(1)),\n",
|
" TokenValue(token_lookup.find_by_symbol(\"ETH\"), Decimal(1)),\n",
|
||||||
" TokenValue(TokenLookup.find_by_name(default_context, \"BTC\"), Decimal(\"0.05\")),\n",
|
" TokenValue(token_lookup.find_by_symbol(\"BTC\"), Decimal(\"0.05\")),\n",
|
||||||
" TokenValue(TokenLookup.find_by_name(default_context, \"USDT\"), Decimal(2000))\n",
|
" TokenValue(token_lookup.find_by_symbol(\"USDT\"), Decimal(2000))\n",
|
||||||
" ]\n",
|
" ]\n",
|
||||||
" timestamp = datetime.datetime(2021, 5, 17, 12, 20, 56)\n",
|
" timestamp = datetime.datetime(2021, 5, 17, 12, 20, 56)\n",
|
||||||
" event = LiquidationEvent(timestamp, \"Liquidator\", \"Group\", True, \"signature\",\n",
|
" event = LiquidationEvent(timestamp, \"Liquidator\", \"Group\", True, \"signature\",\n",
|
||||||
|
@ -1950,7 +2127,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "african-clinic",
|
"id": "variable-employee",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🏃 Running"
|
"# 🏃 Running"
|
||||||
|
@ -1959,12 +2136,15 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "applicable-silence",
|
"id": "accurate-tsunami",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"if __name__ == \"__main__\":\n",
|
"if __name__ == \"__main__\":\n",
|
||||||
" logging.getLogger().setLevel(logging.INFO)\n",
|
" def _notebook_main():\n",
|
||||||
|
" log_level = logging.getLogger().level\n",
|
||||||
|
" try:\n",
|
||||||
|
" logging.getLogger().setLevel(logging.CRITICAL)\n",
|
||||||
"\n",
|
"\n",
|
||||||
" import base64\n",
|
" import base64\n",
|
||||||
" from Context import default_context\n",
|
" from Context import default_context\n",
|
||||||
|
@ -1990,11 +2170,12 @@
|
||||||
" print(\"\\n\\nThis is hard-coded, not live information!\")\n",
|
" print(\"\\n\\nThis is hard-coded, not live information!\")\n",
|
||||||
" print(\"5-token group\", group_5)\n",
|
" print(\"5-token group\", group_5)\n",
|
||||||
"\n",
|
"\n",
|
||||||
" print(TokenLookup.find_by_name(default_context, \"ETH\"))\n",
|
" token_lookup = TokenLookup.default_lookups()\n",
|
||||||
" print(TokenLookup.find_by_name(default_context, \"BTC\"))\n",
|
" print(token_lookup.find_by_symbol(\"ETH\"))\n",
|
||||||
|
" print(token_lookup.find_by_symbol(\"BTC\"))\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # USDT\n",
|
" # USDT\n",
|
||||||
" print(TokenLookup.find_by_mint(default_context, PublicKey(\"Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB\")))\n",
|
" print(token_lookup.find_by_mint(PublicKey(\"Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB\")))\n",
|
||||||
"\n",
|
"\n",
|
||||||
" single_account_info = AccountInfo.load(default_context, default_context.dex_program_id)\n",
|
" single_account_info = AccountInfo.load(default_context, default_context.dex_program_id)\n",
|
||||||
" print(\"DEX account info\", single_account_info)\n",
|
" print(\"DEX account info\", single_account_info)\n",
|
||||||
|
@ -2003,20 +2184,25 @@
|
||||||
" print(\"Mango program and DEX account info\", multiple_account_info)\n",
|
" print(\"Mango program and DEX account info\", multiple_account_info)\n",
|
||||||
"\n",
|
"\n",
|
||||||
" balances_before = [\n",
|
" balances_before = [\n",
|
||||||
" TokenValue(TokenLookup.find_by_name(default_context, \"ETH\"), Decimal(1)),\n",
|
" TokenValue(token_lookup.find_by_symbol(\"ETH\"), Decimal(1)),\n",
|
||||||
" TokenValue(TokenLookup.find_by_name(default_context, \"BTC\"), Decimal(\"0.1\")),\n",
|
" TokenValue(token_lookup.find_by_symbol(\"BTC\"), Decimal(\"0.1\")),\n",
|
||||||
" TokenValue(TokenLookup.find_by_name(default_context, \"USDT\"), Decimal(1000))\n",
|
" TokenValue(token_lookup.find_by_symbol(\"USDT\"), Decimal(1000))\n",
|
||||||
" ]\n",
|
" ]\n",
|
||||||
" balances_after = [\n",
|
" balances_after = [\n",
|
||||||
" TokenValue(TokenLookup.find_by_name(default_context, \"ETH\"), Decimal(1)),\n",
|
" TokenValue(token_lookup.find_by_symbol(\"ETH\"), Decimal(1)),\n",
|
||||||
" TokenValue(TokenLookup.find_by_name(default_context, \"BTC\"), Decimal(\"0.05\")),\n",
|
" TokenValue(token_lookup.find_by_symbol(\"BTC\"), Decimal(\"0.05\")),\n",
|
||||||
" TokenValue(TokenLookup.find_by_name(default_context, \"USDT\"), Decimal(2000))\n",
|
" TokenValue(token_lookup.find_by_symbol(\"USDT\"), Decimal(2000))\n",
|
||||||
" ]\n",
|
" ]\n",
|
||||||
" timestamp = datetime.datetime(2021, 5, 17, 12, 20, 56)\n",
|
" timestamp = datetime.datetime(2021, 5, 17, 12, 20, 56)\n",
|
||||||
" event = LiquidationEvent(timestamp, \"Liquidator\", \"Group\", True, \"signature\",\n",
|
" event = LiquidationEvent(timestamp, \"Liquidator\", \"Group\", True, \"signature\",\n",
|
||||||
" SYSTEM_PROGRAM_ADDRESS, SYSTEM_PROGRAM_ADDRESS,\n",
|
" SYSTEM_PROGRAM_ADDRESS, SYSTEM_PROGRAM_ADDRESS,\n",
|
||||||
" balances_before, balances_after)\n",
|
" balances_before, balances_after)\n",
|
||||||
" print(event)\n"
|
" print(event)\n",
|
||||||
|
" finally:\n",
|
||||||
|
" logging.getLogger().setLevel(log_level)\n",
|
||||||
|
"\n",
|
||||||
|
" _notebook_main()\n",
|
||||||
|
" del _notebook_main\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "fitting-ticket",
|
"id": "successful-ordinary",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# ⚠ Warning\n",
|
"# ⚠ Warning\n",
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "historical-grace",
|
"id": "living-league",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🥭 Constants\n",
|
"# 🥭 Constants\n",
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "subtle-idaho",
|
"id": "spatial-korean",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"jupyter": {
|
"jupyter": {
|
||||||
"source_hidden": true
|
"source_hidden": true
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "institutional-earthquake",
|
"id": "constitutional-former",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## SYSTEM_PROGRAM_ADDRESS\n",
|
"## SYSTEM_PROGRAM_ADDRESS\n",
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "everyday-donna",
|
"id": "undefined-majority",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -64,27 +64,27 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "motivated-northwest",
|
"id": "liberal-hamilton",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## SOL_MINT_ADDRESS\n",
|
"## SOL_MINT_ADDRESS\n",
|
||||||
"\n",
|
"\n",
|
||||||
"The mint address of the SOL token."
|
"The fake mint address of the SOL token. **Note:** Wrapped SOL has a different mint address - it is So11111111111111111111111111111111111111112."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "speaking-homework",
|
"id": "accepting-circumstances",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"SOL_MINT_ADDRESS = PublicKey(\"So11111111111111111111111111111111111111112\")"
|
"SOL_MINT_ADDRESS = PublicKey(\"So11111111111111111111111111111111111111111\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "dated-appeal",
|
"id": "sacred-valve",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## SOL_DECIMALS\n",
|
"## SOL_DECIMALS\n",
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "ready-tension",
|
"id": "female-customs",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -104,7 +104,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "artistic-batch",
|
"id": "excess-tyler",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## SOL_DECIMAL_DIVISOR decimal\n",
|
"## SOL_DECIMAL_DIVISOR decimal\n",
|
||||||
|
@ -115,7 +115,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "powerful-warrior",
|
"id": "divine-concord",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -124,7 +124,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "mathematical-gender",
|
"id": "western-removal",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## NUM_TOKENS\n",
|
"## NUM_TOKENS\n",
|
||||||
|
@ -135,7 +135,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "isolated-sandwich",
|
"id": "hungry-disco",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -144,7 +144,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "marine-florist",
|
"id": "abroad-woman",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## NUM_MARKETS\n",
|
"## NUM_MARKETS\n",
|
||||||
|
@ -155,7 +155,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "defensive-jewel",
|
"id": "flush-wages",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -164,7 +164,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "optimum-wagner",
|
"id": "pleasant-convergence",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# WARNING_DISCLAIMER_TEXT\n",
|
"# WARNING_DISCLAIMER_TEXT\n",
|
||||||
|
@ -175,7 +175,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "arranged-hypothesis",
|
"id": "residential-roots",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -195,7 +195,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "focused-electricity",
|
"id": "surrounded-magnet",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## MangoConstants\n",
|
"## MangoConstants\n",
|
||||||
|
@ -206,7 +206,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "otherwise-pencil",
|
"id": "radical-submission",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -216,7 +216,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "dependent-pursuit",
|
"id": "dutch-tension",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🏃 Running\n",
|
"# 🏃 Running\n",
|
||||||
|
@ -227,7 +227,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "primary-graphic",
|
"id": "settled-clock",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "proud-accommodation",
|
"id": "artistic-cheese",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# ⚠ Warning\n",
|
"# ⚠ Warning\n",
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "manufactured-subcommittee",
|
"id": "endless-table",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🥭 Context\n",
|
"# 🥭 Context\n",
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "academic-liberia",
|
"id": "willing-companion",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Environment Variables\n",
|
"## Environment Variables\n",
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "equivalent-conspiracy",
|
"id": "infinite-ambassador",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Provided Configured Objects\n",
|
"## Provided Configured Objects\n",
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "automotive-diamond",
|
"id": "suffering-soccer",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"jupyter": {
|
"jupyter": {
|
||||||
"source_hidden": true
|
"source_hidden": true
|
||||||
|
@ -86,7 +86,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "private-vessel",
|
"id": "unlimited-plymouth",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Context class"
|
"## Context class"
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "blessed-azerbaijan",
|
"id": "through-factory",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -172,18 +172,9 @@
|
||||||
" return name\n",
|
" return name\n",
|
||||||
" return \"« Unknown Group »\"\n",
|
" return \"« Unknown Group »\"\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def lookup_market_name(self, market_address: PublicKey) -> str:\n",
|
|
||||||
" return Context._lookup_name_by_address(market_address, MangoConstants[self.cluster][\"mango_groups\"][self.group_name][\"spot_market_symbols\"]) or \"« Unknown Market »\"\n",
|
|
||||||
"\n",
|
|
||||||
" def lookup_oracle_name(self, token_address: PublicKey) -> str:\n",
|
" def lookup_oracle_name(self, token_address: PublicKey) -> str:\n",
|
||||||
" return Context._lookup_name_by_address(token_address, MangoConstants[self.cluster][\"oracles\"]) or \"« Unknown Oracle »\"\n",
|
" return Context._lookup_name_by_address(token_address, MangoConstants[self.cluster][\"oracles\"]) or \"« Unknown Oracle »\"\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def lookup_token_name(self, token_address: PublicKey) -> typing.Optional[str]:\n",
|
|
||||||
" return Context._lookup_name_by_address(token_address, MangoConstants[self.cluster][\"mango_groups\"][self.group_name][\"symbols\"])\n",
|
|
||||||
"\n",
|
|
||||||
" def lookup_token_address(self, token_name: str) -> typing.Optional[PublicKey]:\n",
|
|
||||||
" return Context._lookup_address_by_name(token_name, MangoConstants[self.cluster][\"mango_groups\"][self.group_name][\"symbols\"])\n",
|
|
||||||
"\n",
|
|
||||||
" def wait_for_confirmation(self, transaction_id: str, max_wait_in_seconds: int = 60) -> typing.Optional[typing.Dict]:\n",
|
" def wait_for_confirmation(self, transaction_id: str, max_wait_in_seconds: int = 60) -> typing.Optional[typing.Dict]:\n",
|
||||||
" self.logger.info(f\"Waiting up to {max_wait_in_seconds} seconds for {transaction_id}.\")\n",
|
" self.logger.info(f\"Waiting up to {max_wait_in_seconds} seconds for {transaction_id}.\")\n",
|
||||||
" for wait in range(0, max_wait_in_seconds):\n",
|
" for wait in range(0, max_wait_in_seconds):\n",
|
||||||
|
@ -253,7 +244,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "guilty-conservation",
|
"id": "brazilian-ethnic",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## default_context object\n",
|
"## default_context object\n",
|
||||||
|
@ -264,7 +255,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "classified-underground",
|
"id": "scenic-morgan",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -283,7 +274,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "ceramic-nightlife",
|
"id": "educational-equilibrium",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## solana_context object\n",
|
"## solana_context object\n",
|
||||||
|
@ -294,7 +285,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "animated-louisiana",
|
"id": "published-jordan",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -306,7 +297,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "thick-crash",
|
"id": "beautiful-coffee",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## serum_context object\n",
|
"## serum_context object\n",
|
||||||
|
@ -317,7 +308,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "behavioral-laser",
|
"id": "velvet-bride",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -329,7 +320,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "neural-malpractice",
|
"id": "fiscal-contribution",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🏃 Running\n",
|
"# 🏃 Running\n",
|
||||||
|
@ -340,7 +331,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "previous-capacity",
|
"id": "recovered-proceeding",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -349,10 +340,6 @@
|
||||||
"\n",
|
"\n",
|
||||||
" print(default_context)\n",
|
" print(default_context)\n",
|
||||||
"\n",
|
"\n",
|
||||||
" print(\"Lookup ETH token name result:\", default_context.lookup_token_name(PublicKey(\"2FPyTwcZLUg1MDrwsyoP4D6s1tM7hAkHYRjkNb5w6Pxk\")))\n",
|
|
||||||
" print(\"Lookup ETH token address result:\", default_context.lookup_token_address(\"ETH\"))\n",
|
|
||||||
" print(\"Lookup BTC/USDC market name result:\", default_context.lookup_market_name(PublicKey(\"CVfYa8RGXnuDBeGmniCcdkBwoLqVxh92xB1JqgRQx3F\")))\n",
|
|
||||||
"\n",
|
|
||||||
" # Fill out your account address between the quotes below\n",
|
" # Fill out your account address between the quotes below\n",
|
||||||
" MY_ACCOUNT_ADDRESS = \"\"\n",
|
" MY_ACCOUNT_ADDRESS = \"\"\n",
|
||||||
" # Don't edit anything beyond here.\n",
|
" # Don't edit anything beyond here.\n",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "corresponding-metabolism",
|
"id": "numeric-sheep",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# ⚠ Warning\n",
|
"# ⚠ Warning\n",
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "hollywood-victory",
|
"id": "lesser-small",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🥭 Instructions\n",
|
"# 🥭 Instructions\n",
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "disturbed-washer",
|
"id": "african-picking",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"jupyter": {
|
"jupyter": {
|
||||||
"source_hidden": true
|
"source_hidden": true
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "different-philosophy",
|
"id": "trained-cartridge",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# InstructionBuilder class\n",
|
"# InstructionBuilder class\n",
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "secret-eugene",
|
"id": "apparent-plane",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "accessory-drunk",
|
"id": "daily-dependence",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# ForceCancelOrdersInstructionBuilder class"
|
"# ForceCancelOrdersInstructionBuilder class"
|
||||||
|
@ -93,7 +93,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "touched-consideration",
|
"id": "ceramic-football",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Rust Interface\n",
|
"## Rust Interface\n",
|
||||||
|
@ -125,7 +125,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "blank-biodiversity",
|
"id": "empirical-ultimate",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Client API call\n",
|
"## Client API call\n",
|
||||||
|
@ -169,7 +169,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "physical-gentleman",
|
"id": "eligible-madison",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -200,7 +200,7 @@
|
||||||
" AccountMeta(is_signer=False, is_writable=True, pubkey=self.margin_account.address),\n",
|
" AccountMeta(is_signer=False, is_writable=True, pubkey=self.margin_account.address),\n",
|
||||||
" AccountMeta(is_signer=False, is_writable=True, pubkey=self.market_metadata.base.vault),\n",
|
" AccountMeta(is_signer=False, is_writable=True, pubkey=self.market_metadata.base.vault),\n",
|
||||||
" AccountMeta(is_signer=False, is_writable=True, pubkey=self.market_metadata.quote.vault),\n",
|
" AccountMeta(is_signer=False, is_writable=True, pubkey=self.market_metadata.quote.vault),\n",
|
||||||
" AccountMeta(is_signer=False, is_writable=True, pubkey=self.market_metadata.spot),\n",
|
" AccountMeta(is_signer=False, is_writable=True, pubkey=self.market_metadata.spot.address),\n",
|
||||||
" AccountMeta(is_signer=False, is_writable=True, pubkey=self.market.state.bids()),\n",
|
" AccountMeta(is_signer=False, is_writable=True, pubkey=self.market.state.bids()),\n",
|
||||||
" AccountMeta(is_signer=False, is_writable=True, pubkey=self.market.state.asks()),\n",
|
" AccountMeta(is_signer=False, is_writable=True, pubkey=self.market.state.asks()),\n",
|
||||||
" AccountMeta(is_signer=False, is_writable=False, pubkey=self.group.signer_key),\n",
|
" AccountMeta(is_signer=False, is_writable=False, pubkey=self.group.signer_key),\n",
|
||||||
|
@ -224,7 +224,7 @@
|
||||||
" def from_margin_account_and_market(context: Context, group: Group, wallet: Wallet, margin_account: MarginAccount, market_metadata: MarketMetadata) -> \"ForceCancelOrdersInstructionBuilder\":\n",
|
" def from_margin_account_and_market(context: Context, group: Group, wallet: Wallet, margin_account: MarginAccount, market_metadata: MarketMetadata) -> \"ForceCancelOrdersInstructionBuilder\":\n",
|
||||||
" market = market_metadata.fetch_market(context)\n",
|
" market = market_metadata.fetch_market(context)\n",
|
||||||
" nonce = struct.pack(\"<Q\", market.state.vault_signer_nonce())\n",
|
" nonce = struct.pack(\"<Q\", market.state.vault_signer_nonce())\n",
|
||||||
" dex_signer = PublicKey.create_program_address([bytes(market_metadata.spot), nonce], context.dex_program_id)\n",
|
" dex_signer = PublicKey.create_program_address([bytes(market_metadata.spot.address), nonce], context.dex_program_id)\n",
|
||||||
" oracles = list([mkt.oracle for mkt in group.markets])\n",
|
" oracles = list([mkt.oracle for mkt in group.markets])\n",
|
||||||
"\n",
|
"\n",
|
||||||
" return ForceCancelOrdersInstructionBuilder(context, group, wallet, margin_account, market_metadata, market, oracles, dex_signer)\n",
|
" return ForceCancelOrdersInstructionBuilder(context, group, wallet, margin_account, market_metadata, market, oracles, dex_signer)\n",
|
||||||
|
@ -258,7 +258,7 @@
|
||||||
" liqee_margin_account_acc: &Pubkey: {self.margin_account.address},\n",
|
" liqee_margin_account_acc: &Pubkey: {self.margin_account.address},\n",
|
||||||
" base_vault_pk: &Pubkey: {self.market_metadata.base.vault},\n",
|
" base_vault_pk: &Pubkey: {self.market_metadata.base.vault},\n",
|
||||||
" quote_vault_pk: &Pubkey: {self.market_metadata.quote.vault},\n",
|
" quote_vault_pk: &Pubkey: {self.market_metadata.quote.vault},\n",
|
||||||
" spot_market_pk: &Pubkey: {self.market_metadata.spot},\n",
|
" spot_market_pk: &Pubkey: {self.market_metadata.spot.address},\n",
|
||||||
" bids_pk: &Pubkey: {self.market.state.bids()},\n",
|
" bids_pk: &Pubkey: {self.market.state.bids()},\n",
|
||||||
" asks_pk: &Pubkey: {self.market.state.asks()},\n",
|
" asks_pk: &Pubkey: {self.market.state.asks()},\n",
|
||||||
" signer_pk: &Pubkey: {self.group.signer_key},\n",
|
" signer_pk: &Pubkey: {self.group.signer_key},\n",
|
||||||
|
@ -275,7 +275,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "changing-humanity",
|
"id": "expanded-separate",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# LiquidateInstructionBuilder class\n",
|
"# LiquidateInstructionBuilder class\n",
|
||||||
|
@ -287,7 +287,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "occupational-steam",
|
"id": "stupid-arrest",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Rust Interface\n",
|
"## Rust Interface\n",
|
||||||
|
@ -333,7 +333,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "heard-farming",
|
"id": "identical-november",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Client API call\n",
|
"## Client API call\n",
|
||||||
|
@ -370,7 +370,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "changed-literacy",
|
"id": "logical-burning",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## from_margin_account_and_market() function\n",
|
"## from_margin_account_and_market() function\n",
|
||||||
|
@ -391,7 +391,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "former-cemetery",
|
"id": "pending-services",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -503,7 +503,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "traditional-assembly",
|
"id": "retired-bundle",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🏃 Running"
|
"# 🏃 Running"
|
||||||
|
@ -512,7 +512,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "victorian-character",
|
"id": "wrong-rebel",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "enclosed-algebra",
|
"id": "ordinary-duplicate",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# ⚠ Warning\n",
|
"# ⚠ Warning\n",
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "aggressive-physiology",
|
"id": "sound-earthquake",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🥭 Notification\n",
|
"# 🥭 Notification\n",
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "patient-blame",
|
"id": "tamil-carpet",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"jupyter": {
|
"jupyter": {
|
||||||
"source_hidden": true
|
"source_hidden": true
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "global-feature",
|
"id": "brave-coordinate",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# NotificationTarget class\n",
|
"# NotificationTarget class\n",
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "noted-marking",
|
"id": "weekly-financing",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "forward-compact",
|
"id": "negative-madagascar",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# TelegramNotificationTarget class\n",
|
"# TelegramNotificationTarget class\n",
|
||||||
|
@ -113,7 +113,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "quarterly-nothing",
|
"id": "binary-export",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -136,7 +136,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "published-ideal",
|
"id": "whole-design",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# DiscordNotificationTarget class\n",
|
"# DiscordNotificationTarget class\n",
|
||||||
|
@ -147,7 +147,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "junior-conditions",
|
"id": "naughty-disney",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -170,7 +170,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "actual-bronze",
|
"id": "finite-caribbean",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# MailjetNotificationTarget class\n",
|
"# MailjetNotificationTarget class\n",
|
||||||
|
@ -224,7 +224,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "reduced-rabbit",
|
"id": "daily-accreditation",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -271,7 +271,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "gross-stereo",
|
"id": "physical-norfolk",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# CsvFileNotificationTarget class\n",
|
"# CsvFileNotificationTarget class\n",
|
||||||
|
@ -288,7 +288,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "given-african",
|
"id": "awful-airport",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -318,7 +318,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "adult-chicago",
|
"id": "instrumental-adams",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# FilteringNotificationTarget class\n",
|
"# FilteringNotificationTarget class\n",
|
||||||
|
@ -329,7 +329,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "acceptable-christopher",
|
"id": "iraqi-dryer",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -349,7 +349,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "falling-cattle",
|
"id": "monthly-translator",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# parse_subscription_target() function\n",
|
"# parse_subscription_target() function\n",
|
||||||
|
@ -362,7 +362,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "speaking-vocabulary",
|
"id": "overall-camera",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -383,7 +383,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "bacterial-coffee",
|
"id": "original-heating",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## NotificationHandler class\n",
|
"## NotificationHandler class\n",
|
||||||
|
@ -394,7 +394,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "norman-bruce",
|
"id": "different-breach",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -410,7 +410,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "cloudy-czech",
|
"id": "entertaining-mobility",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# ✅ Testing"
|
"# ✅ Testing"
|
||||||
|
@ -419,7 +419,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "rough-structure",
|
"id": "animal-player",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -466,7 +466,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "solved-switzerland",
|
"id": "after-definition",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🏃 Running\n",
|
"# 🏃 Running\n",
|
||||||
|
@ -477,7 +477,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "signed-guyana",
|
"id": "anticipated-destruction",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -503,18 +503,21 @@
|
||||||
" # from Context import default_context\n",
|
" # from Context import default_context\n",
|
||||||
" # from decimal import Decimal\n",
|
" # from decimal import Decimal\n",
|
||||||
" # from Wallet import default_wallet\n",
|
" # from Wallet import default_wallet\n",
|
||||||
|
" # token_lookup = TokenLookup.default_lookups()\n",
|
||||||
" # balances_before = [\n",
|
" # balances_before = [\n",
|
||||||
" # TokenValue(TokenLookup.find_by_name(default_context, \"ETH\"), Decimal(1)),\n",
|
" # TokenValue(token_lookup.find_by_symbol(\"ETH\"), Decimal(1)),\n",
|
||||||
" # TokenValue(TokenLookup.find_by_name(default_context, \"BTC\"), Decimal(\"0.1\")),\n",
|
" # TokenValue(token_lookup.find_by_symbol(\"BTC\"), Decimal(\"0.1\")),\n",
|
||||||
" # TokenValue(TokenLookup.find_by_name(default_context, \"USDT\"), Decimal(1000))\n",
|
" # TokenValue(token_lookup.find_by_symbol(\"USDT\"), Decimal(1000))\n",
|
||||||
" # ]\n",
|
" # ]\n",
|
||||||
" # balances_after = [\n",
|
" # balances_after = [\n",
|
||||||
" # TokenValue(TokenLookup.find_by_name(default_context, \"ETH\"), Decimal(1)),\n",
|
" # TokenValue(token_lookup.find_by_symbol(\"ETH\"), Decimal(1)),\n",
|
||||||
" # TokenValue(TokenLookup.find_by_name(default_context, \"BTC\"), Decimal(\"0.05\")),\n",
|
" # TokenValue(token_lookup.find_by_symbol(\"BTC\"), Decimal(\"0.05\")),\n",
|
||||||
" # TokenValue(TokenLookup.find_by_name(default_context, \"USDT\"), Decimal(2000))\n",
|
" # TokenValue(token_lookup.find_by_symbol(\"USDT\"), Decimal(2000))\n",
|
||||||
" # ]\n",
|
" # ]\n",
|
||||||
" #\n",
|
|
||||||
" # event = LiquidationEvent(datetime.datetime.now(),\n",
|
" # event = LiquidationEvent(datetime.datetime.now(),\n",
|
||||||
|
" # \"Liquidator Name\",\n",
|
||||||
|
" # \"GROUP_NAME\",\n",
|
||||||
|
" # True,\n",
|
||||||
" # \"SIGNATURE\",\n",
|
" # \"SIGNATURE\",\n",
|
||||||
" # default_wallet.address,\n",
|
" # default_wallet.address,\n",
|
||||||
" # default_wallet.address,\n",
|
" # default_wallet.address,\n",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "juvenile-netherlands",
|
"id": "french-mexico",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# ⚠ Warning\n",
|
"# ⚠ Warning\n",
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "changed-correspondence",
|
"id": "eastern-relevance",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🥭 TradeExecutor\n",
|
"# 🥭 TradeExecutor\n",
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "pacific-organic",
|
"id": "descending-attendance",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"jupyter": {
|
"jupyter": {
|
||||||
"source_hidden": true
|
"source_hidden": true
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "champion-wheel",
|
"id": "impressed-hazard",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# TradeExecutor class\n",
|
"# TradeExecutor class\n",
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "competent-former",
|
"id": "thirty-habitat",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -104,7 +104,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "latin-electronics",
|
"id": "possible-blank",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## NullTradeExecutor class\n",
|
"## NullTradeExecutor class\n",
|
||||||
|
@ -115,7 +115,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "accessible-decline",
|
"id": "subjective-violation",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -144,7 +144,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "noted-immunology",
|
"id": "paperback-america",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# SerumImmediateTradeExecutor class\n",
|
"# SerumImmediateTradeExecutor class\n",
|
||||||
|
@ -174,7 +174,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "enabling-convenience",
|
"id": "greatest-impression",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -327,7 +327,7 @@
|
||||||
" self.reporter(\"All settlement transaction IDs confirmed.\")\n",
|
" self.reporter(\"All settlement transaction IDs confirmed.\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def _tokens_and_market(self, symbol: str) -> typing.Tuple[MarketMetadata, Token, Token]:\n",
|
" def _tokens_and_market(self, symbol: str) -> typing.Tuple[MarketMetadata, Token, Token]:\n",
|
||||||
" base_token = BasketToken.find_by_name(self.group.basket_tokens, symbol).token\n",
|
" base_token = BasketToken.find_by_symbol(self.group.basket_tokens, symbol).token\n",
|
||||||
" quote_token = self.group.shared_quote_token.token\n",
|
" quote_token = self.group.shared_quote_token.token\n",
|
||||||
" self.logger.info(f\"Base token: {base_token}\")\n",
|
" self.logger.info(f\"Base token: {base_token}\")\n",
|
||||||
" self.logger.info(f\"Quote token: {quote_token}\")\n",
|
" self.logger.info(f\"Quote token: {quote_token}\")\n",
|
||||||
|
@ -356,7 +356,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "front-queens",
|
"id": "living-mitchell",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🏃 Running\n",
|
"# 🏃 Running\n",
|
||||||
|
@ -369,7 +369,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "optimum-judgment",
|
"id": "collected-simon",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "corrected-sunrise",
|
"id": "described-pencil",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# ⚠ Warning\n",
|
"# ⚠ Warning\n",
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "aware-hollywood",
|
"id": "nervous-bikini",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🥭 TransactionScount\n",
|
"# 🥭 TransactionScount\n",
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "coastal-wilson",
|
"id": "fitting-andrews",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"jupyter": {
|
"jupyter": {
|
||||||
"source_hidden": true
|
"source_hidden": true
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "indirect-mount",
|
"id": "weighted-annotation",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Transaction Indices\n",
|
"## Transaction Indices\n",
|
||||||
|
@ -79,7 +79,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "gothic-grace",
|
"id": "spiritual-buffer",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -149,7 +149,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "oriented-defense",
|
"id": "suspected-broadcasting",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## TransactionInstruction class\n",
|
"## TransactionInstruction class\n",
|
||||||
|
@ -160,7 +160,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "entire-russian",
|
"id": "compact-extreme",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -273,7 +273,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "auburn-liability",
|
"id": "portuguese-implement",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# TransactionScout class"
|
"# TransactionScout class"
|
||||||
|
@ -282,7 +282,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "strong-olive",
|
"id": "focused-poultry",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -358,7 +358,7 @@
|
||||||
" decimals = Decimal(balance[\"uiTokenAmount\"][\"decimals\"])\n",
|
" decimals = Decimal(balance[\"uiTokenAmount\"][\"decimals\"])\n",
|
||||||
" divisor = Decimal(10) ** decimals\n",
|
" divisor = Decimal(10) ** decimals\n",
|
||||||
" value = amount / divisor\n",
|
" value = amount / divisor\n",
|
||||||
" token = TokenLookup.find_by_mint(context, mint)\n",
|
" token = TokenLookup.default_lookups().find_by_mint(mint)\n",
|
||||||
" return OwnedTokenValue(account, TokenValue(token, value))\n",
|
" return OwnedTokenValue(account, TokenValue(token, value))\n",
|
||||||
"\n",
|
"\n",
|
||||||
" try:\n",
|
" try:\n",
|
||||||
|
@ -436,7 +436,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "enormous-boxing",
|
"id": "electronic-cassette",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -462,7 +462,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "lonely-proceeding",
|
"id": "false-merchant",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🏃 Running\n",
|
"# 🏃 Running\n",
|
||||||
|
@ -479,7 +479,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "static-affiliation",
|
"id": "recovered-times",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -489,7 +489,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "quantitative-wellington",
|
"id": "descending-norwegian",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "important-firmware",
|
"id": "intense-illinois",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# ⚠ Warning\n",
|
"# ⚠ Warning\n",
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "limited-ordering",
|
"id": "ceramic-smoke",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🥭 WalletBalancer\n",
|
"# 🥭 WalletBalancer\n",
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "immediate-berlin",
|
"id": "adequate-costume",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"jupyter": {
|
"jupyter": {
|
||||||
"source_hidden": true
|
"source_hidden": true
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "atomic-studio",
|
"id": "special-nomination",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# Target Balances\n",
|
"# Target Balances\n",
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "muslim-whale",
|
"id": "unknown-relationship",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## TargetBalance class\n",
|
"## TargetBalance class\n",
|
||||||
|
@ -86,7 +86,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "fallen-plumbing",
|
"id": "mighty-stock",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -105,7 +105,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "acting-december",
|
"id": "earlier-internship",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## FixedTargetBalance class\n",
|
"## FixedTargetBalance class\n",
|
||||||
|
@ -116,7 +116,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "fuzzy-laptop",
|
"id": "electronic-cycle",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -134,7 +134,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "ready-costume",
|
"id": "muslim-priority",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## PercentageTargetBalance\n",
|
"## PercentageTargetBalance\n",
|
||||||
|
@ -150,7 +150,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "premium-basin",
|
"id": "potential-mustang",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -170,7 +170,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "behavioral-convertible",
|
"id": "assigned-mississippi",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## TargetBalanceParser class\n",
|
"## TargetBalanceParser class\n",
|
||||||
|
@ -183,7 +183,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "democratic-crowd",
|
"id": "hired-laundry",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -197,7 +197,7 @@
|
||||||
" except Exception as exception:\n",
|
" except Exception as exception:\n",
|
||||||
" raise Exception(f\"Could not parse target balance '{to_parse}'\") from exception\n",
|
" raise Exception(f\"Could not parse target balance '{to_parse}'\") from exception\n",
|
||||||
"\n",
|
"\n",
|
||||||
" token = Token.find_by_name(self.tokens, token_name)\n",
|
" token = Token.find_by_symbol(self.tokens, token_name)\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # The value we have may be an int (like 27), a fraction (like 0.1) or a percentage\n",
|
" # The value we have may be an int (like 27), a fraction (like 0.1) or a percentage\n",
|
||||||
" # (like 25%). In all cases we want the number as a number, but we also want to know if\n",
|
" # (like 25%). In all cases we want the number as a number, but we also want to know if\n",
|
||||||
|
@ -221,7 +221,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "supreme-kentucky",
|
"id": "private-colorado",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# sort_changes_for_trades function\n",
|
"# sort_changes_for_trades function\n",
|
||||||
|
@ -234,7 +234,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "small-period",
|
"id": "signal-reputation",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -244,7 +244,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "significant-bearing",
|
"id": "regular-array",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# calculate_required_balance_changes function\n",
|
"# calculate_required_balance_changes function\n",
|
||||||
|
@ -255,7 +255,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "regulation-essay",
|
"id": "minimal-kinase",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -271,7 +271,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "taken-salvation",
|
"id": "round-appendix",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# FilterSmallChanges class\n",
|
"# FilterSmallChanges class\n",
|
||||||
|
@ -286,7 +286,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "clean-horizon",
|
"id": "european-ratio",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -315,7 +315,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "animated-switzerland",
|
"id": "three-shareware",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# WalletBalancers\n",
|
"# WalletBalancers\n",
|
||||||
|
@ -331,7 +331,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "essential-heating",
|
"id": "destroyed-validation",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## WalletBalancer class\n",
|
"## WalletBalancer class\n",
|
||||||
|
@ -342,7 +342,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "behind-product",
|
"id": "engaged-thunder",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -354,7 +354,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "mighty-minimum",
|
"id": "democratic-series",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## NullWalletBalancer class\n",
|
"## NullWalletBalancer class\n",
|
||||||
|
@ -365,7 +365,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "serious-ghost",
|
"id": "wound-flour",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -376,7 +376,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "metric-veteran",
|
"id": "painful-stake",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## LiveWalletBalancer class\n",
|
"## LiveWalletBalancer class\n",
|
||||||
|
@ -387,7 +387,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "shared-craft",
|
"id": "south-ministry",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -454,7 +454,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "living-fitness",
|
"id": "compatible-mustang",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# ✅ Testing"
|
"# ✅ Testing"
|
||||||
|
@ -463,7 +463,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "superb-proportion",
|
"id": "little-exposure",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -548,7 +548,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "built-evidence",
|
"id": "emotional-instruction",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# 🏃 Running\n",
|
"# 🏃 Running\n",
|
||||||
|
@ -559,7 +559,7 @@
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "welcome-secretariat",
|
"id": "adjusted-myrtle",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
@ -569,9 +569,9 @@
|
||||||
" from Context import default_context\n",
|
" from Context import default_context\n",
|
||||||
"\n",
|
"\n",
|
||||||
" group = Group.load(default_context)\n",
|
" group = Group.load(default_context)\n",
|
||||||
" eth = BasketToken.find_by_name(group.basket_tokens, \"eth\").token\n",
|
" eth = BasketToken.find_by_symbol(group.basket_tokens, \"eth\").token\n",
|
||||||
" btc = BasketToken.find_by_name(group.basket_tokens, \"btc\").token\n",
|
" btc = BasketToken.find_by_symbol(group.basket_tokens, \"btc\").token\n",
|
||||||
" usdt = BasketToken.find_by_name(group.basket_tokens, \"usdt\").token\n",
|
" usdt = BasketToken.find_by_symbol(group.basket_tokens, \"usdt\").token\n",
|
||||||
"\n",
|
"\n",
|
||||||
" parser = TargetBalanceParser([eth, btc])\n",
|
" parser = TargetBalanceParser([eth, btc])\n",
|
||||||
" eth_target = parser.parse(\"ETH:20%\")\n",
|
" eth_target = parser.parse(\"ETH:20%\")\n",
|
||||||
|
|
|
@ -80,7 +80,7 @@ try:
|
||||||
logging.info(f"Wallet address: {wallet.address}")
|
logging.info(f"Wallet address: {wallet.address}")
|
||||||
|
|
||||||
group = Group.load(context)
|
group = Group.load(context)
|
||||||
group_basket_token = BasketToken.find_by_name(group.basket_tokens, args.token_symbol)
|
group_basket_token = BasketToken.find_by_symbol(group.basket_tokens, args.token_symbol)
|
||||||
group_token = group_basket_token.token
|
group_token = group_basket_token.token
|
||||||
|
|
||||||
spl_token = Token(context.client, group_token.mint, TOKEN_PROGRAM_ID, wallet.account)
|
spl_token = Token(context.client, group_token.mint, TOKEN_PROGRAM_ID, wallet.account)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue