diff --git a/sdk/python/featurestore_sample/featurestore_sdk_job.py b/sdk/python/featurestore_sample/featurestore_sdk_job.py index 075d3a5b86..b6bd4eb33a 100644 --- a/sdk/python/featurestore_sample/featurestore_sdk_job.py +++ b/sdk/python/featurestore_sample/featurestore_sdk_job.py @@ -15,22 +15,16 @@ exec(f.read()) print("=======Test Notebook 2============") -with open( - "notebooks/sdk_only/2. Enable materialization and backfill feature data.py" -) as f: +with open("notebooks/sdk_only/2. Experiment and train models using features.py") as f: exec(f.read()) print("=======Test Notebook 3============") -with open("notebooks/sdk_only/3. Experiment and train models using features.py") as f: - exec(f.read()) - -print("=======Test Notebook 4============") with open( - "notebooks/sdk_only/4. Enable recurrent materialization and run batch inference.py" + "notebooks/sdk_only/3. Enable recurrent materialization and run batch inference.py" ) as f: exec(f.read()) # # exclude 5th notebook for now -# print("=======Test Notebook 5============") -# with open("notebooks/sdk_only/5. Enable online store and run online inference.py") as f: +# print("=======Test Notebook 4============") +# with open("notebooks/sdk_only/4. Enable online store and run online inference.py") as f: # exec(f.read()) diff --git a/sdk/python/featurestore_sample/notebooks/sdk_only/1. Develop a feature set and register with managed feature store.ipynb b/sdk/python/featurestore_sample/notebooks/sdk_only/1. Develop a feature set and register with managed feature store.ipynb index 70c79f8898..5ba3b8e9f4 100644 --- a/sdk/python/featurestore_sample/notebooks/sdk_only/1. Develop a feature set and register with managed feature store.ipynb +++ b/sdk/python/featurestore_sample/notebooks/sdk_only/1. Develop a feature set and register with managed feature store.ipynb @@ -3,27 +3,20 @@ { "attachments": {}, "cell_type": "markdown", + "source": [ + "# Tutorial: Develop a feature set and register with managed feature store" + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, - "source": [ - "# Tutorial #1: Develop a feature set and register with managed feature store" - ] + } }, { "attachments": {}, "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, "source": [ "Azure ML managed feature store lets you discover, create and operationalize features. Features are the connective tissue in ML lifecycle, starting from prototyping where you experiment with various features to operationalization where models are deployed and feature data is looked up during inference. For information on basics concept of feature store, see [feature store concepts](fs-concepts).\n", "\n", @@ -35,67 +28,68 @@ "- Develop and test featureset locally with feature transformation capability\n", "- Register a feature-store entity with the feature store\n", "- Register the featureset that you developed with the feature store\n", - "- Generate sample training data dataframe using the features you created\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", + "- Generate sample training data dataframe using the features you created\n", + "- Enable offline materialization on the feature sets, and backfill the feature data\n" + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, - "source": [ - "#### Important\n", - "\n", - "This feature is currently in public preview. This preview version is provided without a service-level agreement, and it's not recommended for production workloads. Certain features might not be supported or might have constrained capabilities. For more information, see [Supplemental Terms of Use for Microsoft Azure Previews](https://azure.microsoft.com/support/legal/preview-supplemental-terms/)." - ] + } }, { "attachments": {}, "cell_type": "markdown", + "source": [ + "#### Important\n", + "\n", + "This feature is currently in public preview. This preview version is provided without a service-level agreement, and it's not recommended for production workloads. Certain features might not be supported or might have constrained capabilities. For more information, see [Supplemental Terms of Use for Microsoft Azure Previews](https://azure.microsoft.com/support/legal/preview-supplemental-terms/)." + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, + } + }, + { + "attachments": {}, + "cell_type": "markdown", "source": [ "## Prerequisites\n", "Before following the steps in this article, make sure you have the following prerequisites:\n", "\n", "* An Azure Machine Learning workspace. If you don't have one, use the steps in the [Quickstart: Create workspace resources](https://learn.microsoft.com/en-us/azure/machine-learning/quickstart-create-resources?view=azureml-api-2) article to create one.\n", "* To perform the steps in this article, your user account must be assigned the owner or contributor role to a resource group where the feature store will be created" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, - "source": [ - "## Setup " - ] + } }, { "attachments": {}, "cell_type": "markdown", + "source": [ + "## Setup " + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, + } + }, + { + "attachments": {}, + "cell_type": "markdown", "source": [ "#### Prepare the notebook environment for development\n", "Note: This tutorial uses AzureML spark notebook for development. (placeholder: link to ADB document once ready)\n", @@ -117,28 +111,40 @@ "5. Click on \"configure session\" -> click on \"Python packages\" -> click on \"upload conda file\" -> select the file `azureml-examples/sdk/python/featurestore-sample/project/env/conda.yml` from your local machine; Also increase the session time out (idle time) if you want to reduce serverless spark cluster startup time.\n", "\n", "__Important:__ Except for this step, you need to run all the other steps every time you have a new spark session/session time out\n" - ] + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } }, { "attachments": {}, "cell_type": "markdown", + "source": [ + "#### Start spark session" + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, - "source": [ - "#### Start spark session" - ] + } }, { "cell_type": "code", + "source": [ + "# run this cell to start the spark session (any code block will start the session ). This can take around 10 mins.\n", + "print(\"start spark session\")" + ], + "outputs": [], "execution_count": null, "metadata": { "gather": { - "logged": 1683415277710 + "logged": 1696545108574 }, "jupyter": { "outputs_hidden": false, @@ -151,33 +157,41 @@ } }, "tags": [] - }, - "outputs": [], - "source": [ - "# run this cell to start the spark session (any code block will start the session ). This can take around 10 mins.\n", - "print(\"start spark session\")" - ] + } }, { "attachments": {}, "cell_type": "markdown", + "source": [ + "#### Setup root directory for the samples" + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, - "source": [ - "#### Setup root directory for the samples" - ] + } }, { "cell_type": "code", + "source": [ + "import os\n", + "\n", + "# Please update below (or any custom directory you uploaded the samples to).\n", + "# You can find the name from the directory structure in the left nav\n", + "root_dir = \"./Users//featurestore_sample\"\n", + "\n", + "if os.path.isdir(root_dir):\n", + " print(\"The folder exists.\")\n", + "else:\n", + " print(\"The folder does not exist. Please create or fix the path\")" + ], + "outputs": [], "execution_count": null, "metadata": { "gather": { - "logged": 1683415282100 + "logged": 1696545283706 }, "jupyter": { "outputs_hidden": false, @@ -189,31 +203,11 @@ "deleting": false } } - }, - "outputs": [], - "source": [ - "import os\n", - "\n", - "# Please update your alias belpw (or any custom directory you uploaded the samples to).\n", - "# You can find the name from the directory structure in the left nav\n", - "root_dir = \"./Users//featurestore_sample\"\n", - "\n", - "if os.path.isdir(root_dir):\n", - " print(\"The folder exists.\")\n", - "else:\n", - " print(\"The folder does not exist. Please create or fix the path\")" - ] + } }, { "attachments": {}, "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, "source": [ "## Note\n", "Feature store Vs Project workspace: You will use a featurestore to reuse features across projects. You will use a project workspace(the current workspace) to train and inference models, by leveraging features from feature stores. Many project workspaces can share and reuse a same feature store.\n", @@ -229,43 +223,62 @@ "- Generate training using a point-in-time join\n", "\n", "For this tutorial so you do not need to install any of these explicitly, since the instructions already cover them (conda yaml in the above step include these)" - ] + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } }, { "attachments": {}, "cell_type": "markdown", + "source": [ + "## Step 1: Create a minimal feature store" + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, - "source": [ - "## Step 1: Create a minimal feature store" - ] + } }, { "attachments": {}, "cell_type": "markdown", + "source": [ + "#### Step 1a: Set feature store parameters\n", + "Set name, location and other values for the feature store" + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, - "source": [ - "#### Step 1a: Set feature store parameters\n", - "Set name, location and other values for the feature store" - ] + } }, { "cell_type": "code", + "source": [ + "# We use the subscription, resource group, region of this active project workspace.\n", + "# You can optionally replace them to create the resources in a different subsciprtion/resourceGroup, or use existing resources\n", + "import os\n", + "\n", + "featurestore_name = \"my-featurestore\"\n", + "featurestore_location = \"eastus\"\n", + "featurestore_subscription_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", + "featurestore_resource_group_name = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", + "version = \"\"" + ], + "outputs": [], "execution_count": null, "metadata": { "gather": { - "logged": 1683415347313 + "logged": 1696545370071 }, "jupyter": { "outputs_hidden": false, @@ -277,53 +290,24 @@ "deleting": false } } - }, - "outputs": [], - "source": [ - "# We use the subscription, resource group, region of this active project workspace.\n", - "# You can optionally replace them to create the resources in a different subsciprtion/resourceGroup, or use existing resources\n", - "import os\n", - "\n", - "featurestore_name = \"my-featurestore\"\n", - "featurestore_location = \"eastus\"\n", - "featurestore_subscription_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", - "featurestore_resource_group_name = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", - "version = \"\"" - ] + } }, { "attachments": {}, "cell_type": "markdown", + "source": [ + "#### Step 1b: Create the feature store" + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, - "source": [ - "#### Step 1b: Create the feature store" - ] + } }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683415482376 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "create-fs", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], "source": [ "from azure.ai.ml import MLClient\n", "from azure.ai.ml.entities import (\n", @@ -344,42 +328,42 @@ "# wait for featurestore creation\n", "fs_poller = ml_client.feature_stores.begin_create(fs, update_dependent_resources=True)\n", "print(fs_poller.result())" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", + ], + "outputs": [], + "execution_count": null, "metadata": { + "gather": { + "logged": 1696545478258 + }, + "jupyter": { + "outputs_hidden": true, + "source_hidden": false + }, + "name": "create-fs", "nteract": { "transient": { "deleting": false } } - }, + } + }, + { + "attachments": {}, + "cell_type": "markdown", "source": [ "#### Step 1c: Initialize AzureML feature store core SDK client\n", "As explained above, this is used to develop and consume features" - ] - }, - { - "cell_type": "code", - "execution_count": null, + ], "metadata": { - "gather": { - "logged": 1683415633739 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "init-fs-core-sdk", "nteract": { "transient": { "deleting": false } } - }, - "outputs": [], + } + }, + { + "cell_type": "code", "source": [ "# feature store client\n", "from azureml.featurestore import FeatureStoreClient\n", @@ -391,45 +375,71 @@ " resource_group_name=featurestore_resource_group_name,\n", " name=featurestore_name,\n", ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", + ], + "outputs": [], + "execution_count": null, "metadata": { + "gather": { + "logged": 1696545558268 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "init-fs-core-sdk", "nteract": { "transient": { "deleting": false } } - }, - "source": [ - "## Step 2: Prototype and develop a transaction rolling aggregation featureset in this notebook" - ] + } }, { "attachments": {}, "cell_type": "markdown", + "source": [ + "## Step 2: Prototype and develop a transaction rolling aggregation featureset in this notebook" + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, + } + }, + { + "attachments": {}, + "cell_type": "markdown", "source": [ "#### Step 2a: Explore the transactions source data\n", "\n", "#### Note\n", "The sample data used in this notebook is hosted in a public accessible blob container. It can only be read in Spark via `wasbs` driver. When you create feature sets using your own source data, please host them in adls gen2 account and use `abfss` driver in the data path. " - ] + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } }, { "cell_type": "code", + "source": [ + "# remove the \".\" in the roor directory path as we need to generate absolute path to read from spark\n", + "transactions_source_data_path = \"wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/datasources/transactions-source/*.parquet\"\n", + "transactions_src_df = spark.read.parquet(transactions_source_data_path)\n", + "\n", + "display(transactions_src_df.head(5))\n", + "# Note: display(training_df.head(5)) displays the timestamp column in a different format. You can can call transactions_src_df.show() to see correctly formatted value" + ], + "outputs": [], "execution_count": null, "metadata": { "gather": { - "logged": 1683415673106 + "logged": 1696545597487 }, "jupyter": { "outputs_hidden": false, @@ -441,27 +451,11 @@ "deleting": false } } - }, - "outputs": [], - "source": [ - "# remove the \".\" in the roor directory path as we need to generate absolute path to read from spark\n", - "transactions_source_data_path = \"wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/datasources/transactions-source/*.parquet\"\n", - "transactions_src_df = spark.read.parquet(transactions_source_data_path)\n", - "\n", - "display(transactions_src_df.head(5))\n", - "# Note: display(training_df.head(5)) displays the timestamp column in a different format. You can can call transactions_src_df.show() to see correctly formatted value" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, + } + }, + { + "attachments": {}, + "cell_type": "markdown", "source": [ "#### Step 2b: Develop a transactions featureset locally\n", "\n", @@ -479,27 +473,17 @@ "- Inspect the feature transformation code file: `featurestore/featuresets/transactions/spec/transformation_code/transaction_transform.py`. You will see how is the rolling aggregation defined for the features. This is a spark transformer.\n", "\n", "To understand the feature set and transformations in more detail, see [feature store concepts](fs-concepts-url-todo) and [transformation concepts](fs-transformation-concepts-todo)." - ] - }, - { - "cell_type": "code", - "execution_count": null, + ], "metadata": { - "gather": { - "logged": 1683415951330 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "develop-txn-fset-locally", "nteract": { "transient": { "deleting": false } } - }, - "outputs": [], + } + }, + { + "cell_type": "code", "source": [ "from azureml.featurestore import create_feature_set_spec, FeatureSetSpec\n", "from azureml.featurestore.contracts import (\n", @@ -537,18 +521,28 @@ "transactions_fset_df = transactions_featureset_spec.to_spark_dataframe()\n", "# display few records\n", "display(transactions_fset_df.head(5))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", + ], + "outputs": [], + "execution_count": null, "metadata": { + "gather": { + "logged": 1696545617083 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "develop-txn-fset-locally", "nteract": { "transient": { "deleting": false } } - }, + } + }, + { + "attachments": {}, + "cell_type": "markdown", "source": [ "#### Step 2c: Export as feature set spec\n", "Inorder to register the feature set spec with the feature store, it needs to be saved in a specific format. \n", @@ -563,27 +557,17 @@ "Learn more about it in the [top level feature store entities document](fs-concepts-todo) and the [feature set spec yaml reference](reference-yaml-featureset-spec.md).\n", "\n", "The additional benefit of persisting it is that it can be source controlled." - ] - }, - { - "cell_type": "code", - "execution_count": null, + ], "metadata": { - "gather": { - "logged": 1683416345890 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "dump-transactions-fs-spec", "nteract": { "transient": { "deleting": false } } - }, - "outputs": [], + } + }, + { + "cell_type": "code", "source": [ "import os\n", "\n", @@ -596,47 +580,74 @@ "if not os.path.exists(transactions_featureset_spec_folder):\n", " os.makedirs(transactions_featureset_spec_folder)\n", "\n", - "transactions_featureset_spec.dump(transactions_featureset_spec_folder)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", + "transactions_featureset_spec.dump(transactions_featureset_spec_folder, overwrite=True)" + ], + "outputs": [], + "execution_count": null, "metadata": { + "gather": { + "logged": 1696545629168 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "dump-transactions-fs-spec", "nteract": { "transient": { "deleting": false } } - }, - "source": [ - "## Step 3: Register a feature-store entity\n", - "Entity helps enforce best practice that same join key definitions are used across featuresets which uses the same logical entities. Examples of entities are account entity, customer entity etc. Entities are typically created once and reused across feature-sets. For information on basics concept of feature store, see [feature store concepts](fs-concepts)." - ] + } }, { "attachments": {}, "cell_type": "markdown", + "source": [ + "## Step 3: Register a feature-store entity\n", + "Entity helps enforce best practice that same join key definitions are used across featuresets which uses the same logical entities. Examples of entities are account entity, customer entity etc. Entities are typically created once and reused across feature-sets. For information on basics concept of feature store, see [feature store concepts](fs-concepts)." + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, + } + }, + { + "attachments": {}, + "cell_type": "markdown", "source": [ "#### Step 3a: Initialize the Feature Store CRUD client\n", "\n", "As explained in the beginning of this tutorial, MLClient is used for CRUD of assets in feature store. The below code looks up the feature store we created in an earlier step. We cannot reuse the same ml_client used above here because the former is scoped at resource group level, which is a prerequisite for creation of feature store. The below one is scoped at feature store level.\n", " " - ] + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } }, { "cell_type": "code", + "source": [ + "# mlclient on feature store\n", + "fs_client = MLClient(\n", + " AzureMLOnBehalfOfCredential(),\n", + " featurestore_subscription_id,\n", + " featurestore_resource_group_name,\n", + " featurestore_name,\n", + ")" + ], + "outputs": [], "execution_count": null, "metadata": { "gather": { - "logged": 1683416010696 + "logged": 1696545635654 }, "jupyter": { "outputs_hidden": false, @@ -648,52 +659,25 @@ "deleting": false } } - }, - "outputs": [], - "source": [ - "# mlclient on feature store\n", - "fs_client = MLClient(\n", - " AzureMLOnBehalfOfCredential(),\n", - " featurestore_subscription_id,\n", - " featurestore_resource_group_name,\n", - " featurestore_name,\n", - ")" - ] + } }, { "attachments": {}, "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, "source": [ "#### Step 3b: Register `account` entity with the feature store\n", "Create account entity that has join key `accountID` of `string` type. " - ] - }, - { - "cell_type": "code", - "execution_count": null, + ], "metadata": { - "gather": { - "logged": 1683416051121 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "register-acct-entity", "nteract": { "transient": { "deleting": false } } - }, - "outputs": [], + } + }, + { + "cell_type": "code", "source": [ "from azure.ai.ml.entities import DataColumn, DataColumnType\n", "\n", @@ -708,44 +692,44 @@ "\n", "poller = fs_client.feature_store_entities.begin_create_or_update(account_entity_config)\n", "print(poller.result())" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", + ], + "outputs": [], + "execution_count": null, "metadata": { + "gather": { + "logged": 1696545646811 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "register-acct-entity", "nteract": { "transient": { "deleting": false } } - }, + } + }, + { + "attachments": {}, + "cell_type": "markdown", "source": [ "## Step 4: Register the transaction featureset with the featurestore\n", "You register a feature set asset with the feature store so that you can share and reuse with others. You also get managed capabilities like versioning and materialization (we will learn in this tutorial series).\n", "\n", "The feature set asset has reference to the feature set spec that you created earlier and additional properties like version and materialization settings." - ] - }, - { - "cell_type": "code", - "execution_count": null, + ], "metadata": { - "gather": { - "logged": 1683416442205 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "register-txn-fset", "nteract": { "transient": { "deleting": false } } - }, - "outputs": [], + } + }, + { + "cell_type": "code", "source": [ "from azure.ai.ml.entities import FeatureSetSpecification\n", "\n", @@ -761,18 +745,28 @@ "\n", "poller = fs_client.feature_sets.begin_create_or_update(transaction_fset_config)\n", "print(poller.result())" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", + ], + "outputs": [], + "execution_count": null, "metadata": { + "gather": { + "logged": 1696545663104 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "register-txn-fset", "nteract": { "transient": { "deleting": false } } - }, + } + }, + { + "attachments": {}, + "cell_type": "markdown", "source": [ "#### Explore the FeatureStore UI\n", "* Goto the [Azure ML global landing page](https://ml.azure.com/home?flight=FeatureStores).\n", @@ -782,42 +776,58 @@ "You can see the feature set and entity that you created.\n", "\n", "Note: Creating and updating feature store assets are possible only through SDK and CLI. You can use the UI to search/browse the feature store." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, - "source": [ - "## Step 5: Generate a training data dataframe using the registered features" - ] + } }, { "attachments": {}, "cell_type": "markdown", + "source": [ + "## Step 5: Generate a training data dataframe using the registered features" + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, + } + }, + { + "attachments": {}, + "cell_type": "markdown", "source": [ "#### Step 5a: Load observation data\n", "\n", "We start by exploring the observation data. Observation data is typically the core data used in training and inference data. This is then joined with feature data to create the full training data. Observation data is the data captured during the time of the event: in this case it has core transaction data including transaction id, account id, transaction amount. In this case, since it is for training, it also has the target variable appended (is_fraud).\n", "\n", "To learn more core concepts including observation data, refer to the docs" - ] + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } }, { "cell_type": "code", + "source": [ + "observation_data_path = \"wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/observation_data/train/*.parquet\"\n", + "observation_data_df = spark.read.parquet(observation_data_path)\n", + "obs_data_timestamp_column = \"timestamp\"\n", + "\n", + "display(observation_data_df)\n", + "# Note: the timestamp column is displayed in a different format. Optionally, you can can call training_df.show() to see correctly formatted value" + ], + "outputs": [], "execution_count": null, "metadata": { "gather": { @@ -833,33 +843,31 @@ "deleting": false } } - }, - "outputs": [], - "source": [ - "observation_data_path = \"wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/observation_data/train/*.parquet\"\n", - "observation_data_df = spark.read.parquet(observation_data_path)\n", - "obs_data_timestamp_column = \"timestamp\"\n", - "\n", - "display(observation_data_df)\n", - "# Note: the timestamp column is displayed in a different format. Optionally, you can can call training_df.show() to see correctly formatted value" - ] + } }, { "attachments": {}, "cell_type": "markdown", + "source": [ + "#### Step 5c: Get the registered featureset and list its features" + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, - "source": [ - "#### Step 5c: Get the registered featureset and list its features" - ] + } }, { "cell_type": "code", + "source": [ + "# look up the featureset by providing name and version\n", + "transactions_featureset = featurestore.feature_sets.get(\"transactions\", version)\n", + "# list its features\n", + "transactions_featureset.features" + ], + "outputs": [], "execution_count": null, "metadata": { "gather": { @@ -875,17 +883,15 @@ "deleting": false } } - }, - "outputs": [], - "source": [ - "# look up the featureset by providing name and version\n", - "transactions_featureset = featurestore.feature_sets.get(\"transactions\", version)\n", - "# list its features\n", - "transactions_featureset.features" - ] + } }, { "cell_type": "code", + "source": [ + "# print sample values\n", + "display(transactions_featureset.to_spark_dataframe().head(5))" + ], + "outputs": [], "execution_count": null, "metadata": { "gather": { @@ -901,47 +907,25 @@ "deleting": false } } - }, - "outputs": [], - "source": [ - "# print sample values\n", - "display(transactions_featureset.to_spark_dataframe().head(5))" - ] + } }, { "attachments": {}, "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, "source": [ "#### Step 5d: Select features and generate training data\n", "In this step we will select features that we would like to be part of training data and use the feature store sdk to generate the training data." - ] - }, - { - "cell_type": "code", - "execution_count": null, + ], "metadata": { - "gather": { - "logged": 1683417499373 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "select-features-and-gen-training-data", "nteract": { "transient": { "deleting": false } } - }, - "outputs": [], + } + }, + { + "cell_type": "code", "source": [ "from azureml.featurestore import get_offline_features\n", "\n", @@ -970,54 +954,267 @@ "# Ignore the message that says feature set is not materialized (materialization is optional). We will enable materialization in the next part of the tutorial.\n", "display(training_df)\n", "# Note: the timestamp column is displayed in a different format. Optionally, you can can call training_df.show() to see correctly formatted value" - ] + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1683417499373 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "select-features-and-gen-training-data", + "nteract": { + "transient": { + "deleting": false + } + } + } }, { "attachments": {}, "cell_type": "markdown", + "source": [ + "You can see how the features are appended to the training data using a point-in-time join.\n", + "\n", + "We have reached the end of the tutorial. Now you have your training data using features from feature store. You can either save it to storage for later use, or run model training on it directly." + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, + } + }, + { + "cell_type": "markdown", "source": [ - "You can see how the features are appended to the training data using a point-in-time join.\n", + "## Step 6: Enable offline materialization on transactions featureset\n", + "Once materialization is enabled on a featureset, you can perform backfill (this tutorial) or schedule recurrent materialization jobs(next part of the tutorial)" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "from azure.ai.ml.entities import (\n", + " MaterializationSettings,\n", + " MaterializationComputeResource,\n", + ")\n", "\n", - "We have reached the end of the tutorial. Now you have your training data using features from feature store. You can either save it to storage for later use, or run model training on it directly." - ] + "transactions_fset_config = fs_client._featuresets.get(\n", + " name=\"transactions\", version=version\n", + ")\n", + "\n", + "transactions_fset_config.materialization_settings = MaterializationSettings(\n", + " offline_enabled=True,\n", + " resource=MaterializationComputeResource(instance_type=\"standard_e8s_v3\"),\n", + " spark_configuration={\n", + " \"spark.driver.cores\": 4,\n", + " \"spark.driver.memory\": \"36g\",\n", + " \"spark.executor.cores\": 4,\n", + " \"spark.executor.memory\": \"36g\",\n", + " \"spark.executor.instances\": 2,\n", + " },\n", + " schedule=None,\n", + ")\n", + "\n", + "fs_poller = fs_client.feature_sets.begin_create_or_update(transactions_fset_config)\n", + "print(fs_poller.result())" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": false, + "outputs_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + } }, { - "attachments": {}, "cell_type": "markdown", + "source": [ + "Optionally, you can save the the above feature set asset as yaml" + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, + } + }, + { + "cell_type": "code", "source": [ - "## Cleanup\n", + "## uncomment to run\n", + "transactions_fset_config.dump(\n", + " root_dir\n", + " + \"/featurestore/featuresets/transactions/featureset_asset_offline_enabled.yaml\"\n", + ")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": false, + "outputs_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "markdown", + "source": [ + "## Step 7: Backfill data for transactions featureset\n", + "As explained in the beginning of this tutorial, materialization is the process of computing the feature values for a given feature window and storing this in an materialization store. Materializing the features will increase its reliability and availability. All feature queries will now use the values from the materialization store. In this step you perform a one-time backfill for a feature window of __three months__.\n", + "\n", + "#### Note\n", + "How to determine the window of backfill data needed? It has to match with the window of your training data. For e.g. if you want to train with two years of data, then you will want to be able to retrieve features for the same window, so you will backfill for a two year window." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "from datetime import datetime\n", "\n", - "Part 4 of the tutorial has instructions deleting the resources" - ] + "st = datetime(2023, 1, 1, 0, 0, 0, 0)\n", + "ed = datetime(2023, 4, 1, 0, 0, 0, 0)\n", + "\n", + "poller = fs_client.feature_sets.begin_backfill(\n", + " name=\"transactions\",\n", + " version=version,\n", + " feature_window_start_time=st,\n", + " feature_window_end_time=ed,\n", + ")\n", + "print(poller.result().job_id)" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": false, + "outputs_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "# get the job URL, and stream the job logs\n", + "fs_client.jobs.stream(poller.result().job_id)" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": false, + "outputs_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + }, + "tags": [ + "active-ipynb" + ] + } + }, + { + "cell_type": "markdown", + "source": [ + "Lets print sample data from the featureset. You can notice from the output information that the data was retrieved from the materilization store. `get_offline_features()` method that is used to retrieve training/inference data will also use the materialization store by default." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "# look up the featureset by providing name and version\n", + "transactions_featureset = featurestore.feature_sets.get(\"transactions\", version)\n", + "display(transactions_featureset.to_spark_dataframe().head(5))" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "jupyter": { + "source_hidden": false, + "outputs_hidden": false + }, + "nteract": { + "transient": { + "deleting": false + } + } + } }, { "attachments": {}, "cell_type": "markdown", + "source": [ + "## Cleanup\n", + "\n", + "Tutorial of \"Enable recurrent materialization and run batch inference\" has instructions deleting the resources" + ], "metadata": { "nteract": { "transient": { "deleting": false } } - }, + } + }, + { + "attachments": {}, + "cell_type": "markdown", "source": [ "## Next steps\n", - "* Part 2 of tutorial: Enable materialization and backfill feature data" - ] + "* Experiment and train models using features" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } } ], "metadata": { @@ -1026,21 +1223,18 @@ "name": "synapse_pyspark" }, "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" + "name": "synapse_pyspark", + "language": "Python", + "display_name": "Synapse PySpark" }, "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" + "version": "3.8.0", + "mimetype": "text/x-python", + "file_extension": ".py", + "pygments_lexer": "ipython", + "codemirror_mode": "ipython", + "nbconvert_exporter": "python" }, "microsoft": { "host": { @@ -1060,8 +1254,503 @@ }, "nteract": { "version": "nteract-front-end@1.0.0" + }, + "synapse_widget": { + "version": "0.1", + "state": { + "e28c2a28-1078-4071-94a5-6ceca9b5c439": { + "type": "Synapse.DataFrame", + "sync_state": { + "table": { + "rows": [ + { + "0": "B1E2828A-4A9A-43EF-BFCB-1BF8FEA572A3", + "1": "A1055520426549020", + "2": "299.0", + "3": "AUD", + "4": "21.0", + "6": "119.17", + "7": "312.55965", + "9": "A", + "10": "P", + "13": "victoria", + "14": "3000", + "15": "au", + "16": "false", + "18": "en-AU", + "19": "CREDITCARD", + "20": "VISA", + "24": "2000", + "25": "New South Wales", + "26": "AU", + "33": "M", + "35": "0.0", + "36": "2.0", + "38": "0", + "39": "java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id=\"Etc/UTC\",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=?,YEAR=2023,MONTH=5,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=3,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=11,HOUR_OF_DAY=11,MINUTE=44,SECOND=2,MILLISECOND=0,ZONE_OFFSET=?,DST_OFFSET=?]", + "index": 1 + }, + { + "0": "D57798E0-22FC-420B-9E77-6A5D29A44D2C", + "1": "A1055520427215940", + "2": "139.09", + "3": "USD", + "4": "14.0", + "6": "67.19", + "7": "139.09", + "9": "A", + "10": "P", + "13": "florida", + "14": "32204", + "15": "us", + "16": "false", + "18": "en-US", + "19": "CREDITCARD", + "20": "MC", + "24": "31411", + "25": "GA", + "26": "US", + "33": "M", + "35": "0.0", + "36": "1.0", + "38": "0", + "39": "java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id=\"Etc/UTC\",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=?,YEAR=2023,MONTH=1,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=11,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=1,HOUR=7,HOUR_OF_DAY=19,MINUTE=54,SECOND=55,MILLISECOND=0,ZONE_OFFSET=?,DST_OFFSET=?]", + "index": 2 + }, + { + "0": "E5C8E826-C06A-4C21-B2EF-654C558E3525", + "1": "A1055520427375210", + "2": "14.99", + "3": "USD", + "4": "9.0", + "6": "135.245", + "7": "14.99", + "9": "A", + "10": "P", + "13": "georgia", + "14": "30309", + "15": "us", + "16": "false", + "18": "en-US", + "19": "CREDITCARD", + "20": "VISA", + "24": "60532", + "25": "IL", + "26": "US", + "33": "M", + "35": "1.0", + "36": "0.0", + "38": "0", + "39": "java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id=\"Etc/UTC\",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=?,YEAR=2023,MONTH=1,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=27,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=1,HOUR=2,HOUR_OF_DAY=14,MINUTE=45,SECOND=5,MILLISECOND=0,ZONE_OFFSET=?,DST_OFFSET=?]", + "index": 3 + }, + { + "0": "6F951FE2-1EA9-4E52-87CF-E0395107B3DA", + "1": "A1055520427377310", + "2": "381.8", + "3": "USD", + "4": "21.0", + "6": "99.33", + "7": "381.8", + "9": "A", + "10": "P", + "13": "connecticut", + "14": "6854", + "15": "us", + "16": "false", + "18": "en-US", + "19": "CREDITCARD", + "20": "VISA", + "24": "6850", + "25": "CT", + "26": "US", + "33": "M", + "35": "1.0", + "36": "1.0", + "38": "0", + "39": "java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id=\"Etc/UTC\",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=?,YEAR=2023,MONTH=2,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=10,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=2,HOUR_OF_DAY=2,MINUTE=19,SECOND=49,MILLISECOND=0,ZONE_OFFSET=?,DST_OFFSET=?]", + "index": 4 + }, + { + "0": "936E2FF7-2171-44CC-9E43-3C4FF3B06519", + "1": "A1055520427478840", + "2": "699.47", + "3": "SEK", + "6": "217.12400000000002", + "7": "109.606949", + "9": "A", + "10": "P", + "13": "madrid", + "14": "28001", + "15": "es", + "16": "false", + "18": "sv-SE", + "19": "CREDITCARD", + "20": "VISA", + "24": "192 71", + "26": "SE", + "33": "M", + "35": "0.0", + "36": "2.0", + "38": "0", + "39": "java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id=\"Etc/UTC\",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=?,YEAR=2023,MONTH=2,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=25,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=1,HOUR=0,HOUR_OF_DAY=12,MINUTE=49,SECOND=36,MILLISECOND=0,ZONE_OFFSET=?,DST_OFFSET=?]", + "index": 5 + } + ], + "schema": [ + { + "key": "0", + "name": "transactionID", + "type": "string" + }, + { + "key": "1", + "name": "accountID", + "type": "string" + }, + { + "key": "2", + "name": "transactionAmount", + "type": "string" + }, + { + "key": "3", + "name": "transactionCurrencyCode", + "type": "string" + }, + { + "key": "4", + "name": "localHour", + "type": "string" + }, + { + "key": "5", + "name": "transactionDeviceId", + "type": "string" + }, + { + "key": "6", + "name": "transactionIPaddress", + "type": "string" + }, + { + "key": "7", + "name": "transactionAmountUSD", + "type": "string" + }, + { + "key": "8", + "name": "transactionCurrencyConversionRate", + "type": "string" + }, + { + "key": "9", + "name": "transactionScenario", + "type": "string" + }, + { + "key": "10", + "name": "transactionType", + "type": "string" + }, + { + "key": "11", + "name": "transactionMethod", + "type": "string" + }, + { + "key": "12", + "name": "transactionDeviceType", + "type": "string" + }, + { + "key": "13", + "name": "ipState", + "type": "string" + }, + { + "key": "14", + "name": "ipPostcode", + "type": "string" + }, + { + "key": "15", + "name": "ipCountryCode", + "type": "string" + }, + { + "key": "16", + "name": "isProxyIP", + "type": "string" + }, + { + "key": "17", + "name": "browserType", + "type": "string" + }, + { + "key": "18", + "name": "browserLanguage", + "type": "string" + }, + { + "key": "19", + "name": "paymentInstrumentType", + "type": "string" + }, + { + "key": "20", + "name": "cardType", + "type": "string" + }, + { + "key": "21", + "name": "cardNumberInputMethod", + "type": "string" + }, + { + "key": "22", + "name": "paymentInstrumentID", + "type": "string" + }, + { + "key": "23", + "name": "paymentBillingAddress", + "type": "string" + }, + { + "key": "24", + "name": "paymentBillingPostalCode", + "type": "string" + }, + { + "key": "25", + "name": "paymentBillingState", + "type": "string" + }, + { + "key": "26", + "name": "paymentBillingCountryCode", + "type": "string" + }, + { + "key": "27", + "name": "paymentBillingName", + "type": "string" + }, + { + "key": "28", + "name": "shippingAddress", + "type": "string" + }, + { + "key": "29", + "name": "shippingPostalCode", + "type": "string" + }, + { + "key": "30", + "name": "shippingCity", + "type": "string" + }, + { + "key": "31", + "name": "shippingState", + "type": "string" + }, + { + "key": "32", + "name": "shippingCountry", + "type": "string" + }, + { + "key": "33", + "name": "cvvVerifyResult", + "type": "string" + }, + { + "key": "34", + "name": "responseCode", + "type": "string" + }, + { + "key": "35", + "name": "digitalItemCount", + "type": "string" + }, + { + "key": "36", + "name": "physicalItemCount", + "type": "string" + }, + { + "key": "37", + "name": "purchaseProductType", + "type": "string" + }, + { + "key": "38", + "name": "is_fraud", + "type": "string" + }, + { + "key": "39", + "name": "timestamp", + "type": "string" + } + ], + "truncated": false + }, + "isSummary": false, + "language": "scala" + }, + "persist_state": { + "view": { + "type": "details", + "tableOptions": {}, + "chartOptions": { + "chartType": "bar", + "categoryFieldKeys": [ + "0" + ], + "seriesFieldKeys": [ + "2" + ], + "aggregationType": "count", + "isStacked": false + } + } + } + }, + "ec65117b-abbf-43c9-9ef9-b89d6fb644fd": { + "type": "Synapse.DataFrame", + "sync_state": { + "table": { + "rows": [ + { + "0": "A1055520426191820", + "1": "2023-01-01 19:15:53", + "2": "1", + "3": "133.28", + "4": "133.28", + "5": "1", + "6": "133.28", + "7": "133.28", + "index": 1 + }, + { + "0": "A1055520426191820", + "1": "2023-01-12 00:04:10", + "2": "1", + "3": "543.66", + "4": "543.66", + "5": "1", + "6": "543.66", + "7": "543.66", + "index": 2 + }, + { + "0": "A1055520426719380", + "1": "2023-04-17 21:42:09", + "2": "1", + "3": "217.09", + "4": "217.09", + "5": "1", + "6": "217.09", + "7": "217.09", + "index": 3 + }, + { + "0": "A1055520426806680", + "1": "2023-04-08 14:43:09", + "2": "1", + "3": "923.98", + "4": "923.98", + "5": "1", + "6": "923.98", + "7": "923.98", + "index": 4 + }, + { + "0": "A1055520426936410", + "1": "2023-03-27 03:40:54", + "2": "1", + "3": "139.99", + "4": "139.99", + "5": "1", + "6": "139.99", + "7": "139.99", + "index": 5 + } + ], + "schema": [ + { + "key": "0", + "name": "accountID", + "type": "string" + }, + { + "key": "1", + "name": "timestamp", + "type": "timestamp" + }, + { + "key": "2", + "name": "transaction_3d_count", + "type": "bigint" + }, + { + "key": "3", + "name": "transaction_amount_3d_sum", + "type": "double" + }, + { + "key": "4", + "name": "transaction_amount_3d_avg", + "type": "double" + }, + { + "key": "5", + "name": "transaction_7d_count", + "type": "bigint" + }, + { + "key": "6", + "name": "transaction_amount_7d_sum", + "type": "double" + }, + { + "key": "7", + "name": "transaction_amount_7d_avg", + "type": "double" + } + ], + "truncated": false + }, + "isSummary": false, + "language": "scala" + }, + "persist_state": { + "view": { + "type": "details", + "tableOptions": {}, + "chartOptions": { + "chartType": "bar", + "categoryFieldKeys": [ + "0" + ], + "seriesFieldKeys": [ + "3" + ], + "aggregationType": "sum", + "isStacked": false + } + } + } + } + } } }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/sdk/python/featurestore_sample/notebooks/sdk_only/2. Enable materialization and backfill feature data.ipynb b/sdk/python/featurestore_sample/notebooks/sdk_only/2. Enable materialization and backfill feature data.ipynb deleted file mode 100644 index 8e4455aee4..0000000000 --- a/sdk/python/featurestore_sample/notebooks/sdk_only/2. Enable materialization and backfill feature data.ipynb +++ /dev/null @@ -1,1102 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "# Tutorial #2: Enable materialization and backfill feature data" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "In this tutorial series you will experience how features seamlessly integrates all the phases of ML lifecycle: Prototyping features, training and operationalizing. \n", - "\n", - "In the part 1 of the tutorial you learnt how to create a feature set and use it to generate training data. When you query the featureset, the transformations will be applied on the source on-the-fly to compute the features before returning the values. This is fine for prototyping. However when you run training and inference in production environment, it is recommended that you materialize the features for higher reliability and availability. Materialization is the process of computing the feature values for a given feature window and storing this in an materialization store. All feature queries will now use the values from the materialization store.\n", - "\n", - "In this tutorial (part 2 of the series) you will:\n", - "- Enable offline store on the feature store by creating and attaching an ADLS gen2 container and a user assigned managed identity\n", - "- Enable offline materialization on the feature sets, and backfill the feature data" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Important\n", - "\n", - "This feature is currently in public preview. This preview version is provided without a service-level agreement, and it's not recommended for production workloads. Certain features might not be supported or might have constrained capabilities. For more information, see [Supplemental Terms of Use for Microsoft Azure Previews](https://azure.microsoft.com/support/legal/preview-supplemental-terms/)." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "# Prerequsite\n", - "1. Please ensure you have executed part 1 of the tutorial\n", - "1. An Azure Resource group, in which you (or the service principal you use) need to have `User Access Administrator` role and `Contributor` role." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "# Setup\n", - "Summary of setup steps you will execute:\n", - "- In your project workspace, create Azure ML compute to run training pipeline\n", - "- In your feature store workspace, create a offline materialization store: create a Azure gen2 storage account and a container in it and attach to feature store. Optionally you can use existing storage container.\n", - "- Create and assign user-assigned managed identity to feature store. Optionally you can use existing one. This will be used by the system managed materialization jobs i.e. recurrent job that will be used in part 3 of the tutorial\n", - "- Grant required RBAC permissions to the user-assigned managed identity\n", - "- Grant required RBAC to your AAD identity. Users (like you) need to have read access to (a) sources (b) materialization store" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Configure Azure ML spark notebook\n", - "\n", - "1. In the \"Compute\" dropdown in the top nav, select \"Serverless Spark Compute\". \n", - "1. Click on \"configure session\" in top status bar -> click on \"Python packages\" -> click on \"upload conda file\" -> select the file azureml-examples/sdk/python/featurestore-sample/project/env/conda.yml from your local machine; Also increase the session time out (idle time) if you want to avoid running the prerequisites frequently\n", - "\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683422232605 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "start-spark-session", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "print(\"started spark session\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Setup root directory for the samples" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683422281498 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "root-dir", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "import os\n", - "\n", - "# please update the dir to ./Users/{your-alias} (or any custom directory you uploaded the samples to).\n", - "# You can find the name from the directory structure inm the left nav\n", - "root_dir = \"./Users//featurestore_sample\"\n", - "\n", - "if os.path.isdir(root_dir):\n", - " print(\"The folder exists.\")\n", - "else:\n", - " print(\"The folder does not exist. Please create or fix the path\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Initialize the project workspace CRUD client\n", - "This is the current workspace where you will be running the tutorial notebook from" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683422293418 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "init-ws-crud-client", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "### Initialize the MLClient of this project workspace\n", - "import os\n", - "from azure.ai.ml import MLClient\n", - "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", - "\n", - "project_ws_sub_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", - "project_ws_rg = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", - "project_ws_name = os.environ[\"AZUREML_ARM_WORKSPACE_NAME\"]\n", - "version = \"\"\n", - "# connect to the project workspace\n", - "ws_client = MLClient(\n", - " AzureMLOnBehalfOfCredential(), project_ws_sub_id, project_ws_rg, project_ws_name\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Initialize the feature store CRUD client\n", - "Ensure you update the `featurestore_name` to reflect what you created in part 1 of this tutorial" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683422298466 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "init-fs-crud-client", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.ai.ml import MLClient\n", - "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", - "\n", - "# feature store\n", - "featurestore_name = \"my-featurestore\" # use the same name from part #1 of the tutorial\n", - "featurestore_subscription_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", - "featurestore_resource_group_name = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", - "\n", - "# feature store ml client\n", - "fs_client = MLClient(\n", - " AzureMLOnBehalfOfCredential(),\n", - " featurestore_subscription_id,\n", - " featurestore_resource_group_name,\n", - " featurestore_name,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Initialize the feature store core sdk client" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683422304506 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "init-fs-core-sdk", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# feature store client\n", - "from azureml.featurestore import FeatureStoreClient\n", - "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", - "\n", - "featurestore = FeatureStoreClient(\n", - " credential=AzureMLOnBehalfOfCredential(),\n", - " subscription_id=featurestore_subscription_id,\n", - " resource_group_name=featurestore_resource_group_name,\n", - " name=featurestore_name,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Setup offline materialization store\n", - "You can create a new gen2 storage account and a container, or reuse existing one to be used as the offline materilization store for the feature store" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "##### Setup utility functions\n", - "Note: The below code sets up utility functions to create storage and user assigned identity. These utility functions use standard azure SDKs. These are provided to keep the tutorial concise. However do not use this for production purposes as it might not implement best practices." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683422311529 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "setup-utility-fns", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "import sys\n", - "\n", - "sys.path.insert(0, root_dir + \"/featurestore/setup\")\n", - "from setup_storage_uai import (\n", - " create_gen2_storage_container,\n", - " create_user_assigned_managed_identity,\n", - " grant_rbac_permissions,\n", - " grant_user_aad_storage_data_reader_role,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "##### Set values for the adls gen 2 storage that will be used as materialization store\n", - "You can optionally override the default settings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683422350826 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "set-offline-store-params", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", - "\n", - "## Default Setting\n", - "# We use the subscription, resource group, region of this active project workspace,\n", - "# We hard-coded resource names for creating new resources\n", - "\n", - "## Overwrite\n", - "# You can replace them if you want to create the resources in a different subsciprtion/resourceGroup, or use existing resources\n", - "\n", - "ws_location = ws_client.workspaces.get(ws_client.workspace_name).location\n", - "\n", - "# storage\n", - "storage_subscription_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", - "storage_resource_group_name = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", - "storage_account_name = \"\"\n", - "storage_location = ws_location\n", - "storage_file_system_name = \"offlinestore\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "##### Storage container (option 1): create new storage container" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683418495136 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "create-new-storage", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "gen2_container_arm_id = create_gen2_storage_container(\n", - " AzureMLOnBehalfOfCredential(),\n", - " storage_subscription_id=storage_subscription_id,\n", - " storage_resource_group_name=storage_resource_group_name,\n", - " storage_account_name=storage_account_name,\n", - " storage_location=storage_location,\n", - " storage_file_system_name=storage_file_system_name,\n", - ")\n", - "\n", - "print(gen2_container_arm_id)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "##### Storage container (option 2): If you have an existing storage container that you want to reuse" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683421319637 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "use-existing-storage", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "gen2_container_arm_id = \"/subscriptions/{sub_id}/resourceGroups/{rg}/providers/Microsoft.Storage/storageAccounts/{account}/blobServices/default/containers/{container}\".format(\n", - " sub_id=storage_subscription_id,\n", - " rg=storage_resource_group_name,\n", - " account=storage_account_name,\n", - " container=storage_file_system_name,\n", - ")\n", - "\n", - "print(gen2_container_arm_id)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "### Setup user assigned managed identity (UAI)\n", - "This will be used by the system managed materialization jobs i.e. recurrent job that will be used in part 3 of the tutorial" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "##### Set values for UAI" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683421358493 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "set-uai-params", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# User assigned managed identity values. Optionally you may change the values.\n", - "uai_subscription_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", - "uai_resource_group_name = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", - "uai_name = \"\"\n", - "uai_location = ws_location" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "##### User-assigned managed identity (option 1): create new one" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683418554848 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "create-new-uai", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "uai_principal_id, uai_client_id, uai_arm_id = create_user_assigned_managed_identity(\n", - " AzureMLOnBehalfOfCredential(),\n", - " uai_subscription_id=uai_subscription_id,\n", - " uai_resource_group_name=uai_resource_group_name,\n", - " uai_name=uai_name,\n", - " uai_location=uai_location,\n", - ")\n", - "\n", - "print(\"uai_principal_id:\" + uai_principal_id)\n", - "print(\"uai_client_id:\" + uai_client_id)\n", - "print(\"uai_arm_id:\" + uai_arm_id)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "##### User-assigned managed identity (option 2): If you have an existing one that you want to reuse" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683421366072 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "use-existing-uai", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.mgmt.msi import ManagedServiceIdentityClient\n", - "\n", - "msi_client = ManagedServiceIdentityClient(\n", - " AzureMLOnBehalfOfCredential(), uai_subscription_id\n", - ")\n", - "\n", - "managed_identity = msi_client.user_assigned_identities.get(\n", - " uai_resource_group_name, uai_name\n", - ")\n", - "\n", - "uai_principal_id = managed_identity.principal_id\n", - "uai_client_id = managed_identity.client_id\n", - "uai_arm_id = managed_identity.id\n", - "\n", - "print(\"uai_principal_id:\" + uai_principal_id)\n", - "print(\"uai_client_id:\" + uai_client_id)\n", - "print(\"uai_arm_id:\" + uai_arm_id)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "##### Grant RBAC permission to the user assigned managed identity (UAI)\n", - "\n", - "This UAI will be assigned to the feature store shortly. It requires the following permissions:\n", - "\n", - "|Scope|\tAction/Role|\n", - "|--|--|\n", - "|Feature store\t|AzureML Data Scientist role|\n", - "|Storage account of feature store offline store\t|Blob storage data contributor role|\n", - "|Storage accounts of source data\t|Blob storage data reader role|\n", - "\n", - "The below code utility function will assign the first two roles to the UAI. In this example \"Storage accounts of source data\" is not applicable since we are reading the sample data from a public access blob storage. If you have your own data sources then you want to assign the required roles to the UAI. To learn more about access control, see access control document in the docs" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683418605920 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "grant-rbac-to-uai", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# This utility function is created for ease of use in the docs tutorials. It uses standard azure API's. You can optionally inspect it `featurestore/setup/setup_storage_uai.py`\n", - "grant_rbac_permissions(\n", - " AzureMLOnBehalfOfCredential(),\n", - " uai_principal_id,\n", - " storage_subscription_id=storage_subscription_id,\n", - " storage_resource_group_name=storage_resource_group_name,\n", - " storage_account_name=storage_account_name,\n", - " featurestore_subscription_id=featurestore_subscription_id,\n", - " featurestore_resource_group_name=featurestore_resource_group_name,\n", - " featurestore_name=featurestore_name,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Grant your user account \"Blob data reader\" role on the offline store\n", - "If feature data is materialized, then you need this role to read feature data from offline materialization store.\n", - "\n", - "Get your AAD object id from Azure portal following this instruction: https://learn.microsoft.com/en-us/partner-center/find-ids-and-domain-names#find-the-user-object-id\n", - "\n", - "To learn more about access control, see access control document in the docs." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683126235070 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "grant-rbac-to-user-identity", - "nteract": { - "transient": { - "deleting": false - } - }, - "tags": [ - "active-ipynb" - ] - }, - "outputs": [], - "source": [ - "# This utility function is created for ease of use in the docs tutorials. It uses standard azure API's. You can optionally inspect it `featurestore/setup/setup_storage_uai.py`\n", - "your_aad_objectid = \"\"\n", - "\n", - "grant_user_aad_storage_data_reader_role(\n", - " AzureMLOnBehalfOfCredential(),\n", - " your_aad_objectid,\n", - " storage_subscription_id,\n", - " storage_resource_group_name,\n", - " storage_account_name,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Step 1: Enable offline store on the feature store by attaching offline materialization store and UAI" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683421376728 - }, - "jupyter": { - "outputs_hidden": true, - "source_hidden": false - }, - "name": "enable-offline-store", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.ai.ml.entities import (\n", - " ManagedIdentityConfiguration,\n", - " FeatureStore,\n", - " MaterializationStore,\n", - ")\n", - "\n", - "offline_store = MaterializationStore(\n", - " type=\"azure_data_lake_gen2\",\n", - " target=gen2_container_arm_id,\n", - ")\n", - "\n", - "materialization_identity1 = ManagedIdentityConfiguration(\n", - " client_id=uai_client_id, principal_id=uai_principal_id, resource_id=uai_arm_id\n", - ")\n", - "\n", - "fs = FeatureStore(\n", - " name=featurestore_name,\n", - " offline_store=offline_store,\n", - " materialization_identity=materialization_identity1,\n", - ")\n", - "\n", - "fs_poller = fs_client.feature_stores.begin_update(fs, update_dependent_resources=True)\n", - "\n", - "print(fs_poller.result())" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Step 2: Enable offline materialization on transactions featureset\n", - "Once materialization is enabled on a featureset, you can perform backfill (this tutorial) or schedule recurrent materialization jobs(next part of the tutorial)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683422398454 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "enable-offline-mat-txns-fset", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.ai.ml.entities import (\n", - " MaterializationSettings,\n", - " MaterializationComputeResource,\n", - ")\n", - "\n", - "transactions_fset_config = fs_client._featuresets.get(\n", - " name=\"transactions\", version=version\n", - ")\n", - "\n", - "transactions_fset_config.materialization_settings = MaterializationSettings(\n", - " offline_enabled=True,\n", - " resource=MaterializationComputeResource(instance_type=\"standard_e8s_v3\"),\n", - " spark_configuration={\n", - " \"spark.driver.cores\": 4,\n", - " \"spark.driver.memory\": \"36g\",\n", - " \"spark.executor.cores\": 4,\n", - " \"spark.executor.memory\": \"36g\",\n", - " \"spark.executor.instances\": 2,\n", - " },\n", - " schedule=None,\n", - ")\n", - "\n", - "fs_poller = fs_client.feature_sets.begin_create_or_update(transactions_fset_config)\n", - "print(fs_poller.result())" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "Optionally, you can save the the above feature set asset as yaml" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683422407359 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "dump-txn-fset-yaml", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "## uncomment to run\n", - "# transactions_fset_config.dump(root_dir + \"/featurestore/featuresets/transactions/featureset_asset_offline_enabled.yaml\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Step 3: Backfill data for transactions featureset\n", - "As explained in the beginning of this tutorial, materialization is the process of computing the feature values for a given feature window and storing this in an materialization store. Materializing the features will increase its reliability and availability. All feature queries will now use the values from the materialization store. In this step you perform a one-time backfill for a feature window of __three months__.\n", - "\n", - "#### Note\n", - "How to determine the window of backfill data needed? It has to match with the window of your training data. For e.g. if you want to train with two years of data, then you will want to be able to retrieve features for the same window, so you will backfill for a two year window." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683422440549 - }, - "jupyter": { - "outputs_hidden": true, - "source_hidden": false - }, - "name": "backfill-txns-fset", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from datetime import datetime\n", - "\n", - "st = datetime(2023, 1, 1, 0, 0, 0, 0)\n", - "ed = datetime(2023, 4, 1, 0, 0, 0, 0)\n", - "\n", - "poller = fs_client.feature_sets.begin_backfill(\n", - " name=\"transactions\",\n", - " version=version,\n", - " feature_window_start_time=st,\n", - " feature_window_end_time=ed,\n", - ")\n", - "print(poller.result().job_id)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "active-ipynb" - ] - }, - "outputs": [], - "source": [ - "# get the job URL, and stream the job logs\n", - "fs_client.jobs.stream(poller.result().job_id)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "Lets print sample data from the featureset. You can notice from the output information that the data was retrieved from the materilization store. `get_offline_features()` method that is used to retrieve training/inference data will also use the materialization store by default ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683422850258 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "sample-txns-fset-data", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# look up the featureset by providing name and version\n", - "transactions_featureset = featurestore.feature_sets.get(\"transactions\", version)\n", - "display(transactions_featureset.to_spark_dataframe().head(5))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Cleanup\n", - "Part 4 of the tutorial has instructions for deleting the resources" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Next steps\n", - "* Part 3 of tutorial: Experiment and train models using features" - ] - } - ], - "metadata": { - "celltoolbar": "Edit Metadata", - "kernel_info": { - "name": "synapse_pyspark" - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - }, - "microsoft": { - "host": { - "AzureML": { - "notebookHasBeenCompleted": true - } - }, - "ms_spell_check": { - "ms_spell_check_language": "en" - } - }, - "nteract": { - "version": "nteract-front-end@1.0.0" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/sdk/python/featurestore_sample/notebooks/sdk_only/2. Experiment and train models using features.ipynb b/sdk/python/featurestore_sample/notebooks/sdk_only/2. Experiment and train models using features.ipynb new file mode 100644 index 0000000000..2409f132b3 --- /dev/null +++ b/sdk/python/featurestore_sample/notebooks/sdk_only/2. Experiment and train models using features.ipynb @@ -0,0 +1,17010 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "# Tutorial: Experiment and train models using features" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "In this tutorial series you will experience how features seamlessly integrates all the phases of ML lifecycle: Prototyping features, training and operationalizing.\n", + "\n", + "In part 1 of the tutorial you learnt how to create a feature set spec with custom transformations. In part 2 of the tutorial you learnt how to enable materialization and perform backfill. In this tutorial you will will learn how to experiment with features to improve model performance. You will see how feature store increasing agility in the experimentation and training flows. \n", + "\n", + "You will perform the following:\n", + "- Prototype a create new `acccounts` feature set spec using existing precomputed values as features, unlike part 1 of the tutorial where we created feature set that had custom transformations. You will then Register the local feature set spec as a feature set in the feature store\n", + "- Select features for the model: You will select features from the `transactions` and `accounts` feature sets and save them as a feature-retrieval spec\n", + "- Run training pipeline that uses the Feature retrieval spec to train a new model. This pipeline will use the built in feature-retrieval component to generate the training data" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Important\n", + "\n", + "This feature is currently in public preview. This preview version is provided without a service-level agreement, and it's not recommended for production workloads. Certain features might not be supported or might have constrained capabilities. For more information, see [Supplemental Terms of Use for Microsoft Azure Previews](https://azure.microsoft.com/support/legal/preview-supplemental-terms/)." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "# Prerequisites\n", + "1. Please ensure you have executed part 1 and 2 of the tutorial" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "# Setup" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Configure Azure ML spark notebook\n", + "\n", + "1. In the \"Compute\" dropdown in the top nav, select \"Serverless Spark Compute\". \n", + "1. Click on \"configure session\" in top status bar -> click on \"Python packages\" -> click on \"upload conda file\" -> select the file azureml-examples/sdk/python/featurestore-sample/project/env/conda.yml from your local machine; Also increase the session time out (idle time) if you want to avoid running the prerequisites frequently\n", + "\n", + "\n" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Start spark session" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "# run this cell to start the spark session (any code block will start the session ). This can take around 10 mins.\n", + "print(\"start spark session\")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550147448 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "start-spark-session", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Setup root directory for the samples" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "import os\n", + "\n", + "# please update the dir to ./Users/ (or any custom directory you uploaded the samples to).\n", + "# You can find the name from the directory structure in the left nav\n", + "root_dir = \"./Users//featurestore_sample\"\n", + "\n", + "if os.path.isdir(root_dir):\n", + " print(\"The folder exists.\")\n", + "else:\n", + " print(\"The folder does not exist. Please create or fix the path\")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550160587 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "root-dir", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Initialize the project workspace CRUD client\n", + "This is the current workspace where you will be running the tutorial notebook from" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "### Initialize the MLClient of this project workspace\n", + "import os\n", + "from azure.ai.ml import MLClient\n", + "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", + "\n", + "project_ws_sub_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", + "project_ws_rg = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", + "project_ws_name = os.environ[\"AZUREML_ARM_WORKSPACE_NAME\"]\n", + "version = \"\"\n", + "\n", + "# connect to the project workspace\n", + "ws_client = MLClient(\n", + " AzureMLOnBehalfOfCredential(), project_ws_sub_id, project_ws_rg, project_ws_name\n", + ")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550177764 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "init-ws-crud-client", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Initialize the feature store CRUD client\n", + "Ensure you update the `featurestore_name` to reflect what you created in part 1 of this tutorial" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "from azure.ai.ml import MLClient\n", + "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", + "\n", + "# feature store\n", + "featurestore_name = \"my-featurestore\" # use the same name from part #1 of the tutorial\n", + "featurestore_subscription_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", + "featurestore_resource_group_name = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", + "\n", + "# feature store ml client\n", + "fs_client = MLClient(\n", + " AzureMLOnBehalfOfCredential(),\n", + " featurestore_subscription_id,\n", + " featurestore_resource_group_name,\n", + " featurestore_name,\n", + ")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550201549 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "init-fs-crud-client", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Initialize the feature store core sdk client" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "# feature store client\n", + "from azureml.featurestore import FeatureStoreClient\n", + "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", + "\n", + "featurestore = FeatureStoreClient(\n", + " credential=AzureMLOnBehalfOfCredential(),\n", + " subscription_id=featurestore_subscription_id,\n", + " resource_group_name=featurestore_resource_group_name,\n", + " name=featurestore_name,\n", + ")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550214535 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "init-fs-core-sdk", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Create compute cluster with name `cpu-cluster` in the project workspace\n", + "This will be needed when we run training/batch inference jobs" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "from azure.ai.ml.entities import AmlCompute\n", + "\n", + "cluster_basic = AmlCompute(\n", + " name=\"cpu-cluster\",\n", + " type=\"amlcompute\",\n", + " size=\"STANDARD_F4S_V2\", # you can replace it with other supported VM SKUs\n", + " location=ws_client.workspaces.get(ws_client.workspace_name).location,\n", + " min_instances=0,\n", + " max_instances=1,\n", + " idle_time_before_scale_down=360,\n", + ")\n", + "ws_client.begin_create_or_update(cluster_basic).result()" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550257007 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "create-compute-cluster", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "## Step 1: Create accounts featureset locally from precomputed data\n", + "In tutorial part 1, we created a transactions featureset that had custom transformations. Now we will create an accounts featureset that will use precomputed values. \n", + "\n", + "For onboarding precomputed features, you can create a featureset spec without writing any transformation code. Featureset spec is a specification to develop and test a featureset in a fully local/dev environment without connecting to any featurestore. In this step you will create the feature set spec locally and sample the values from it. If you want to get managed featurestore capabilities, you need to register the featureset spec with a feature store using a feature asset definition (a future step in this tutorial)." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Step 1a: Explore the source data for accounts\n", + "\n", + "##### Note\n", + " Note that the sample data used in this notebook is hosted in a public accessible blob container. It can only be read in Spark via `wasbs` driver. When you create feature sets using your own source data, please host them in adls gen2 account and use `abfss` driver in the data path. " + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "accounts_data_path = \"wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/datasources/accounts-precalculated/*.parquet\"\n", + "accounts_df = spark.read.parquet(accounts_data_path)\n", + "\n", + "display(accounts_df.head(5))" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550281756 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "explore-accts-fset-src-data", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Step 1b: Create `accounts` feature set spec in local from these precomputed features\n", + "Note that we do not need any transformation code here since we are referencing precomputed features." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "from azureml.featurestore import create_feature_set_spec, FeatureSetSpec\n", + "from azureml.featurestore.contracts import (\n", + " DateTimeOffset,\n", + " FeatureSource,\n", + " TransformationCode,\n", + " Column,\n", + " ColumnType,\n", + " SourceType,\n", + " TimestampColumn,\n", + ")\n", + "\n", + "\n", + "accounts_featureset_spec = create_feature_set_spec(\n", + " source=FeatureSource(\n", + " type=SourceType.parquet,\n", + " path=\"wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/datasources/accounts-precalculated/*.parquet\",\n", + " timestamp_column=TimestampColumn(name=\"timestamp\"),\n", + " ),\n", + " index_columns=[Column(name=\"accountID\", type=ColumnType.string)],\n", + " # account profiles in the source are updated once a year. set temporal_join_lookback to 365 days\n", + " temporal_join_lookback=DateTimeOffset(days=365, hours=0, minutes=0),\n", + " infer_schema=True,\n", + ")\n", + "# Generate a spark dataframe from the feature set specification\n", + "accounts_fset_df = accounts_featureset_spec.to_spark_dataframe()\n", + "# display few records\n", + "display(accounts_fset_df.head(5))" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550310950 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "create-accts-fset-spec", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Step 1c: Export as feature set spec\n", + "In order to register the feature set spec with the feature store, it needs to be saved in a specific format. \n", + "Action: After running the below cell, please inspect the generated `accounts` FeatureSetSpec: Open this file from the file tree to see the spec: `featurestore/featuresets/accounts/spec/FeatureSetSpec.yaml`\n", + "\n", + "Spec contains these important elements:\n", + "\n", + "1. `source`: reference to a storage. In this case a parquet file in a blob storage.\n", + "1. `features`: list of features and their datatypes. If you provide transformation code (see Day 2 section), the code has to return a dataframe that maps to the features and datatypes. In case where you do not provide transformation code (in this case of `accounts` because it is precomputed), the system will build the query to to map these to the source \n", + "1. `index_columns`: the join keys required to access values from the feature set\n", + "\n", + "Learn more about it in the [top level feature store entities document](fs-concepts-todo) and the [feature set spec yaml reference](reference-yaml-featureset-spec.md).\n", + "\n", + "The additional benefit of persisting it is that it can be source controlled." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "import os\n", + "\n", + "# create a new folder to dump the feature set spec\n", + "accounts_featureset_spec_folder = root_dir + \"/featurestore/featuresets/accounts/spec\"\n", + "\n", + "# check if the folder exists, create one if not\n", + "if not os.path.exists(accounts_featureset_spec_folder):\n", + " os.makedirs(accounts_featureset_spec_folder)\n", + "\n", + "accounts_featureset_spec.dump(accounts_featureset_spec_folder, overwrite=True)" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550317763 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "dump-accts-fset-spec", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "## Step 2: Experiment with unregistered features locally and register with feature store when ready\n", + "When you are developing features, you might want to test/validate locally before registering with the feature store or running training pipelines in the cloud. In this step you will generate training data for the ML model from combination of features from a local unregistered feature set (`accounts`) and feature set registered in the feature store (`transactions`)." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Step 2a: Select features for model" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "# get the registered transactions feature set, version 1\n", + "transactions_featureset = featurestore.feature_sets.get(\"transactions\", version)\n", + "# Notice that account feature set spec is in your local dev environment (this notebook): not registered with feature store yet\n", + "features = [\n", + " accounts_featureset_spec.get_feature(\"accountAge\"),\n", + " accounts_featureset_spec.get_feature(\"numPaymentRejects1dPerUser\"),\n", + " transactions_featureset.get_feature(\"transaction_amount_7d_sum\"),\n", + " transactions_featureset.get_feature(\"transaction_amount_3d_sum\"),\n", + " transactions_featureset.get_feature(\"transaction_amount_7d_avg\"),\n", + "]" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550328371 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "select-unreg-features-for-model", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Step 2b: Generate training data locally\n", + "In this step we generate training data for illustrative purpose. You can optionally train models locally with this. In the upcoming steps in this tutorial, you will train a model in the cloud." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "from azureml.featurestore import get_offline_features\n", + "\n", + "# Load the observation data. To understand observatio ndata, refer to part 1 of this tutorial\n", + "observation_data_path = \"wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/observation_data/train/*.parquet\"\n", + "observation_data_df = spark.read.parquet(observation_data_path)\n", + "obs_data_timestamp_column = \"timestamp\"\n", + "\n", + "# generate training dataframe by using feature data and observation data\n", + "training_df = get_offline_features(\n", + " features=features,\n", + " observation_data=observation_data_df,\n", + " timestamp_column=obs_data_timestamp_column,\n", + ")\n", + "\n", + "# Ignore the message that says feature set is not materialized (materialization is optional). We will enable materialization in the next part of the tutorial.\n", + "display(training_df)\n", + "# Note: display(training_df.head(5)) displays the timestamp column in a different format. You can can call training_df.show() to see correctly formatted value" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550539714 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "gen-training-data-locally", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Step 2c: Register the `accounts` featureset with the featurestore\n", + "Once you have experimented with different feature definitions locally and sanity tested it, you can register it with the feature store.\n", + "For this you will register a featureset asset definition with the feature store.\n" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "from azure.ai.ml.entities import FeatureSet, FeatureSetSpecification\n", + "\n", + "accounts_fset_config = FeatureSet(\n", + " name=\"accounts\",\n", + " version=version,\n", + " description=\"accounts featureset\",\n", + " entities=[f\"azureml:account:{version}\"],\n", + " stage=\"Development\",\n", + " specification=FeatureSetSpecification(path=accounts_featureset_spec_folder),\n", + " tags={\"data_type\": \"nonPII\"},\n", + ")\n", + "\n", + "poller = fs_client.feature_sets.begin_create_or_update(accounts_fset_config)\n", + "print(poller.result())" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550813095 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "reg-accts-fset", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Step 2d: Get registered featureset and sanity test" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "# look up the featureset by providing name and version\n", + "accounts_featureset = featurestore.feature_sets.get(\"accounts\", version)\n", + "# get access to the feature data\n", + "accounts_feature_df = accounts_featureset.to_spark_dataframe()\n", + "display(accounts_feature_df.head(5))\n", + "# Note: Please ignore this warning: Failure while loading azureml_run_type_providers. Failed to load entrypoint azureml.scriptrun" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550826621 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "sample-accts-fset-data", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "## Step 3: Run training experiment\n", + "In this step you will select a list of features, run a training pipeline, and register the model. You can repeat this step till you are happy with the model performance." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### (Optional) Step 3a: Discover features from Feature Store UI\n", + "You have already done this in part 1 of the tutorial after registering the `transactions` feature set. Since you also have `accounts` featureset, you can browse the available features:\n", + "* Goto the [Azure ML global landing page](https://ml.azure.com/home?flight=FeatureStores).\n", + "* Click on `Feature stores` in the left nav\n", + "* You will see the list of feature stores that you have access to. Click on the feature store that you created above.\n", + "\n", + "You can see the feature sets and entity that you created. Click on the feature sets to browse the feature definitions. You can also search for feature sets across feature stores by using the global search box." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### (Optional) Step 3b: Discover features from SDK" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "# List available feature sets\n", + "all_featuresets = featurestore.feature_sets.list()\n", + "for fs in all_featuresets:\n", + " print(fs)\n", + "\n", + "# List of versions for transactions feature set\n", + "all_transactions_featureset_versions = featurestore.feature_sets.list(\n", + " name=\"transactions\"\n", + ")\n", + "for fs in all_transactions_featureset_versions:\n", + " print(fs)\n", + "\n", + "# See properties of the transactions featureset including list of features\n", + "featurestore.feature_sets.get(name=\"transactions\", version=version).features" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550851764 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "discover-features-from-sdk", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Step 3c: Select features for the model and export it as a feature-retrieval spec\n", + "In the previous steps, you selected features from a combination unregistered and registered feature sets for local experimentation and testing. Now you are ready to experiment in the cloud. Saving the selected features as a feature-retrieval spec and using it in the mlops/cicd flow for training/inference increases your agility in shipping models." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "Select features for the model" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "# you can select features in pythonic way\n", + "features = [\n", + " accounts_featureset.get_feature(\"accountAge\"),\n", + " transactions_featureset.get_feature(\"transaction_amount_7d_sum\"),\n", + " transactions_featureset.get_feature(\"transaction_amount_3d_sum\"),\n", + "]\n", + "\n", + "# you can also specify features in string form: featurestore:featureset:version:feature\n", + "more_features = [\n", + " f\"accounts:{version}:numPaymentRejects1dPerUser\",\n", + " f\"transactions:{version}:transaction_amount_7d_avg\",\n", + "]\n", + "\n", + "more_features = featurestore.resolve_feature_uri(more_features)\n", + "\n", + "features.extend(more_features)" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550863111 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "select-reg-features", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "Export selected features as a feature-retrieval spec\n", + "\n", + "#### Note\n", + "Feature retrieval spec is a portable definition of list of features associated with a model. This can help streamline ML model development and operationalizing.This will be an input to the training pipeline (used to generate the training data), then will be packaged along with the model, and will be used during inference to lookup the features. It will be a glue that integrates all phases of the ML lifecycle. Changes to training/inference pipeline can be kept minimal as you experiment and deploy. \n", + "\n", + "Using feature retrieval spec and the built-in feature retrieval component is optional: you can directly use `get_offline_features()` api as shown above.\n", + "\n", + "Note that the name of the spec should be `feature_retrieval_spec.yaml` when it is packaged with the model for the system to recognize it." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "# Create feature retrieval spec\n", + "feature_retrieval_spec_folder = root_dir + \"/project/fraud_model/feature_retrieval_spec\"\n", + "\n", + "# check if the folder exists, create one if not\n", + "if not os.path.exists(feature_retrieval_spec_folder):\n", + " os.makedirs(feature_retrieval_spec_folder)\n", + "\n", + "featurestore.generate_feature_retrieval_spec(feature_retrieval_spec_folder, features)" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696550891771 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "export-as-frspec", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "## Step 4: Train in the cloud using pipelines and register model if satisfactory\n", + "In this step you will manually trigger the training pipeline. In a production scenario, this could be triggered by a ci/cd pipeline based on changes to the feature-retrieval spec in the source repository." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Step 4a: Run the training pipeline\n", + "The training pipeline has the following steps:\n", + "\n", + "1. Feature retrieval step: This is a built-in component takes as input the feature retrieval spec, the observation data and timestamp column name. It then generates the training data as output. It runs this as a managed spark job.\n", + "1. Training step: This step trains the model based on the training data and generates a model (not registered yet)\n", + "1. Evaluation step: This step validates whether model performance/quailty is within threshold (in our case it is a placeholder/dummy step for illustration purpose)\n", + "1. Register model step: This step registers the model\n", + "\n", + "Note: In part 2 of this tutorial you ran a backfill job to materialize data for `transactions` feature set. Feature retrieval step will read feature values from offline store for this feature set. The behavior will same even if you use `get_offline_features()` api." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "from azure.ai.ml import load_job # will be used later\n", + "\n", + "training_pipeline_path = (\n", + " root_dir + \"/project/fraud_model/pipelines/training_pipeline.yaml\"\n", + ")\n", + "training_pipeline_definition = load_job(source=training_pipeline_path)\n", + "training_pipeline_job = ws_client.jobs.create_or_update(training_pipeline_definition)\n", + "ws_client.jobs.stream(training_pipeline_job.name)\n", + "# Note: First time it runs, each step in pipeline can take ~ 15 mins. However subsequent runs can be faster (assuming spark pool is warm - default timeout is 30 mins)" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1683429020656 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "run-training-pipeline", + "nteract": { + "transient": { + "deleting": false + } + }, + "tags": [ + "active-ipynb" + ] + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Inspect the training pipeline and the model\n", + "Open the above pipeline run \"web view\" in new window to see the steps in the pipeline.\n" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Step 4b: Notice the feature retrieval spec in the model artifacts\n", + "1. In the left nav of the current workspace -> right click on `Models` -> Open in new tab or window\n", + "1. Click on `fraud_model`\n", + "1. Click on `Artifacts` in the top nav\n", + "\n", + "You can notice that the feature retrieval spec is packaged along with the model. The model registration step in the training pipeline has done this. You created feature retrieval spec during experimentation, now it has become part of the model definition. In the next tutorial you will see how this will be used during inferencing.\n" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "## Step 5: View the feature set and model dependencies" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Step 5a: View the list of feature sets associated with the model\n", + "In the same models page, click on the `feature sets` tab. Here you can see both `transactions` and `accounts` featuresets that this model depends on." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Step 5b: View the list of models using the feature sets\n", + "1. Open the feature store UI (expalined in a previous step in this tutorial)\n", + "1. Click on `Feature sets` on the left nav\n", + "1. Click on any of the feature set -> click on `Models` tab\n", + "\n", + "You can see the list of models that are using the feature sets (determined from the feature retrieval spec when the model was registered)." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "## Cleanup\n", + "\n", + "Tutorial of \"Enable recurrent materialization and run batch inference\" has instructions deleting the resources" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "## Next steps\n", + "* Enable recurrent materialization and run batch inference" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + } + ], + "metadata": { + "celltoolbar": "Edit Metadata", + "kernel_info": { + "name": "synapse_pyspark" + }, + "kernelspec": { + "name": "synapse_pyspark", + "language": "Python", + "display_name": "Synapse PySpark" + }, + "language_info": { + "name": "python", + "version": "3.8.0", + "mimetype": "text/x-python", + "file_extension": ".py", + "pygments_lexer": "ipython", + "codemirror_mode": "ipython", + "nbconvert_exporter": "python" + }, + "microsoft": { + "host": { + "AzureML": { + "notebookHasBeenCompleted": true + } + }, + "ms_spell_check": { + "ms_spell_check_language": "en" + } + }, + "nteract": { + "version": "nteract-front-end@1.0.0" + }, + "synapse_widget": { + "version": "0.1", + "state": { + "1f11d9a6-6ce2-4ae1-bebf-2f25c69bb6d4": { + "type": "Synapse.DataFrame", + "sync_state": { + "table": { + "rows": [ + { + "0": "A1055520426185580", + "1": "GB", + "2": "true", + "3": "0.0", + "4": "2000.0", + "5": "2021-12-31 00:00:00", + "index": 1 + }, + { + "0": "A1055520426191820", + "1": "US", + "2": "true", + "3": "0.0", + "4": "1.0", + "5": "2021-12-31 00:00:00", + "index": 2 + }, + { + "0": "A1055520426549020", + "1": "AU", + "2": "true", + "3": "0.0", + "4": "1.0", + "5": "2021-12-31 00:00:00", + "index": 3 + }, + { + "0": "A1055520426719380", + "1": "US", + "2": "true", + "3": "0.0", + "4": "2000.0", + "5": "2021-12-31 00:00:00", + "index": 4 + }, + { + "0": "A1055520426806680", + "1": "GB", + "2": "true", + "3": "1.0", + "4": "2000.0", + "5": "2021-12-31 00:00:00", + "index": 5 + } + ], + "schema": [ + { + "key": "0", + "name": "accountID", + "type": "string" + }, + { + "key": "1", + "name": "accountCountry", + "type": "string" + }, + { + "key": "2", + "name": "isUserRegistered", + "type": "boolean" + }, + { + "key": "3", + "name": "numPaymentRejects1dPerUser", + "type": "double" + }, + { + "key": "4", + "name": "accountAge", + "type": "double" + }, + { + "key": "5", + "name": "timestamp", + "type": "string" + } + ], + "truncated": false + }, + "isSummary": false, + "language": "scala" + }, + "persist_state": { + "view": { + "type": "details", + "tableOptions": {}, + "chartOptions": { + "chartType": "bar", + "categoryFieldKeys": [ + "0" + ], + "seriesFieldKeys": [ + "4" + ], + "aggregationType": "sum", + "isStacked": false + } + } + } + }, + "2a1ce29e-e5c3-464f-b93d-a70fafa9a437": { + "type": "Synapse.DataFrame", + "sync_state": { + "table": { + "rows": [ + { + "0": "A1055520426185580", + "1": "2021-12-31 00:00:00", + "2": "GB", + "3": "true", + "4": "0.0", + "5": "2000.0", + "index": 1 + }, + { + "0": "A1055520426191820", + "1": "2021-12-31 00:00:00", + "2": "US", + "3": "true", + "4": "0.0", + "5": "1.0", + "index": 2 + }, + { + "0": "A1055520426549020", + "1": "2021-12-31 00:00:00", + "2": "AU", + "3": "true", + "4": "0.0", + "5": "1.0", + "index": 3 + }, + { + "0": "A1055520426719380", + "1": "2021-12-31 00:00:00", + "2": "US", + "3": "true", + "4": "0.0", + "5": "2000.0", + "index": 4 + }, + { + "0": "A1055520426806680", + "1": "2021-12-31 00:00:00", + "2": "GB", + "3": "true", + "4": "1.0", + "5": "2000.0", + "index": 5 + } + ], + "schema": [ + { + "key": "0", + "name": "accountID", + "type": "string" + }, + { + "key": "1", + "name": "timestamp", + "type": "timestamp" + }, + { + "key": "2", + "name": "accountCountry", + "type": "string" + }, + { + "key": "3", + "name": "isUserRegistered", + "type": "boolean" + }, + { + "key": "4", + "name": "numPaymentRejects1dPerUser", + "type": "double" + }, + { + "key": "5", + "name": "accountAge", + "type": "double" + } + ], + "truncated": false + }, + "isSummary": false, + "language": "scala" + }, + "persist_state": { + "view": { + "type": "details", + "tableOptions": {}, + "chartOptions": { + "chartType": "bar", + "categoryFieldKeys": [ + "0" + ], + "seriesFieldKeys": [ + "5" + ], + "aggregationType": "sum", + "isStacked": false + } + } + } + }, + "b9c758fa-2dd0-416c-bc32-950b9d2c96ca": { + "type": "Synapse.DataFrame", + "sync_state": { + "table": { + "rows": [ + { + "0": "EFFCEF09-9E31-4B39-AD1B-8E169D27C749", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:34:26", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "359.94", + "13": "359.94", + "14": "59.99", + "index": 1 + }, + { + "0": "EE5AF4F5-3678-4552-90BF-C178A1073A13", + "1": "A985157000491580", + "2": "399.99", + "3": "19.0", + "4": "2023-02-05 09:42:29", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "399.99", + "13": "399.99", + "14": "399.99", + "index": 2 + }, + { + "0": "EE5AF4F5-3678-4552-90BF-C178A1073A13", + "1": "A985157000491580", + "2": "399.99", + "3": "19.0", + "4": "2023-02-05 09:42:29", + "5": "418.129547", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "399.99", + "13": "399.99", + "14": "399.99", + "index": 3 + }, + { + "0": "2D6EB785-22EC-4879-82A2-C643810EA7C1", + "1": "A844427390246047", + "2": "5.39", + "3": "14.0", + "4": "2023-02-24 20:18:56", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "43.12", + "13": "43.12", + "14": "5.39", + "index": 4 + }, + { + "0": "C365FB49-1531-4219-977D-CBA8CBEF8389", + "1": "A1759222234549920", + "2": "73080.0", + "3": "8.0", + "4": "2023-03-05 23:37:08", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 5 + }, + { + "0": "86E7F3BE-FA69-4D61-A458-12E8E726858D", + "1": "A1899947009495620", + "2": "73080.0", + "3": "10.0", + "4": "2023-03-13 02:16:29", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 6 + }, + { + "0": "86E7F3BE-FA69-4D61-A458-12E8E726858D", + "1": "A1899947009495620", + "2": "73080.0", + "3": "10.0", + "4": "2023-03-13 02:16:29", + "5": "806.0724", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 7 + }, + { + "0": "A8E3D8C2-10C0-429E-B6E1-743A0D5C3C17", + "1": "A1688853657886190", + "2": "53.99", + "3": "13.0", + "4": "2023-01-03 18:26:46", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "971.82", + "13": "971.82", + "14": "53.99", + "index": 8 + }, + { + "0": "F7C5B3E6-5372-474E-B4A0-60912B726639", + "1": "A309681307561823", + "2": "149.44", + "3": "18.0", + "4": "2023-01-18 23:25:19", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "149.44", + "13": "149.44", + "14": "149.44", + "index": 9 + }, + { + "0": "F7C5B3E6-5372-474E-B4A0-60912B726639", + "1": "A309681307561823", + "2": "149.44", + "3": "18.0", + "4": "2023-01-18 23:25:19", + "5": "149.44", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "149.44", + "13": "149.44", + "14": "149.44", + "index": 10 + }, + { + "0": "87FD50BB-5621-4778-9CBF-604522DDC605", + "1": "A1759222167950540", + "2": "59.99", + "3": "23.0", + "4": "2023-02-17 07:36:43", + "5": "59.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.98", + "13": "119.98", + "14": "59.99", + "index": 11 + }, + { + "0": "E70D13AE-274C-404F-B2C2-F1AF18F702B3", + "1": "A1055521405851730", + "2": "85.59", + "4": "2023-02-22 14:29:05", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "85.59", + "13": "85.59", + "14": "85.59", + "index": 12 + }, + { + "0": "E70D13AE-274C-404F-B2C2-F1AF18F702B3", + "1": "A1055521405851730", + "2": "85.59", + "4": "2023-02-22 14:29:05", + "5": "85.59", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "85.59", + "13": "85.59", + "14": "85.59", + "index": 13 + }, + { + "0": "ECB14CCC-D8F9-43C1-8EC2-D94AA69A2ECA", + "1": "A1055520437302600", + "2": "1200.68", + "3": "16.0", + "4": "2023-02-24 21:55:26", + "9": "1", + "10": "1414.0", + "11": "0.0", + "12": "1200.68", + "13": "1200.68", + "14": "1200.68", + "index": 14 + }, + { + "0": "ECB14CCC-D8F9-43C1-8EC2-D94AA69A2ECA", + "1": "A1055520437302600", + "2": "1200.68", + "3": "16.0", + "4": "2023-02-24 21:55:26", + "5": "1200.68", + "6": "false", + "7": "1.0", + "8": "2.0", + "9": "1", + "10": "1414.0", + "11": "0.0", + "12": "1200.68", + "13": "1200.68", + "14": "1200.68", + "index": 15 + }, + { + "0": "1CE81EB0-7399-41B6-8E55-79A52BBFE9AC", + "1": "A362221882887902", + "2": "0.0", + "4": "2023-03-06 18:07:51", + "5": "0.0", + "6": "false", + "7": "1.0", + "8": "1.0", + "9": "0", + "10": "1971.0", + "11": "0.0", + "12": "0.0", + "13": "0.0", + "14": "0.0", + "index": 16 + }, + { + "0": "76770317-5FD5-4C96-B77B-43BE377FDC6D", + "1": "A1829582580775700", + "2": "65.57", + "3": "12.0", + "4": "2023-01-03 19:48:25", + "5": "65.57", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "655.6999999999998", + "13": "655.6999999999998", + "14": "65.56999999999998", + "index": 17 + }, + { + "0": "B6F5ED72-DC16-47A4-9921-3824C780A815", + "1": "A914801004943538", + "2": "31.94", + "3": "19.0", + "4": "2023-01-20 02:01:58", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "91.93", + "13": "91.93", + "14": "45.965", + "index": 18 + }, + { + "0": "B6F5ED72-DC16-47A4-9921-3824C780A815", + "1": "A914801004943538", + "2": "31.94", + "3": "19.0", + "4": "2023-01-20 02:01:58", + "5": "31.94", + "6": "false", + "7": "1.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "91.93", + "13": "91.93", + "14": "45.965", + "index": 19 + }, + { + "0": "294A76D1-B583-432B-AA49-F32AA4974B94", + "1": "A1829582519832190", + "2": "59.99", + "3": "8.0", + "4": "2023-02-16 13:50:47", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "59.99", + "13": "59.99", + "14": "59.99", + "index": 20 + }, + { + "0": "294A76D1-B583-432B-AA49-F32AA4974B94", + "1": "A1829582519832190", + "2": "59.99", + "3": "8.0", + "4": "2023-02-16 13:50:47", + "5": "59.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "59.99", + "13": "59.99", + "14": "59.99", + "index": 21 + }, + { + "0": "7C8DB972-42E3-4C98-B13B-C338C0714D3F", + "1": "A1759222167950540", + "2": "59.99", + "3": "2.0", + "4": "2023-02-17 07:55:32", + "5": "59.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "239.96", + "13": "239.96", + "14": "59.99", + "index": 22 + }, + { + "0": "24AC8E71-2B1E-4A4A-A416-64736D04783B", + "1": "A844428082778441", + "2": "157.07", + "3": "12.0", + "4": "2023-03-21 17:36:05", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "314.14", + "13": "314.14", + "14": "157.07", + "index": 23 + }, + { + "0": "24AC8E71-2B1E-4A4A-A416-64736D04783B", + "1": "A844428082778441", + "2": "157.07", + "3": "12.0", + "4": "2023-03-21 17:36:05", + "5": "156.421301", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "314.14", + "13": "314.14", + "14": "157.07", + "index": 24 + }, + { + "0": "826E2F8E-D033-4287-A065-A26210923F90", + "1": "A1688853657886190", + "2": "53.99", + "3": "13.0", + "4": "2023-01-03 18:40:40", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1457.73", + "13": "1457.73", + "14": "53.99", + "index": 25 + }, + { + "0": "3743BB47-3637-40B7-A462-2548CFB7C663", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 03:05:54", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "517.439999999999", + "13": "506.65999999999906", + "14": "5.38999999999999", + "index": 26 + }, + { + "0": "3743BB47-3637-40B7-A462-2548CFB7C663", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 03:05:54", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "517.439999999999", + "13": "506.65999999999906", + "14": "5.38999999999999", + "index": 27 + }, + { + "0": "C1BC707F-E92A-4FD4-A709-39C1C7666465", + "1": "A985157026745005", + "2": "36540.0", + "3": "9.0", + "4": "2023-03-13 00:38:59", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "36540.0", + "13": "36540.0", + "14": "36540.0", + "index": 28 + }, + { + "0": "C1BC707F-E92A-4FD4-A709-39C1C7666465", + "1": "A985157026745005", + "2": "36540.0", + "3": "9.0", + "4": "2023-03-13 00:38:59", + "5": "403.0362", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "36540.0", + "13": "36540.0", + "14": "36540.0", + "index": 29 + }, + { + "0": "027C22C5-135C-47DF-8C96-3289EB88AE52", + "1": "A1759222219270900", + "2": "235.39", + "3": "20.0", + "4": "2023-02-28 01:27:26", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "235.39", + "13": "235.39", + "14": "235.39", + "index": 30 + }, + { + "0": "027C22C5-135C-47DF-8C96-3289EB88AE52", + "1": "A1759222219270900", + "2": "235.39", + "3": "20.0", + "4": "2023-02-28 01:27:26", + "5": "235.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "235.39", + "13": "235.39", + "14": "235.39", + "index": 31 + }, + { + "0": "A0C4B8CE-4587-469B-B447-1B99D45187BD", + "1": "A844428089229497", + "2": "261.45", + "3": "23.0", + "4": "2023-03-29 07:59:07", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "522.9", + "13": "522.9", + "14": "261.45", + "index": 32 + }, + { + "0": "A0C4B8CE-4587-469B-B447-1B99D45187BD", + "1": "A844428089229497", + "2": "261.45", + "3": "23.0", + "4": "2023-03-29 07:59:07", + "5": "260.370211", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "522.9", + "13": "522.9", + "14": "261.45", + "index": 33 + }, + { + "0": "8D7BE688-4CD9-4703-B03B-5ECC7BBD11E7", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:04:48", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "161.97", + "13": "161.97", + "14": "53.99", + "index": 34 + }, + { + "0": "8D7BE688-4CD9-4703-B03B-5ECC7BBD11E7", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:04:48", + "5": "53.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "161.97", + "13": "161.97", + "14": "53.99", + "index": 35 + }, + { + "0": "88A8FA38-800E-459D-A11C-77477E41FC5B", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 20:08:13", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "5258.949999999999", + "13": "5258.949999999999", + "14": "146.08194444444442", + "index": 36 + }, + { + "0": "0E2AB375-BA94-41B4-A0A5-9C173653D5F7", + "1": "A844428044533734", + "2": "599.0", + "3": "22.0", + "4": "2023-01-24 12:38:32", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "599.0", + "13": "599.0", + "14": "599.0", + "index": 37 + }, + { + "0": "0E2AB375-BA94-41B4-A0A5-9C173653D5F7", + "1": "A844428044533734", + "2": "599.0", + "3": "22.0", + "4": "2023-01-24 12:38:32", + "5": "626.16465", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "599.0", + "13": "599.0", + "14": "599.0", + "index": 38 + }, + { + "0": "88CFD0B0-2A86-4BD2-9CED-4F37E1E9DFFE", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:21:26", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "48.51", + "13": "48.51", + "14": "5.39", + "index": 39 + }, + { + "0": "3FBDA277-FA1B-4355-856A-91A8D9CB828C", + "1": "A985157015268058", + "2": "4.99", + "3": "15.0", + "4": "2023-02-27 20:34:32", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "134.72999999999996", + "13": "134.72999999999996", + "14": "4.989999999999998", + "index": 40 + }, + { + "0": "3FBDA277-FA1B-4355-856A-91A8D9CB828C", + "1": "A985157015268058", + "2": "4.99", + "3": "15.0", + "4": "2023-02-27 20:34:32", + "5": "4.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "134.72999999999996", + "13": "134.72999999999996", + "14": "4.989999999999998", + "index": 41 + }, + { + "0": "8FCE1AE5-6A19-46A3-8EC1-8D62B83C29A3", + "1": "A1759221435782970", + "2": "157.07", + "3": "18.0", + "4": "2023-03-05 00:17:53", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "157.07", + "13": "157.07", + "14": "157.07", + "index": 42 + }, + { + "0": "8FCE1AE5-6A19-46A3-8EC1-8D62B83C29A3", + "1": "A1759221435782970", + "2": "157.07", + "3": "18.0", + "4": "2023-03-05 00:17:53", + "5": "156.421301", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "157.07", + "13": "157.07", + "14": "157.07", + "index": 43 + }, + { + "0": "27281C9B-0119-4284-A39C-603C356C6ADB", + "1": "A1055521381717350", + "2": "479.0", + "3": "16.0", + "4": "2023-01-05 16:22:27", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "479.0", + "13": "479.0", + "14": "479.0", + "index": 44 + }, + { + "0": "27281C9B-0119-4284-A39C-603C356C6ADB", + "1": "A1055521381717350", + "2": "479.0", + "3": "16.0", + "4": "2023-01-05 16:22:27", + "5": "754.3771", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "479.0", + "13": "479.0", + "14": "479.0", + "index": 45 + }, + { + "0": "36F5A50E-CBF2-4D33-87C5-1F8F7736F562", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:38:37", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "659.89", + "13": "659.89", + "14": "59.99", + "index": 46 + }, + { + "0": "36F5A50E-CBF2-4D33-87C5-1F8F7736F562", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:38:37", + "5": "59.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "659.89", + "13": "659.89", + "14": "59.99", + "index": 47 + }, + { + "0": "5D333262-9627-4E42-84EA-615E7031CD48", + "1": "A1055521406038580", + "2": "73080.0", + "3": "3.0", + "4": "2023-02-22 18:29:43", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "146160.0", + "13": "146160.0", + "14": "73080.0", + "index": 48 + }, + { + "0": "5D333262-9627-4E42-84EA-615E7031CD48", + "1": "A1055521406038580", + "2": "73080.0", + "3": "3.0", + "4": "2023-02-22 18:29:43", + "5": "806.0724", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "146160.0", + "13": "146160.0", + "14": "73080.0", + "index": 49 + }, + { + "0": "3C38413D-BA5E-4F68-9CE5-BAF48E13DE3C", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:21:29", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "264.1099999999997", + "13": "253.32999999999967", + "14": "5.3899999999999935", + "index": 50 + }, + { + "0": "3A0ABDCD-6F28-4C1F-BE5A-F341A4084E50", + "1": "A1759222105153830", + "2": "108.38", + "3": "10.0", + "4": "2023-02-16 18:54:15", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "216.76", + "13": "216.76", + "14": "108.38", + "index": 51 + }, + { + "0": "3A0ABDCD-6F28-4C1F-BE5A-F341A4084E50", + "1": "A1759222105153830", + "2": "108.38", + "3": "10.0", + "4": "2023-02-16 18:54:15", + "5": "108.38", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "216.76", + "13": "216.76", + "14": "108.38", + "index": 52 + }, + { + "0": "AC86DB3A-EEED-44C1-85CF-79DA0AF47B0F", + "1": "A1688853657886190", + "2": "53.99", + "3": "13.0", + "4": "2023-01-03 18:39:29", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1403.74", + "13": "1403.74", + "14": "53.99", + "index": 53 + }, + { + "0": "28C2478A-7236-40ED-A5C4-5BB8A29E561B", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:43:14", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "839.86", + "13": "839.86", + "14": "59.99", + "index": 54 + }, + { + "0": "2F6CE5C9-1702-4E7A-8A88-40CE991E99BB", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:34:17", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "279.86", + "13": "279.86", + "14": "19.990000000000002", + "index": 55 + }, + { + "0": "B9F2630D-2677-44EF-9DAF-CAACE7EF989E", + "1": "A1759222164863410", + "2": "109.99", + "3": "0.0", + "4": "2023-01-24 08:59:40", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "109.99", + "13": "109.99", + "14": "109.99", + "index": 56 + }, + { + "0": "B9F2630D-2677-44EF-9DAF-CAACE7EF989E", + "1": "A1759222164863410", + "2": "109.99", + "3": "0.0", + "4": "2023-01-24 08:59:40", + "5": "109.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "109.99", + "13": "109.99", + "14": "109.99", + "index": 57 + }, + { + "0": "E1DF3460-24B4-43A6-9E8C-8432ED03D018", + "1": "A362840681200346", + "2": "159.85", + "3": "16.0", + "4": "2023-02-15 20:36:32", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "319.7", + "13": "319.7", + "14": "159.85", + "index": 58 + }, + { + "0": "E1DF3460-24B4-43A6-9E8C-8432ED03D018", + "1": "A362840681200346", + "2": "159.85", + "3": "16.0", + "4": "2023-02-15 20:36:32", + "5": "159.189819", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "319.7", + "13": "319.7", + "14": "159.85", + "index": 59 + }, + { + "0": "9D2F95B4-73B9-4427-88FF-B82EB58087BB", + "1": "A985157008993462", + "2": "105.48", + "3": "5.0", + "4": "2023-02-17 12:03:05", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "210.96", + "13": "210.96", + "14": "105.48", + "index": 60 + }, + { + "0": "9D2F95B4-73B9-4427-88FF-B82EB58087BB", + "1": "A985157008993462", + "2": "105.48", + "3": "5.0", + "4": "2023-02-17 12:03:05", + "5": "105.48", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "210.96", + "13": "210.96", + "14": "105.48", + "index": 61 + }, + { + "0": "DD2D73FD-7DAF-49A5-AC4A-47117E6DE03C", + "1": "A1759222095873190", + "2": "53.49", + "3": "11.0", + "4": "2023-01-03 17:37:53", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "53.49", + "13": "53.49", + "14": "53.49", + "index": 62 + }, + { + "0": "D1A1DEF3-8373-40A4-8337-742C4BC68770", + "1": "A914800996051170", + "2": "215.64", + "3": "17.0", + "4": "2023-01-07 22:50:44", + "5": "215.64", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "571.27", + "13": "571.27", + "14": "190.42333333333332", + "index": 63 + }, + { + "0": "DA660AD0-C47C-4012-9B2A-A74B9867F517", + "1": "A1829581642988470", + "2": "239.0", + "3": "17.0", + "4": "2023-02-13 20:58:33", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "239.0", + "13": "239.0", + "14": "239.0", + "index": 64 + }, + { + "0": "DA660AD0-C47C-4012-9B2A-A74B9867F517", + "1": "A1829581642988470", + "2": "239.0", + "3": "17.0", + "4": "2023-02-13 20:58:33", + "5": "120.10945", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "239.0", + "13": "239.0", + "14": "239.0", + "index": 65 + }, + { + "0": "7F5B344A-6274-4032-94D2-A21461F977A2", + "1": "A914801025693987", + "2": "278.88", + "3": "19.0", + "4": "2023-02-18 02:01:07", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "278.88", + "13": "278.88", + "14": "278.88", + "index": 66 + }, + { + "0": "7F5B344A-6274-4032-94D2-A21461F977A2", + "1": "A914801025693987", + "2": "278.88", + "3": "19.0", + "4": "2023-02-18 02:01:07", + "5": "277.72822599999995", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "278.88", + "13": "278.88", + "14": "278.88", + "index": 67 + }, + { + "0": "E87F43AB-36CC-481F-A7CB-E5F9C1B08F57", + "1": "A1899947009495620", + "2": "62580.0", + "3": "10.0", + "4": "2023-03-13 02:18:34", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "135660.0", + "13": "135660.0", + "14": "67830.0", + "index": 68 + }, + { + "0": "79BC1796-1C62-4C53-8F6D-301C03D1C4BF", + "1": "A914801004122929", + "2": "210.19", + "3": "11.0", + "4": "2023-01-18 17:23:13", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "210.19", + "13": "210.19", + "14": "210.19", + "index": 69 + }, + { + "0": "79BC1796-1C62-4C53-8F6D-301C03D1C4BF", + "1": "A914801004122929", + "2": "210.19", + "3": "11.0", + "4": "2023-01-18 17:23:13", + "5": "210.19", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "210.19", + "13": "210.19", + "14": "210.19", + "index": 70 + }, + { + "0": "A6C7101E-7794-4149-A00C-86F43AC4AF08", + "1": "A1055521397087470", + "2": "299.0", + "3": "23.0", + "4": "2023-02-09 13:59:50", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "299.0", + "13": "299.0", + "14": "299.0", + "index": 71 + }, + { + "0": "A6C7101E-7794-4149-A00C-86F43AC4AF08", + "1": "A1055521397087470", + "2": "299.0", + "3": "23.0", + "4": "2023-02-09 13:59:50", + "5": "312.55965", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "299.0", + "13": "299.0", + "14": "299.0", + "index": 72 + }, + { + "0": "6DC4F5F7-598E-4782-9981-5466DF994D2B", + "1": "A1055520836257310", + "2": "5.04", + "3": "5.0", + "4": "2023-02-28 10:34:02", + "9": "1", + "10": "1555.0", + "11": "0.0", + "12": "25.2", + "13": "25.2", + "14": "5.04", + "index": 73 + }, + { + "0": "2193EA41-7C0E-442B-9A2A-A7E6F6CF6D0F", + "1": "A1899947010059410", + "2": "156450.0", + "3": "23.0", + "4": "2023-03-07 14:26:10", + "5": "1725.6435", + "6": "false", + "7": "5.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "302610.0", + "13": "302610.0", + "14": "100870.0", + "index": 74 + }, + { + "0": "BCBDF6C6-1D5A-42F2-A912-E295526FF9B7", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 20:04:05", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "4809.039999999998", + "13": "4809.039999999998", + "14": "145.72848484848478", + "index": 75 + }, + { + "0": "A891E91F-34EB-47BE-87EC-EF06767A0E5E", + "1": "A914801026387229", + "2": "301.26", + "3": "19.0", + "4": "2023-02-19 04:03:58", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "301.26", + "13": "301.26", + "14": "301.26", + "index": 76 + }, + { + "0": "A891E91F-34EB-47BE-87EC-EF06767A0E5E", + "1": "A914801026387229", + "2": "301.26", + "3": "19.0", + "4": "2023-02-19 04:03:58", + "5": "301.26", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "301.26", + "13": "301.26", + "14": "301.26", + "index": 77 + }, + { + "0": "06CF9747-053E-4361-8048-CD6D0F16812C", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:45:31", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "355.73999999999944", + "13": "344.95999999999947", + "14": "5.389999999999992", + "index": 78 + }, + { + "0": "3BBA55DF-FAE7-4F71-A7E9-2CE883BE50C2", + "1": "A985156290472668", + "2": "5.34", + "3": "8.0", + "4": "2023-02-27 15:11:10", + "5": "5.34", + "6": "true", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "2365.0", + "11": "0.0", + "12": "21.36", + "13": "21.36", + "14": "5.34", + "index": 79 + }, + { + "0": "F178386E-86A3-4F08-B9B0-6778898CAD4E", + "1": "A1688853657869890", + "2": "52.99", + "3": "10.0", + "4": "2023-01-03 16:56:06", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "158.97", + "13": "158.97", + "14": "52.99", + "index": 80 + }, + { + "0": "50C46472-B928-49BF-82E2-D1BE1C9DBCF4", + "1": "A1899946943634320", + "2": "149.99", + "3": "12.0", + "4": "2023-01-15 12:57:30", + "5": "236.21925099999999", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "339.98", + "13": "339.98", + "14": "169.99", + "index": 81 + }, + { + "0": "F5606360-D929-4903-8771-E51207DAF2C6", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 18:53:31", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "909.82", + "13": "909.82", + "14": "129.9742857142857", + "index": 82 + }, + { + "0": "C8AA8B84-1C89-4B76-B2BF-3C10C3444D89", + "1": "A914801007105746", + "2": "80.73", + "3": "9.0", + "4": "2023-01-25 18:07:59", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "257.64", + "13": "257.64", + "14": "85.88", + "index": 83 + }, + { + "0": "F461D35F-457F-40E7-BF42-4C116CF0D921", + "1": "A296624604869030", + "2": "139.99", + "3": "13.0", + "4": "2023-02-17 21:48:49", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "139.99", + "13": "139.99", + "14": "139.99", + "index": 84 + }, + { + "0": "996C6CB5-D9A8-4B88-A723-6A002E6B893F", + "1": "A985157015268058", + "2": "4.99", + "3": "10.0", + "4": "2023-02-27 15:44:00", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "79.84", + "13": "79.84", + "14": "4.99", + "index": 85 + }, + { + "0": "CBE31B92-8D8D-422D-BF1C-2883222AC68B", + "1": "A1688853657869890", + "2": "52.99", + "3": "10.0", + "4": "2023-01-03 16:51:29", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "52.99", + "13": "52.99", + "14": "52.99", + "index": 86 + }, + { + "0": "CBE31B92-8D8D-422D-BF1C-2883222AC68B", + "1": "A1688853657869890", + "2": "52.99", + "3": "10.0", + "4": "2023-01-03 16:51:29", + "5": "52.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "52.99", + "13": "52.99", + "14": "52.99", + "index": 87 + }, + { + "0": "2120F51D-E109-4481-88D7-023757351EDF", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 20:05:23", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "4959.009999999998", + "13": "4959.009999999998", + "14": "145.8532352941176", + "index": 88 + }, + { + "0": "DF9AFB75-2D64-4A8A-8743-AA39724E34AD", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:39:41", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "339.83000000000004", + "13": "339.83000000000004", + "14": "19.990000000000002", + "index": 89 + }, + { + "0": "F325312B-1722-414B-8969-07E1BADC9D75", + "1": "A1688853647393240", + "2": "147.69", + "3": "8.0", + "4": "2023-01-25 16:45:52", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "147.69", + "13": "147.69", + "14": "147.69", + "index": 90 + }, + { + "0": "F325312B-1722-414B-8969-07E1BADC9D75", + "1": "A1688853647393240", + "2": "147.69", + "3": "8.0", + "4": "2023-01-25 16:45:52", + "5": "147.69", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "147.69", + "13": "147.69", + "14": "147.69", + "index": 91 + }, + { + "0": "DF029819-0B5D-4201-8195-325BE6202E50", + "1": "A1829582519835540", + "2": "63.59", + "3": "23.0", + "4": "2023-02-17 08:12:30", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "63.59", + "13": "63.59", + "14": "63.59", + "index": 92 + }, + { + "0": "DF029819-0B5D-4201-8195-325BE6202E50", + "1": "A1829582519835540", + "2": "63.59", + "3": "23.0", + "4": "2023-02-17 08:12:30", + "5": "63.59", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "63.59", + "13": "63.59", + "14": "63.59", + "index": 93 + }, + { + "0": "8A753C7E-56CE-4D4C-8910-767868183DD5", + "1": "A914801029782303", + "2": "148.74", + "3": "18.0", + "4": "2023-02-24 00:19:09", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "148.74", + "13": "148.74", + "14": "148.74", + "index": 94 + }, + { + "0": "8A753C7E-56CE-4D4C-8910-767868183DD5", + "1": "A914801029782303", + "2": "148.74", + "3": "18.0", + "4": "2023-02-24 00:19:09", + "5": "148.74", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "148.74", + "13": "148.74", + "14": "148.74", + "index": 95 + }, + { + "0": "021535A3-03BA-43FF-9ADF-9EB8ED0DCCD2", + "1": "A844427388621092", + "2": "85.59", + "3": "19.0", + "4": "2023-02-24 00:35:20", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "85.59", + "13": "85.59", + "14": "85.59", + "index": 96 + }, + { + "0": "021535A3-03BA-43FF-9ADF-9EB8ED0DCCD2", + "1": "A844427388621092", + "2": "85.59", + "3": "19.0", + "4": "2023-02-24 00:35:20", + "5": "85.59", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "85.59", + "13": "85.59", + "14": "85.59", + "index": 97 + }, + { + "0": "5FE36C4E-BDCE-4C58-B35A-2077ED72CDFF", + "1": "A1055521420182040", + "2": "752.68", + "3": "18.0", + "4": "2023-03-13 00:37:15", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "752.68", + "13": "752.68", + "14": "752.68", + "index": 98 + }, + { + "0": "5FE36C4E-BDCE-4C58-B35A-2077ED72CDFF", + "1": "A1055521420182040", + "2": "752.68", + "3": "18.0", + "4": "2023-03-13 00:37:15", + "5": "752.68", + "6": "false", + "7": "0.0", + "8": "2.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "752.68", + "13": "752.68", + "14": "752.68", + "index": 99 + }, + { + "0": "415F4169-0DE1-4D1D-B056-823D02BFEDF6", + "1": "A1829582580775700", + "2": "65.57", + "3": "11.0", + "4": "2023-01-03 18:51:45", + "5": "65.57", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "131.14", + "13": "131.14", + "14": "65.57", + "index": 100 + }, + { + "0": "B634C814-3ADD-41B5-BBA6-34BD46A8EA65", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 19:18:13", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "2409.5199999999995", + "13": "2409.5199999999995", + "14": "141.73647058823528", + "index": 101 + }, + { + "0": "3CF32319-BFF3-4CFE-8792-8C4775AD619F", + "1": "A1899946873142120", + "2": "99.98", + "3": "13.0", + "4": "2023-01-03 18:45:18", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "159.97", + "13": "159.97", + "14": "79.985", + "index": 102 + }, + { + "0": "B634C814-3ADD-41B5-BBA6-34BD46A8EA65", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 19:18:13", + "5": "149.97", + "6": "false", + "7": "3.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "2409.5199999999995", + "13": "2409.5199999999995", + "14": "141.73647058823528", + "index": 103 + }, + { + "0": "2589C5DD-012D-429C-A3C1-8333C3ECE2A4", + "1": "A1829582519835540", + "2": "59.99", + "3": "5.0", + "4": "2023-02-17 11:22:08", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "247.16000000000003", + "13": "247.16000000000003", + "14": "61.790000000000006", + "index": 104 + }, + { + "0": "D7E5266B-1C45-4BAA-AAEC-15D771DDF4D9", + "1": "A1055521406380930", + "2": "139.99", + "3": "19.0", + "4": "2023-02-24 01:12:56", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "139.99", + "13": "139.99", + "14": "139.99", + "index": 105 + }, + { + "0": "D7E5266B-1C45-4BAA-AAEC-15D771DDF4D9", + "1": "A1055521406380930", + "2": "139.99", + "3": "19.0", + "4": "2023-02-24 01:12:56", + "5": "139.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "139.99", + "13": "139.99", + "14": "139.99", + "index": 106 + }, + { + "0": "961FCF4A-7930-4C04-B37B-A5FDFA414D9E", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:41:14", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "359.82000000000005", + "13": "359.82000000000005", + "14": "19.990000000000002", + "index": 107 + }, + { + "0": "6D7890A5-DA17-43B5-AA06-79189795DEF8", + "1": "A1688853613564590", + "2": "62.39", + "3": "2.0", + "4": "2023-01-17 08:17:25", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "62.39", + "13": "62.39", + "14": "62.39", + "index": 108 + }, + { + "0": "6D7890A5-DA17-43B5-AA06-79189795DEF8", + "1": "A1688853613564590", + "2": "62.39", + "3": "2.0", + "4": "2023-01-17 08:17:25", + "5": "62.39", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "62.39", + "13": "62.39", + "14": "62.39", + "index": 109 + }, + { + "0": "156194EC-C71A-4807-B417-BE00180D9FC0", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:38:28", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "118.58", + "13": "118.58", + "14": "5.39", + "index": 110 + }, + { + "0": "10F2E1BB-B84B-425E-9CF4-1E9A6AB041D8", + "1": "A844427390246047", + "2": "5.39", + "3": "6.0", + "4": "2023-02-26 11:28:28", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "549.779999999999", + "13": "538.999999999999", + "14": "5.38999999999999", + "index": 111 + }, + { + "0": "156194EC-C71A-4807-B417-BE00180D9FC0", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:38:28", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "118.58", + "13": "118.58", + "14": "5.39", + "index": 112 + }, + { + "0": "CFF67307-A9EF-43AC-AE45-D448E2991474", + "1": "A844428041547410", + "2": "99.99", + "4": "2023-01-19 10:39:12", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "99.99", + "13": "99.99", + "14": "99.99", + "index": 113 + }, + { + "0": "44E0A6A4-06F8-40B7-9CAA-7E421AB8FD69", + "1": "A844427703526719", + "2": "102.48", + "4": "2023-01-23 03:36:00", + "9": "1", + "10": "1980.0", + "11": "0.0", + "12": "102.48", + "13": "102.48", + "14": "102.48", + "index": 114 + }, + { + "0": "44E0A6A4-06F8-40B7-9CAA-7E421AB8FD69", + "1": "A844427703526719", + "2": "102.48", + "4": "2023-01-23 03:36:00", + "5": "102.48", + "6": "false", + "7": "2.0", + "8": "1.0", + "9": "1", + "10": "1980.0", + "11": "0.0", + "12": "102.48", + "13": "102.48", + "14": "102.48", + "index": 115 + }, + { + "0": "69A49BAA-59B0-4AEC-AD40-EEE900AE308A", + "1": "A1759222219270870", + "2": "424.99", + "3": "22.0", + "4": "2023-02-28 05:01:08", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "849.98", + "13": "849.98", + "14": "424.99", + "index": 116 + }, + { + "0": "ACB1088D-CB05-45F9-9B3E-4709989A7443", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:06:03", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "215.96", + "13": "215.96", + "14": "53.99", + "index": 117 + }, + { + "0": "07C1A129-EF6A-4B87-BFE4-C4D4CDF7049B", + "1": "A844427926468579", + "2": "54.11", + "3": "0.0", + "4": "2023-02-17 06:01:39", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "54.11", + "13": "54.11", + "14": "54.11", + "index": 118 + }, + { + "0": "1A68B478-E49B-4052-9BCD-2DC43AFA57B9", + "1": "A1688853682035130", + "2": "490.0", + "4": "2023-03-07 17:23:13", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "490.0", + "13": "490.0", + "14": "490.0", + "index": 119 + }, + { + "0": "1A68B478-E49B-4052-9BCD-2DC43AFA57B9", + "1": "A1688853682035130", + "2": "490.0", + "4": "2023-03-07 17:23:13", + "5": "660.422", + "6": "false", + "7": "0.0", + "8": "2.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "490.0", + "13": "490.0", + "14": "490.0", + "index": 120 + }, + { + "0": "C173A9A3-90B7-4B38-8DAC-D001CDD47814", + "1": "A1899946873128090", + "2": "127.48", + "3": "22.0", + "4": "2023-02-15 03:51:29", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "570.5", + "13": "570.5", + "14": "114.1", + "index": 121 + }, + { + "0": "CC3A3235-D2C0-4050-B3FA-1874B30260D6", + "1": "A1899946865208980", + "2": "62580.0", + "3": "1.0", + "4": "2023-03-09 16:22:35", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "135660.0", + "13": "135660.0", + "14": "67830.0", + "index": 122 + }, + { + "0": "CC3A3235-D2C0-4050-B3FA-1874B30260D6", + "1": "A1899946865208980", + "2": "62580.0", + "3": "1.0", + "4": "2023-03-09 16:22:35", + "5": "690.2574", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "135660.0", + "13": "135660.0", + "14": "67830.0", + "index": 123 + }, + { + "0": "C4005755-95ED-4A4F-B1CD-B3943278DA54", + "1": "A1759222235006700", + "2": "212.49", + "3": "7.0", + "4": "2023-01-19 13:48:20", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "212.49", + "13": "212.49", + "14": "212.49", + "index": 124 + }, + { + "0": "C4005755-95ED-4A4F-B1CD-B3943278DA54", + "1": "A1759222235006700", + "2": "212.49", + "3": "7.0", + "4": "2023-01-19 13:48:20", + "5": "212.49", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "212.49", + "13": "212.49", + "14": "212.49", + "index": 125 + }, + { + "0": "4B1F2669-E141-4218-8048-95E751DCF8F1", + "1": "A1759222167950540", + "2": "59.99", + "3": "2.0", + "4": "2023-02-17 07:54:20", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "179.97", + "13": "179.97", + "14": "59.99", + "index": 126 + }, + { + "0": "ABA1D7A5-99A8-4416-B120-BD5E39AF612A", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:45:00", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "350.34999999999945", + "13": "339.5699999999995", + "14": "5.389999999999992", + "index": 127 + }, + { + "0": "ABA1D7A5-99A8-4416-B120-BD5E39AF612A", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:45:00", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "350.34999999999945", + "13": "339.5699999999995", + "14": "5.389999999999992", + "index": 128 + }, + { + "0": "CEDBDEF3-E681-4CCF-81AC-8EA4433E3DB2", + "1": "A985157015268058", + "2": "4.99", + "3": "15.0", + "4": "2023-02-27 20:36:09", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "139.71999999999997", + "13": "139.71999999999997", + "14": "4.989999999999999", + "index": 129 + }, + { + "0": "CEDBDEF3-E681-4CCF-81AC-8EA4433E3DB2", + "1": "A985157015268058", + "2": "4.99", + "3": "15.0", + "4": "2023-02-27 20:36:09", + "5": "4.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "139.71999999999997", + "13": "139.71999999999997", + "14": "4.989999999999999", + "index": 130 + }, + { + "0": "6E4A323D-0142-4015-88CC-74C85F2D1261", + "1": "A844428039854278", + "2": "76.19", + "3": "13.0", + "4": "2023-01-19 18:36:52", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "152.38", + "13": "152.38", + "14": "76.19", + "index": 131 + }, + { + "0": "6E4A323D-0142-4015-88CC-74C85F2D1261", + "1": "A844428039854278", + "2": "76.19", + "3": "13.0", + "4": "2023-01-19 18:36:52", + "5": "76.19", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "152.38", + "13": "152.38", + "14": "76.19", + "index": 132 + }, + { + "0": "72B7AED1-0944-4DE8-8BEF-74680BBAC3F1", + "1": "A1829582519832190", + "2": "59.99", + "3": "8.0", + "4": "2023-02-16 13:55:28", + "5": "59.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "179.97", + "13": "179.97", + "14": "59.99", + "index": 133 + }, + { + "0": "938457F3-FCC6-463A-A037-89D33413C348", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 21:20:56", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "199.4299999999998", + "13": "188.64999999999984", + "14": "5.389999999999995", + "index": 134 + }, + { + "0": "938457F3-FCC6-463A-A037-89D33413C348", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 21:20:56", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "199.4299999999998", + "13": "188.64999999999984", + "14": "5.389999999999995", + "index": 135 + }, + { + "0": "7CD74B1F-ACC8-4C37-B00F-11151C50D758", + "1": "A1055520703430980", + "2": "119.75", + "3": "20.0", + "4": "2023-03-25 02:17:14", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.75", + "13": "119.75", + "14": "119.75", + "index": 136 + }, + { + "0": "7CD74B1F-ACC8-4C37-B00F-11151C50D758", + "1": "A1055520703430980", + "2": "119.75", + "3": "20.0", + "4": "2023-03-25 02:17:14", + "5": "119.75", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.75", + "13": "119.75", + "14": "119.75", + "index": 137 + }, + { + "0": "40F8D07E-67EF-4678-8612-FC130DC84F5E", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 19:00:08", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1359.73", + "13": "1359.73", + "14": "135.973", + "index": 138 + }, + { + "0": "0A82E4ED-93EC-4386-AA16-0EA1FC946B6C", + "1": "A1899946895455190", + "2": "19.99", + "3": "13.0", + "4": "2023-01-13 19:20:25", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "159.92", + "13": "159.92", + "14": "19.99", + "index": 139 + }, + { + "0": "DF0ECDA4-9184-4A60-A227-C9193CD08C63", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 21:03:15", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "145.52999999999994", + "13": "134.74999999999997", + "14": "5.389999999999998", + "index": 140 + }, + { + "0": "411DF6C0-02DE-4D70-977B-EF261BF1D4A1", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:43:06", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "318.00999999999954", + "13": "307.22999999999956", + "14": "5.389999999999993", + "index": 141 + }, + { + "0": "DF0ECDA4-9184-4A60-A227-C9193CD08C63", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 21:03:15", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "145.52999999999994", + "13": "134.74999999999997", + "14": "5.389999999999998", + "index": 142 + }, + { + "0": "0B724B9C-2D5A-4DA6-8D99-570DA7C20933", + "1": "A2111055908627200", + "2": "74.89", + "3": "19.0", + "4": "2023-03-26 01:10:22", + "9": "1", + "10": "1518.0", + "11": "0.0", + "12": "74.89", + "13": "74.89", + "14": "74.89", + "index": 143 + }, + { + "0": "0B724B9C-2D5A-4DA6-8D99-570DA7C20933", + "1": "A2111055908627200", + "2": "74.89", + "3": "19.0", + "4": "2023-03-26 01:10:22", + "5": "74.89", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "1518.0", + "11": "0.0", + "12": "74.89", + "13": "74.89", + "14": "74.89", + "index": 144 + }, + { + "0": "9E6DC7FE-2F2F-4508-BBF2-BC31F249B637", + "1": "A1759222229520370", + "2": "169.0", + "3": "23.0", + "4": "2023-01-03 14:10:32", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "768.0", + "13": "768.0", + "14": "384.0", + "index": 145 + }, + { + "0": "9E6DC7FE-2F2F-4508-BBF2-BC31F249B637", + "1": "A1759222229520370", + "2": "169.0", + "3": "23.0", + "4": "2023-01-03 14:10:32", + "5": "176.66415", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "768.0", + "13": "768.0", + "14": "384.0", + "index": 146 + }, + { + "0": "41C41A19-2063-47C1-BAFB-B1BF50578374", + "1": "A844428029243587", + "2": "148.74", + "3": "19.0", + "4": "2023-01-04 01:23:14", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "148.74", + "13": "148.74", + "14": "148.74", + "index": 147 + }, + { + "0": "41C41A19-2063-47C1-BAFB-B1BF50578374", + "1": "A844428029243587", + "2": "148.74", + "3": "19.0", + "4": "2023-01-04 01:23:14", + "5": "148.74", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "148.74", + "13": "148.74", + "14": "148.74", + "index": 148 + }, + { + "0": "8C0CDFD5-0A74-405D-9360-B99DC5F5A658", + "1": "A1829582571100710", + "2": "239.51", + "3": "16.0", + "4": "2023-02-01 21:54:42", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "239.51", + "13": "239.51", + "14": "239.51", + "index": 149 + }, + { + "0": "8C0CDFD5-0A74-405D-9360-B99DC5F5A658", + "1": "A1829582571100710", + "2": "239.51", + "3": "16.0", + "4": "2023-02-01 21:54:42", + "5": "239.51", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "239.51", + "13": "239.51", + "14": "239.51", + "index": 150 + }, + { + "0": "51D66EFC-6211-4DF0-BB4C-1BCE5F248330", + "1": "A296624604869030", + "2": "139.99", + "3": "13.0", + "4": "2023-02-17 21:59:16", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "279.98", + "13": "279.98", + "14": "139.99", + "index": 151 + }, + { + "0": "51D66EFC-6211-4DF0-BB4C-1BCE5F248330", + "1": "A296624604869030", + "2": "139.99", + "3": "13.0", + "4": "2023-02-17 21:59:16", + "5": "139.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "279.98", + "13": "279.98", + "14": "139.99", + "index": 152 + }, + { + "0": "DE15CA12-F07E-4C7C-9C30-19EF38B2B3E6", + "1": "A1688853657886190", + "2": "53.99", + "3": "13.0", + "4": "2023-01-03 18:42:16", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1511.72", + "13": "1511.72", + "14": "53.99", + "index": 153 + }, + { + "0": "B30F54F2-BBB5-4DFC-B4D6-F3BA03220790", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:28:43", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "59.99", + "13": "59.99", + "14": "59.99", + "index": 154 + }, + { + "0": "964F4854-0D2F-4852-BA0E-2FF1CAC93990", + "1": "A985156954406966", + "2": "240.45", + "3": "19.0", + "4": "2023-02-28 01:50:02", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "240.45", + "13": "240.45", + "14": "240.45", + "index": 155 + }, + { + "0": "D7391AE6-467B-4C82-9310-7AA348F9D0C4", + "1": "A914800267247225", + "2": "139.99", + "3": "20.0", + "4": "2023-03-12 01:47:29", + "9": "1", + "10": "370.0", + "11": "0.0", + "12": "139.99", + "13": "139.99", + "14": "139.99", + "index": 156 + }, + { + "0": "D7391AE6-467B-4C82-9310-7AA348F9D0C4", + "1": "A914800267247225", + "2": "139.99", + "3": "20.0", + "4": "2023-03-12 01:47:29", + "5": "139.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "370.0", + "11": "0.0", + "12": "139.99", + "13": "139.99", + "14": "139.99", + "index": 157 + }, + { + "0": "6EE898DD-C20C-4784-9CD5-3A630B4113AB", + "1": "A914801045428170", + "2": "85.59", + "3": "13.0", + "4": "2023-03-15 18:30:29", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "85.59", + "13": "85.59", + "14": "85.59", + "index": 158 + }, + { + "0": "6EE898DD-C20C-4784-9CD5-3A630B4113AB", + "1": "A914801045428170", + "2": "85.59", + "3": "13.0", + "4": "2023-03-15 18:30:29", + "5": "85.59", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "85.59", + "13": "85.59", + "14": "85.59", + "index": 159 + }, + { + "0": "C4F7FAB1-FE05-4F4D-8E52-8C6A3EE96115", + "1": "A844427390246047", + "2": "5.39", + "3": "11.0", + "4": "2023-02-28 17:14:10", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "609.0699999999988", + "13": "269.49999999999966", + "14": "5.389999999999989", + "index": 160 + }, + { + "0": "B49DBC29-4D81-4FEE-8B9F-44415FD7BC80", + "1": "A985157015268058", + "2": "4.99", + "3": "10.0", + "4": "2023-02-27 15:42:26", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "74.85000000000001", + "13": "74.85000000000001", + "14": "4.99", + "index": 161 + }, + { + "0": "1BFE4527-0634-4541-AE5B-36B56B92F78B", + "1": "A985156996696141", + "2": "1199.0", + "3": "9.0", + "4": "2023-01-25 09:00:09", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "2398.0", + "13": "2398.0", + "14": "1199.0", + "index": 162 + }, + { + "0": "1BFE4527-0634-4541-AE5B-36B56B92F78B", + "1": "A985156996696141", + "2": "1199.0", + "3": "9.0", + "4": "2023-01-25 09:00:09", + "5": "187.8833", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "2398.0", + "13": "2398.0", + "14": "1199.0", + "index": 163 + }, + { + "0": "6BC0D760-19D3-41AB-B24A-87509876A25B", + "1": "A1759222251254350", + "2": "516.24", + "3": "10.0", + "4": "2023-02-23 18:27:57", + "9": "1", + "10": "368.0", + "11": "0.0", + "12": "1032.48", + "13": "1032.48", + "14": "516.24", + "index": 164 + }, + { + "0": "6BC0D760-19D3-41AB-B24A-87509876A25B", + "1": "A1759222251254350", + "2": "516.24", + "3": "10.0", + "4": "2023-02-23 18:27:57", + "5": "514.107929", + "6": "true", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "368.0", + "11": "0.0", + "12": "1032.48", + "13": "1032.48", + "14": "516.24", + "index": 165 + }, + { + "0": "50EA1C3A-CE63-435C-BA22-4846C2024425", + "1": "A844427328211634", + "2": "104.7", + "3": "14.0", + "4": "2023-02-28 00:47:16", + "9": "1", + "10": "1893.0", + "11": "0.0", + "12": "104.7", + "13": "104.7", + "14": "104.7", + "index": 166 + }, + { + "0": "50EA1C3A-CE63-435C-BA22-4846C2024425", + "1": "A844427328211634", + "2": "104.7", + "3": "14.0", + "4": "2023-02-28 00:47:16", + "5": "104.7", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "1893.0", + "11": "0.0", + "12": "104.7", + "13": "104.7", + "14": "104.7", + "index": 167 + }, + { + "0": "4BE98D88-C717-4C24-809B-1A92A1FFCEBC", + "1": "A1759222234548900", + "2": "73080.0", + "3": "23.0", + "4": "2023-03-07 15:02:16", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "146160.0", + "13": "146160.0", + "14": "73080.0", + "index": 168 + }, + { + "0": "C110E452-388B-4D53-A271-DE2C06DB410A", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:17:45", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "647.88", + "13": "647.88", + "14": "53.99", + "index": 169 + }, + { + "0": "AF5BC5D5-9280-4F4A-860B-D8A4772823AD", + "1": "A985157000299534", + "2": "281.37", + "3": "14.0", + "4": "2023-02-03 19:43:12", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "438.44", + "13": "438.44", + "14": "219.22", + "index": 170 + }, + { + "0": "3A27F1D6-6B38-461C-ACAE-DCF4F171948C", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:48:53", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "377.2999999999994", + "13": "366.5199999999994", + "14": "5.389999999999991", + "index": 171 + }, + { + "0": "3A27F1D6-6B38-461C-ACAE-DCF4F171948C", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:48:53", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "377.2999999999994", + "13": "366.5199999999994", + "14": "5.389999999999991", + "index": 172 + }, + { + "0": "96007AC1-F260-4648-97B6-3D3527611B1B", + "1": "A985157015268058", + "2": "4.99", + "3": "14.0", + "4": "2023-02-27 19:29:39", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "89.82", + "13": "89.82", + "14": "4.989999999999999", + "index": 173 + }, + { + "0": "F825E26E-89D0-43AB-B281-D62588C4779A", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 19:49:42", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "3609.279999999998", + "13": "3609.279999999998", + "14": "144.37119999999993", + "index": 174 + }, + { + "0": "4F5BE866-AC36-4BD4-8DE5-40B48B2AFD9F", + "1": "A914800364713675", + "2": "24.99", + "3": "20.0", + "4": "2023-01-06 02:18:37", + "9": "1", + "10": "911.0", + "11": "0.0", + "12": "24.99", + "13": "24.99", + "14": "24.99", + "index": 175 + }, + { + "0": "4F5BE866-AC36-4BD4-8DE5-40B48B2AFD9F", + "1": "A914800364713675", + "2": "24.99", + "3": "20.0", + "4": "2023-01-06 02:18:37", + "5": "24.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "911.0", + "11": "0.0", + "12": "24.99", + "13": "24.99", + "14": "24.99", + "index": 176 + }, + { + "0": "E23AEB7C-E6E5-45AC-BF52-15318F230F7C", + "1": "A1688852408331370", + "2": "159.85", + "3": "17.0", + "4": "2023-02-05 21:21:44", + "9": "1", + "10": "462.0", + "11": "0.0", + "12": "159.85", + "13": "159.85", + "14": "159.85", + "index": 177 + }, + { + "0": "E23AEB7C-E6E5-45AC-BF52-15318F230F7C", + "1": "A1688852408331370", + "2": "159.85", + "3": "17.0", + "4": "2023-02-05 21:21:44", + "5": "159.189819", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "462.0", + "11": "0.0", + "12": "159.85", + "13": "159.85", + "14": "159.85", + "index": 178 + }, + { + "0": "3826E27E-AAFD-4443-A7E9-A0586D2F0729", + "1": "A1829582583896790", + "2": "127.18", + "3": "7.0", + "4": "2023-02-16 12:26:58", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "254.36", + "13": "254.36", + "14": "127.18", + "index": 179 + }, + { + "0": "93796897-06CD-4111-8F2D-E27D5CE46B66", + "1": "A844427218518467", + "2": "157.94", + "3": "18.0", + "4": "2023-02-17 23:30:32", + "9": "1", + "10": "1274.0", + "11": "0.0", + "12": "315.88", + "13": "315.88", + "14": "157.94", + "index": 180 + }, + { + "0": "194011B7-EB22-403A-9B71-9964CCD499B9", + "1": "A985157024003479", + "2": "219.99", + "3": "9.0", + "4": "2023-03-09 14:44:26", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "219.99", + "13": "219.99", + "14": "219.99", + "index": 181 + }, + { + "0": "194011B7-EB22-403A-9B71-9964CCD499B9", + "1": "A985157024003479", + "2": "219.99", + "3": "9.0", + "4": "2023-03-09 14:44:26", + "5": "219.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "219.99", + "13": "219.99", + "14": "219.99", + "index": 182 + }, + { + "0": "21EB96F0-6C2C-4168-BEEA-A253EE75FE7B", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:57:10", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "458.1499999999992", + "13": "447.3699999999992", + "14": "5.389999999999991", + "index": 183 + }, + { + "0": "9BE72279-7902-492D-9265-744491E4F86D", + "1": "A985157015268058", + "2": "4.99", + "3": "14.0", + "4": "2023-02-27 20:16:50", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "124.74999999999996", + "13": "124.74999999999996", + "14": "4.989999999999998", + "index": 184 + }, + { + "0": "8717C0FD-51C1-4457-BABB-D356176DDF24", + "1": "A1899947009495910", + "2": "538.0", + "3": "21.0", + "4": "2023-03-14 13:09:53", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "538.0", + "13": "538.0", + "14": "538.0", + "index": 185 + }, + { + "0": "9B5ACCF3-D278-48E9-867E-6027988CEA01", + "1": "A1829582580775700", + "2": "65.57", + "3": "12.0", + "4": "2023-01-03 19:24:33", + "5": "65.57", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "196.70999999999998", + "13": "196.70999999999998", + "14": "65.57", + "index": 186 + }, + { + "0": "5B14DBAD-62C5-4144-B131-E1C358C623E7", + "1": "A985156723649620", + "2": "139.99", + "3": "21.0", + "4": "2023-01-11 02:28:26", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "139.99", + "13": "139.99", + "14": "139.99", + "index": 187 + }, + { + "0": "5B14DBAD-62C5-4144-B131-E1C358C623E7", + "1": "A985156723649620", + "2": "139.99", + "3": "21.0", + "4": "2023-01-11 02:28:26", + "5": "139.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "139.99", + "13": "139.99", + "14": "139.99", + "index": 188 + }, + { + "0": "11EDBDC9-2F68-4E09-8DB8-FB0D9B70B121", + "1": "A1899947003739520", + "2": "239.24", + "3": "5.0", + "4": "2023-02-17 12:13:53", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "239.24", + "13": "239.24", + "14": "239.24", + "index": 189 + }, + { + "0": "11EDBDC9-2F68-4E09-8DB8-FB0D9B70B121", + "1": "A1899947003739520", + "2": "239.24", + "3": "5.0", + "4": "2023-02-17 12:13:53", + "5": "239.24", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "239.24", + "13": "239.24", + "14": "239.24", + "index": 190 + }, + { + "0": "5CE4020A-ABA5-4B60-9BC3-131A126670C6", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:03:22", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "107.98", + "13": "107.98", + "14": "53.99", + "index": 191 + }, + { + "0": "C92FFA51-901D-4F5E-AF5A-A0F05FD9EE49", + "1": "A1899946263303050", + "2": "939.0", + "3": "19.0", + "4": "2023-02-03 18:26:23", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "939.0", + "13": "939.0", + "14": "939.0", + "index": 192 + }, + { + "0": "C92FFA51-901D-4F5E-AF5A-A0F05FD9EE49", + "1": "A1899946263303050", + "2": "939.0", + "3": "19.0", + "4": "2023-02-03 18:26:23", + "5": "170.67264", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "939.0", + "13": "939.0", + "14": "939.0", + "index": 193 + }, + { + "0": "0B666A57-4CBF-411F-A855-A7B615726FED", + "1": "A985157008993462", + "2": "105.48", + "3": "5.0", + "4": "2023-02-17 12:11:06", + "5": "105.48", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "316.44", + "13": "316.44", + "14": "105.48", + "index": 194 + }, + { + "0": "16346EB5-B1D7-438D-8F50-E46ADB6AEE9A", + "1": "A844428082778441", + "2": "157.07", + "3": "12.0", + "4": "2023-03-21 17:31:16", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "157.07", + "13": "157.07", + "14": "157.07", + "index": 195 + }, + { + "0": "038E2738-E619-431A-8597-5952B7710EF8", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 20:20:26", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "6158.77", + "13": "6158.77", + "14": "146.63738095238097", + "index": 196 + }, + { + "0": "4C959775-D5F7-4529-8198-B5CD3007D04C", + "1": "A1829581437162310", + "2": "233.19", + "3": "7.0", + "4": "2023-03-27 13:10:38", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "233.19", + "13": "233.19", + "14": "233.19", + "index": 197 + }, + { + "0": "4C959775-D5F7-4529-8198-B5CD3007D04C", + "1": "A1829581437162310", + "2": "233.19", + "3": "7.0", + "4": "2023-03-27 13:10:38", + "5": "233.19", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "233.19", + "13": "233.19", + "14": "233.19", + "index": 198 + }, + { + "0": "618987FF-BE7A-451C-B8C3-62E31CC9444E", + "1": "A985156287053363", + "2": "151.54", + "3": "18.0", + "4": "2023-01-28 00:37:51", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "151.54", + "13": "151.54", + "14": "151.54", + "index": 199 + }, + { + "0": "618987FF-BE7A-451C-B8C3-62E31CC9444E", + "1": "A985156287053363", + "2": "151.54", + "3": "18.0", + "4": "2023-01-28 00:37:51", + "5": "151.54", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "151.54", + "13": "151.54", + "14": "151.54", + "index": 200 + }, + { + "0": "2616D25E-605D-4D13-A747-8056ACC9FECC", + "1": "A1759221088015650", + "2": "239.0", + "3": "14.0", + "4": "2023-02-15 18:07:30", + "9": "1", + "10": "370.0", + "11": "0.0", + "12": "239.0", + "13": "239.0", + "14": "239.0", + "index": 201 + }, + { + "0": "2616D25E-605D-4D13-A747-8056ACC9FECC", + "1": "A1759221088015650", + "2": "239.0", + "3": "14.0", + "4": "2023-02-15 18:07:30", + "5": "120.10945", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "370.0", + "11": "0.0", + "12": "239.0", + "13": "239.0", + "14": "239.0", + "index": 202 + }, + { + "0": "0D20ED93-B1A8-4C3D-A492-FB63C8C2D3D6", + "1": "A1688853596363060", + "2": "60.59", + "3": "6.0", + "4": "2023-02-16 12:00:13", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "181.77", + "13": "181.77", + "14": "60.59", + "index": 203 + }, + { + "0": "0D20ED93-B1A8-4C3D-A492-FB63C8C2D3D6", + "1": "A1688853596363060", + "2": "60.59", + "3": "6.0", + "4": "2023-02-16 12:00:13", + "5": "60.59", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "181.77", + "13": "181.77", + "14": "60.59", + "index": 204 + }, + { + "0": "A6FD29AF-1C86-4558-8D18-89D7F53EC691", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:29:54", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "70.07", + "13": "70.07", + "14": "5.39", + "index": 205 + }, + { + "0": "A06EBEB4-92ED-4F42-8211-F28EC67E5DF5", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-28 13:18:42", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "560.5599999999989", + "13": "220.98999999999975", + "14": "5.38999999999999", + "index": 206 + }, + { + "0": "833FA1C1-EC94-4F61-AE86-EAF339165BD2", + "1": "A1688852068178080", + "2": "109.99", + "3": "20.0", + "4": "2023-01-07 05:19:25", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "109.99", + "13": "109.99", + "14": "109.99", + "index": 207 + }, + { + "0": "833FA1C1-EC94-4F61-AE86-EAF339165BD2", + "1": "A1688852068178080", + "2": "109.99", + "3": "20.0", + "4": "2023-01-07 05:19:25", + "5": "109.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "109.99", + "13": "109.99", + "14": "109.99", + "index": 208 + }, + { + "0": "14284612-9202-42B8-B994-098182BD9553", + "1": "A1055521397087470", + "2": "299.0", + "3": "23.0", + "4": "2023-02-09 14:07:44", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "598.0", + "13": "598.0", + "14": "299.0", + "index": 209 + }, + { + "0": "14284612-9202-42B8-B994-098182BD9553", + "1": "A1055521397087470", + "2": "299.0", + "3": "23.0", + "4": "2023-02-09 14:07:44", + "5": "312.55965", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "598.0", + "13": "598.0", + "14": "299.0", + "index": 210 + }, + { + "0": "B9388B0B-6649-4EC4-8C4F-D6E9293CC8CA", + "1": "A1899946341703750", + "2": "406.78", + "3": "19.0", + "4": "2023-01-02 00:41:25", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "406.78", + "13": "406.78", + "14": "406.78", + "index": 211 + }, + { + "0": "B9388B0B-6649-4EC4-8C4F-D6E9293CC8CA", + "1": "A1899946341703750", + "2": "406.78", + "3": "19.0", + "4": "2023-01-02 00:41:25", + "5": "405.099999", + "6": "false", + "7": "0.0", + "8": "2.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "406.78", + "13": "406.78", + "14": "406.78", + "index": 212 + }, + { + "0": "57C6D5D6-43F4-4BD0-9FF5-67E4BB395B99", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 19:15:43", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "2259.5499999999997", + "13": "2259.5499999999997", + "14": "141.22187499999998", + "index": 213 + }, + { + "0": "2FAF5C96-CEE4-4D17-BEE6-EB27DF5351E7", + "1": "A844427390246047", + "2": "5.39", + "3": "6.0", + "4": "2023-02-25 12:20:41", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "258.7199999999997", + "13": "247.93999999999969", + "14": "5.3899999999999935", + "index": 214 + }, + { + "0": "1E8F78CA-543C-46F5-A429-593B1B48D8E9", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:33:02", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "91.63", + "13": "91.63", + "14": "5.39", + "index": 215 + }, + { + "0": "2FAF5C96-CEE4-4D17-BEE6-EB27DF5351E7", + "1": "A844427390246047", + "2": "5.39", + "3": "6.0", + "4": "2023-02-25 12:20:41", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "258.7199999999997", + "13": "247.93999999999969", + "14": "5.3899999999999935", + "index": 216 + }, + { + "0": "3FB022CD-5FEE-43CE-A742-F25EFC9F48DF", + "1": "A1688853657869890", + "2": "52.99", + "3": "10.0", + "4": "2023-01-03 17:06:11", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "370.93", + "13": "370.93", + "14": "52.99", + "index": 217 + }, + { + "0": "636DA8EE-8D04-49D9-9BFE-21FAE9991FE6", + "1": "A1055521380537310", + "2": "129.58", + "3": "13.0", + "4": "2023-01-03 18:57:29", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "323.95000000000005", + "13": "323.95000000000005", + "14": "107.98333333333335", + "index": 218 + }, + { + "0": "4324B9F6-5D21-4327-B80F-99057A3B541C", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:33:20", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "299.95", + "13": "299.95", + "14": "59.989999999999995", + "index": 219 + }, + { + "0": "7DCB85C6-1524-4E97-8638-7324B5A49568", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:45:54", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "459.7700000000001", + "13": "459.7700000000001", + "14": "19.990000000000006", + "index": 220 + }, + { + "0": "9E492C70-9940-4103-9414-FC8F0C741490", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:27:34", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "219.89000000000001", + "13": "219.89000000000001", + "14": "19.990000000000002", + "index": 221 + }, + { + "0": "7DCB85C6-1524-4E97-8638-7324B5A49568", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:45:54", + "5": "19.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "459.7700000000001", + "13": "459.7700000000001", + "14": "19.990000000000006", + "index": 222 + }, + { + "0": "A4B91F8E-04B2-4A1C-B612-10F42C760989", + "1": "A844427101383089", + "2": "519.99", + "3": "14.0", + "4": "2023-03-10 22:51:49", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "519.99", + "13": "519.99", + "14": "519.99", + "index": 223 + }, + { + "0": "A4B91F8E-04B2-4A1C-B612-10F42C760989", + "1": "A844427101383089", + "2": "519.99", + "3": "14.0", + "4": "2023-03-10 22:51:49", + "5": "519.99", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "519.99", + "13": "519.99", + "14": "519.99", + "index": 224 + }, + { + "0": "3D4366E9-508C-4391-A2BD-1CD19A6A3E28", + "1": "A1899946665040220", + "2": "75.76", + "3": "10.0", + "4": "2023-03-23 08:35:31", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "75.76", + "13": "75.76", + "14": "75.76", + "index": 225 + }, + { + "0": "3D4366E9-508C-4391-A2BD-1CD19A6A3E28", + "1": "A1899946665040220", + "2": "75.76", + "3": "10.0", + "4": "2023-03-23 08:35:31", + "5": "75.76", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "75.76", + "13": "75.76", + "14": "75.76", + "index": 226 + }, + { + "0": "9E9BB950-7681-4213-B8D7-1E71AE232C43", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 19:55:40", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "4059.1899999999973", + "13": "4059.1899999999973", + "14": "144.97107142857132", + "index": 227 + }, + { + "0": "E112F541-98DE-420B-B009-FAA21420164B", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:45:00", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "459.7700000000001", + "13": "459.7700000000001", + "14": "19.990000000000006", + "index": 228 + }, + { + "0": "A9D4BF3B-D29D-4BDA-9209-AEED53CF20D3", + "1": "A1899946943634320", + "2": "189.99", + "3": "12.0", + "4": "2023-01-15 12:46:20", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "189.99", + "13": "189.99", + "14": "189.99", + "index": 229 + }, + { + "0": "A9D4BF3B-D29D-4BDA-9209-AEED53CF20D3", + "1": "A1899946943634320", + "2": "189.99", + "3": "12.0", + "4": "2023-01-15 12:46:20", + "5": "299.21525099999997", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "189.99", + "13": "189.99", + "14": "189.99", + "index": 230 + }, + { + "0": "B44556BB-1C72-4B05-B89B-8B078FE110FC", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:58:46", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "140.13999999999996", + "13": "129.35999999999999", + "14": "5.389999999999999", + "index": 231 + }, + { + "0": "F6A4299A-ECE2-4DBA-BFC5-07E405117646", + "1": "A985157039468116", + "2": "719.0", + "3": "13.0", + "4": "2023-03-27 13:39:14", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "719.0", + "13": "719.0", + "14": "719.0", + "index": 232 + }, + { + "0": "F6A4299A-ECE2-4DBA-BFC5-07E405117646", + "1": "A985157039468116", + "2": "719.0", + "3": "13.0", + "4": "2023-03-27 13:39:14", + "5": "1132.3531", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "719.0", + "13": "719.0", + "14": "719.0", + "index": 233 + }, + { + "0": "84633227-12F0-4157-AEA8-4F844146BC47", + "1": "A985156984009293", + "2": "15.85", + "3": "9.0", + "4": "2023-01-06 17:45:55", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "143.04", + "13": "143.04", + "14": "71.52", + "index": 234 + }, + { + "0": "287F81B6-06F6-4C3B-8714-401FA70EC7DA", + "1": "A1688853657886190", + "2": "53.99", + "3": "13.0", + "4": "2023-01-03 18:29:49", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1025.81", + "13": "1025.81", + "14": "53.989999999999995", + "index": 235 + }, + { + "0": "19DB47CE-E027-4D8D-8439-ADCC4BBE9879", + "1": "A1899946873142120", + "2": "59.99", + "3": "13.0", + "4": "2023-01-03 18:42:51", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "59.99", + "13": "59.99", + "14": "59.99", + "index": 236 + }, + { + "0": "C00398AE-B078-415C-BB5D-1F29152F4B00", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:26:26", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "53.9", + "13": "53.9", + "14": "5.39", + "index": 237 + }, + { + "0": "C00398AE-B078-415C-BB5D-1F29152F4B00", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:26:26", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "53.9", + "13": "53.9", + "14": "5.39", + "index": 238 + }, + { + "0": "813EDBBA-D2FF-4316-AA18-DCBCC923619D", + "1": "A1899947010059410", + "2": "73080.0", + "3": "23.0", + "4": "2023-03-07 14:23:01", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 239 + }, + { + "0": "813EDBBA-D2FF-4316-AA18-DCBCC923619D", + "1": "A1899947010059410", + "2": "73080.0", + "3": "23.0", + "4": "2023-03-07 14:23:01", + "5": "806.0724", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 240 + }, + { + "0": "4845B1D4-5FDF-49EA-B755-594CBEF3B4E6", + "1": "A1829582358242680", + "2": "239.51", + "3": "9.0", + "4": "2023-02-23 14:52:47", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "479.02", + "13": "479.02", + "14": "239.51", + "index": 241 + }, + { + "0": "4845B1D4-5FDF-49EA-B755-594CBEF3B4E6", + "1": "A1829582358242680", + "2": "239.51", + "3": "9.0", + "4": "2023-02-23 14:52:47", + "5": "239.51", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "479.02", + "13": "479.02", + "14": "239.51", + "index": 242 + }, + { + "0": "128EAA6F-8869-498D-8ADD-990F268B7F4D", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:35:59", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "285.6699999999996", + "13": "274.88999999999965", + "14": "5.389999999999993", + "index": 243 + }, + { + "0": "D52E262C-77C6-4C20-B9FA-F5A408BED455", + "1": "A985157015268058", + "2": "4.99", + "3": "14.0", + "4": "2023-02-27 19:31:12", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "99.79999999999998", + "13": "99.79999999999998", + "14": "4.989999999999999", + "index": 244 + }, + { + "0": "04A6E453-2077-4703-BA51-A0803BBC7F94", + "1": "A564049508937862", + "2": "99.0", + "4": "2023-02-09 07:53:48", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "99.0", + "13": "99.0", + "14": "99.0", + "index": 245 + }, + { + "0": "04A6E453-2077-4703-BA51-A0803BBC7F94", + "1": "A564049508937862", + "2": "99.0", + "4": "2023-02-09 07:53:48", + "5": "99.0", + "6": "false", + "7": "1.0", + "8": "1.0", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "99.0", + "13": "99.0", + "14": "99.0", + "index": 246 + }, + { + "0": "043408BB-F09D-4E53-B3BB-A24E0AD4BDF6", + "1": "A844427390246047", + "2": "5.39", + "3": "5.0", + "4": "2023-02-25 11:17:46", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "220.98999999999975", + "13": "210.20999999999978", + "14": "5.389999999999994", + "index": 247 + }, + { + "0": "FB41B881-4D5F-4357-9363-35FB4856F4B6", + "1": "A844427390246047", + "2": "5.39", + "3": "9.0", + "4": "2023-02-28 14:34:37", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "592.8999999999988", + "13": "253.32999999999967", + "14": "5.389999999999989", + "index": 248 + }, + { + "0": "043408BB-F09D-4E53-B3BB-A24E0AD4BDF6", + "1": "A844427390246047", + "2": "5.39", + "3": "5.0", + "4": "2023-02-25 11:17:46", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "220.98999999999975", + "13": "210.20999999999978", + "14": "5.389999999999994", + "index": 249 + }, + { + "0": "63C571C9-4D3A-4A6F-84AF-7339ABF5FDDA", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 21:15:21", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "177.86999999999986", + "13": "167.0899999999999", + "14": "5.389999999999996", + "index": 250 + }, + { + "0": "63C571C9-4D3A-4A6F-84AF-7339ABF5FDDA", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 21:15:21", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "177.86999999999986", + "13": "167.0899999999999", + "14": "5.389999999999996", + "index": 251 + }, + { + "0": "E08DDC49-612E-4227-90CA-79EBCF477113", + "1": "A1055520836257310", + "2": "5.04", + "3": "5.0", + "4": "2023-02-27 10:37:29", + "5": "5.04", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "1555.0", + "11": "0.0", + "12": "5.04", + "13": "5.04", + "14": "5.04", + "index": 252 + }, + { + "0": "C43487B3-4C79-46C9-B163-EB704D6F28A1", + "1": "A1899947009494720", + "2": "538.0", + "3": "13.0", + "4": "2023-03-17 04:53:51", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "538.0", + "13": "538.0", + "14": "538.0", + "index": 253 + }, + { + "0": "C43487B3-4C79-46C9-B163-EB704D6F28A1", + "1": "A1899947009494720", + "2": "538.0", + "3": "13.0", + "4": "2023-03-17 04:53:51", + "5": "725.1164", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "538.0", + "13": "538.0", + "14": "538.0", + "index": 254 + }, + { + "0": "45544389-E451-4D60-9BF6-261176776209", + "1": "A914801018161878", + "2": "99.99", + "3": "3.0", + "4": "2023-03-19 11:28:54", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "99.99", + "13": "99.99", + "14": "99.99", + "index": 255 + }, + { + "0": "45544389-E451-4D60-9BF6-261176776209", + "1": "A914801018161878", + "2": "99.99", + "3": "3.0", + "4": "2023-03-19 11:28:54", + "5": "99.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "99.99", + "13": "99.99", + "14": "99.99", + "index": 256 + }, + { + "0": "ADB8EB04-9D65-43A5-9CF1-5F86D904FC18", + "1": "A1055521380537310", + "2": "129.58", + "3": "13.0", + "4": "2023-01-03 18:59:06", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "453.5300000000001", + "13": "453.5300000000001", + "14": "113.38250000000002", + "index": 257 + }, + { + "0": "F2CD36F5-0FC9-4DBF-9D5A-D6B043795C0C", + "1": "A914801007105746", + "2": "83.06", + "3": "8.0", + "4": "2023-01-23 16:39:58", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "83.06", + "13": "83.06", + "14": "83.06", + "index": 258 + }, + { + "0": "A6447B92-1029-48D5-9B03-086284B006CB", + "1": "A1055521395048230", + "2": "83.14", + "3": "12.0", + "4": "2023-01-26 18:16:50", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "164.74", + "13": "164.74", + "14": "82.37", + "index": 259 + }, + { + "0": "A6447B92-1029-48D5-9B03-086284B006CB", + "1": "A1055521395048230", + "2": "83.14", + "3": "12.0", + "4": "2023-01-26 18:16:50", + "5": "83.14", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "164.74", + "13": "164.74", + "14": "82.37", + "index": 260 + }, + { + "0": "F6D8E9B1-CC74-48F9-B46C-F74DE6E82491", + "1": "A1759220976223180", + "2": "1079.0", + "3": "12.0", + "4": "2023-02-12 16:12:13", + "9": "1", + "10": "477.0", + "11": "0.0", + "12": "1079.0", + "13": "1079.0", + "14": "1079.0", + "index": 261 + }, + { + "0": "F6D8E9B1-CC74-48F9-B46C-F74DE6E82491", + "1": "A1759220976223180", + "2": "1079.0", + "3": "12.0", + "4": "2023-02-12 16:12:13", + "5": "542.25145", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "477.0", + "11": "0.0", + "12": "1079.0", + "13": "1079.0", + "14": "1079.0", + "index": 262 + }, + { + "0": "5F25E7A1-C8CF-4262-9365-D8D8BBADBD2A", + "1": "A1055520529067390", + "2": "163.16", + "3": "21.0", + "4": "2023-02-18 06:00:32", + "9": "1", + "10": "708.0", + "11": "0.0", + "12": "163.16", + "13": "163.16", + "14": "163.16", + "index": 263 + }, + { + "0": "5F25E7A1-C8CF-4262-9365-D8D8BBADBD2A", + "1": "A1055520529067390", + "2": "163.16", + "3": "21.0", + "4": "2023-02-18 06:00:32", + "5": "163.16", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "708.0", + "11": "0.0", + "12": "163.16", + "13": "163.16", + "14": "163.16", + "index": 264 + }, + { + "0": "2389B79E-4A88-416B-BF63-86DDD4CE0095", + "1": "A985156821621035", + "2": "152.03", + "3": "22.0", + "4": "2023-02-22 05:28:18", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "304.06", + "13": "304.06", + "14": "152.03", + "index": 265 + }, + { + "0": "2389B79E-4A88-416B-BF63-86DDD4CE0095", + "1": "A985156821621035", + "2": "152.03", + "3": "22.0", + "4": "2023-02-22 05:28:18", + "5": "152.03", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "304.06", + "13": "304.06", + "14": "152.03", + "index": 266 + }, + { + "0": "3FC40238-6110-46A6-BE38-CF80320791A1", + "1": "A985157015268058", + "2": "4.99", + "3": "15.0", + "4": "2023-02-27 20:28:41", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "129.73999999999995", + "13": "129.73999999999995", + "14": "4.989999999999998", + "index": 267 + }, + { + "0": "C2AE42D7-53F6-424F-8470-4B2EF42612EB", + "1": "A1688853662168790", + "2": "62580.0", + "3": "12.0", + "4": "2023-03-13 04:19:44", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "62580.0", + "13": "62580.0", + "14": "62580.0", + "index": 268 + }, + { + "0": "A8410FBF-9EE3-4200-A0ED-05631423E0F9", + "1": "A985156996696141", + "2": "1199.0", + "3": "9.0", + "4": "2023-01-25 08:58:29", + "5": "187.8833", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "1199.0", + "13": "1199.0", + "14": "1199.0", + "index": 269 + }, + { + "0": "EA452A8D-BA16-42A9-BC9E-D2A1ECE62675", + "1": "A844427390246047", + "2": "5.39", + "3": "13.0", + "4": "2023-02-24 19:13:51", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "2365.0", + "11": "3.0", + "12": "21.56", + "13": "21.56", + "14": "5.39", + "index": 270 + }, + { + "0": "F70F7BCA-6F5F-4C6C-BEE4-6C92B53E5816", + "1": "A1829582586398540", + "2": "587.0", + "3": "21.0", + "4": "2023-02-03 21:10:03", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "587.0", + "13": "587.0", + "14": "587.0", + "index": 271 + }, + { + "0": "8BD69B6D-0367-4EED-AE01-5A28B815C999", + "1": "A1899945509487400", + "2": "10.81", + "3": "20.0", + "4": "2023-02-26 03:01:05", + "9": "1", + "10": "1310.0", + "11": "0.0", + "12": "16.21", + "13": "16.21", + "14": "8.105", + "index": 272 + }, + { + "0": "8BD69B6D-0367-4EED-AE01-5A28B815C999", + "1": "A1899945509487400", + "2": "10.81", + "3": "20.0", + "4": "2023-02-26 03:01:05", + "5": "10.81", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "1310.0", + "11": "0.0", + "12": "16.21", + "13": "16.21", + "14": "8.105", + "index": 273 + }, + { + "0": "4DA0DA18-1900-48F9-8FAD-2E31FA77C64F", + "1": "A1829581772655040", + "2": "1499.0", + "3": "14.0", + "4": "2023-01-16 21:02:41", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1499.0", + "13": "1499.0", + "14": "1499.0", + "index": 274 + }, + { + "0": "4DA0DA18-1900-48F9-8FAD-2E31FA77C64F", + "1": "A1829581772655040", + "2": "1499.0", + "3": "14.0", + "4": "2023-01-16 21:02:41", + "5": "118.002779", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1499.0", + "13": "1499.0", + "14": "1499.0", + "index": 275 + }, + { + "0": "EE63EE82-8A5F-4422-8CFA-3CF0C48D05FD", + "1": "A1688853524321290", + "2": "49.98", + "3": "19.0", + "4": "2023-01-05 00:32:25", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "74.97", + "13": "74.97", + "14": "37.485", + "index": 276 + }, + { + "0": "673A772C-71A1-4541-8468-7298A4FC0844", + "1": "A1899946873128090", + "2": "75.58", + "3": "20.0", + "4": "2023-02-15 02:34:45", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "75.58", + "13": "75.58", + "14": "75.58", + "index": 277 + }, + { + "0": "EC8BF756-2E01-4485-9B7E-12363CAAE435", + "1": "A1688853432603810", + "2": "238.14", + "3": "5.0", + "4": "2023-02-22 12:12:28", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "238.14", + "13": "238.14", + "14": "238.14", + "index": 278 + }, + { + "0": "EC8BF756-2E01-4485-9B7E-12363CAAE435", + "1": "A1688853432603810", + "2": "238.14", + "3": "5.0", + "4": "2023-02-22 12:12:28", + "5": "238.14", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "238.14", + "13": "238.14", + "14": "238.14", + "index": 279 + }, + { + "0": "D0F517D0-F18C-41DE-A53F-65C3264C4C5E", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:13:40", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "485.91", + "13": "485.91", + "14": "53.99", + "index": 280 + }, + { + "0": "8B6010EB-EB1A-4AFE-9E41-0EB3FFF81CC7", + "1": "A844428024841325", + "2": "149.79", + "3": "6.0", + "4": "2023-02-14 12:06:06", + "9": "1", + "10": "413.0", + "11": "0.0", + "12": "149.79", + "13": "149.79", + "14": "149.79", + "index": 281 + }, + { + "0": "8B6010EB-EB1A-4AFE-9E41-0EB3FFF81CC7", + "1": "A844428024841325", + "2": "149.79", + "3": "6.0", + "4": "2023-02-14 12:06:06", + "5": "149.79", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "413.0", + "11": "0.0", + "12": "149.79", + "13": "149.79", + "14": "149.79", + "index": 282 + }, + { + "0": "A67953E3-06C2-413F-BD06-8473F7C202F4", + "1": "A1055521435190160", + "2": "281.37", + "3": "17.0", + "4": "2023-03-29 23:20:24", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "281.37", + "13": "281.37", + "14": "281.37", + "index": 283 + }, + { + "0": "A67953E3-06C2-413F-BD06-8473F7C202F4", + "1": "A1055521435190160", + "2": "281.37", + "3": "17.0", + "4": "2023-03-29 23:20:24", + "5": "280.207942", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "281.37", + "13": "281.37", + "14": "281.37", + "index": 284 + }, + { + "0": "E2D03B65-3D85-4453-902F-6AED9194A7AD", + "1": "A1899946969878610", + "2": "65.54", + "3": "13.0", + "4": "2023-01-30 18:38:24", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "65.54", + "13": "65.54", + "14": "65.54", + "index": 285 + }, + { + "0": "E2D03B65-3D85-4453-902F-6AED9194A7AD", + "1": "A1899946969878610", + "2": "65.54", + "3": "13.0", + "4": "2023-01-30 18:38:24", + "5": "65.54", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "65.54", + "13": "65.54", + "14": "65.54", + "index": 286 + }, + { + "0": "43BF9531-63BE-46A1-AA90-CFD08FEB3BBB", + "1": "A985157015268058", + "2": "4.99", + "3": "10.0", + "4": "2023-02-27 15:41:50", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "74.85000000000001", + "13": "74.85000000000001", + "14": "4.99", + "index": 287 + }, + { + "0": "783D965E-660F-4591-8AB5-3F3327E0B8AB", + "1": "A1759222095873190", + "2": "160.47", + "3": "11.0", + "4": "2023-01-03 17:41:15", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "320.94", + "13": "320.94", + "14": "106.98", + "index": 288 + }, + { + "0": "ECC38318-E094-4FAA-9638-6C664AB49DB8", + "1": "A985157000491580", + "2": "299.0", + "3": "19.0", + "4": "2023-02-05 10:03:12", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "698.99", + "13": "698.99", + "14": "349.495", + "index": 289 + }, + { + "0": "29111CE5-5A24-49BB-A358-0793FC585801", + "1": "A985157010264242", + "2": "73080.0", + "3": "15.0", + "4": "2023-02-19 07:09:04", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 290 + }, + { + "0": "29111CE5-5A24-49BB-A358-0793FC585801", + "1": "A985157010264242", + "2": "73080.0", + "3": "15.0", + "4": "2023-02-19 07:09:04", + "5": "806.0724", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 291 + }, + { + "0": "0B787893-9340-4DE8-9CEF-AFFCD6BB8AB0", + "1": "A914800689334401", + "2": "109.99", + "3": "10.0", + "4": "2023-03-04 18:46:15", + "9": "1", + "10": "372.0", + "11": "0.0", + "12": "109.99", + "13": "109.99", + "14": "109.99", + "index": 292 + }, + { + "0": "B117C813-5EB9-4747-92B5-C52D520AC13F", + "1": "A1688853657886190", + "2": "53.99", + "3": "13.0", + "4": "2023-01-03 18:36:39", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1295.76", + "13": "1295.76", + "14": "53.99", + "index": 293 + }, + { + "0": "4560AC71-6EB0-4590-8C1D-F39E8C2B743A", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:48:57", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "339.5699999999995", + "13": "328.7899999999995", + "14": "5.389999999999992", + "index": 294 + }, + { + "0": "A02AA3CD-C055-4B0D-93B3-5D84CFDED0D7", + "1": "A1759222251254350", + "2": "516.24", + "3": "12.0", + "4": "2023-02-21 17:46:31", + "9": "1", + "10": "368.0", + "11": "0.0", + "12": "516.24", + "13": "516.24", + "14": "516.24", + "index": 295 + }, + { + "0": "B40CF2C8-A5D3-439B-BEC7-E8E70A0E3317", + "1": "A1759222234549810", + "2": "73080.0", + "3": "19.0", + "4": "2023-03-01 10:39:15", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 296 + }, + { + "0": "B40CF2C8-A5D3-439B-BEC7-E8E70A0E3317", + "1": "A1759222234549810", + "2": "73080.0", + "3": "19.0", + "4": "2023-03-01 10:39:15", + "5": "806.0724", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 297 + }, + { + "0": "DA98CDF2-61C3-44C2-9ABA-1364BB7671AF", + "1": "A914800150734044", + "2": "593.58", + "3": "16.0", + "4": "2023-03-13 22:02:01", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "593.58", + "13": "593.58", + "14": "593.58", + "index": 298 + }, + { + "0": "DA98CDF2-61C3-44C2-9ABA-1364BB7671AF", + "1": "A914800150734044", + "2": "593.58", + "3": "16.0", + "4": "2023-03-13 22:02:01", + "5": "593.58", + "6": "false", + "7": "0.0", + "8": "2.0", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "593.58", + "13": "593.58", + "14": "593.58", + "index": 299 + }, + { + "0": "53F9A1F3-DB12-474B-8E9B-E6ADF22699AF", + "1": "A914800996051170", + "2": "139.99", + "3": "17.0", + "4": "2023-01-07 22:30:40", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "139.99", + "13": "139.99", + "14": "139.99", + "index": 300 + }, + { + "0": "C61F74AD-F654-4042-9DFF-567978FA7CF7", + "1": "A1829582571089880", + "2": "233.19", + "3": "21.0", + "4": "2023-01-28 05:57:11", + "5": "233.19", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "699.5699999999999", + "13": "699.5699999999999", + "14": "233.18999999999997", + "index": 301 + }, + { + "0": "B887357A-871E-425D-B17D-B1E7DF59A7EC", + "1": "A914801011218316", + "2": "224.11", + "3": "7.0", + "4": "2023-01-29 13:19:28", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "224.11", + "13": "224.11", + "14": "224.11", + "index": 302 + }, + { + "0": "B887357A-871E-425D-B17D-B1E7DF59A7EC", + "1": "A914801011218316", + "2": "224.11", + "3": "7.0", + "4": "2023-01-29 13:19:28", + "5": "224.11", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "224.11", + "13": "224.11", + "14": "224.11", + "index": 303 + }, + { + "0": "34DE06CA-82E2-44D3-8E83-E650A493EE27", + "1": "A1899946873142120", + "2": "149.97", + "3": "15.0", + "4": "2023-01-03 20:50:42", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "7958.4100000000035", + "13": "7958.4100000000035", + "14": "147.37796296296304", + "index": 304 + }, + { + "0": "E904965B-8DFE-4819-80DF-FE6E0F50F4E4", + "1": "A914801013785993", + "2": "95.02", + "3": "9.0", + "4": "2023-02-02 15:05:15", + "9": "1", + "10": "371.0", + "11": "0.0", + "12": "95.02", + "13": "95.02", + "14": "95.02", + "index": 305 + }, + { + "0": "E904965B-8DFE-4819-80DF-FE6E0F50F4E4", + "1": "A914801013785993", + "2": "95.02", + "3": "9.0", + "4": "2023-02-02 15:05:15", + "5": "95.02", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "371.0", + "11": "0.0", + "12": "95.02", + "13": "95.02", + "14": "95.02", + "index": 306 + }, + { + "0": "86EB854A-E34C-444F-92F2-3567FEEA91A3", + "1": "A1759222219152450", + "2": "237.04", + "3": "10.0", + "4": "2023-01-18 17:19:48", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "237.04", + "13": "237.04", + "14": "237.04", + "index": 307 + }, + { + "0": "86EB854A-E34C-444F-92F2-3567FEEA91A3", + "1": "A1759222219152450", + "2": "237.04", + "3": "10.0", + "4": "2023-01-18 17:19:48", + "5": "237.04", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "237.04", + "13": "237.04", + "14": "237.04", + "index": 308 + }, + { + "0": "2CBAE444-87AF-4760-9B86-846E0F5A8DBF", + "1": "A1759221413220100", + "2": "999999.0", + "3": "19.0", + "4": "2023-01-29 12:43:18", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "999999.0", + "13": "999999.0", + "14": "999999.0", + "index": 309 + }, + { + "0": "2CBAE444-87AF-4760-9B86-846E0F5A8DBF", + "1": "A1759221413220100", + "2": "999999.0", + "3": "19.0", + "4": "2023-01-29 12:43:18", + "5": "102.999897", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "999999.0", + "13": "999999.0", + "14": "999999.0", + "index": 310 + }, + { + "0": "D74E0304-9D1B-40AC-8418-33C7FD7FDBD9", + "1": "A844428056745591", + "2": "249.95", + "3": "12.0", + "4": "2023-02-16 20:40:53", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "299.94", + "13": "299.94", + "14": "149.97", + "index": 311 + }, + { + "0": "E720050B-91AD-4ECE-8F88-CA91D6A18E39", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:41:10", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "307.22999999999956", + "13": "296.4499999999996", + "14": "5.389999999999993", + "index": 312 + }, + { + "0": "96AEA45B-C521-487A-890A-A5EFD5109973", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-28 13:16:17", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "555.1699999999989", + "13": "215.59999999999977", + "14": "5.38999999999999", + "index": 313 + }, + { + "0": "E720050B-91AD-4ECE-8F88-CA91D6A18E39", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:41:10", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "307.22999999999956", + "13": "296.4499999999996", + "14": "5.389999999999993", + "index": 314 + }, + { + "0": "96AEA45B-C521-487A-890A-A5EFD5109973", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-28 13:16:17", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "555.1699999999989", + "13": "215.59999999999977", + "14": "5.38999999999999", + "index": 315 + }, + { + "0": "375FCC05-7C62-492F-92F5-53AF0EEDE57A", + "1": "A1759222234549920", + "2": "73080.0", + "3": "8.0", + "4": "2023-03-05 23:38:47", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "146160.0", + "13": "146160.0", + "14": "73080.0", + "index": 316 + }, + { + "0": "375FCC05-7C62-492F-92F5-53AF0EEDE57A", + "1": "A1759222234549920", + "2": "73080.0", + "3": "8.0", + "4": "2023-03-05 23:38:47", + "5": "806.0724", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "146160.0", + "13": "146160.0", + "14": "73080.0", + "index": 317 + }, + { + "0": "43C9065E-A514-4250-85E7-77C8768EB061", + "1": "A985157038112964", + "2": "150.14", + "3": "21.0", + "4": "2023-03-26 03:20:21", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "150.14", + "13": "150.14", + "14": "150.14", + "index": 318 + }, + { + "0": "43C9065E-A514-4250-85E7-77C8768EB061", + "1": "A985157038112964", + "2": "150.14", + "3": "21.0", + "4": "2023-03-26 03:20:21", + "5": "150.14", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "150.14", + "13": "150.14", + "14": "150.14", + "index": 319 + }, + { + "0": "56176B76-FFD4-4252-8BAD-C8F0E105EE2E", + "1": "A985157008993462", + "2": "105.48", + "3": "5.0", + "4": "2023-02-17 11:52:43", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "105.48", + "13": "105.48", + "14": "105.48", + "index": 320 + }, + { + "0": "EA959383-BCF0-465E-AF30-DC2E5938E855", + "1": "A844427218518467", + "2": "157.94", + "3": "15.0", + "4": "2023-02-17 21:13:23", + "9": "1", + "10": "1274.0", + "11": "0.0", + "12": "157.94", + "13": "157.94", + "14": "157.94", + "index": 321 + }, + { + "0": "EA959383-BCF0-465E-AF30-DC2E5938E855", + "1": "A844427218518467", + "2": "157.94", + "3": "15.0", + "4": "2023-02-17 21:13:23", + "5": "157.94", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "1274.0", + "11": "0.0", + "12": "157.94", + "13": "157.94", + "14": "157.94", + "index": 322 + }, + { + "0": "C37B550B-F3BB-4C9A-9A7F-5133D4C9496C", + "1": "A1829582514718140", + "2": "238.14", + "3": "0.0", + "4": "2023-02-18 07:08:45", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "238.14", + "13": "238.14", + "14": "238.14", + "index": 323 + }, + { + "0": "C37B550B-F3BB-4C9A-9A7F-5133D4C9496C", + "1": "A1829582514718140", + "2": "238.14", + "3": "0.0", + "4": "2023-02-18 07:08:45", + "5": "238.14", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "238.14", + "13": "238.14", + "14": "238.14", + "index": 324 + }, + { + "0": "A440EC4D-B52B-4F0E-949A-EB6699D67175", + "1": "A844427390246047", + "2": "5.39", + "3": "6.0", + "4": "2023-02-25 12:19:54", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "253.32999999999967", + "13": "242.5499999999997", + "14": "5.389999999999993", + "index": 325 + }, + { + "0": "E32B5896-DD3D-4C40-BFAB-75C27190A55C", + "1": "A985156972392398", + "2": "152.94", + "3": "2.0", + "4": "2023-03-13 08:54:53", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "152.94", + "13": "152.94", + "14": "152.94", + "index": 326 + }, + { + "0": "E32B5896-DD3D-4C40-BFAB-75C27190A55C", + "1": "A985156972392398", + "2": "152.94", + "3": "2.0", + "4": "2023-03-13 08:54:53", + "5": "152.94", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "152.94", + "13": "152.94", + "14": "152.94", + "index": 327 + }, + { + "0": "D12B9922-D2E5-4BD2-BC6C-7486816F0AD7", + "1": "A985156993509507", + "2": "75.58", + "3": "9.0", + "4": "2023-01-19 17:28:50", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "75.58", + "13": "75.58", + "14": "75.58", + "index": 328 + }, + { + "0": "D12B9922-D2E5-4BD2-BC6C-7486816F0AD7", + "1": "A985156993509507", + "2": "75.58", + "3": "9.0", + "4": "2023-01-19 17:28:50", + "5": "75.58", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "75.58", + "13": "75.58", + "14": "75.58", + "index": 329 + }, + { + "0": "35AC8DA0-24ED-4461-B732-7994EAC7AD2C", + "1": "A1055521406038580", + "2": "73080.0", + "3": "3.0", + "4": "2023-02-22 18:23:47", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 330 + }, + { + "0": "B3B0727B-ADF3-4621-9DFC-D0C8CB6E6F26", + "1": "A985157015268058", + "2": "4.99", + "3": "14.0", + "4": "2023-02-27 19:30:41", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "99.79999999999998", + "13": "99.79999999999998", + "14": "4.989999999999999", + "index": 331 + }, + { + "0": "6EB304F3-0D0F-4767-BFBB-2ACD515CAA42", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:37:35", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "296.4499999999996", + "13": "285.6699999999996", + "14": "5.389999999999993", + "index": 332 + }, + { + "0": "389398A4-D295-416A-91AE-E890749EFC58", + "1": "A1055520836257310", + "2": "5.04", + "3": "5.0", + "4": "2023-02-28 10:30:28", + "9": "1", + "10": "1555.0", + "11": "0.0", + "12": "20.16", + "13": "20.16", + "14": "5.04", + "index": 333 + }, + { + "0": "E11DC416-B4F6-4637-9D28-1DAC96F009DA", + "1": "A1829582586398540", + "2": "119.0", + "4": "2023-01-20 09:25:52", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "905.79", + "13": "905.79", + "14": "452.895", + "index": 334 + }, + { + "0": "E11DC416-B4F6-4637-9D28-1DAC96F009DA", + "1": "A1829582586398540", + "2": "119.0", + "4": "2023-01-20 09:25:52", + "5": "160.3882", + "6": "false", + "7": "1.0", + "8": "4.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "905.79", + "13": "905.79", + "14": "452.895", + "index": 335 + }, + { + "0": "E6789403-5C39-4D44-BA7C-3A1F481E718B", + "1": "A1688853657886190", + "2": "53.99", + "3": "13.0", + "4": "2023-01-03 18:37:59", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1349.75", + "13": "1349.75", + "14": "53.99", + "index": 336 + }, + { + "0": "7F739A3C-DA4E-4B79-BF65-7D33BFD1BC39", + "1": "A844428039942859", + "2": "479.0", + "3": "22.0", + "4": "2023-01-16 23:06:38", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "479.0", + "13": "479.0", + "14": "479.0", + "index": 337 + }, + { + "0": "7F739A3C-DA4E-4B79-BF65-7D33BFD1BC39", + "1": "A844428039942859", + "2": "479.0", + "3": "22.0", + "4": "2023-01-16 23:06:38", + "5": "754.3771", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "479.0", + "13": "479.0", + "14": "479.0", + "index": 338 + }, + { + "0": "834A0619-7166-452A-9D31-1224EBB54505", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:50:48", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "404.2499999999993", + "13": "393.46999999999935", + "14": "5.389999999999991", + "index": 339 + }, + { + "0": "834A0619-7166-452A-9D31-1224EBB54505", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:50:48", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "404.2499999999993", + "13": "393.46999999999935", + "14": "5.389999999999991", + "index": 340 + }, + { + "0": "2E8C3C5B-4ECB-451D-8F50-BD946950FAC4", + "1": "A1899945509487400", + "2": "5.4", + "3": "20.0", + "4": "2023-02-26 02:50:39", + "9": "1", + "10": "1310.0", + "11": "0.0", + "12": "5.4", + "13": "5.4", + "14": "5.4", + "index": 341 + }, + { + "0": "2959008D-82E5-4A92-ABAD-15BF31D4D860", + "1": "A1055521428449680", + "2": "278.88", + "3": "22.0", + "4": "2023-03-22 03:37:49", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "557.76", + "13": "557.76", + "14": "278.88", + "index": 342 + }, + { + "0": "2959008D-82E5-4A92-ABAD-15BF31D4D860", + "1": "A1055521428449680", + "2": "278.88", + "3": "22.0", + "4": "2023-03-22 03:37:49", + "5": "277.72822599999995", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "557.76", + "13": "557.76", + "14": "278.88", + "index": 343 + }, + { + "0": "5BDE388B-8A30-4D45-8122-F7CA341442C8", + "1": "A914800889932462", + "2": "53.36", + "3": "6.0", + "4": "2023-02-16 13:00:25", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "106.72", + "13": "106.72", + "14": "53.36", + "index": 344 + }, + { + "0": "A7FC7EAE-BB1E-4E93-8BFE-E9C1B71792AB", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:52:49", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "420.4199999999993", + "13": "409.6399999999993", + "14": "5.389999999999991", + "index": 345 + }, + { + "0": "D024ED6A-545B-44B2-827E-D7B9D98C592D", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:48:23", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "377.2999999999994", + "13": "366.5199999999994", + "14": "5.389999999999991", + "index": 346 + }, + { + "0": "EFAE71B3-0EB4-413B-BFA1-541328AD3FB1", + "1": "A1055520836257310", + "2": "5.04", + "3": "6.0", + "4": "2023-02-28 12:20:56", + "9": "1", + "10": "1555.0", + "11": "0.0", + "12": "40.32", + "13": "40.32", + "14": "5.04", + "index": 347 + }, + { + "0": "EFAE71B3-0EB4-413B-BFA1-541328AD3FB1", + "1": "A1055520836257310", + "2": "5.04", + "3": "6.0", + "4": "2023-02-28 12:20:56", + "5": "5.04", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "1555.0", + "11": "0.0", + "12": "40.32", + "13": "40.32", + "14": "5.04", + "index": 348 + }, + { + "0": "DDE0B1F6-40B2-44CA-B0A7-AE46453D51A0", + "1": "A1688853657886190", + "2": "53.99", + "3": "13.0", + "4": "2023-01-03 18:25:29", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "917.83", + "13": "917.83", + "14": "53.99", + "index": 349 + }, + { + "0": "74E7FBFA-551A-4324-89BA-6CD22AA7B832", + "1": "A914800996051170", + "2": "215.64", + "3": "17.0", + "4": "2023-01-07 22:36:31", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "355.63", + "13": "355.63", + "14": "177.815", + "index": 350 + }, + { + "0": "74E7FBFA-551A-4324-89BA-6CD22AA7B832", + "1": "A914800996051170", + "2": "215.64", + "3": "17.0", + "4": "2023-01-07 22:36:31", + "5": "215.64", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "355.63", + "13": "355.63", + "14": "177.815", + "index": 351 + }, + { + "0": "7833DDCC-84C1-4818-8D57-D635B858475C", + "1": "A844427390246047", + "2": "5.39", + "3": "6.0", + "4": "2023-02-26 11:27:57", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "549.779999999999", + "13": "538.999999999999", + "14": "5.38999999999999", + "index": 352 + }, + { + "0": "7833DDCC-84C1-4818-8D57-D635B858475C", + "1": "A844427390246047", + "2": "5.39", + "3": "6.0", + "4": "2023-02-26 11:27:57", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "549.779999999999", + "13": "538.999999999999", + "14": "5.38999999999999", + "index": 353 + }, + { + "0": "138D8A92-4C50-4A5F-BA5B-7E6517F3B0B9", + "1": "A844428087822266", + "2": "278.88", + "3": "10.0", + "4": "2023-03-27 15:48:08", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "557.76", + "13": "557.76", + "14": "278.88", + "index": 354 + }, + { + "0": "CACD0238-79D3-4506-B78A-F24E494B3AAC", + "1": "A1055521395048230", + "2": "81.6", + "3": "2.0", + "4": "2023-01-25 08:02:13", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "81.6", + "13": "81.6", + "14": "81.6", + "index": 355 + }, + { + "0": "8FBB1DE1-60CE-4F82-A2E8-8CBAB946FED7", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 21:19:02", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "194.03999999999982", + "13": "183.25999999999985", + "14": "5.389999999999995", + "index": 356 + }, + { + "0": "E8CA30F7-3805-48E0-A5E6-6FD71ACF2BE2", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 21:11:36", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "167.0899999999999", + "13": "156.30999999999992", + "14": "5.389999999999996", + "index": 357 + }, + { + "0": "88CA2590-A2EA-4C19-B7E0-6B5C5DFFAABB", + "1": "A844428041278796", + "2": "789.87", + "3": "19.0", + "4": "2023-01-19 00:39:54", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "789.87", + "13": "789.87", + "14": "789.87", + "index": 358 + }, + { + "0": "88CA2590-A2EA-4C19-B7E0-6B5C5DFFAABB", + "1": "A844428041278796", + "2": "789.87", + "3": "19.0", + "4": "2023-01-19 00:39:54", + "5": "786.607837", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "789.87", + "13": "789.87", + "14": "789.87", + "index": 359 + }, + { + "0": "F4B5B955-8DD8-4BB5-9281-66E87013C42D", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:07:16", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "269.95", + "13": "269.95", + "14": "53.989999999999995", + "index": 360 + }, + { + "0": "A45B5295-84D3-47CD-AFA3-E074A9DF9EF6", + "1": "A1688853657886190", + "2": "53.99", + "3": "13.0", + "4": "2023-01-03 18:43:38", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1565.71", + "13": "1565.71", + "14": "53.99", + "index": 361 + }, + { + "0": "F4B5B955-8DD8-4BB5-9281-66E87013C42D", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:07:16", + "5": "53.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "269.95", + "13": "269.95", + "14": "53.989999999999995", + "index": 362 + }, + { + "0": "E7F77A61-785B-4E7D-8C99-6A237E368BC5", + "1": "A1899946895455190", + "2": "19.99", + "3": "12.0", + "4": "2023-01-13 17:22:25", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "39.98", + "13": "39.98", + "14": "19.99", + "index": 363 + }, + { + "0": "640D2C62-1A20-47FC-9443-79F93E1896C2", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:30:42", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "75.46", + "13": "75.46", + "14": "5.39", + "index": 364 + }, + { + "0": "640D2C62-1A20-47FC-9443-79F93E1896C2", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:30:42", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "75.46", + "13": "75.46", + "14": "5.39", + "index": 365 + }, + { + "0": "CB9D1331-694E-46E6-8A0A-0C16404FD315", + "1": "A1829582580775700", + "2": "65.57", + "3": "12.0", + "4": "2023-01-03 19:46:26", + "5": "65.57", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "590.1299999999999", + "13": "590.1299999999999", + "14": "65.57", + "index": 366 + }, + { + "0": "2CABEE6F-6606-48AA-87C9-D96C328A8C5A", + "1": "A844428046730497", + "2": "278.88", + "3": "11.0", + "4": "2023-01-29 16:24:29", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "278.88", + "13": "278.88", + "14": "278.88", + "index": 367 + }, + { + "0": "2CABEE6F-6606-48AA-87C9-D96C328A8C5A", + "1": "A844428046730497", + "2": "278.88", + "3": "11.0", + "4": "2023-01-29 16:24:29", + "5": "277.72822599999995", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "278.88", + "13": "278.88", + "14": "278.88", + "index": 368 + }, + { + "0": "17D5B8ED-6683-4647-B551-D2BBE8C798E5", + "1": "A914800889937190", + "2": "53.11", + "3": "13.0", + "4": "2023-02-16 18:28:59", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "53.11", + "13": "53.11", + "14": "53.11", + "index": 369 + }, + { + "0": "17D5B8ED-6683-4647-B551-D2BBE8C798E5", + "1": "A914800889937190", + "2": "53.11", + "3": "13.0", + "4": "2023-02-16 18:28:59", + "5": "53.11", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "53.11", + "13": "53.11", + "14": "53.11", + "index": 370 + }, + { + "0": "AAC80D62-E482-4488-801A-941B8B43E034", + "1": "A844427926468579", + "2": "54.11", + "3": "0.0", + "4": "2023-02-17 06:06:01", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "108.22", + "13": "108.22", + "14": "54.11", + "index": 371 + }, + { + "0": "AAC80D62-E482-4488-801A-941B8B43E034", + "1": "A844427926468579", + "2": "54.11", + "3": "0.0", + "4": "2023-02-17 06:06:01", + "5": "54.11", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "108.22", + "13": "108.22", + "14": "54.11", + "index": 372 + }, + { + "0": "5ABD00A4-C232-4D58-8A78-63ABE223F182", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:36:58", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "113.19", + "13": "113.19", + "14": "5.39", + "index": 373 + }, + { + "0": "88869C17-D26A-476A-95C9-A6E93170CA62", + "1": "A1688853596360510", + "2": "65.16", + "3": "0.0", + "4": "2023-02-17 06:07:08", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "65.16", + "13": "65.16", + "14": "65.16", + "index": 374 + }, + { + "0": "88869C17-D26A-476A-95C9-A6E93170CA62", + "1": "A1688853596360510", + "2": "65.16", + "3": "0.0", + "4": "2023-02-17 06:07:08", + "5": "65.16", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "65.16", + "13": "65.16", + "14": "65.16", + "index": 375 + }, + { + "0": "33A4A802-37D2-454B-9960-1B92DD51B771", + "1": "A1899947008864830", + "2": "137.3", + "3": "11.0", + "4": "2023-01-14 19:07:33", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "137.3", + "13": "137.3", + "14": "137.3", + "index": 376 + }, + { + "0": "33A4A802-37D2-454B-9960-1B92DD51B771", + "1": "A1899947008864830", + "2": "137.3", + "3": "11.0", + "4": "2023-01-14 19:07:33", + "5": "137.3", + "6": "false", + "7": "5.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "137.3", + "13": "137.3", + "14": "137.3", + "index": 377 + }, + { + "0": "AD22A063-D3FB-4623-B7A2-69A6C8E5CEE0", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 19:53:28", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "3909.2199999999975", + "13": "3909.2199999999975", + "14": "144.78592592592582", + "index": 378 + }, + { + "0": "BE25CE28-7142-4EB4-8157-77654E4816D0", + "1": "A1899946873142120", + "2": "149.97", + "3": "15.0", + "4": "2023-01-03 20:24:35", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "6458.710000000001", + "13": "6458.710000000001", + "14": "146.78886363636366", + "index": 379 + }, + { + "0": "D3F14FD5-C8C3-4401-8053-A5DCB4086473", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:30:44", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "179.97", + "13": "179.97", + "14": "59.99", + "index": 380 + }, + { + "0": "D02E8FB4-3170-4C47-8886-ABE470F197C3", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 19:03:30", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1659.67", + "13": "1659.67", + "14": "138.30583333333334", + "index": 381 + }, + { + "0": "8FD67A34-3815-4050-AD67-DF29BC551351", + "1": "A844428045623555", + "2": "80.79", + "3": "18.0", + "4": "2023-01-27 23:59:04", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "80.79", + "13": "80.79", + "14": "80.79", + "index": 382 + }, + { + "0": "8FD67A34-3815-4050-AD67-DF29BC551351", + "1": "A844428045623555", + "2": "80.79", + "3": "18.0", + "4": "2023-01-27 23:59:04", + "5": "80.79", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "80.79", + "13": "80.79", + "14": "80.79", + "index": 383 + }, + { + "0": "0D385B17-41FC-4D3B-8C36-BFD0FAF6AA20", + "1": "A1688853647452210", + "2": "423.99", + "3": "13.0", + "4": "2023-02-09 18:26:33", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "847.98", + "13": "847.98", + "14": "423.99", + "index": 384 + }, + { + "0": "03D4C75E-6EE7-421E-85F5-BD0BF2158BD4", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:33:21", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "280.27999999999963", + "13": "269.49999999999966", + "14": "5.389999999999993", + "index": 385 + }, + { + "0": "8625D6A1-D881-4521-8246-5F1B2381D71D", + "1": "A1899946865209040", + "2": "79380.0", + "3": "9.0", + "4": "2023-03-11 00:59:31", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "158760.0", + "13": "158760.0", + "14": "79380.0", + "index": 386 + }, + { + "0": "8625D6A1-D881-4521-8246-5F1B2381D71D", + "1": "A1899946865209040", + "2": "79380.0", + "3": "9.0", + "4": "2023-03-11 00:59:31", + "5": "875.5614", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "158760.0", + "13": "158760.0", + "14": "79380.0", + "index": 387 + }, + { + "0": "E44AA2DD-8814-4746-839A-4A3D8EE5F243", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:12:20", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "431.92", + "13": "431.92", + "14": "53.99", + "index": 388 + }, + { + "0": "DE6C7FAE-FE3C-4316-8585-6C5942D43B19", + "1": "A1055521395382470", + "2": "153.29", + "3": "20.0", + "4": "2023-02-06 04:24:03", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "153.29", + "13": "153.29", + "14": "153.29", + "index": 389 + }, + { + "0": "DE6C7FAE-FE3C-4316-8585-6C5942D43B19", + "1": "A1055521395382470", + "2": "153.29", + "3": "20.0", + "4": "2023-02-06 04:24:03", + "5": "153.29", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "153.29", + "13": "153.29", + "14": "153.29", + "index": 390 + }, + { + "0": "8F080C35-BA5C-41A5-8169-0EDBF1F27219", + "1": "A1759222234549860", + "2": "62580.0", + "3": "11.0", + "4": "2023-03-03 02:24:02", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "125160.0", + "13": "125160.0", + "14": "62580.0", + "index": 391 + }, + { + "0": "5AF9F5B3-7386-426B-878E-3F1B7BBF48D9", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 18:56:55", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1209.76", + "13": "1209.76", + "14": "134.4177777777778", + "index": 392 + }, + { + "0": "73F74DE9-9679-417D-A7A8-6D1D74769D9D", + "1": "A1899946873142120", + "2": "149.97", + "3": "15.0", + "4": "2023-01-03 20:28:23", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "6758.6500000000015", + "13": "6758.6500000000015", + "14": "146.9271739130435", + "index": 393 + }, + { + "0": "52961216-05ED-4183-8EF5-5237F0352C41", + "1": "A1899946944829860", + "2": "59.99", + "3": "7.0", + "4": "2023-02-16 13:17:31", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.98", + "13": "119.98", + "14": "59.99", + "index": 394 + }, + { + "0": "9824B652-A52C-42EA-8BF0-A23D678B9527", + "1": "A844427390246047", + "2": "5.39", + "3": "6.0", + "4": "2023-02-25 12:18:49", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "242.5499999999997", + "13": "231.76999999999973", + "14": "5.3899999999999935", + "index": 395 + }, + { + "0": "9824B652-A52C-42EA-8BF0-A23D678B9527", + "1": "A844427390246047", + "2": "5.39", + "3": "6.0", + "4": "2023-02-25 12:18:49", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "242.5499999999997", + "13": "231.76999999999973", + "14": "5.3899999999999935", + "index": 396 + }, + { + "0": "B2F718B0-6639-44C6-9E86-04BCCB6765B6", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:15:03", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "539.9", + "13": "539.9", + "14": "53.989999999999995", + "index": 397 + }, + { + "0": "0C8F4CEC-54F7-44BE-A57B-CC2382BA5B2B", + "1": "A1688853524309620", + "2": "119.98", + "3": "22.0", + "4": "2023-02-15 04:46:23", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.98", + "13": "119.98", + "14": "119.98", + "index": 398 + }, + { + "0": "0C8F4CEC-54F7-44BE-A57B-CC2382BA5B2B", + "1": "A1688853524309620", + "2": "119.98", + "3": "22.0", + "4": "2023-02-15 04:46:23", + "5": "119.98", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.98", + "13": "119.98", + "14": "119.98", + "index": 399 + }, + { + "0": "10366C01-E5BE-4DD8-BD52-1B22971F1F4B", + "1": "A1688853596241210", + "2": "65.31", + "3": "22.0", + "4": "2023-02-17 03:39:39", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "125.30000000000001", + "13": "125.30000000000001", + "14": "62.650000000000006", + "index": 400 + }, + { + "0": "0C27D583-960D-4757-B7A9-E207BB91FF38", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 21:17:03", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "188.64999999999984", + "13": "177.86999999999986", + "14": "5.389999999999995", + "index": 401 + }, + { + "0": "8DDECA4B-95EF-4FAD-8781-99F8134532FF", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 21:17:51", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "188.64999999999984", + "13": "177.86999999999986", + "14": "5.389999999999995", + "index": 402 + }, + { + "0": "0C27D583-960D-4757-B7A9-E207BB91FF38", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 21:17:03", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "188.64999999999984", + "13": "177.86999999999986", + "14": "5.389999999999995", + "index": 403 + }, + { + "0": "8DAB4CC5-905C-4646-904A-F981F3F7D0BA", + "1": "A844427868914574", + "2": "389.99", + "3": "11.0", + "4": "2023-03-17 11:32:46", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "389.99", + "13": "389.99", + "14": "389.99", + "index": 404 + }, + { + "0": "8DAB4CC5-905C-4646-904A-F981F3F7D0BA", + "1": "A844427868914574", + "2": "389.99", + "3": "11.0", + "4": "2023-03-17 11:32:46", + "5": "614.195251", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "389.99", + "13": "389.99", + "14": "389.99", + "index": 405 + }, + { + "0": "06243234-E503-47F2-919F-6F9EA1513C3F", + "1": "A1055521380537310", + "2": "64.79", + "3": "13.0", + "4": "2023-01-03 18:53:51", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "64.79", + "13": "64.79", + "14": "64.79", + "index": 406 + }, + { + "0": "06243234-E503-47F2-919F-6F9EA1513C3F", + "1": "A1055521380537310", + "2": "64.79", + "3": "13.0", + "4": "2023-01-03 18:53:51", + "5": "64.79", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "64.79", + "13": "64.79", + "14": "64.79", + "index": 407 + }, + { + "0": "630F1681-99D1-4F3C-BCE0-69C6B28E5A98", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:43:12", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "419.7900000000001", + "13": "419.7900000000001", + "14": "19.990000000000002", + "index": 408 + }, + { + "0": "69CEC859-4F1A-4837-8898-BAE6DBC4E1BD", + "1": "A985156998227558", + "2": "231.56", + "3": "16.0", + "4": "2023-01-28 23:47:41", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "231.56", + "13": "231.56", + "14": "231.56", + "index": 409 + }, + { + "0": "69CEC859-4F1A-4837-8898-BAE6DBC4E1BD", + "1": "A985156998227558", + "2": "231.56", + "3": "16.0", + "4": "2023-01-28 23:47:41", + "5": "231.56", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "231.56", + "13": "231.56", + "14": "231.56", + "index": 410 + }, + { + "0": "A5D379FD-D933-4F68-8763-0C5AF07F7834", + "1": "A914801013785993", + "2": "86.98", + "3": "4.0", + "4": "2023-02-03 09:47:07", + "9": "1", + "10": "371.0", + "11": "0.0", + "12": "182.0", + "13": "182.0", + "14": "91.0", + "index": 411 + }, + { + "0": "29140357-C78E-4066-9BE5-CB7D5364BBD0", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:49:56", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "393.46999999999935", + "13": "382.6899999999994", + "14": "5.389999999999991", + "index": 412 + }, + { + "0": "46C30D4B-09B0-432A-AC46-DDD857CBD1FF", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 03:07:38", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "528.219999999999", + "13": "517.439999999999", + "14": "5.38999999999999", + "index": 413 + }, + { + "0": "33615076-74BA-414F-A51C-470C5AFD1FD7", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:42:37", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "318.00999999999954", + "13": "307.22999999999956", + "14": "5.389999999999993", + "index": 414 + }, + { + "0": "46C30D4B-09B0-432A-AC46-DDD857CBD1FF", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 03:07:38", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "528.219999999999", + "13": "517.439999999999", + "14": "5.38999999999999", + "index": 415 + }, + { + "0": "F1B5AEFF-0701-44A7-8BFF-F44A9FCD8F2C", + "1": "A914801050992809", + "2": "281.37", + "3": "17.0", + "4": "2023-03-21 23:24:04", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "281.37", + "13": "281.37", + "14": "281.37", + "index": 416 + }, + { + "0": "F1B5AEFF-0701-44A7-8BFF-F44A9FCD8F2C", + "1": "A914801050992809", + "2": "281.37", + "3": "17.0", + "4": "2023-03-21 23:24:04", + "5": "280.207942", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "281.37", + "13": "281.37", + "14": "281.37", + "index": 417 + }, + { + "0": "D6AE2567-ECC7-46FF-8389-BCF43C8A81D4", + "1": "A1055521435373420", + "2": "278.88", + "3": "0.0", + "4": "2023-03-30 06:20:02", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "278.88", + "13": "278.88", + "14": "278.88", + "index": 418 + }, + { + "0": "BA22D839-F441-414B-8062-5BA7B6875708", + "1": "A1759222192247110", + "2": "145.59", + "3": "3.0", + "4": "2023-01-11 08:27:26", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "145.59", + "13": "145.59", + "14": "145.59", + "index": 419 + }, + { + "0": "BA22D839-F441-414B-8062-5BA7B6875708", + "1": "A1759222192247110", + "2": "145.59", + "3": "3.0", + "4": "2023-01-11 08:27:26", + "5": "145.59", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "145.59", + "13": "145.59", + "14": "145.59", + "index": 420 + }, + { + "0": "E9D60DF2-0E4B-4396-A84B-A0B9E88B3B63", + "1": "A1688853657869890", + "2": "52.99", + "3": "10.0", + "4": "2023-01-03 17:02:50", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "264.95", + "13": "264.95", + "14": "52.989999999999995", + "index": 421 + }, + { + "0": "973F228D-6E34-4E2C-A8ED-86A560FFE993", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 19:37:33", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "3159.3699999999985", + "13": "3159.3699999999985", + "14": "143.6077272727272", + "index": 422 + }, + { + "0": "499056C6-A358-4E98-8685-9EC28E333CF7", + "1": "A1759222094070230", + "2": "281.37", + "3": "14.0", + "4": "2023-01-20 19:36:53", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "281.37", + "13": "281.37", + "14": "281.37", + "index": 423 + }, + { + "0": "499056C6-A358-4E98-8685-9EC28E333CF7", + "1": "A1759222094070230", + "2": "281.37", + "3": "14.0", + "4": "2023-01-20 19:36:53", + "5": "280.207942", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "281.37", + "13": "281.37", + "14": "281.37", + "index": 424 + }, + { + "0": "DE2C2A1F-DE62-4A91-8FB1-D40C46B96DF6", + "1": "A985157009164620", + "2": "151.54", + "3": "10.0", + "4": "2023-02-17 17:00:01", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "151.54", + "13": "151.54", + "14": "151.54", + "index": 425 + }, + { + "0": "DE2C2A1F-DE62-4A91-8FB1-D40C46B96DF6", + "1": "A985157009164620", + "2": "151.54", + "3": "10.0", + "4": "2023-02-17 17:00:01", + "5": "151.54", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "151.54", + "13": "151.54", + "14": "151.54", + "index": 426 + }, + { + "0": "73FD0C82-ABD2-483C-93B3-9E0B6D5F1793", + "1": "A1759222234548900", + "2": "73080.0", + "3": "23.0", + "4": "2023-03-07 14:59:33", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 427 + }, + { + "0": "73FD0C82-ABD2-483C-93B3-9E0B6D5F1793", + "1": "A1759222234548900", + "2": "73080.0", + "3": "23.0", + "4": "2023-03-07 14:59:33", + "5": "806.0724", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 428 + }, + { + "0": "A053C59B-6929-4895-AC1D-658F81AB3CB6", + "1": "A985157039921196", + "2": "1438.0", + "3": "3.0", + "4": "2023-03-28 04:00:00", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1438.0", + "13": "1438.0", + "14": "1438.0", + "index": 429 + }, + { + "0": "A053C59B-6929-4895-AC1D-658F81AB3CB6", + "1": "A985157039921196", + "2": "1438.0", + "3": "3.0", + "4": "2023-03-28 04:00:00", + "5": "2264.7062", + "6": "true", + "7": "0.0", + "8": "2.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1438.0", + "13": "1438.0", + "14": "1438.0", + "index": 430 + }, + { + "0": "C125DD40-6BE3-40E2-8604-5B9540751467", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:18:59", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "701.87", + "13": "701.87", + "14": "53.99", + "index": 431 + }, + { + "0": "C125DD40-6BE3-40E2-8604-5B9540751467", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:18:59", + "5": "53.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "701.87", + "13": "701.87", + "14": "53.99", + "index": 432 + }, + { + "0": "64A65086-D78C-4C67-994D-06DC95737FB5", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 19:09:49", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "2109.58", + "13": "2109.58", + "14": "140.63866666666667", + "index": 433 + }, + { + "0": "44D80959-7137-4EDB-AEEE-1B7654A9A2A2", + "1": "A1055521400546730", + "2": "119.99", + "4": "2023-02-23 01:16:41", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.99", + "13": "119.99", + "14": "119.99", + "index": 434 + }, + { + "0": "FBB33185-B7C4-47B3-9118-11693E3BE83C", + "1": "A1759222167950540", + "2": "59.99", + "3": "23.0", + "4": "2023-02-17 07:35:34", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "59.99", + "13": "59.99", + "14": "59.99", + "index": 435 + }, + { + "0": "FBB33185-B7C4-47B3-9118-11693E3BE83C", + "1": "A1759222167950540", + "2": "59.99", + "3": "23.0", + "4": "2023-02-17 07:35:34", + "5": "59.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "59.99", + "13": "59.99", + "14": "59.99", + "index": 436 + }, + { + "0": "F558D2DF-78BC-4A0E-A230-4B7291A94F78", + "1": "A1899946887996110", + "2": "235.39", + "3": "18.0", + "4": "2023-02-19 23:48:56", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "235.39", + "13": "235.39", + "14": "235.39", + "index": 437 + }, + { + "0": "F558D2DF-78BC-4A0E-A230-4B7291A94F78", + "1": "A1899946887996110", + "2": "235.39", + "3": "18.0", + "4": "2023-02-19 23:48:56", + "5": "235.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "235.39", + "13": "235.39", + "14": "235.39", + "index": 438 + }, + { + "0": "AA8F1576-451B-4B38-927D-2AB406CC8E8C", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:59:41", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "479.7099999999991", + "13": "468.92999999999915", + "14": "5.38999999999999", + "index": 439 + }, + { + "0": "47E230FD-DD71-432D-8EDA-F6F721A0611B", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:56:09", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "447.3699999999992", + "13": "436.58999999999924", + "14": "5.389999999999991", + "index": 440 + }, + { + "0": "910E41CD-FF30-4CFB-80F2-9799BDC60C48", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:31:33", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "80.85", + "13": "80.85", + "14": "5.39", + "index": 441 + }, + { + "0": "AA8F1576-451B-4B38-927D-2AB406CC8E8C", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:59:41", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "479.7099999999991", + "13": "468.92999999999915", + "14": "5.38999999999999", + "index": 442 + }, + { + "0": "EF766941-87DA-47B7-B312-B351B0172307", + "1": "A1899947010054330", + "2": "73080.0", + "3": "20.0", + "4": "2023-03-01 12:01:28", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "146160.0", + "13": "146160.0", + "14": "73080.0", + "index": 443 + }, + { + "0": "EF766941-87DA-47B7-B312-B351B0172307", + "1": "A1899947010054330", + "2": "73080.0", + "3": "20.0", + "4": "2023-03-01 12:01:28", + "5": "806.0724", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "146160.0", + "13": "146160.0", + "14": "73080.0", + "index": 444 + }, + { + "0": "947519EE-C2DE-42CC-A5CA-B075AEEA05D3", + "1": "A844427390246047", + "2": "5.39", + "3": "22.0", + "4": "2023-02-26 03:30:51", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "533.609999999999", + "13": "522.829999999999", + "14": "5.38999999999999", + "index": 445 + }, + { + "0": "C70F7DCA-97F0-4486-83DC-B06483D9CFF5", + "1": "A1829582571089880", + "2": "233.19", + "3": "21.0", + "4": "2023-01-28 05:55:53", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "466.38", + "13": "466.38", + "14": "233.19", + "index": 446 + }, + { + "0": "C70F7DCA-97F0-4486-83DC-B06483D9CFF5", + "1": "A1829582571089880", + "2": "233.19", + "3": "21.0", + "4": "2023-01-28 05:55:53", + "5": "233.19", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "466.38", + "13": "466.38", + "14": "233.19", + "index": 447 + }, + { + "0": "EA8C66F4-8916-4822-85FA-583C2186501A", + "1": "A985156821621035", + "2": "152.03", + "3": "21.0", + "4": "2023-02-22 05:05:07", + "5": "152.03", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "152.03", + "13": "152.03", + "14": "152.03", + "index": 448 + }, + { + "0": "69A8BDFE-9310-4098-B8E9-D5C0D938E851", + "1": "A844427390246047", + "2": "5.39", + "3": "12.0", + "4": "2023-02-28 17:43:02", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "641.4099999999987", + "13": "301.8399999999996", + "14": "5.389999999999989", + "index": 449 + }, + { + "0": "FF74DFD9-5015-440B-97A1-BDAB4A95B272", + "1": "A985156971082067", + "2": "119.98", + "3": "13.0", + "4": "2023-01-03 18:33:56", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.98", + "13": "119.98", + "14": "119.98", + "index": 450 + }, + { + "0": "FF74DFD9-5015-440B-97A1-BDAB4A95B272", + "1": "A985156971082067", + "2": "119.98", + "3": "13.0", + "4": "2023-01-03 18:33:56", + "5": "119.98", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.98", + "13": "119.98", + "14": "119.98", + "index": 451 + }, + { + "0": "8875BFC3-B41E-416A-A334-65EB49672BEC", + "1": "A844428017843376", + "2": "119.98", + "3": "15.0", + "4": "2023-01-03 20:29:02", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "227.5", + "13": "227.5", + "14": "113.75", + "index": 452 + }, + { + "0": "B0F016BB-D6B1-4812-91DD-41C1FE9C91BA", + "1": "A1688853524321290", + "2": "74.97", + "3": "19.0", + "4": "2023-01-05 00:42:34", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "149.94", + "13": "149.94", + "14": "49.98", + "index": 453 + }, + { + "0": "B0F016BB-D6B1-4812-91DD-41C1FE9C91BA", + "1": "A1688853524321290", + "2": "74.97", + "3": "19.0", + "4": "2023-01-05 00:42:34", + "5": "74.97", + "6": "false", + "7": "3.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "149.94", + "13": "149.94", + "14": "49.98", + "index": 454 + }, + { + "0": "0C044F40-9685-4113-882F-D605AAD744BE", + "1": "A1829582519832190", + "2": "59.99", + "3": "8.0", + "4": "2023-02-16 13:52:42", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.98", + "13": "119.98", + "14": "59.99", + "index": 455 + }, + { + "0": "0C044F40-9685-4113-882F-D605AAD744BE", + "1": "A1829582519832190", + "2": "59.99", + "3": "8.0", + "4": "2023-02-16 13:52:42", + "5": "59.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.98", + "13": "119.98", + "14": "59.99", + "index": 456 + }, + { + "0": "6867FF41-D687-4B12-B2D2-A7B54F3728B9", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:58:52", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "474.31999999999914", + "13": "463.53999999999917", + "14": "5.38999999999999", + "index": 457 + }, + { + "0": "1ECF8464-01D3-40DC-AC34-DC665D7839C4", + "1": "A844427390246047", + "2": "5.39", + "3": "5.0", + "4": "2023-02-25 11:14:50", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "210.20999999999978", + "13": "199.4299999999998", + "14": "5.389999999999994", + "index": 458 + }, + { + "0": "78A67431-762B-4266-9942-E6EEB4A268BF", + "1": "A1688853662170320", + "2": "839.97", + "3": "19.0", + "4": "2023-03-13 10:56:33", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "839.97", + "13": "839.97", + "14": "839.97", + "index": 459 + }, + { + "0": "78A67431-762B-4266-9942-E6EEB4A268BF", + "1": "A1688853662170320", + "2": "839.97", + "3": "19.0", + "4": "2023-03-13 10:56:33", + "5": "839.97", + "6": "false", + "7": "3.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "839.97", + "13": "839.97", + "14": "839.97", + "index": 460 + }, + { + "0": "3147828E-D9DA-4C96-AB5C-56ECE7A35403", + "1": "A985157032922252", + "2": "211.89", + "3": "15.0", + "4": "2023-03-19 22:27:02", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "211.89", + "13": "211.89", + "14": "211.89", + "index": 461 + }, + { + "0": "3147828E-D9DA-4C96-AB5C-56ECE7A35403", + "1": "A985157032922252", + "2": "211.89", + "3": "15.0", + "4": "2023-03-19 22:27:02", + "5": "211.89", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "211.89", + "13": "211.89", + "14": "211.89", + "index": 462 + }, + { + "0": "76824E16-8144-4C10-8769-DF9049DE4BB3", + "1": "A1899946873128090", + "2": "119.98", + "3": "22.0", + "4": "2023-02-15 03:38:31", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "315.54", + "13": "315.54", + "14": "105.18", + "index": 463 + }, + { + "0": "95B931E2-7A0A-4173-ACA5-8B43ED291019", + "1": "A1759222219270870", + "2": "424.99", + "3": "22.0", + "4": "2023-02-28 04:59:09", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "424.99", + "13": "424.99", + "14": "424.99", + "index": 464 + }, + { + "0": "95B931E2-7A0A-4173-ACA5-8B43ED291019", + "1": "A1759222219270870", + "2": "424.99", + "3": "22.0", + "4": "2023-02-28 04:59:09", + "5": "424.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "424.99", + "13": "424.99", + "14": "424.99", + "index": 465 + }, + { + "0": "A541504B-98D3-492E-89A4-994617EFA9CA", + "1": "A1759222088015940", + "2": "78750.0", + "3": "17.0", + "4": "2023-03-15 08:58:56", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "157500.0", + "13": "157500.0", + "14": "78750.0", + "index": 466 + }, + { + "0": "EAA2680C-AD71-4139-BBCA-D74E0B373E33", + "1": "A1055521383712530", + "2": "210.99", + "4": "2023-03-15 20:16:57", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "210.99", + "13": "210.99", + "14": "210.99", + "index": 467 + }, + { + "0": "EAA2680C-AD71-4139-BBCA-D74E0B373E33", + "1": "A1055521383712530", + "2": "210.99", + "4": "2023-03-15 20:16:57", + "5": "210.99", + "6": "false", + "7": "1.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "210.99", + "13": "210.99", + "14": "210.99", + "index": 468 + }, + { + "0": "87726A9D-DF55-4685-82A1-5D4F9E022F5A", + "1": "A914801058711211", + "2": "145.95", + "3": "17.0", + "4": "2023-03-30 23:30:46", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "145.95", + "13": "145.95", + "14": "145.95", + "index": 469 + }, + { + "0": "D1119E3D-720D-46A4-9772-C456EA3B0D4D", + "1": "A1688853596356500", + "2": "59.99", + "3": "1.0", + "4": "2023-02-17 06:46:16", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "59.99", + "13": "59.99", + "14": "59.99", + "index": 470 + }, + { + "0": "A5DA7BE5-A6BA-492B-B43E-588713661CDE", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:46:32", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "361.1299999999994", + "13": "350.34999999999945", + "14": "5.389999999999992", + "index": 471 + }, + { + "0": "FE12EF10-2C8B-4F97-8D72-8CA106A2FDB6", + "1": "A1055521380537310", + "2": "129.58", + "3": "13.0", + "4": "2023-01-03 18:56:12", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "194.37", + "13": "194.37", + "14": "97.185", + "index": 472 + }, + { + "0": "2DC3FDC7-C677-4479-A4C4-85C9A5E2F4FC", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 20:11:32", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "5558.889999999999", + "13": "5558.889999999999", + "14": "146.2865789473684", + "index": 473 + }, + { + "0": "A3BEE7DE-D634-4C72-A05D-77A80D7D613B", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:44:48", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "899.85", + "13": "899.85", + "14": "59.99", + "index": 474 + }, + { + "0": "CD77E40B-B5DF-4C24-9A41-6E55793A90BD", + "1": "A1899946963731140", + "2": "62.49", + "3": "5.0", + "4": "2023-01-19 12:12:26", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "62.49", + "13": "62.49", + "14": "62.49", + "index": 475 + }, + { + "0": "CD77E40B-B5DF-4C24-9A41-6E55793A90BD", + "1": "A1899946963731140", + "2": "62.49", + "3": "5.0", + "4": "2023-01-19 12:12:26", + "5": "62.49", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "62.49", + "13": "62.49", + "14": "62.49", + "index": 476 + }, + { + "0": "169212AC-3DBA-4EA6-A5AE-031C407DC3AA", + "1": "A1688853657869890", + "2": "52.99", + "3": "10.0", + "4": "2023-01-03 17:00:28", + "5": "52.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "211.96", + "13": "211.96", + "14": "52.99", + "index": 477 + }, + { + "0": "D1834580-E9C8-4D34-9433-0BA410FA0DF4", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:30:31", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "239.88000000000002", + "13": "239.88000000000002", + "14": "19.990000000000002", + "index": 478 + }, + { + "0": "D1884A1A-0865-47C3-A8DC-43DC991D661C", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:41:02", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "719.88", + "13": "719.88", + "14": "59.99", + "index": 479 + }, + { + "0": "2ED99F79-890A-42CD-81C5-0813D241BD01", + "1": "A844428040495230", + "2": "75.58", + "3": "13.0", + "4": "2023-01-17 18:24:03", + "9": "1", + "10": "366.0", + "11": "1.0", + "12": "75.58", + "13": "75.58", + "14": "75.58", + "index": 480 + }, + { + "0": "2ED99F79-890A-42CD-81C5-0813D241BD01", + "1": "A844428040495230", + "2": "75.58", + "3": "13.0", + "4": "2023-01-17 18:24:03", + "5": "75.58", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "1.0", + "12": "75.58", + "13": "75.58", + "14": "75.58", + "index": 481 + }, + { + "0": "A55591A0-4BA2-4DB4-8881-619C2000D5FA", + "1": "A1759222095873190", + "2": "106.98", + "3": "11.0", + "4": "2023-01-03 17:39:26", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "160.47", + "13": "160.47", + "14": "80.235", + "index": 482 + }, + { + "0": "A55591A0-4BA2-4DB4-8881-619C2000D5FA", + "1": "A1759222095873190", + "2": "106.98", + "3": "11.0", + "4": "2023-01-03 17:39:26", + "5": "106.98", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "160.47", + "13": "160.47", + "14": "80.235", + "index": 483 + }, + { + "0": "C49AA590-F545-4A2A-B096-FA1626918587", + "1": "A1759222185358430", + "2": "86.74", + "3": "9.0", + "4": "2023-01-17 14:44:35", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "86.74", + "13": "86.74", + "14": "86.74", + "index": 484 + }, + { + "0": "C49AA590-F545-4A2A-B096-FA1626918587", + "1": "A1759222185358430", + "2": "86.74", + "3": "9.0", + "4": "2023-01-17 14:44:35", + "5": "86.74", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "86.74", + "13": "86.74", + "14": "86.74", + "index": 485 + }, + { + "0": "32E64963-58DD-4FBC-9125-ED1ACBFE62EF", + "1": "A1899946781648580", + "2": "228.79", + "3": "9.0", + "4": "2023-02-23 15:26:52", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "457.58", + "13": "457.58", + "14": "228.79", + "index": 486 + }, + { + "0": "32E64963-58DD-4FBC-9125-ED1ACBFE62EF", + "1": "A1899946781648580", + "2": "228.79", + "3": "9.0", + "4": "2023-02-23 15:26:52", + "5": "228.79", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "457.58", + "13": "457.58", + "14": "228.79", + "index": 487 + }, + { + "0": "62C66790-989B-43C0-8FCD-12C5829A6D77", + "1": "A914800278864743", + "2": "151.54", + "3": "15.0", + "4": "2023-02-25 21:28:57", + "9": "1", + "10": "604.0", + "11": "0.0", + "12": "151.54", + "13": "151.54", + "14": "151.54", + "index": 488 + }, + { + "0": "62C66790-989B-43C0-8FCD-12C5829A6D77", + "1": "A914800278864743", + "2": "151.54", + "3": "15.0", + "4": "2023-02-25 21:28:57", + "5": "151.54", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "604.0", + "11": "0.0", + "12": "151.54", + "13": "151.54", + "14": "151.54", + "index": 489 + }, + { + "0": "3E6FEB4B-BCD3-4FFE-BBB3-1CB0BFA39C82", + "1": "A914800340295166", + "2": "79.99", + "3": "18.0", + "4": "2023-01-15 01:17:44", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "79.99", + "13": "79.99", + "14": "79.99", + "index": 490 + }, + { + "0": "3E6FEB4B-BCD3-4FFE-BBB3-1CB0BFA39C82", + "1": "A914800340295166", + "2": "79.99", + "3": "18.0", + "4": "2023-01-15 01:17:44", + "5": "79.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "79.99", + "13": "79.99", + "14": "79.99", + "index": 491 + }, + { + "0": "94BEE01F-8FA2-4685-9870-0172A53F3981", + "1": "A1759222234549860", + "2": "62580.0", + "3": "11.0", + "4": "2023-03-03 02:25:14", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "187740.0", + "13": "187740.0", + "14": "62580.0", + "index": 492 + }, + { + "0": "6BA9D314-0ECC-425F-BCA8-FE3DC74581C8", + "1": "A914801012822158", + "2": "104.25", + "3": "6.0", + "4": "2023-02-01 11:41:23", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "104.25", + "13": "104.25", + "14": "104.25", + "index": 493 + }, + { + "0": "3BDC3741-807B-447D-9A8D-9396CB1519BA", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 21:16:10", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "183.25999999999985", + "13": "172.47999999999988", + "14": "5.389999999999995", + "index": 494 + }, + { + "0": "A1979FD7-32C8-4BE2-AB5F-3FFDDD7C584A", + "1": "A1688853657886190", + "2": "53.99", + "3": "13.0", + "4": "2023-01-03 18:24:17", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "863.84", + "13": "863.84", + "14": "53.99", + "index": 495 + }, + { + "0": "D141370E-DD9D-4316-A2F9-A5D8244C61A2", + "1": "A1899946873128090", + "2": "119.98", + "3": "20.0", + "4": "2023-02-15 02:37:52", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "195.56", + "13": "195.56", + "14": "97.78", + "index": 496 + }, + { + "0": "D2155FC9-8E47-46A6-B8F3-1395DECE7D82", + "1": "A844427390246047", + "2": "5.39", + "3": "9.0", + "4": "2023-02-28 14:35:07", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "592.8999999999988", + "13": "253.32999999999967", + "14": "5.389999999999989", + "index": 497 + }, + { + "0": "B6A87790-25B1-4E1D-8F1C-DBF01DA1B7B7", + "1": "A1759221887824430", + "2": "153.29", + "3": "17.0", + "4": "2023-01-05 02:05:55", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "153.29", + "13": "153.29", + "14": "153.29", + "index": 498 + }, + { + "0": "B6A87790-25B1-4E1D-8F1C-DBF01DA1B7B7", + "1": "A1759221887824430", + "2": "153.29", + "3": "17.0", + "4": "2023-01-05 02:05:55", + "5": "153.29", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "153.29", + "13": "153.29", + "14": "153.29", + "index": 499 + }, + { + "0": "5403C73E-98E5-47B4-B3A8-82335C48C6C0", + "1": "A1055521396853140", + "2": "150.49", + "3": "18.0", + "4": "2023-02-09 00:38:33", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "150.49", + "13": "150.49", + "14": "150.49", + "index": 500 + }, + { + "0": "5403C73E-98E5-47B4-B3A8-82335C48C6C0", + "1": "A1055521396853140", + "2": "150.49", + "3": "18.0", + "4": "2023-02-09 00:38:33", + "5": "150.49", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "150.49", + "13": "150.49", + "14": "150.49", + "index": 501 + }, + { + "0": "1517BB82-21EB-40EF-AF3D-65614C90297C", + "1": "A1829582583896790", + "2": "127.18", + "3": "7.0", + "4": "2023-02-16 12:25:13", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "127.18", + "13": "127.18", + "14": "127.18", + "index": 502 + }, + { + "0": "1517BB82-21EB-40EF-AF3D-65614C90297C", + "1": "A1829582583896790", + "2": "127.18", + "3": "7.0", + "4": "2023-02-16 12:25:13", + "5": "127.18", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "127.18", + "13": "127.18", + "14": "127.18", + "index": 503 + }, + { + "0": "C2440D4D-3768-4108-BCAF-E43441537783", + "1": "A1899946873142120", + "2": "149.97", + "3": "15.0", + "4": "2023-01-03 20:38:15", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "7208.560000000002", + "13": "7208.560000000002", + "14": "147.11346938775515", + "index": 504 + }, + { + "0": "B544758B-8F40-45DE-94EB-BC3B8B7B1401", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:42:16", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "399.80000000000007", + "13": "399.80000000000007", + "14": "19.990000000000002", + "index": 505 + }, + { + "0": "B544758B-8F40-45DE-94EB-BC3B8B7B1401", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:42:16", + "5": "19.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "399.80000000000007", + "13": "399.80000000000007", + "14": "19.990000000000002", + "index": 506 + }, + { + "0": "A66793DD-03E4-4E15-9CDB-79EC4733C3CA", + "1": "A985157015268058", + "2": "4.99", + "3": "14.0", + "4": "2023-02-27 19:39:54", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "104.78999999999998", + "13": "104.78999999999998", + "14": "4.989999999999999", + "index": 507 + }, + { + "0": "573FCD19-5AF1-4C96-B2B6-D09E91B02381", + "1": "A985157025448796", + "2": "73080.0", + "3": "21.0", + "4": "2023-03-11 12:54:28", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "146160.0", + "13": "146160.0", + "14": "73080.0", + "index": 508 + }, + { + "0": "573FCD19-5AF1-4C96-B2B6-D09E91B02381", + "1": "A985157025448796", + "2": "73080.0", + "3": "21.0", + "4": "2023-03-11 12:54:28", + "5": "806.0724", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "146160.0", + "13": "146160.0", + "14": "73080.0", + "index": 509 + }, + { + "0": "B76E185F-504D-437A-9865-ECDA737870F3", + "1": "A914801007105746", + "2": "93.85", + "3": "9.0", + "4": "2023-01-24 17:53:21", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "176.91", + "13": "176.91", + "14": "88.455", + "index": 510 + }, + { + "0": "B76E185F-504D-437A-9865-ECDA737870F3", + "1": "A914801007105746", + "2": "93.85", + "3": "9.0", + "4": "2023-01-24 17:53:21", + "5": "93.85", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "176.91", + "13": "176.91", + "14": "88.455", + "index": 511 + }, + { + "0": "D43FE025-6D1B-4FE0-8E42-BC3E95A76823", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:47:52", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "334.1799999999995", + "13": "323.3999999999995", + "14": "5.389999999999992", + "index": 512 + }, + { + "0": "9C4E2317-10BB-4BDE-AE2F-09EA29B0FD8A", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:36:14", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "113.19", + "13": "113.19", + "14": "5.39", + "index": 513 + }, + { + "0": "979DF1CE-FE47-47FE-A8ED-ED1119F41065", + "1": "A1688853657869890", + "2": "52.99", + "3": "10.0", + "4": "2023-01-03 17:03:58", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "317.94", + "13": "317.94", + "14": "52.99", + "index": 514 + }, + { + "0": "7829E3D8-EAF7-44CE-8AD6-0F11BC182D65", + "1": "A1829582580775700", + "2": "65.57", + "3": "12.0", + "4": "2023-01-03 19:39:40", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "458.98999999999995", + "13": "458.98999999999995", + "14": "65.57", + "index": 515 + }, + { + "0": "7829E3D8-EAF7-44CE-8AD6-0F11BC182D65", + "1": "A1829582580775700", + "2": "65.57", + "3": "12.0", + "4": "2023-01-03 19:39:40", + "5": "65.57", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "458.98999999999995", + "13": "458.98999999999995", + "14": "65.57", + "index": 516 + }, + { + "0": "105FE6E4-4E43-4042-937C-4E6748781A3D", + "1": "A914801012822158", + "2": "92.63", + "3": "0.0", + "4": "2023-02-03 05:37:23", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "289.08", + "13": "289.08", + "14": "96.36", + "index": 517 + }, + { + "0": "B5550A72-81D1-4F96-8294-690A060C0071", + "1": "A1688853605359930", + "2": "66.05", + "3": "19.0", + "4": "2023-02-14 01:09:37", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "66.05", + "13": "66.05", + "14": "66.05", + "index": 518 + }, + { + "0": "B5550A72-81D1-4F96-8294-690A060C0071", + "1": "A1688853605359930", + "2": "66.05", + "3": "19.0", + "4": "2023-02-14 01:09:37", + "5": "66.05", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "66.05", + "13": "66.05", + "14": "66.05", + "index": 519 + }, + { + "0": "0D43D3F2-A352-4700-8FEC-8E02EF44A514", + "1": "A985157015268058", + "2": "4.99", + "3": "10.0", + "4": "2023-02-27 15:34:45", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "39.92000000000001", + "13": "39.92000000000001", + "14": "4.990000000000001", + "index": 520 + }, + { + "0": "9606F304-48F8-47E9-A666-2BD97690632F", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:51:47", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "409.6399999999993", + "13": "398.85999999999933", + "14": "5.389999999999991", + "index": 521 + }, + { + "0": "566C00BC-EB37-41D8-9202-CCAC36616EB0", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-21 20:43:37", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "2365.0", + "11": "3.0", + "12": "5.39", + "13": "5.39", + "14": "5.39", + "index": 522 + }, + { + "0": "66709ABD-6D12-456B-82D6-CBD25CFBE285", + "1": "A985157015268058", + "2": "4.99", + "3": "10.0", + "4": "2023-02-27 15:39:19", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "64.87000000000002", + "13": "64.87000000000002", + "14": "4.990000000000001", + "index": 523 + }, + { + "0": "9E151E5A-C4BE-4AE6-A0F2-62320FD3FD14", + "1": "A985157015268058", + "2": "4.99", + "3": "11.0", + "4": "2023-02-26 16:49:39", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "9.98", + "13": "9.98", + "14": "4.99", + "index": 524 + }, + { + "0": "9F442404-8F9E-45E0-8A10-D5B4C0B3A36A", + "1": "A1688853516414440", + "2": "79380.0", + "3": "0.0", + "4": "2023-03-10 15:47:03", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "79380.0", + "13": "79380.0", + "14": "79380.0", + "index": 525 + }, + { + "0": "AA345197-EC08-4848-9F43-97862C99593E", + "1": "A914801028323265", + "2": "150.31", + "3": "12.0", + "4": "2023-02-21 19:00:49", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "150.31", + "13": "150.31", + "14": "150.31", + "index": 526 + }, + { + "0": "AA345197-EC08-4848-9F43-97862C99593E", + "1": "A914801028323265", + "2": "150.31", + "3": "12.0", + "4": "2023-02-21 19:00:49", + "5": "150.31", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "150.31", + "13": "150.31", + "14": "150.31", + "index": 527 + }, + { + "0": "A75939D1-EE17-4E78-8478-6937CD08D5E9", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 18:52:01", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "759.85", + "13": "759.85", + "14": "126.64166666666667", + "index": 528 + }, + { + "0": "78CF721D-0FC0-4CE6-B458-D1DF03C16C16", + "1": "A985156986195261", + "2": "169.0", + "3": "20.0", + "4": "2023-01-10 10:28:38", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "169.0", + "13": "169.0", + "14": "169.0", + "index": 529 + }, + { + "0": "78CF721D-0FC0-4CE6-B458-D1DF03C16C16", + "1": "A985156986195261", + "2": "169.0", + "3": "20.0", + "4": "2023-01-10 10:28:38", + "5": "176.66415", + "6": "true", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "169.0", + "13": "169.0", + "14": "169.0", + "index": 530 + }, + { + "0": "4A7523C3-17EE-4AB6-92D9-6535A3A41331", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:22:20", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "179.91", + "13": "179.91", + "14": "19.99", + "index": 531 + }, + { + "0": "DDBCD8B8-C45B-45BB-8373-E184F6776E09", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 20:01:13", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "4509.099999999998", + "13": "4509.099999999998", + "14": "145.45483870967735", + "index": 532 + }, + { + "0": "104D3F8D-6772-4535-AC30-D78279A10F53", + "1": "A914801027937767", + "2": "149.99", + "3": "14.0", + "4": "2023-02-21 05:05:44", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "149.99", + "13": "149.99", + "14": "149.99", + "index": 533 + }, + { + "0": "104D3F8D-6772-4535-AC30-D78279A10F53", + "1": "A914801027937767", + "2": "149.99", + "3": "14.0", + "4": "2023-02-21 05:05:44", + "5": "156.792046", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "149.99", + "13": "149.99", + "14": "149.99", + "index": 534 + }, + { + "0": "A012EE4D-7688-4A68-BAA1-6E372A040ADA", + "1": "A1055521399136000", + "2": "5.4", + "3": "23.0", + "4": "2023-02-27 04:55:35", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "27.0", + "13": "27.0", + "14": "5.4", + "index": 535 + }, + { + "0": "A012EE4D-7688-4A68-BAA1-6E372A040ADA", + "1": "A1055521399136000", + "2": "5.4", + "3": "23.0", + "4": "2023-02-27 04:55:35", + "5": "5.4", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "27.0", + "13": "27.0", + "14": "5.4", + "index": 536 + }, + { + "0": "11FAFE8A-E9F5-4FB4-BC04-4C96AE6E852F", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:16:26", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "593.89", + "13": "593.89", + "14": "53.99", + "index": 537 + }, + { + "0": "1570C1F3-15CF-473D-A630-24D1151F7D94", + "1": "A1759222185240050", + "2": "64.19", + "3": "3.0", + "4": "2023-01-17 08:57:19", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "64.19", + "13": "64.19", + "14": "64.19", + "index": 538 + }, + { + "0": "1570C1F3-15CF-473D-A630-24D1151F7D94", + "1": "A1759222185240050", + "2": "64.19", + "3": "3.0", + "4": "2023-01-17 08:57:19", + "5": "64.19", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "64.19", + "13": "64.19", + "14": "64.19", + "index": 539 + }, + { + "0": "A6B5B02E-3974-4BD3-9F9F-98FF549E114F", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 03:06:22", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "517.439999999999", + "13": "506.65999999999906", + "14": "5.38999999999999", + "index": 540 + }, + { + "0": "460FA98A-658B-4543-BBC0-EFBFCD7436FD", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:58:07", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "140.13999999999996", + "13": "129.35999999999999", + "14": "5.389999999999999", + "index": 541 + }, + { + "0": "A6B5B02E-3974-4BD3-9F9F-98FF549E114F", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 03:06:22", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "517.439999999999", + "13": "506.65999999999906", + "14": "5.38999999999999", + "index": 542 + }, + { + "0": "7CD9A9C3-3CE1-49B9-8299-039B7955F0F4", + "1": "A985156290472668", + "2": "5.34", + "3": "17.0", + "4": "2023-02-27 22:55:15", + "5": "5.34", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "2365.0", + "11": "0.0", + "12": "26.7", + "13": "26.7", + "14": "5.34", + "index": 543 + }, + { + "0": "FE374A34-0463-4D17-926A-7F697581AA35", + "1": "A1055520836257310", + "2": "5.04", + "3": "5.0", + "4": "2023-02-28 10:24:44", + "9": "1", + "10": "1555.0", + "11": "0.0", + "12": "15.120000000000001", + "13": "15.120000000000001", + "14": "5.04", + "index": 544 + }, + { + "0": "D2CE31CE-7D5A-4E80-8D3E-F2E184DFAC98", + "1": "A844428017843376", + "2": "107.52", + "3": "15.0", + "4": "2023-01-03 20:27:17", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "107.52", + "13": "107.52", + "14": "107.52", + "index": 545 + }, + { + "0": "53FB03E4-3872-4E94-B597-12F0C1C8E38D", + "1": "A360434769010983", + "2": "149.44", + "3": "15.0", + "4": "2023-02-17 21:06:39", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "149.44", + "13": "149.44", + "14": "149.44", + "index": 546 + }, + { + "0": "53FB03E4-3872-4E94-B597-12F0C1C8E38D", + "1": "A360434769010983", + "2": "149.44", + "3": "15.0", + "4": "2023-02-17 21:06:39", + "5": "149.44", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "149.44", + "13": "149.44", + "14": "149.44", + "index": 547 + }, + { + "0": "16212511-57EB-4206-95EA-1AD25B767926", + "1": "A985157022379291", + "2": "279.98", + "3": "17.0", + "4": "2023-03-06 23:19:42", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "279.98", + "13": "279.98", + "14": "279.98", + "index": 548 + }, + { + "0": "16212511-57EB-4206-95EA-1AD25B767926", + "1": "A985157022379291", + "2": "279.98", + "3": "17.0", + "4": "2023-03-06 23:19:42", + "5": "279.98", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "279.98", + "13": "279.98", + "14": "279.98", + "index": 549 + }, + { + "0": "EDE9E934-451A-491D-84E1-090D1A22D191", + "1": "A1759222185351430", + "2": "79.99", + "3": "7.0", + "4": "2023-01-17 13:14:40", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "79.99", + "13": "79.99", + "14": "79.99", + "index": 550 + }, + { + "0": "EDE9E934-451A-491D-84E1-090D1A22D191", + "1": "A1759222185351430", + "2": "79.99", + "3": "7.0", + "4": "2023-01-17 13:14:40", + "5": "79.99", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "79.99", + "13": "79.99", + "14": "79.99", + "index": 551 + }, + { + "0": "6FEBCE16-D75E-4426-92B8-7F7A9CE058BB", + "1": "A1055521406108610", + "2": "973.17", + "3": "11.0", + "4": "2023-02-22 17:39:23", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "973.17", + "13": "973.17", + "14": "973.17", + "index": 552 + }, + { + "0": "6FEBCE16-D75E-4426-92B8-7F7A9CE058BB", + "1": "A1055521406108610", + "2": "973.17", + "3": "11.0", + "4": "2023-02-22 17:39:23", + "5": "973.17", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "973.17", + "13": "973.17", + "14": "973.17", + "index": 553 + }, + { + "0": "B4FA5FE0-EBF4-48B9-BDD1-A1D85984E9ED", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:57:42", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "463.53999999999917", + "13": "452.7599999999992", + "14": "5.38999999999999", + "index": 554 + }, + { + "0": "B4FA5FE0-EBF4-48B9-BDD1-A1D85984E9ED", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:57:42", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "463.53999999999917", + "13": "452.7599999999992", + "14": "5.38999999999999", + "index": 555 + }, + { + "0": "F8A27B27-C73C-4DD1-AED7-97F5A6761294", + "1": "A1899947010054330", + "2": "73080.0", + "3": "20.0", + "4": "2023-03-01 12:00:21", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 556 + }, + { + "0": "F8A27B27-C73C-4DD1-AED7-97F5A6761294", + "1": "A1899947010054330", + "2": "73080.0", + "3": "20.0", + "4": "2023-03-01 12:00:21", + "5": "806.0724", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 557 + }, + { + "0": "9751B6CA-AE84-41C9-8BAE-F2608CCE17E4", + "1": "A1055521435190160", + "2": "281.37", + "3": "18.0", + "4": "2023-03-29 23:22:01", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "562.74", + "13": "562.74", + "14": "281.37", + "index": 558 + }, + { + "0": "9751B6CA-AE84-41C9-8BAE-F2608CCE17E4", + "1": "A1055521435190160", + "2": "281.37", + "3": "18.0", + "4": "2023-03-29 23:22:01", + "5": "280.207942", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "562.74", + "13": "562.74", + "14": "281.37", + "index": 559 + }, + { + "0": "B375BB8C-242A-4DC6-8FC3-F35EA5ADDADD", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:21:25", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "179.91", + "13": "179.91", + "14": "19.99", + "index": 560 + }, + { + "0": "F1FE235C-84E4-4770-BA47-2F70994718C1", + "1": "A914801011218316", + "2": "330.86", + "3": "17.0", + "4": "2023-02-12 23:03:05", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "330.86", + "13": "330.86", + "14": "330.86", + "index": 561 + }, + { + "0": "FC750F5F-8402-4006-AFAC-4DD63C61F2F2", + "1": "A985156554634689", + "2": "116.86", + "3": "14.0", + "4": "2023-02-17 19:22:51", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "116.86", + "13": "116.86", + "14": "116.86", + "index": 562 + }, + { + "0": "FC750F5F-8402-4006-AFAC-4DD63C61F2F2", + "1": "A985156554634689", + "2": "116.86", + "3": "14.0", + "4": "2023-02-17 19:22:51", + "5": "116.86", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "116.86", + "13": "116.86", + "14": "116.86", + "index": 563 + }, + { + "0": "5C9ABE6A-E977-4767-BCC8-A9A0952DB43A", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-28 13:19:49", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "565.9499999999989", + "13": "226.37999999999974", + "14": "5.38999999999999", + "index": 564 + }, + { + "0": "42FC2159-6C83-4CBE-A323-DE9E0546A311", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:34:38", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "102.41", + "13": "102.41", + "14": "5.39", + "index": 565 + }, + { + "0": "5EE5C089-EEC1-40F9-B997-D8EA4BDA79C1", + "1": "A844427390246047", + "2": "5.39", + "3": "13.0", + "4": "2023-02-24 19:19:40", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "2365.0", + "11": "3.0", + "12": "26.95", + "13": "26.95", + "14": "5.39", + "index": 566 + }, + { + "0": "0D5E955B-EC9E-48EA-B499-587B73B8AB69", + "1": "A1055521435373420", + "2": "278.88", + "3": "1.0", + "4": "2023-03-30 06:22:46", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "557.76", + "13": "557.76", + "14": "278.88", + "index": 567 + }, + { + "0": "0D5E955B-EC9E-48EA-B499-587B73B8AB69", + "1": "A1055521435373420", + "2": "278.88", + "3": "1.0", + "4": "2023-03-30 06:22:46", + "5": "277.72822599999995", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "557.76", + "13": "557.76", + "14": "278.88", + "index": 568 + }, + { + "0": "441AEEE6-AAA6-40CB-9173-FBEF1C355ACC", + "1": "A985157015268058", + "2": "4.99", + "3": "14.0", + "4": "2023-02-27 19:46:27", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "114.76999999999997", + "13": "114.76999999999997", + "14": "4.989999999999998", + "index": 569 + }, + { + "0": "36AD5A93-8DB0-4134-93EA-26D0A7EE8C3B", + "1": "A1759222234549810", + "2": "73080.0", + "3": "19.0", + "4": "2023-03-01 10:41:19", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "146160.0", + "13": "146160.0", + "14": "73080.0", + "index": 570 + }, + { + "0": "CF161FC1-9EE6-42F9-92F4-84E0B45957D6", + "1": "A1829582439663370", + "2": "569.97", + "3": "11.0", + "4": "2023-03-15 02:21:19", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "569.97", + "13": "569.97", + "14": "569.97", + "index": 571 + }, + { + "0": "CF161FC1-9EE6-42F9-92F4-84E0B45957D6", + "1": "A1829582439663370", + "2": "569.97", + "3": "11.0", + "4": "2023-03-15 02:21:19", + "5": "768.205566", + "6": "false", + "7": "3.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "569.97", + "13": "569.97", + "14": "569.97", + "index": 572 + }, + { + "0": "976B65D5-19C3-48A1-A57A-E67899D3E4DE", + "1": "A1688853660541850", + "2": "105.98", + "3": "14.0", + "4": "2023-02-15 20:12:39", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "105.98", + "13": "105.98", + "14": "105.98", + "index": 573 + }, + { + "0": "976B65D5-19C3-48A1-A57A-E67899D3E4DE", + "1": "A1688853660541850", + "2": "105.98", + "3": "14.0", + "4": "2023-02-15 20:12:39", + "5": "105.98", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "105.98", + "13": "105.98", + "14": "105.98", + "index": 574 + }, + { + "0": "E9AE2FFC-1BA4-45CC-858C-DCE5E3BA51B8", + "1": "A1759222105153830", + "2": "108.38", + "3": "10.0", + "4": "2023-02-16 18:51:45", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "108.38", + "13": "108.38", + "14": "108.38", + "index": 575 + }, + { + "0": "F3606B8D-3008-4781-AC9C-BA159F1BF3B5", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:24:09", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "199.9", + "13": "199.9", + "14": "19.990000000000002", + "index": 576 + }, + { + "0": "1353C004-23CE-4887-8611-0986140B9411", + "1": "A1899946873142120", + "2": "149.97", + "3": "15.0", + "4": "2023-01-03 20:22:26", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "6308.740000000001", + "13": "6308.740000000001", + "14": "146.71488372093026", + "index": 577 + }, + { + "0": "B67BDFBC-B7D7-414A-A781-964A9C80E8B1", + "1": "A1759222234548420", + "2": "538.0", + "3": "14.0", + "4": "2023-03-02 05:28:47", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "538.0", + "13": "538.0", + "14": "538.0", + "index": 578 + }, + { + "0": "B67BDFBC-B7D7-414A-A781-964A9C80E8B1", + "1": "A1759222234548420", + "2": "538.0", + "3": "14.0", + "4": "2023-03-02 05:28:47", + "5": "725.1164", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "538.0", + "13": "538.0", + "14": "538.0", + "index": 579 + }, + { + "0": "F1476029-DD3C-4695-924A-0D951E1540CE", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 20:02:36", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "4659.069999999998", + "13": "4659.069999999998", + "14": "145.59593749999993", + "index": 580 + }, + { + "0": "F1476029-DD3C-4695-924A-0D951E1540CE", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 20:02:36", + "5": "149.97", + "6": "false", + "7": "3.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "4659.069999999998", + "13": "4659.069999999998", + "14": "145.59593749999993", + "index": 581 + }, + { + "0": "4A4AF956-41C3-4723-8BAD-527243728FE8", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:33:54", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "97.02", + "13": "97.02", + "14": "5.39", + "index": 582 + }, + { + "0": "A721A0ED-7D53-4627-AC26-9D1C825D3E29", + "1": "A844428035905405", + "2": "119.75", + "3": "22.0", + "4": "2023-01-12 04:15:29", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.75", + "13": "119.75", + "14": "119.75", + "index": 583 + }, + { + "0": "A721A0ED-7D53-4627-AC26-9D1C825D3E29", + "1": "A844428035905405", + "2": "119.75", + "3": "22.0", + "4": "2023-01-12 04:15:29", + "5": "119.75", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.75", + "13": "119.75", + "14": "119.75", + "index": 584 + }, + { + "0": "98D7E9CF-D308-4B97-BF45-00263A93B702", + "1": "A914801004943538", + "2": "59.99", + "4": "2023-01-20 02:02:01", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "91.93", + "13": "91.93", + "14": "45.965", + "index": 585 + }, + { + "0": "761ADA43-FAD5-44FC-877C-82B8FD06CA58", + "1": "A311880327984872", + "2": "109.99", + "3": "11.0", + "4": "2023-02-24 17:06:07", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "109.99", + "13": "109.99", + "14": "109.99", + "index": 586 + }, + { + "0": "761ADA43-FAD5-44FC-877C-82B8FD06CA58", + "1": "A311880327984872", + "2": "109.99", + "3": "11.0", + "4": "2023-02-24 17:06:07", + "5": "109.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "109.99", + "13": "109.99", + "14": "109.99", + "index": 587 + }, + { + "0": "1DA8653D-7E02-48A4-AECA-CF30E3784FD3", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:54:40", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "431.19999999999925", + "13": "420.4199999999993", + "14": "5.389999999999991", + "index": 588 + }, + { + "0": "667490FD-D4B7-4039-A69B-C4E70A9F5DE3", + "1": "A1688853657886190", + "2": "53.99", + "3": "13.0", + "4": "2023-01-03 18:23:04", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "809.85", + "13": "809.85", + "14": "53.99", + "index": 589 + }, + { + "0": "F70513F4-FCD6-4FB3-9BDA-E1339E4DD86F", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 19:24:53", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "2709.459999999999", + "13": "2709.459999999999", + "14": "142.6031578947368", + "index": 590 + }, + { + "0": "F70513F4-FCD6-4FB3-9BDA-E1339E4DD86F", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 19:24:53", + "5": "149.97", + "6": "false", + "7": "3.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "2709.459999999999", + "13": "2709.459999999999", + "14": "142.6031578947368", + "index": 591 + }, + { + "0": "22F1F04E-3F22-4BA6-AE81-6329C97E613F", + "1": "A2181420350587670", + "2": "149.99", + "3": "9.0", + "4": "2023-01-23 17:58:49", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "149.99", + "13": "149.99", + "14": "149.99", + "index": 592 + }, + { + "0": "22F1F04E-3F22-4BA6-AE81-6329C97E613F", + "1": "A2181420350587670", + "2": "149.99", + "3": "9.0", + "4": "2023-01-23 17:58:49", + "5": "149.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "149.99", + "13": "149.99", + "14": "149.99", + "index": 593 + }, + { + "0": "DBC4622E-A4BD-478C-A958-D67E1C11A000", + "1": "A1759222219189020", + "2": "222.19", + "3": "3.0", + "4": "2023-01-28 08:54:40", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "444.38", + "13": "444.38", + "14": "222.19", + "index": 594 + }, + { + "0": "DBC4622E-A4BD-478C-A958-D67E1C11A000", + "1": "A1759222219189020", + "2": "222.19", + "3": "3.0", + "4": "2023-01-28 08:54:40", + "5": "222.19", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "444.38", + "13": "444.38", + "14": "222.19", + "index": 595 + }, + { + "0": "C1BB5DA1-3DB9-47B3-BF4E-25C402A14AE8", + "1": "A914801013775218", + "2": "92.2", + "3": "4.0", + "4": "2023-02-03 09:41:23", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "185.82", + "13": "185.82", + "14": "92.91", + "index": 596 + }, + { + "0": "C1BB5DA1-3DB9-47B3-BF4E-25C402A14AE8", + "1": "A914801013775218", + "2": "92.2", + "3": "4.0", + "4": "2023-02-03 09:41:23", + "5": "92.2", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "185.82", + "13": "185.82", + "14": "92.91", + "index": 597 + }, + { + "0": "6083FE06-FDAB-4725-8CB2-DDB0B978E826", + "1": "A1688853596363060", + "2": "60.59", + "3": "6.0", + "4": "2023-02-16 11:58:56", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "121.18", + "13": "121.18", + "14": "60.59", + "index": 598 + }, + { + "0": "AB06E897-E5CB-408B-957A-9E77B9EBD71E", + "1": "A914801013775218", + "2": "93.62", + "3": "9.0", + "4": "2023-02-02 14:49:48", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "93.62", + "13": "93.62", + "14": "93.62", + "index": 599 + }, + { + "0": "23FB57DD-40E6-49D4-8F47-29EC2357E548", + "1": "A564049508937862", + "2": "0.0", + "4": "2023-03-06 19:52:07", + "5": "0.0", + "6": "false", + "7": "1.0", + "8": "1.0", + "9": "0", + "10": "2365.0", + "11": "0.0", + "12": "482.68", + "13": "482.68", + "14": "241.34", + "index": 600 + }, + { + "0": "DBECA025-8715-4299-B743-F2DC5C5D32FA", + "1": "A985157010653462", + "2": "80.92", + "3": "9.0", + "4": "2023-02-19 18:10:09", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "80.92", + "13": "80.92", + "14": "80.92", + "index": 601 + }, + { + "0": "DBECA025-8715-4299-B743-F2DC5C5D32FA", + "1": "A985157010653462", + "2": "80.92", + "3": "9.0", + "4": "2023-02-19 18:10:09", + "5": "80.92", + "6": "true", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "80.92", + "13": "80.92", + "14": "80.92", + "index": 602 + }, + { + "0": "5E74AE55-CFA6-4337-9B6B-CA9933D5A6D8", + "1": "A985157015268058", + "2": "4.99", + "3": "11.0", + "4": "2023-02-26 17:06:09", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "29.940000000000005", + "13": "29.940000000000005", + "14": "4.990000000000001", + "index": 603 + }, + { + "0": "531E0DC8-53E7-40A2-A8E4-A28F3ACE3F45", + "1": "A1688852207604610", + "2": "99.0", + "3": "11.0", + "4": "2023-03-11 01:58:24", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "99.0", + "13": "99.0", + "14": "99.0", + "index": 604 + }, + { + "0": "531E0DC8-53E7-40A2-A8E4-A28F3ACE3F45", + "1": "A1688852207604610", + "2": "99.0", + "3": "11.0", + "4": "2023-03-11 01:58:24", + "5": "103.48965", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "99.0", + "13": "99.0", + "14": "99.0", + "index": 605 + }, + { + "0": "0F4F57CC-5436-4377-9B91-B6C7D0CC67E8", + "1": "A844427868914574", + "2": "389.99", + "3": "11.0", + "4": "2023-03-17 11:35:53", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "779.98", + "13": "779.98", + "14": "389.99", + "index": 606 + }, + { + "0": "9D92C6BC-E560-4C32-A034-1E1F0814E46E", + "1": "A844428017843376", + "2": "107.52", + "3": "15.0", + "4": "2023-01-03 20:42:58", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "790.02", + "13": "790.02", + "14": "112.86", + "index": 607 + }, + { + "0": "12E12CAD-EC37-4E94-8D22-38BBE241C040", + "1": "A1899947010057920", + "2": "5097.0", + "3": "14.0", + "4": "2023-02-23 05:22:36", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "5097.0", + "13": "5097.0", + "14": "5097.0", + "index": 608 + }, + { + "0": "12E12CAD-EC37-4E94-8D22-38BBE241C040", + "1": "A1899947010057920", + "2": "5097.0", + "3": "14.0", + "4": "2023-02-23 05:22:36", + "5": "656.95233", + "6": "false", + "7": "3.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "5097.0", + "13": "5097.0", + "14": "5097.0", + "index": 609 + }, + { + "0": "F8226068-961C-4004-9061-B71F6C1665A2", + "1": "A1688853647452210", + "2": "423.99", + "3": "13.0", + "4": "2023-02-09 18:23:44", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "423.99", + "13": "423.99", + "14": "423.99", + "index": 610 + }, + { + "0": "F8226068-961C-4004-9061-B71F6C1665A2", + "1": "A1688853647452210", + "2": "423.99", + "3": "13.0", + "4": "2023-02-09 18:23:44", + "5": "423.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "423.99", + "13": "423.99", + "14": "423.99", + "index": 611 + }, + { + "0": "2DD082E0-85FA-4967-91C7-FB34908A1D89", + "1": "A1759222168021270", + "2": "63.95", + "3": "0.0", + "4": "2023-02-17 06:35:22", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "63.95", + "13": "63.95", + "14": "63.95", + "index": 612 + }, + { + "0": "2DD082E0-85FA-4967-91C7-FB34908A1D89", + "1": "A1759222168021270", + "2": "63.95", + "3": "0.0", + "4": "2023-02-17 06:35:22", + "5": "63.95", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "63.95", + "13": "63.95", + "14": "63.95", + "index": 613 + }, + { + "0": "57E282C4-3F49-485B-B5B8-CACAEEF05078", + "1": "A1759222088017710", + "2": "78750.0", + "3": "16.0", + "4": "2023-03-15 07:47:32", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "78750.0", + "13": "78750.0", + "14": "78750.0", + "index": 614 + }, + { + "0": "F6FBBB59-BFD5-4736-B635-64301B04D71C", + "1": "A1899946873142120", + "2": "149.97", + "3": "15.0", + "4": "2023-01-03 20:42:53", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "7508.500000000003", + "13": "7508.500000000003", + "14": "147.22549019607848", + "index": 615 + }, + { + "0": "4EC3DEEC-D21B-4515-A3DE-5CC895397F21", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 19:59:16", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "4359.129999999997", + "13": "4359.129999999997", + "14": "145.30433333333323", + "index": 616 + }, + { + "0": "99E39E43-B8E7-48C8-8C6E-EE09902A63E0", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:36:07", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "299.85", + "13": "299.85", + "14": "19.990000000000002", + "index": 617 + }, + { + "0": "C6FD141A-3BE6-49A4-84BE-421F35CA31B2", + "1": "A914800247987042", + "2": "21.71", + "3": "19.0", + "4": "2023-02-24 00:50:43", + "9": "1", + "10": "2127.0", + "11": "0.0", + "12": "21.71", + "13": "21.71", + "14": "21.71", + "index": 618 + }, + { + "0": "C6FD141A-3BE6-49A4-84BE-421F35CA31B2", + "1": "A914800247987042", + "2": "21.71", + "3": "19.0", + "4": "2023-02-24 00:50:43", + "5": "21.71", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "2127.0", + "11": "0.0", + "12": "21.71", + "13": "21.71", + "14": "21.71", + "index": 619 + }, + { + "0": "E4BE3429-CFC8-44D0-B48F-BCD7D875D0E9", + "1": "A1759222229520370", + "2": "599.0", + "3": "23.0", + "4": "2023-01-03 14:02:57", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "599.0", + "13": "599.0", + "14": "599.0", + "index": 620 + }, + { + "0": "E261B8E8-F241-46F3-89AA-5CC0283C8040", + "1": "A985156999024771", + "2": "92.5", + "3": "2.0", + "4": "2023-02-01 10:37:54", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "92.5", + "13": "92.5", + "14": "92.5", + "index": 621 + }, + { + "0": "13CC7673-A59D-45CF-8287-2B4E8EE05396", + "1": "A1055521399136000", + "2": "5.4", + "3": "23.0", + "4": "2023-02-27 04:46:49", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "16.200000000000003", + "13": "16.200000000000003", + "14": "5.400000000000001", + "index": 622 + }, + { + "0": "E52016D2-8898-4D8F-94EE-9D3357692C21", + "1": "A844428031214472", + "2": "2199.0", + "3": "9.0", + "4": "2023-01-06 13:14:20", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "2199.0", + "13": "2199.0", + "14": "2199.0", + "index": 623 + }, + { + "0": "E52016D2-8898-4D8F-94EE-9D3357692C21", + "1": "A844428031214472", + "2": "2199.0", + "3": "9.0", + "4": "2023-01-06 13:14:20", + "5": "442.12214400000005", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "2199.0", + "13": "2199.0", + "14": "2199.0", + "index": 624 + }, + { + "0": "10B457AE-179C-457B-90BA-1A0E6D8F5143", + "1": "A1055521388773990", + "2": "119.06", + "3": "20.0", + "4": "2023-01-15 02:43:22", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.06", + "13": "119.06", + "14": "119.06", + "index": 625 + }, + { + "0": "8B065D0D-9FBB-4815-B341-DDA432223550", + "1": "A1829582580775700", + "2": "65.57", + "3": "12.0", + "4": "2023-01-03 19:35:25", + "5": "65.57", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "262.28", + "13": "262.28", + "14": "65.57", + "index": 626 + }, + { + "0": "E24846FB-89B2-4304-8039-23C9271D1889", + "1": "A1688853516417610", + "2": "78750.0", + "3": "20.0", + "4": "2023-03-11 11:47:11", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "157500.0", + "13": "157500.0", + "14": "78750.0", + "index": 627 + }, + { + "0": "E24846FB-89B2-4304-8039-23C9271D1889", + "1": "A1688853516417610", + "2": "78750.0", + "3": "20.0", + "4": "2023-03-11 11:47:11", + "5": "868.6125", + "6": "false", + "7": "3.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "157500.0", + "13": "157500.0", + "14": "78750.0", + "index": 628 + }, + { + "0": "92CDB9E5-D34B-415C-B5D5-F4BA4C221855", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 19:57:07", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "4209.159999999997", + "13": "4209.159999999997", + "14": "145.14344827586197", + "index": 629 + }, + { + "0": "92CDB9E5-D34B-415C-B5D5-F4BA4C221855", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 19:57:07", + "5": "149.97", + "6": "false", + "7": "3.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "4209.159999999997", + "13": "4209.159999999997", + "14": "145.14344827586197", + "index": 630 + }, + { + "0": "CFE1CF54-83D2-4396-88F9-7F0E7C2ED586", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 03:03:16", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "490.4899999999991", + "13": "479.7099999999991", + "14": "5.38999999999999", + "index": 631 + }, + { + "0": "427FDE58-CA6D-4D48-B528-AD194856D115", + "1": "A985157015268058", + "2": "4.99", + "3": "11.0", + "4": "2023-02-26 17:02:10", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "19.96", + "13": "19.96", + "14": "4.99", + "index": 632 + }, + { + "0": "A5343E7D-5553-4F25-B916-E18FE75CF2AC", + "1": "A1688853516414440", + "2": "125580.0", + "3": "0.0", + "4": "2023-03-10 15:51:52", + "5": "1385.1474", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "284340.0", + "13": "284340.0", + "14": "94780.0", + "index": 633 + }, + { + "0": "90BAD1BA-E6EE-4EA6-B27F-7162B22CDBFA", + "1": "A844428017843376", + "2": "107.52", + "3": "15.0", + "4": "2023-01-03 20:39:16", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "562.52", + "13": "562.52", + "14": "112.50399999999999", + "index": 634 + }, + { + "0": "F69ECCC1-8BF7-48B4-80D8-75CF064D6017", + "1": "A914801012822158", + "2": "92.2", + "3": "9.0", + "4": "2023-02-02 14:42:25", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "196.45", + "13": "196.45", + "14": "98.225", + "index": 635 + }, + { + "0": "F69ECCC1-8BF7-48B4-80D8-75CF064D6017", + "1": "A914801012822158", + "2": "92.2", + "3": "9.0", + "4": "2023-02-02 14:42:25", + "5": "92.2", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "196.45", + "13": "196.45", + "14": "98.225", + "index": 636 + }, + { + "0": "1504CCD5-386C-4201-8362-D235C13D93AC", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 21:07:35", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "156.30999999999992", + "13": "145.52999999999994", + "14": "5.389999999999997", + "index": 637 + }, + { + "0": "7C1A8002-1E95-4100-B2E3-2EDAEFA7AC4E", + "1": "A1688853516414440", + "2": "79380.0", + "3": "0.0", + "4": "2023-03-10 15:49:34", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "158760.0", + "13": "158760.0", + "14": "79380.0", + "index": 638 + }, + { + "0": "7C1A8002-1E95-4100-B2E3-2EDAEFA7AC4E", + "1": "A1688853516414440", + "2": "79380.0", + "3": "0.0", + "4": "2023-03-10 15:49:34", + "5": "875.5614", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "158760.0", + "13": "158760.0", + "14": "79380.0", + "index": 639 + }, + { + "0": "BDA24FA7-E187-478C-82AE-865DBCF769F0", + "1": "A844428087822266", + "2": "278.88", + "3": "10.0", + "4": "2023-03-27 15:45:21", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "278.88", + "13": "278.88", + "14": "278.88", + "index": 640 + }, + { + "0": "BDA24FA7-E187-478C-82AE-865DBCF769F0", + "1": "A844428087822266", + "2": "278.88", + "3": "10.0", + "4": "2023-03-27 15:45:21", + "5": "277.72822599999995", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "278.88", + "13": "278.88", + "14": "278.88", + "index": 641 + }, + { + "0": "65020E58-781D-4FFC-BEF2-0FDF87BE671D", + "1": "A985156981092344", + "2": "1148.6", + "3": "20.0", + "4": "2023-01-02 02:05:50", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1148.6", + "13": "1148.6", + "14": "1148.6", + "index": 642 + }, + { + "0": "65020E58-781D-4FFC-BEF2-0FDF87BE671D", + "1": "A985156981092344", + "2": "1148.6", + "3": "20.0", + "4": "2023-01-02 02:05:50", + "5": "1143.856282", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1148.6", + "13": "1148.6", + "14": "1148.6", + "index": 643 + }, + { + "0": "CA5F63D9-CA1B-41E6-8C42-7F89EA103D1D", + "1": "A1899946895455190", + "2": "19.99", + "3": "13.0", + "4": "2023-01-13 18:31:01", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "59.97", + "13": "59.97", + "14": "19.99", + "index": 644 + }, + { + "0": "8454CEA5-B059-4E44-8ADE-100460ED0992", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:26:24", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "274.88999999999965", + "13": "264.1099999999997", + "14": "5.3899999999999935", + "index": 645 + }, + { + "0": "CEA84E44-9194-48A0-A5F7-5BFA43E671BF", + "1": "A1055521399136000", + "2": "5.4", + "3": "23.0", + "4": "2023-02-27 04:44:44", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "5.4", + "13": "5.4", + "14": "5.4", + "index": 646 + }, + { + "0": "68162486-44E1-44E6-AB46-44EAF9D72EF6", + "1": "A985157024246345", + "2": "51.24", + "4": "2023-03-10 00:44:53", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "51.24", + "13": "51.24", + "14": "51.24", + "index": 647 + }, + { + "0": "68162486-44E1-44E6-AB46-44EAF9D72EF6", + "1": "A985157024246345", + "2": "51.24", + "4": "2023-03-10 00:44:53", + "5": "51.24", + "6": "false", + "7": "1.0", + "8": "3.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "51.24", + "13": "51.24", + "14": "51.24", + "index": 648 + }, + { + "0": "4BCAC6B0-3937-47E3-9AB8-6519D09321B1", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:01:57", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "53.99", + "13": "53.99", + "14": "53.99", + "index": 649 + }, + { + "0": "3F556D13-8CCB-400E-B9BD-582162BE610B", + "1": "A1899946873142120", + "2": "149.97", + "3": "15.0", + "4": "2023-01-03 20:36:12", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "7058.590000000002", + "13": "7058.590000000002", + "14": "147.05395833333338", + "index": 650 + }, + { + "0": "C09DE962-3605-4A0E-B82F-A09B2B618D1F", + "1": "A1829582571089880", + "2": "233.19", + "3": "21.0", + "4": "2023-01-28 05:54:27", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "233.19", + "13": "233.19", + "14": "233.19", + "index": 651 + }, + { + "0": "D4C38B0B-DFEF-4F21-A66B-AC87B626BBFA", + "1": "A985156999024771", + "2": "93.07", + "3": "6.0", + "4": "2023-02-02 14:35:38", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "185.57", + "13": "185.57", + "14": "92.785", + "index": 652 + }, + { + "0": "D4C38B0B-DFEF-4F21-A66B-AC87B626BBFA", + "1": "A985156999024771", + "2": "93.07", + "3": "6.0", + "4": "2023-02-02 14:35:38", + "5": "93.07", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "185.57", + "13": "185.57", + "14": "92.785", + "index": 653 + }, + { + "0": "70A54CA5-D32A-4DB1-8F56-B406D827A7B7", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 21:08:34", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "161.6999999999999", + "13": "150.91999999999993", + "14": "5.389999999999997", + "index": 654 + }, + { + "0": "8C92EAEE-3E47-4410-89C9-F95000EC0707", + "1": "A985157015268058", + "2": "4.99", + "3": "11.0", + "4": "2023-02-26 16:57:54", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "14.97", + "13": "14.97", + "14": "4.99", + "index": 655 + }, + { + "0": "8C92EAEE-3E47-4410-89C9-F95000EC0707", + "1": "A985157015268058", + "2": "4.99", + "3": "11.0", + "4": "2023-02-26 16:57:54", + "5": "4.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "14.97", + "13": "14.97", + "14": "4.99", + "index": 656 + }, + { + "0": "306D1B72-286E-44A1-AF1E-BC01B6551B83", + "1": "A1688853662168790", + "2": "73080.0", + "3": "13.0", + "4": "2023-03-13 04:21:12", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "135660.0", + "13": "135660.0", + "14": "67830.0", + "index": 657 + }, + { + "0": "306D1B72-286E-44A1-AF1E-BC01B6551B83", + "1": "A1688853662168790", + "2": "73080.0", + "3": "13.0", + "4": "2023-03-13 04:21:12", + "5": "806.0724", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "135660.0", + "13": "135660.0", + "14": "67830.0", + "index": 658 + }, + { + "0": "DE2E99AB-BCA3-4E62-9774-17E62E4C50E0", + "1": "A985156985071493", + "2": "74.89", + "3": "16.0", + "4": "2023-01-08 15:39:26", + "9": "1", + "10": "366.0", + "11": "1.0", + "12": "74.89", + "13": "74.89", + "14": "74.89", + "index": 659 + }, + { + "0": "DE2E99AB-BCA3-4E62-9774-17E62E4C50E0", + "1": "A985156985071493", + "2": "74.89", + "3": "16.0", + "4": "2023-01-08 15:39:26", + "5": "74.89", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "1.0", + "12": "74.89", + "13": "74.89", + "14": "74.89", + "index": 660 + }, + { + "0": "3A13F395-6C81-4DD9-ABEB-FE7089DD21E2", + "1": "A985157000299534", + "2": "157.07", + "3": "14.0", + "4": "2023-02-03 19:29:54", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "157.07", + "13": "157.07", + "14": "157.07", + "index": 661 + }, + { + "0": "3A13F395-6C81-4DD9-ABEB-FE7089DD21E2", + "1": "A985157000299534", + "2": "157.07", + "3": "14.0", + "4": "2023-02-03 19:29:54", + "5": "156.421301", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "157.07", + "13": "157.07", + "14": "157.07", + "index": 662 + }, + { + "0": "5BCD2DBE-8524-4445-87E0-910F21C71046", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:58:13", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "468.92999999999915", + "13": "458.1499999999992", + "14": "5.38999999999999", + "index": 663 + }, + { + "0": "5BCD2DBE-8524-4445-87E0-910F21C71046", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:58:13", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "468.92999999999915", + "13": "458.1499999999992", + "14": "5.38999999999999", + "index": 664 + }, + { + "0": "56BAD8D6-088E-4AD9-99E4-2C23D10C32B0", + "1": "A985156345961425", + "2": "109.99", + "3": "23.0", + "4": "2023-01-30 06:48:24", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "109.99", + "13": "109.99", + "14": "109.99", + "index": 665 + }, + { + "0": "CCA3EB41-5AB7-4C77-AFD0-BC552C95E019", + "1": "A844427390246047", + "2": "5.39", + "3": "6.0", + "4": "2023-02-26 11:27:30", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "549.779999999999", + "13": "538.999999999999", + "14": "5.38999999999999", + "index": 666 + }, + { + "0": "2D228D45-7E38-45CF-BD23-8D4F3445FFF8", + "1": "A1688853657869890", + "2": "52.99", + "3": "10.0", + "4": "2023-01-03 16:52:56", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "105.98", + "13": "105.98", + "14": "52.99", + "index": 667 + }, + { + "0": "3FBAFD91-D3AC-41CB-BC17-4CAAAC0C52EA", + "1": "A844428046730497", + "2": "278.88", + "3": "11.0", + "4": "2023-01-29 16:36:34", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "557.76", + "13": "557.76", + "14": "278.88", + "index": 668 + }, + { + "0": "18C1A371-128D-4C3E-BFA3-AD8A96C5A26E", + "1": "A1899946781648580", + "2": "228.79", + "3": "9.0", + "4": "2023-02-23 15:23:32", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "228.79", + "13": "228.79", + "14": "228.79", + "index": 669 + }, + { + "0": "61841EEB-00BE-478C-8142-677F86A55BD1", + "1": "A1899946873142120", + "2": "149.97", + "3": "15.0", + "4": "2023-01-03 20:26:54", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "6608.680000000001", + "13": "6608.680000000001", + "14": "146.85955555555557", + "index": 670 + }, + { + "0": "F6C39AEA-B9AC-4718-9690-A47F81A7C38D", + "1": "A844427754541367", + "2": "116.86", + "3": "15.0", + "4": "2023-01-25 21:33:42", + "9": "1", + "10": "888.0", + "11": "0.0", + "12": "116.86", + "13": "116.86", + "14": "116.86", + "index": 671 + }, + { + "0": "F6C39AEA-B9AC-4718-9690-A47F81A7C38D", + "1": "A844427754541367", + "2": "116.86", + "3": "15.0", + "4": "2023-01-25 21:33:42", + "5": "116.86", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "888.0", + "11": "0.0", + "12": "116.86", + "13": "116.86", + "14": "116.86", + "index": 672 + }, + { + "0": "624230B8-10F5-4BA5-A45B-BFF259872D75", + "1": "A985157010652653", + "2": "73080.0", + "3": "3.0", + "4": "2023-02-19 18:58:36", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "146160.0", + "13": "146160.0", + "14": "73080.0", + "index": 673 + }, + { + "0": "624230B8-10F5-4BA5-A45B-BFF259872D75", + "1": "A985157010652653", + "2": "73080.0", + "3": "3.0", + "4": "2023-02-19 18:58:36", + "5": "806.0724", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "146160.0", + "13": "146160.0", + "14": "73080.0", + "index": 674 + }, + { + "0": "7B14E6C6-F218-4C61-A29A-B3157D7A0E4A", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:26:55", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "274.88999999999965", + "13": "264.1099999999997", + "14": "5.3899999999999935", + "index": 675 + }, + { + "0": "F6E6F205-C915-4FBF-837A-38163126A25A", + "1": "A985156290472668", + "2": "5.34", + "3": "20.0", + "4": "2023-02-26 02:10:31", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "16.02", + "13": "16.02", + "14": "5.34", + "index": 676 + }, + { + "0": "F6E6F205-C915-4FBF-837A-38163126A25A", + "1": "A985156290472668", + "2": "5.34", + "3": "20.0", + "4": "2023-02-26 02:10:31", + "5": "5.34", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "16.02", + "13": "16.02", + "14": "5.34", + "index": 677 + }, + { + "0": "218C5731-A37A-4CBA-8D3B-EF20FF23DEAE", + "1": "A985157015268058", + "2": "4.99", + "3": "10.0", + "4": "2023-02-27 15:37:03", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "54.890000000000015", + "13": "54.890000000000015", + "14": "4.990000000000001", + "index": 678 + }, + { + "0": "216991DF-33A6-4090-90AA-3E09DDF390E4", + "1": "A985157015268058", + "2": "4.99", + "3": "11.0", + "4": "2023-02-26 16:48:52", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "9.98", + "13": "9.98", + "14": "4.99", + "index": 679 + }, + { + "0": "1E7C21A8-930E-43D4-8044-8356F16FACB2", + "1": "A844428039854278", + "2": "76.19", + "3": "14.0", + "4": "2023-01-16 19:23:46", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "76.19", + "13": "76.19", + "14": "76.19", + "index": 680 + }, + { + "0": "1E7C21A8-930E-43D4-8044-8356F16FACB2", + "1": "A844428039854278", + "2": "76.19", + "3": "14.0", + "4": "2023-01-16 19:23:46", + "5": "76.19", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "76.19", + "13": "76.19", + "14": "76.19", + "index": 681 + }, + { + "0": "2C8A9E18-E28E-4555-B5F9-98F0D34FCEAE", + "1": "A985157010652653", + "2": "73080.0", + "3": "3.0", + "4": "2023-02-19 18:48:28", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 682 + }, + { + "0": "E498A57D-E5CF-4883-932E-6B39D7CFF7A0", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:38:18", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "296.4499999999996", + "13": "285.6699999999996", + "14": "5.389999999999993", + "index": 683 + }, + { + "0": "37E89109-BF6A-4056-AAE5-3CECBB90641E", + "1": "A985156954406966", + "2": "240.45", + "3": "19.0", + "4": "2023-02-28 01:52:31", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "480.9", + "13": "480.9", + "14": "240.45", + "index": 684 + }, + { + "0": "37E89109-BF6A-4056-AAE5-3CECBB90641E", + "1": "A985156954406966", + "2": "240.45", + "3": "19.0", + "4": "2023-02-28 01:52:31", + "5": "240.45", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "480.9", + "13": "480.9", + "14": "240.45", + "index": 685 + }, + { + "0": "92EA085E-FD70-425B-80EB-4513BFBA8AF1", + "1": "A985157038112964", + "2": "150.14", + "3": "22.0", + "4": "2023-03-26 03:25:46", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "300.28", + "13": "300.28", + "14": "150.14", + "index": 686 + }, + { + "0": "F06A587E-F353-481B-9BBA-FFAC28C60777", + "1": "A1899946873142120", + "2": "149.97", + "3": "15.0", + "4": "2023-01-03 20:46:21", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "7658.470000000003", + "13": "7658.470000000003", + "14": "147.2782692307693", + "index": 687 + }, + { + "0": "F06A587E-F353-481B-9BBA-FFAC28C60777", + "1": "A1899946873142120", + "2": "149.97", + "3": "15.0", + "4": "2023-01-03 20:46:21", + "5": "149.97", + "6": "false", + "7": "3.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "7658.470000000003", + "13": "7658.470000000003", + "14": "147.2782692307693", + "index": 688 + }, + { + "0": "8C337F6E-E17F-4CDA-833A-CBEF20C65CF9", + "1": "A985157015268058", + "2": "4.99", + "3": "11.0", + "4": "2023-02-26 17:04:05", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "24.950000000000003", + "13": "24.950000000000003", + "14": "4.99", + "index": 689 + }, + { + "0": "8C99CEBB-0BCA-4D2C-BEB7-09A627F46CDF", + "1": "A1055520836257310", + "2": "5.04", + "3": "5.0", + "4": "2023-02-28 10:45:27", + "9": "1", + "10": "1555.0", + "11": "0.0", + "12": "30.24", + "13": "30.24", + "14": "5.04", + "index": 690 + }, + { + "0": "C077446E-640F-4769-9527-5A727F34A4B4", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:38:29", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "319.84000000000003", + "13": "319.84000000000003", + "14": "19.990000000000002", + "index": 691 + }, + { + "0": "9BC1E2D0-E438-4343-B319-212B06186B71", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:29:01", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "64.67999999999999", + "13": "64.67999999999999", + "14": "5.39", + "index": 692 + }, + { + "0": "1FB77AC2-B16B-468E-B8AD-D83F82586D10", + "1": "A1829582571084310", + "2": "222.19", + "3": "22.0", + "4": "2023-02-28 04:17:41", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "222.19", + "13": "222.19", + "14": "222.19", + "index": 693 + }, + { + "0": "1FB77AC2-B16B-468E-B8AD-D83F82586D10", + "1": "A1829582571084310", + "2": "222.19", + "3": "22.0", + "4": "2023-02-28 04:17:41", + "5": "222.19", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "222.19", + "13": "222.19", + "14": "222.19", + "index": 694 + }, + { + "0": "990FAC29-0BAC-4D26-A896-27E71BA5144A", + "1": "A844428035915015", + "2": "86.17", + "3": "23.0", + "4": "2023-01-12 04:22:36", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "86.17", + "13": "86.17", + "14": "86.17", + "index": 695 + }, + { + "0": "990FAC29-0BAC-4D26-A896-27E71BA5144A", + "1": "A844428035915015", + "2": "86.17", + "3": "23.0", + "4": "2023-01-12 04:22:36", + "5": "86.17", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "86.17", + "13": "86.17", + "14": "86.17", + "index": 696 + }, + { + "0": "EC085107-C5DF-4814-8E31-374D3D8BD5AD", + "1": "A564049508937862", + "2": "482.68", + "3": "10.0", + "4": "2023-03-06 18:31:45", + "5": "482.68", + "6": "false", + "7": "1.0", + "8": "1.0", + "9": "0", + "10": "2365.0", + "11": "0.0", + "12": "482.68", + "13": "482.68", + "14": "482.68", + "index": 697 + }, + { + "0": "0C9B4BE7-CEDB-4B19-9061-855CEC55B0FF", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:48:25", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "339.5699999999995", + "13": "328.7899999999995", + "14": "5.389999999999992", + "index": 698 + }, + { + "0": "0C9B4BE7-CEDB-4B19-9061-855CEC55B0FF", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:48:25", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "339.5699999999995", + "13": "328.7899999999995", + "14": "5.389999999999992", + "index": 699 + }, + { + "0": "4B54A952-E219-4AD1-8DB2-CAD464FCC43A", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 18:46:44", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "309.94", + "13": "309.94", + "14": "103.31333333333333", + "index": 700 + }, + { + "0": "B6B66DCD-8211-47F8-A921-AED2FD47536F", + "1": "A844427390246047", + "2": "5.39", + "3": "6.0", + "4": "2023-02-25 12:18:16", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "237.1599999999997", + "13": "226.37999999999974", + "14": "5.3899999999999935", + "index": 701 + }, + { + "0": "D74EFAAF-1FCC-4F41-AB01-317001E86EF1", + "1": "A844427390246047", + "2": "5.39", + "3": "14.0", + "4": "2023-02-24 19:42:15", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "2365.0", + "11": "3.0", + "12": "32.339999999999996", + "13": "32.339999999999996", + "14": "5.39", + "index": 702 + }, + { + "0": "B6B66DCD-8211-47F8-A921-AED2FD47536F", + "1": "A844427390246047", + "2": "5.39", + "3": "6.0", + "4": "2023-02-25 12:18:16", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "237.1599999999997", + "13": "226.37999999999974", + "14": "5.3899999999999935", + "index": 703 + }, + { + "0": "976C63FB-B108-4C8E-B190-C37F1FF602B4", + "1": "A985156290472668", + "2": "5.34", + "3": "20.0", + "4": "2023-02-26 02:09:47", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "10.68", + "13": "10.68", + "14": "5.34", + "index": 704 + }, + { + "0": "976C63FB-B108-4C8E-B190-C37F1FF602B4", + "1": "A985156290472668", + "2": "5.34", + "3": "20.0", + "4": "2023-02-26 02:09:47", + "5": "5.34", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "10.68", + "13": "10.68", + "14": "5.34", + "index": 705 + }, + { + "0": "DFDDB7C2-7E6D-41A1-86CC-84FCF8F3C8E8", + "1": "A914800689334401", + "2": "109.99", + "3": "16.0", + "4": "2023-03-11 01:06:36", + "9": "1", + "10": "372.0", + "11": "0.0", + "12": "219.98", + "13": "109.99", + "14": "109.99", + "index": 706 + }, + { + "0": "DFDDB7C2-7E6D-41A1-86CC-84FCF8F3C8E8", + "1": "A914800689334401", + "2": "109.99", + "3": "16.0", + "4": "2023-03-11 01:06:36", + "5": "109.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "372.0", + "11": "0.0", + "12": "219.98", + "13": "109.99", + "14": "109.99", + "index": 707 + }, + { + "0": "241DBB1D-3092-4FCE-A4A5-00219ECD6C99", + "1": "A1055521428449680", + "2": "278.88", + "3": "22.0", + "4": "2023-03-22 03:35:42", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "278.88", + "13": "278.88", + "14": "278.88", + "index": 708 + }, + { + "0": "C5369F85-BC0A-43F2-B7F2-4930B89DC246", + "1": "A844428031222008", + "2": "54.26", + "3": "19.0", + "4": "2023-01-05 01:15:30", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "54.26", + "13": "54.26", + "14": "54.26", + "index": 709 + }, + { + "0": "C5369F85-BC0A-43F2-B7F2-4930B89DC246", + "1": "A844428031222008", + "2": "54.26", + "3": "19.0", + "4": "2023-01-05 01:15:30", + "5": "54.26", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "54.26", + "13": "54.26", + "14": "54.26", + "index": 710 + }, + { + "0": "C7D4CBEF-2E68-41A2-B83A-D064795E296E", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 20:16:55", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "5858.83", + "13": "5858.83", + "14": "146.47075", + "index": 711 + }, + { + "0": "C4286407-3D76-4187-8FD8-EEF5CE3E26A2", + "1": "A844428047343854", + "2": "106.24", + "3": "19.0", + "4": "2023-02-01 01:23:58", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "106.24", + "13": "106.24", + "14": "106.24", + "index": 712 + }, + { + "0": "C4286407-3D76-4187-8FD8-EEF5CE3E26A2", + "1": "A844428047343854", + "2": "106.24", + "3": "19.0", + "4": "2023-02-01 01:23:58", + "5": "106.24", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "106.24", + "13": "106.24", + "14": "106.24", + "index": 713 + }, + { + "0": "2104E85A-B76B-419E-8204-3EAB76C7D122", + "1": "A844427390246047", + "2": "5.39", + "3": "13.0", + "4": "2023-02-24 19:11:03", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "2365.0", + "11": "3.0", + "12": "16.169999999999998", + "13": "16.169999999999998", + "14": "5.39", + "index": 714 + }, + { + "0": "FFCA8791-18C3-4C81-9D89-1250936E41E1", + "1": "A844428082845952", + "2": "147.83", + "3": "13.0", + "4": "2023-03-21 19:04:04", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "295.66", + "13": "295.66", + "14": "147.83", + "index": 715 + }, + { + "0": "704EA48E-FAA1-485B-88C9-6F3E21CAC2E7", + "1": "A914800134032375", + "2": "109.99", + "3": "17.0", + "4": "2023-02-12 22:52:26", + "9": "1", + "10": "562.0", + "11": "0.0", + "12": "109.99", + "13": "109.99", + "14": "109.99", + "index": 716 + }, + { + "0": "704EA48E-FAA1-485B-88C9-6F3E21CAC2E7", + "1": "A914800134032375", + "2": "109.99", + "3": "17.0", + "4": "2023-02-12 22:52:26", + "5": "109.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "562.0", + "11": "0.0", + "12": "109.99", + "13": "109.99", + "14": "109.99", + "index": 717 + }, + { + "0": "64C56D07-3CE5-42DD-8ACD-86FCEC01CC7A", + "1": "A1899946873128090", + "2": "127.48", + "3": "22.0", + "4": "2023-02-15 03:48:42", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "443.02000000000004", + "13": "443.02000000000004", + "14": "110.75500000000001", + "index": 718 + }, + { + "0": "64C56D07-3CE5-42DD-8ACD-86FCEC01CC7A", + "1": "A1899946873128090", + "2": "127.48", + "3": "22.0", + "4": "2023-02-15 03:48:42", + "5": "127.48", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "443.02000000000004", + "13": "443.02000000000004", + "14": "110.75500000000001", + "index": 719 + }, + { + "0": "A23C51AD-50BC-4719-B489-A29643BB3C74", + "1": "A1829582519835540", + "2": "59.99", + "3": "4.0", + "4": "2023-02-17 11:20:25", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "187.17000000000002", + "13": "187.17000000000002", + "14": "62.39000000000001", + "index": 720 + }, + { + "0": "DE94FF49-79D4-417C-87B2-6682EC4AA382", + "1": "A1829582580775700", + "2": "65.57", + "3": "12.0", + "4": "2023-01-03 19:38:47", + "5": "65.57", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "458.98999999999995", + "13": "458.98999999999995", + "14": "65.57", + "index": 721 + }, + { + "0": "B070007C-549E-4211-920D-AF0712332B4B", + "1": "A985156984009293", + "2": "127.19", + "4": "2023-01-06 17:45:56", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "143.04", + "13": "143.04", + "14": "71.52", + "index": 722 + }, + { + "0": "B070007C-549E-4211-920D-AF0712332B4B", + "1": "A985156984009293", + "2": "127.19", + "4": "2023-01-06 17:45:56", + "5": "127.19", + "6": "false", + "7": "1.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "143.04", + "13": "143.04", + "14": "71.52", + "index": 723 + }, + { + "0": "F5F315E9-DA90-463E-B981-7D7EB8FFB197", + "1": "A914801014875116", + "2": "238.14", + "3": "15.0", + "4": "2023-02-03 20:37:59", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "238.14", + "13": "238.14", + "14": "238.14", + "index": 724 + }, + { + "0": "F5F315E9-DA90-463E-B981-7D7EB8FFB197", + "1": "A914801014875116", + "2": "238.14", + "3": "15.0", + "4": "2023-02-03 20:37:59", + "5": "238.14", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "238.14", + "13": "238.14", + "14": "238.14", + "index": 725 + }, + { + "0": "CF2FC7F2-2924-4EC3-8951-1F5785BE3003", + "1": "A914800889932462", + "2": "53.36", + "3": "6.0", + "4": "2023-02-16 12:58:46", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "53.36", + "13": "53.36", + "14": "53.36", + "index": 726 + }, + { + "0": "CF2FC7F2-2924-4EC3-8951-1F5785BE3003", + "1": "A914800889932462", + "2": "53.36", + "3": "6.0", + "4": "2023-02-16 12:58:46", + "5": "53.36", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "53.36", + "13": "53.36", + "14": "53.36", + "index": 727 + }, + { + "0": "0EB011D9-CAF2-4A02-8ACF-03895BE44128", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-21 20:53:06", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "2365.0", + "11": "3.0", + "12": "10.78", + "13": "10.78", + "14": "5.39", + "index": 728 + }, + { + "0": "D3507A5B-38A9-40F9-B992-DB1547B281C9", + "1": "A1688853516417610", + "2": "78750.0", + "3": "20.0", + "4": "2023-03-11 11:45:45", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "78750.0", + "13": "78750.0", + "14": "78750.0", + "index": 729 + }, + { + "0": "E617D42C-798C-455C-8372-BC06259DE735", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:11:03", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "377.93", + "13": "377.93", + "14": "53.99", + "index": 730 + }, + { + "0": "C0C109CA-5ECF-40E1-8D9E-55025AB4FBCF", + "1": "A844428041547410", + "2": "99.99", + "4": "2023-01-19 10:44:26", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "199.98", + "13": "199.98", + "14": "99.99", + "index": 731 + }, + { + "0": "C0C109CA-5ECF-40E1-8D9E-55025AB4FBCF", + "1": "A844428041547410", + "2": "99.99", + "4": "2023-01-19 10:44:26", + "5": "157.474251", + "6": "false", + "7": "1.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "199.98", + "13": "199.98", + "14": "99.99", + "index": 732 + }, + { + "0": "EC41414F-5244-47AC-9F4F-DC7EAF66FA86", + "1": "A985156344741724", + "2": "239.0", + "3": "22.0", + "4": "2023-02-10 01:50:17", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "239.0", + "13": "239.0", + "14": "239.0", + "index": 733 + }, + { + "0": "EC41414F-5244-47AC-9F4F-DC7EAF66FA86", + "1": "A985156344741724", + "2": "239.0", + "3": "22.0", + "4": "2023-02-10 01:50:17", + "5": "120.10945", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "239.0", + "13": "239.0", + "14": "239.0", + "index": 734 + }, + { + "0": "6645E186-2EE1-4F51-883A-7C4333C753C3", + "1": "A296624604869030", + "2": "139.99", + "3": "13.0", + "4": "2023-02-17 22:08:38", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "419.97", + "13": "419.97", + "14": "139.99", + "index": 735 + }, + { + "0": "14B43B88-2D00-4D03-BDDA-3484C0D86769", + "1": "A1688853524321290", + "2": "24.99", + "3": "19.0", + "4": "2023-01-05 00:26:00", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "24.99", + "13": "24.99", + "14": "24.99", + "index": 736 + }, + { + "0": "2E0F3E5F-83E2-4414-8D46-00367E4279AD", + "1": "A844427390246047", + "2": "5.39", + "3": "12.0", + "4": "2023-02-28 17:41:39", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "636.0199999999987", + "13": "296.4499999999996", + "14": "5.389999999999989", + "index": 737 + }, + { + "0": "547D4C95-528D-46FC-A5A5-FA307B44A329", + "1": "A844427390246047", + "2": "5.39", + "3": "5.0", + "4": "2023-02-25 11:16:20", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "215.59999999999977", + "13": "204.8199999999998", + "14": "5.389999999999994", + "index": 738 + }, + { + "0": "AED3F5DA-87AB-45C8-A0FF-426E353FB102", + "1": "A1688853657886190", + "2": "53.99", + "3": "13.0", + "4": "2023-01-03 18:31:04", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1079.8", + "13": "1079.8", + "14": "53.989999999999995", + "index": 739 + }, + { + "0": "AFC2F084-490B-4B4F-AF6A-05B999BC0C81", + "1": "A914801014875116", + "2": "238.14", + "3": "15.0", + "4": "2023-02-03 20:45:40", + "5": "238.14", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "476.28", + "13": "476.28", + "14": "238.14", + "index": 740 + }, + { + "0": "3319C4C1-94A7-45C7-AFC3-D1FD19FDEA8E", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:54:06", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "431.19999999999925", + "13": "420.4199999999993", + "14": "5.389999999999991", + "index": 741 + }, + { + "0": "E8E24E34-5D81-4891-BACF-7CD208CD56D4", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 21:09:15", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "161.6999999999999", + "13": "150.91999999999993", + "14": "5.389999999999997", + "index": 742 + }, + { + "0": "3319C4C1-94A7-45C7-AFC3-D1FD19FDEA8E", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:54:06", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "431.19999999999925", + "13": "420.4199999999993", + "14": "5.389999999999991", + "index": 743 + }, + { + "0": "D247B57A-BE03-44A2-ABCB-E73EA6FCD843", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 19:29:52", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "2859.429999999999", + "13": "2859.429999999999", + "14": "142.97149999999993", + "index": 744 + }, + { + "0": "6D96EB12-FD10-4D59-8262-C477E3B4A7FF", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 20:18:40", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "6008.8", + "13": "6008.8", + "14": "146.55609756097562", + "index": 745 + }, + { + "0": "442116BE-E400-48F2-80E8-C15B1DECFB1E", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 19:51:35", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "3759.2499999999977", + "13": "3759.2499999999977", + "14": "144.58653846153837", + "index": 746 + }, + { + "0": "4AD79610-DF94-40EA-AA57-0D0C4C107950", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:49:19", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "382.6899999999994", + "13": "371.9099999999994", + "14": "5.389999999999991", + "index": 747 + }, + { + "0": "D8EFBBA0-BEF9-4BEA-A6F0-4A5CBE4C1287", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 20:09:43", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "5408.919999999999", + "13": "5408.919999999999", + "14": "146.187027027027", + "index": 748 + }, + { + "0": "770A0525-2D27-4173-B6BF-A5EA905162DC", + "1": "A1055521399136000", + "2": "5.4", + "3": "23.0", + "4": "2023-02-27 04:47:43", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "16.200000000000003", + "13": "16.200000000000003", + "14": "5.400000000000001", + "index": 749 + }, + { + "0": "2C5B2DC8-5E8D-407D-8894-A0D0EB229AA3", + "1": "A914800389046486", + "2": "107.99", + "3": "12.0", + "4": "2023-01-14 17:25:43", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "107.99", + "13": "107.99", + "14": "107.99", + "index": 750 + }, + { + "0": "2C5B2DC8-5E8D-407D-8894-A0D0EB229AA3", + "1": "A914800389046486", + "2": "107.99", + "3": "12.0", + "4": "2023-01-14 17:25:43", + "5": "107.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "107.99", + "13": "107.99", + "14": "107.99", + "index": 751 + }, + { + "0": "4186FC50-1BBE-4188-94FD-5659E850B7A3", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 19:45:29", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "3459.309999999998", + "13": "3459.309999999998", + "14": "144.1379166666666", + "index": 752 + }, + { + "0": "2132335C-082B-4B7E-9B63-DA007878168D", + "1": "A844428017843376", + "2": "107.52", + "3": "15.0", + "4": "2023-01-03 20:32:18", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "335.02", + "13": "335.02", + "14": "111.67333333333333", + "index": 753 + }, + { + "0": "2132335C-082B-4B7E-9B63-DA007878168D", + "1": "A844428017843376", + "2": "107.52", + "3": "15.0", + "4": "2023-01-03 20:32:18", + "5": "107.52", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "335.02", + "13": "335.02", + "14": "111.67333333333333", + "index": 754 + }, + { + "0": "41F4234C-1659-48C5-A9D1-4C2324A0891B", + "1": "A1899946895455190", + "2": "19.99", + "3": "11.0", + "4": "2023-01-13 16:52:56", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "19.99", + "13": "19.99", + "14": "19.99", + "index": 755 + }, + { + "0": "6A2D4479-6262-4C32-95B5-AC5BE0205E24", + "1": "A1899946895455190", + "2": "19.99", + "3": "13.0", + "4": "2023-01-13 18:47:34", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "99.94999999999999", + "13": "99.94999999999999", + "14": "19.99", + "index": 756 + }, + { + "0": "6F7F79E1-1A74-4AF6-9706-830302FC7942", + "1": "A844428029043738", + "2": "21.6", + "3": "10.0", + "4": "2023-02-07 17:01:22", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "21.6", + "13": "21.6", + "14": "21.6", + "index": 757 + }, + { + "0": "6F7F79E1-1A74-4AF6-9706-830302FC7942", + "1": "A844428029043738", + "2": "21.6", + "3": "10.0", + "4": "2023-02-07 17:01:22", + "5": "21.6", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "21.6", + "13": "21.6", + "14": "21.6", + "index": 758 + }, + { + "0": "CBCE65DD-1D82-4C65-91BD-683020CF1D6E", + "1": "A1688853596241210", + "2": "59.99", + "3": "6.0", + "4": "2023-02-16 12:54:17", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "59.99", + "13": "59.99", + "14": "59.99", + "index": 759 + }, + { + "0": "CBCE65DD-1D82-4C65-91BD-683020CF1D6E", + "1": "A1688853596241210", + "2": "59.99", + "3": "6.0", + "4": "2023-02-16 12:54:17", + "5": "59.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "59.99", + "13": "59.99", + "14": "59.99", + "index": 760 + }, + { + "0": "CDD70229-CFCE-4192-829D-980CC5F0AD96", + "1": "A844427390246047", + "2": "5.39", + "3": "9.0", + "4": "2023-02-28 14:30:20", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "571.3399999999989", + "13": "231.76999999999973", + "14": "5.38999999999999", + "index": 761 + }, + { + "0": "209685D0-27D7-42CE-A3A2-24F643DD387F", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:52:17", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "415.0299999999993", + "13": "404.2499999999993", + "14": "5.389999999999991", + "index": 762 + }, + { + "0": "EC68A65E-1901-4CE2-8BAF-92E4734A4D74", + "1": "A985157026813391", + "2": "226.95", + "3": "17.0", + "4": "2023-03-13 01:35:43", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "226.95", + "13": "226.95", + "14": "226.95", + "index": 763 + }, + { + "0": "EC68A65E-1901-4CE2-8BAF-92E4734A4D74", + "1": "A985157026813391", + "2": "226.95", + "3": "17.0", + "4": "2023-03-13 01:35:43", + "5": "226.95", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "226.95", + "13": "226.95", + "14": "226.95", + "index": 764 + }, + { + "0": "5F5F30FC-7EA0-41CE-B5A4-FA459FDDBE38", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:09:49", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "323.94", + "13": "323.94", + "14": "53.99", + "index": 765 + }, + { + "0": "552F9E0D-5395-4995-9047-D71CD17F48CB", + "1": "A1055520836257310", + "2": "5.04", + "3": "6.0", + "4": "2023-02-28 12:19:58", + "9": "1", + "10": "1555.0", + "11": "0.0", + "12": "40.32", + "13": "40.32", + "14": "5.04", + "index": 766 + }, + { + "0": "BD06116A-1C08-45CB-8BAC-515E522168AE", + "1": "A844428082845952", + "2": "147.83", + "3": "13.0", + "4": "2023-03-21 19:00:49", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "147.83", + "13": "147.83", + "14": "147.83", + "index": 767 + }, + { + "0": "BD06116A-1C08-45CB-8BAC-515E522168AE", + "1": "A844428082845952", + "2": "147.83", + "3": "13.0", + "4": "2023-03-21 19:00:49", + "5": "147.83", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "147.83", + "13": "147.83", + "14": "147.83", + "index": 768 + }, + { + "0": "63065B44-AA7C-46D9-A9B3-E4E1C36667F8", + "1": "A2040691497893890", + "2": "279.98", + "3": "11.0", + "4": "2023-01-14 17:58:29", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "279.98", + "13": "279.98", + "14": "279.98", + "index": 769 + }, + { + "0": "63065B44-AA7C-46D9-A9B3-E4E1C36667F8", + "1": "A2040691497893890", + "2": "279.98", + "3": "11.0", + "4": "2023-01-14 17:58:29", + "5": "279.98", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "279.98", + "13": "279.98", + "14": "279.98", + "index": 770 + }, + { + "0": "298F7C38-80B2-4CC3-8D84-29A2B5B7797C", + "1": "A1899946873142120", + "2": "149.97", + "3": "15.0", + "4": "2023-01-03 20:48:42", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "7808.440000000003", + "13": "7808.440000000003", + "14": "147.32905660377364", + "index": 771 + }, + { + "0": "A6420C3F-3816-4043-B8F2-73B7C384475E", + "1": "A1688852501978320", + "2": "134.81", + "3": "14.0", + "4": "2023-01-27 19:30:57", + "9": "1", + "10": "2184.0", + "11": "0.0", + "12": "134.81", + "13": "134.81", + "14": "134.81", + "index": 772 + }, + { + "0": "A6420C3F-3816-4043-B8F2-73B7C384475E", + "1": "A1688852501978320", + "2": "134.81", + "3": "14.0", + "4": "2023-01-27 19:30:57", + "5": "134.81", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2184.0", + "11": "0.0", + "12": "134.81", + "13": "134.81", + "14": "134.81", + "index": 773 + }, + { + "0": "FEE49FF0-87EB-402B-8EBB-8F9F4C9CB225", + "1": "A1688853657886190", + "2": "53.99", + "3": "13.0", + "4": "2023-01-03 18:33:55", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1187.78", + "13": "1187.78", + "14": "53.99", + "index": 774 + }, + { + "0": "4FD412FF-3716-4007-8C81-80FDA381E04A", + "1": "A914800889937190", + "2": "53.11", + "3": "13.0", + "4": "2023-02-16 18:37:03", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "106.22", + "13": "106.22", + "14": "53.11", + "index": 775 + }, + { + "0": "4D988189-A1DB-41FE-80CA-E338285D302F", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:46:05", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "361.1299999999994", + "13": "350.34999999999945", + "14": "5.389999999999992", + "index": 776 + }, + { + "0": "4D988189-A1DB-41FE-80CA-E338285D302F", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:46:05", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "361.1299999999994", + "13": "350.34999999999945", + "14": "5.389999999999992", + "index": 777 + }, + { + "0": "903D435A-A4E4-489C-95E8-E97B11439B7C", + "1": "A1829582571084310", + "2": "222.19", + "3": "22.0", + "4": "2023-02-28 04:19:19", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "444.38", + "13": "444.38", + "14": "222.19", + "index": 778 + }, + { + "0": "B1DCEA69-8515-497E-8CAF-FEF5A9A4E5C5", + "1": "A1899947009495910", + "2": "538.0", + "3": "22.0", + "4": "2023-03-14 13:49:32", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1614.0", + "13": "1614.0", + "14": "538.0", + "index": 779 + }, + { + "0": "B1DCEA69-8515-497E-8CAF-FEF5A9A4E5C5", + "1": "A1899947009495910", + "2": "538.0", + "3": "22.0", + "4": "2023-03-14 13:49:32", + "5": "725.1164", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1614.0", + "13": "1614.0", + "14": "538.0", + "index": 780 + }, + { + "0": "AF64911E-A295-4337-BBAF-835F82DD77BA", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 19:41:16", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "3309.3399999999983", + "13": "3309.3399999999983", + "14": "143.8843478260869", + "index": 781 + }, + { + "0": "422D5F57-6B6E-4803-AD06-9BF33330F102", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 18:48:55", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "459.90999999999997", + "13": "459.90999999999997", + "14": "114.97749999999999", + "index": 782 + }, + { + "0": "ABA4D27A-EDFF-47E7-9F92-DE6F02753299", + "1": "A1688853596356500", + "2": "59.99", + "3": "1.0", + "4": "2023-02-17 06:50:03", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.98", + "13": "119.98", + "14": "59.99", + "index": 783 + }, + { + "0": "ABA4D27A-EDFF-47E7-9F92-DE6F02753299", + "1": "A1688853596356500", + "2": "59.99", + "3": "1.0", + "4": "2023-02-17 06:50:03", + "5": "59.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.98", + "13": "119.98", + "14": "59.99", + "index": 784 + }, + { + "0": "01CE8E80-F8C6-4EA6-92A5-4D3077CE9449", + "1": "A844427390246047", + "2": "5.39", + "3": "14.0", + "4": "2023-02-24 20:06:05", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "2365.0", + "11": "3.0", + "12": "37.73", + "13": "37.73", + "14": "5.39", + "index": 785 + }, + { + "0": "7898FC86-CDBF-469B-B369-5E70B9BAC1F1", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 19:01:54", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1509.7", + "13": "1509.7", + "14": "137.24545454545455", + "index": 786 + }, + { + "0": "3CFD786C-1D49-4D2D-94DA-C3A0E26ACB02", + "1": "A914801013785993", + "2": "93.94", + "3": "0.0", + "4": "2023-02-08 06:19:27", + "5": "93.94", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "0", + "10": "371.0", + "11": "0.0", + "12": "275.94", + "13": "93.94", + "14": "91.98", + "index": 787 + }, + { + "0": "209C8814-08A3-4199-99FE-B7E3C99EB101", + "1": "A1055521400546730", + "2": "119.99", + "4": "2023-02-14 20:25:30", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.99", + "13": "119.99", + "14": "119.99", + "index": 788 + }, + { + "0": "209C8814-08A3-4199-99FE-B7E3C99EB101", + "1": "A1055521400546730", + "2": "119.99", + "4": "2023-02-14 20:25:30", + "5": "119.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.99", + "13": "119.99", + "14": "119.99", + "index": 789 + }, + { + "0": "C54EC40B-86FC-497A-A701-8FBDE5A2375D", + "1": "A844427390246047", + "2": "5.39", + "3": "11.0", + "4": "2023-02-28 17:08:37", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "598.2899999999988", + "13": "258.7199999999997", + "14": "5.389999999999989", + "index": 790 + }, + { + "0": "1D803FD7-051D-4D75-94DC-214FC9E55633", + "1": "A1759222219270900", + "2": "235.39", + "3": "20.0", + "4": "2023-02-28 01:28:55", + "5": "235.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "470.78", + "13": "470.78", + "14": "235.39", + "index": 791 + }, + { + "0": "1AB327E5-AD02-4407-853C-1024966EAEA6", + "1": "A1055521435204170", + "2": "286.35", + "3": "18.0", + "4": "2023-03-29 23:52:59", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "572.7", + "13": "572.7", + "14": "286.35", + "index": 792 + }, + { + "0": "1AB327E5-AD02-4407-853C-1024966EAEA6", + "1": "A1055521435204170", + "2": "286.35", + "3": "18.0", + "4": "2023-03-29 23:52:59", + "5": "285.167374", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "572.7", + "13": "572.7", + "14": "286.35", + "index": 793 + }, + { + "0": "5867EAE8-3A64-4EB2-8CCF-F4F6A119B088", + "1": "A844428035402480", + "2": "63.89", + "3": "11.0", + "4": "2023-01-11 16:24:52", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "63.89", + "13": "63.89", + "14": "63.89", + "index": 794 + }, + { + "0": "5867EAE8-3A64-4EB2-8CCF-F4F6A119B088", + "1": "A844428035402480", + "2": "63.89", + "3": "11.0", + "4": "2023-01-11 16:24:52", + "5": "63.89", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "63.89", + "13": "63.89", + "14": "63.89", + "index": 795 + }, + { + "0": "F53D4B5F-01AB-48A8-A833-F1CBA086B76D", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:44:03", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "439.7800000000001", + "13": "439.7800000000001", + "14": "19.990000000000006", + "index": 796 + }, + { + "0": "F53D4B5F-01AB-48A8-A833-F1CBA086B76D", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:44:03", + "5": "19.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "439.7800000000001", + "13": "439.7800000000001", + "14": "19.990000000000006", + "index": 797 + }, + { + "0": "0C064A95-7D41-4C84-A18E-816228CAB89E", + "1": "A1829582571100710", + "2": "239.51", + "3": "16.0", + "4": "2023-02-01 21:56:13", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "479.02", + "13": "479.02", + "14": "239.51", + "index": 798 + }, + { + "0": "635526D8-1F35-4ABE-88EC-7D5276A36C51", + "1": "A1055521381916150", + "2": "26.54", + "3": "18.0", + "4": "2023-01-06 00:33:10", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "26.54", + "13": "26.54", + "14": "26.54", + "index": 799 + }, + { + "0": "635526D8-1F35-4ABE-88EC-7D5276A36C51", + "1": "A1055521381916150", + "2": "26.54", + "3": "18.0", + "4": "2023-01-06 00:33:10", + "5": "26.54", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "26.54", + "13": "26.54", + "14": "26.54", + "index": 800 + }, + { + "0": "E9D36D5B-FDCD-440A-BC1A-C53A9110CF22", + "1": "A844428017843376", + "2": "119.98", + "3": "15.0", + "4": "2023-01-03 20:46:52", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "910.0", + "13": "910.0", + "14": "113.75", + "index": 801 + }, + { + "0": "AC844DF5-52D9-4A71-A6B8-690139185C7B", + "1": "A1055521395382470", + "2": "153.29", + "3": "20.0", + "4": "2023-02-06 04:27:22", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "306.58", + "13": "306.58", + "14": "153.29", + "index": 802 + }, + { + "0": "AC844DF5-52D9-4A71-A6B8-690139185C7B", + "1": "A1055521395382470", + "2": "153.29", + "3": "20.0", + "4": "2023-02-06 04:27:22", + "5": "153.29", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "306.58", + "13": "306.58", + "14": "153.29", + "index": 803 + }, + { + "0": "1901E38A-A427-4BA3-8C82-C9DB2B8C2735", + "1": "A1829582519832190", + "2": "59.99", + "3": "2.0", + "4": "2023-02-17 08:15:30", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "239.96", + "13": "239.96", + "14": "59.99", + "index": 804 + }, + { + "0": "1901E38A-A427-4BA3-8C82-C9DB2B8C2735", + "1": "A1829582519832190", + "2": "59.99", + "3": "2.0", + "4": "2023-02-17 08:15:30", + "5": "59.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "239.96", + "13": "239.96", + "14": "59.99", + "index": 805 + }, + { + "0": "C1399C61-74D6-40B3-8289-AC99FAFF4988", + "1": "A1829582580775700", + "2": "65.57", + "3": "12.0", + "4": "2023-01-03 19:36:45", + "5": "65.57", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "327.84999999999997", + "13": "327.84999999999997", + "14": "65.57", + "index": 806 + }, + { + "0": "CD624353-E473-4EE0-8BDF-A818627AA1D1", + "1": "A985156970845915", + "2": "99.98", + "3": "11.0", + "4": "2023-01-03 16:40:50", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "99.98", + "13": "99.98", + "14": "99.98", + "index": 807 + }, + { + "0": "CD624353-E473-4EE0-8BDF-A818627AA1D1", + "1": "A985156970845915", + "2": "99.98", + "3": "11.0", + "4": "2023-01-03 16:40:50", + "5": "99.98", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "99.98", + "13": "99.98", + "14": "99.98", + "index": 808 + }, + { + "0": "6B3337E4-83E7-49DA-97BA-D0DC2B44F42F", + "1": "A844428017843376", + "2": "119.98", + "3": "15.0", + "4": "2023-01-03 20:41:07", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "682.5", + "13": "682.5", + "14": "113.75", + "index": 809 + }, + { + "0": "DCCC41EB-D464-4684-B53D-C89C70D194B3", + "1": "A844428056745591", + "2": "49.99", + "3": "12.0", + "4": "2023-02-16 20:29:30", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "49.99", + "13": "49.99", + "14": "49.99", + "index": 810 + }, + { + "0": "DCCC41EB-D464-4684-B53D-C89C70D194B3", + "1": "A844428056745591", + "2": "49.99", + "3": "12.0", + "4": "2023-02-16 20:29:30", + "5": "49.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "49.99", + "13": "49.99", + "14": "49.99", + "index": 811 + }, + { + "0": "B94780BA-6067-4DAD-AA2A-BACE10FA26EA", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:55:42", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "447.3699999999992", + "13": "436.58999999999924", + "14": "5.389999999999991", + "index": 812 + }, + { + "0": "897B514D-E758-4690-84B8-6549559C52EE", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 18:50:29", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "609.88", + "13": "609.88", + "14": "121.976", + "index": 813 + }, + { + "0": "494D137C-73F9-4388-B775-A97A4F2EF725", + "1": "A985156345961425", + "2": "109.99", + "3": "23.0", + "4": "2023-01-30 06:54:18", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "219.98", + "13": "219.98", + "14": "109.99", + "index": 814 + }, + { + "0": "494D137C-73F9-4388-B775-A97A4F2EF725", + "1": "A985156345961425", + "2": "109.99", + "3": "23.0", + "4": "2023-01-30 06:54:18", + "5": "109.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "219.98", + "13": "219.98", + "14": "109.99", + "index": 815 + }, + { + "0": "8D4F3115-A1D5-459A-A847-A4C3E43A74A7", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:39:35", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "659.89", + "13": "659.89", + "14": "59.99", + "index": 816 + }, + { + "0": "DC52C196-52BA-45B3-9C3A-50EEAAF9A12E", + "1": "A985156921982186", + "2": "50.49", + "3": "15.0", + "4": "2023-02-15 20:36:44", + "9": "1", + "10": "425.0", + "11": "0.0", + "12": "50.49", + "13": "50.49", + "14": "50.49", + "index": 817 + }, + { + "0": "DC52C196-52BA-45B3-9C3A-50EEAAF9A12E", + "1": "A985156921982186", + "2": "50.49", + "3": "15.0", + "4": "2023-02-15 20:36:44", + "5": "50.49", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "425.0", + "11": "0.0", + "12": "50.49", + "13": "50.49", + "14": "50.49", + "index": 818 + }, + { + "0": "6A4D6552-8D68-49DA-8B16-D5094B3ED747", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:35:26", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "107.8", + "13": "107.8", + "14": "5.39", + "index": 819 + }, + { + "0": "B352C087-14C9-4B8A-B239-0C4D861AF091", + "1": "A1829582580775700", + "2": "65.57", + "3": "12.0", + "4": "2023-01-03 19:45:31", + "5": "65.57", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "590.1299999999999", + "13": "590.1299999999999", + "14": "65.57", + "index": 820 + }, + { + "0": "CA193A45-31F8-4EB5-A19D-BF5D2602277D", + "1": "A1899946873142120", + "2": "149.97", + "3": "15.0", + "4": "2023-01-03 20:40:11", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "7358.5300000000025", + "13": "7358.5300000000025", + "14": "147.17060000000004", + "index": 821 + }, + { + "0": "6C9E1AA1-9D12-49F6-8CC2-F4E5B1053CCA", + "1": "A985157021080233", + "2": "479.0", + "3": "18.0", + "4": "2023-03-06 18:59:46", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "479.0", + "13": "479.0", + "14": "479.0", + "index": 822 + }, + { + "0": "6C9E1AA1-9D12-49F6-8CC2-F4E5B1053CCA", + "1": "A985157021080233", + "2": "479.0", + "3": "18.0", + "4": "2023-03-06 18:59:46", + "5": "754.3771", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "479.0", + "13": "479.0", + "14": "479.0", + "index": 823 + }, + { + "0": "C4FDAA41-391E-4449-93C8-0C7E984921E8", + "1": "A1759221221524030", + "2": "119.99", + "3": "11.0", + "4": "2023-01-14 11:13:14", + "9": "1", + "10": "1098.0", + "11": "0.0", + "12": "119.99", + "13": "119.99", + "14": "119.99", + "index": 824 + }, + { + "0": "C4FDAA41-391E-4449-93C8-0C7E984921E8", + "1": "A1759221221524030", + "2": "119.99", + "3": "11.0", + "4": "2023-01-14 11:13:14", + "5": "161.722522", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "1098.0", + "11": "0.0", + "12": "119.99", + "13": "119.99", + "14": "119.99", + "index": 825 + }, + { + "0": "0EE3572D-7311-4F07-B930-0A89C79983EF", + "1": "A985156712327404", + "2": "219.99", + "3": "17.0", + "4": "2023-02-04 18:18:08", + "9": "1", + "10": "544.0", + "11": "0.0", + "12": "219.99", + "13": "219.99", + "14": "219.99", + "index": 826 + }, + { + "0": "0EE3572D-7311-4F07-B930-0A89C79983EF", + "1": "A985156712327404", + "2": "219.99", + "3": "17.0", + "4": "2023-02-04 18:18:08", + "5": "346.462251", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "544.0", + "11": "0.0", + "12": "219.99", + "13": "219.99", + "14": "219.99", + "index": 827 + }, + { + "0": "8B634588-BDD1-4B61-B2C0-00A24CD77D7B", + "1": "A914801025693987", + "2": "278.88", + "3": "19.0", + "4": "2023-02-18 02:07:01", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "557.76", + "13": "557.76", + "14": "278.88", + "index": 828 + }, + { + "0": "A2709A9F-1697-4CB3-B0A2-8DDF7237D6FF", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 03:06:48", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "522.829999999999", + "13": "512.049999999999", + "14": "5.38999999999999", + "index": 829 + }, + { + "0": "A2709A9F-1697-4CB3-B0A2-8DDF7237D6FF", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 03:06:48", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "522.829999999999", + "13": "512.049999999999", + "14": "5.38999999999999", + "index": 830 + }, + { + "0": "7E42BCAB-5590-41AD-A18E-8964C2D9CDAA", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:56:38", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "452.7599999999992", + "13": "441.9799999999992", + "14": "5.389999999999991", + "index": 831 + }, + { + "0": "A161FE84-6920-43CD-9AFE-7D1A04800640", + "1": "A1688853657886190", + "2": "53.99", + "3": "12.0", + "4": "2023-01-03 18:20:14", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "755.86", + "13": "755.86", + "14": "53.99", + "index": 832 + }, + { + "0": "9B6410A2-B896-4E0E-9929-B3D3FF23D091", + "1": "A1055521396853140", + "2": "150.49", + "3": "18.0", + "4": "2023-02-09 00:43:38", + "5": "150.49", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "300.98", + "13": "300.98", + "14": "150.49", + "index": 833 + }, + { + "0": "5CAB8F98-F87D-4FB5-8647-F83EF559A9E7", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:51:22", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "409.6399999999993", + "13": "398.85999999999933", + "14": "5.389999999999991", + "index": 834 + }, + { + "0": "086FDEAF-BF57-4B51-93F4-169E3609D287", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 03:03:44", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "495.8799999999991", + "13": "485.0999999999991", + "14": "5.38999999999999", + "index": 835 + }, + { + "0": "3F889B35-49FC-47BC-9E5E-2DF06FA12290", + "1": "A844427390246047", + "2": "5.39", + "3": "9.0", + "4": "2023-02-28 14:34:01", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "587.5099999999989", + "13": "247.93999999999969", + "14": "5.38999999999999", + "index": 836 + }, + { + "0": "0FBA8C42-194E-4E18-85DB-D1FA1EB7C05D", + "1": "A985157015268058", + "2": "4.99", + "3": "14.0", + "4": "2023-02-27 19:41:53", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "109.77999999999997", + "13": "109.77999999999997", + "14": "4.989999999999998", + "index": 837 + }, + { + "0": "D0A2E6EF-037B-4A22-816B-35DCC965C228", + "1": "A985156995541712", + "2": "3298.0", + "3": "20.0", + "4": "2023-01-23 02:23:53", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "3298.0", + "13": "3298.0", + "14": "3298.0", + "index": 838 + }, + { + "0": "D0A2E6EF-037B-4A22-816B-35DCC965C228", + "1": "A985156995541712", + "2": "3298.0", + "3": "20.0", + "4": "2023-01-23 02:23:53", + "5": "259.62185800000003", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "3298.0", + "13": "3298.0", + "14": "3298.0", + "index": 839 + }, + { + "0": "158D5606-DB73-4DAE-8041-331070779CD3", + "1": "A1055521436064760", + "2": "155.68", + "3": "17.0", + "4": "2023-03-30 23:16:28", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "155.68", + "13": "155.68", + "14": "155.68", + "index": 840 + }, + { + "0": "158D5606-DB73-4DAE-8041-331070779CD3", + "1": "A1055521436064760", + "2": "155.68", + "3": "17.0", + "4": "2023-03-30 23:16:28", + "5": "155.03704199999999", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "155.68", + "13": "155.68", + "14": "155.68", + "index": 841 + }, + { + "0": "EAD34905-DE0B-4FC8-A4AE-C2248AF29A08", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:37:32", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "539.91", + "13": "539.91", + "14": "59.989999999999995", + "index": 842 + }, + { + "0": "81BCECDA-79F8-470D-9407-44198BD3EC06", + "1": "A1055520964660610", + "2": "219.99", + "3": "19.0", + "4": "2023-01-28 00:31:21", + "9": "1", + "10": "1220.0", + "11": "0.0", + "12": "219.99", + "13": "219.99", + "14": "219.99", + "index": 843 + }, + { + "0": "81BCECDA-79F8-470D-9407-44198BD3EC06", + "1": "A1055520964660610", + "2": "219.99", + "3": "19.0", + "4": "2023-01-28 00:31:21", + "5": "219.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "1220.0", + "11": "0.0", + "12": "219.99", + "13": "219.99", + "14": "219.99", + "index": 844 + }, + { + "0": "9E498776-6998-4308-B28B-93AF92DE4924", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 03:08:07", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "528.219999999999", + "13": "517.439999999999", + "14": "5.38999999999999", + "index": 845 + }, + { + "0": "C869ECF0-2A2F-4898-BC65-AD6422144BA5", + "1": "A844427390246047", + "2": "5.39", + "3": "6.0", + "4": "2023-02-25 12:17:22", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "231.76999999999973", + "13": "220.98999999999975", + "14": "5.3899999999999935", + "index": 846 + }, + { + "0": "9E498776-6998-4308-B28B-93AF92DE4924", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 03:08:07", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "528.219999999999", + "13": "517.439999999999", + "14": "5.38999999999999", + "index": 847 + }, + { + "0": "237AD504-9222-4DAF-BBB9-5C86C4A0DF90", + "1": "A844428089229497", + "2": "261.45", + "3": "23.0", + "4": "2023-03-29 07:57:24", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "261.45", + "13": "261.45", + "14": "261.45", + "index": 848 + }, + { + "0": "12BE1B15-1042-4C4A-9B0D-30823F42E3D6", + "1": "A985157041378120", + "2": "159.0", + "3": "11.0", + "4": "2023-03-29 16:34:53", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "159.0", + "13": "159.0", + "14": "159.0", + "index": 849 + }, + { + "0": "12BE1B15-1042-4C4A-9B0D-30823F42E3D6", + "1": "A985157041378120", + "2": "159.0", + "3": "11.0", + "4": "2023-03-29 16:34:53", + "5": "159.0", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "159.0", + "13": "159.0", + "14": "159.0", + "index": 850 + }, + { + "0": "7F6AEAAA-ED61-4163-8C5E-289FB74045B4", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:50:23", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "398.85999999999933", + "13": "388.07999999999936", + "14": "5.389999999999991", + "index": 851 + }, + { + "0": "A76875A6-59E2-4D02-8FF1-48EADE6B83A7", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 03:00:13", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "479.7099999999991", + "13": "468.92999999999915", + "14": "5.38999999999999", + "index": 852 + }, + { + "0": "F7690559-B2FA-42E4-910F-DF65A0250586", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:29:47", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "179.97", + "13": "179.97", + "14": "59.99", + "index": 853 + }, + { + "0": "D7BC1361-E730-4463-9DE7-2B9D92DB5A5B", + "1": "A985157015268058", + "2": "4.99", + "3": "10.0", + "4": "2023-02-27 15:34:13", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "39.92000000000001", + "13": "39.92000000000001", + "14": "4.990000000000001", + "index": 854 + }, + { + "0": "EE72DD0F-F132-4E86-9CC5-9FB6386668A0", + "1": "A1829582580775700", + "2": "65.57", + "3": "11.0", + "4": "2023-01-03 18:41:24", + "5": "65.57", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "65.57", + "13": "65.57", + "14": "65.57", + "index": 855 + }, + { + "0": "17B73DB4-D6C9-4F0D-A8CA-A1BD9334FABC", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:42:15", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "839.86", + "13": "839.86", + "14": "59.99", + "index": 856 + }, + { + "0": "D797769A-8A65-47DF-8473-35A29AC81B24", + "1": "A844427390246047", + "2": "5.39", + "3": "5.0", + "4": "2023-02-25 11:15:33", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "215.59999999999977", + "13": "204.8199999999998", + "14": "5.389999999999994", + "index": 857 + }, + { + "0": "DE46E518-A85B-40FA-8D00-0527941DF682", + "1": "A1829582602002910", + "2": "589.0", + "3": "17.0", + "4": "2023-02-28 17:17:05", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "589.0", + "13": "589.0", + "14": "589.0", + "index": 858 + }, + { + "0": "DE46E518-A85B-40FA-8D00-0527941DF682", + "1": "A1829582602002910", + "2": "589.0", + "3": "17.0", + "4": "2023-02-28 17:17:05", + "5": "793.8542", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "589.0", + "13": "589.0", + "14": "589.0", + "index": 859 + }, + { + "0": "05EB1AA9-8B8C-416C-9637-01DBCE588FD4", + "1": "A914801058711211", + "2": "145.95", + "3": "17.0", + "4": "2023-03-30 23:32:11", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "291.9", + "13": "291.9", + "14": "145.95", + "index": 860 + }, + { + "0": "05EB1AA9-8B8C-416C-9637-01DBCE588FD4", + "1": "A914801058711211", + "2": "145.95", + "3": "17.0", + "4": "2023-03-30 23:32:11", + "5": "145.347227", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "291.9", + "13": "291.9", + "14": "145.95", + "index": 861 + }, + { + "0": "72399945-3AC5-461E-BF85-228552DF71E1", + "1": "A985156971082067", + "2": "119.98", + "3": "13.0", + "4": "2023-01-03 18:35:42", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "239.96", + "13": "239.96", + "14": "119.98", + "index": 862 + }, + { + "0": "C1040C0D-A701-4AD0-B4E3-1BC1F06AB4AA", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 20:13:25", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "5708.86", + "13": "5708.86", + "14": "146.38102564102564", + "index": 863 + }, + { + "0": "7DDF174A-C6BF-4245-8148-650BBEC82DA8", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:36:35", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "539.91", + "13": "539.91", + "14": "59.989999999999995", + "index": 864 + }, + { + "0": "1731D105-5F5C-4CEE-955B-AD9B4372603D", + "1": "A844427390246047", + "2": "5.39", + "3": "9.0", + "4": "2023-02-28 14:32:27", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "576.7299999999989", + "13": "237.1599999999997", + "14": "5.38999999999999", + "index": 865 + }, + { + "0": "C187B038-E19A-46AA-A9E0-5BF87BAEE2C1", + "1": "A985157015268058", + "2": "4.99", + "3": "10.0", + "4": "2023-02-27 15:38:51", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "64.87000000000002", + "13": "64.87000000000002", + "14": "4.990000000000001", + "index": 866 + }, + { + "0": "AA20954D-6483-48D8-9E0D-D3BDFF8B197A", + "1": "A1759222088017710", + "2": "78750.0", + "3": "16.0", + "4": "2023-03-15 07:48:58", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "157500.0", + "13": "157500.0", + "14": "78750.0", + "index": 867 + }, + { + "0": "AA20954D-6483-48D8-9E0D-D3BDFF8B197A", + "1": "A1759222088017710", + "2": "78750.0", + "3": "16.0", + "4": "2023-03-15 07:48:58", + "5": "868.6125", + "6": "false", + "7": "3.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "157500.0", + "13": "157500.0", + "14": "78750.0", + "index": 868 + }, + { + "0": "2F246963-29D5-4570-BF39-54494E929938", + "1": "A1055521390784220", + "2": "219.99", + "4": "2023-03-19 22:45:20", + "9": "1", + "10": "366.0", + "11": "1.0", + "12": "219.99", + "13": "219.99", + "14": "219.99", + "index": 869 + }, + { + "0": "2F246963-29D5-4570-BF39-54494E929938", + "1": "A1055521390784220", + "2": "219.99", + "4": "2023-03-19 22:45:20", + "5": "219.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "1.0", + "12": "219.99", + "13": "219.99", + "14": "219.99", + "index": 870 + }, + { + "0": "14EF7AD5-A3AA-4E9E-B377-74A47CDC2785", + "1": "A1688853662170320", + "2": "839.97", + "3": "19.0", + "4": "2023-03-13 10:58:58", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1679.94", + "13": "1679.94", + "14": "839.97", + "index": 871 + }, + { + "0": "EB09177A-B225-47E7-B177-E8610B3E618F", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 18:55:13", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1059.79", + "13": "1059.79", + "14": "132.47375", + "index": 872 + }, + { + "0": "EB09177A-B225-47E7-B177-E8610B3E618F", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 18:55:13", + "5": "149.97", + "6": "false", + "7": "3.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1059.79", + "13": "1059.79", + "14": "132.47375", + "index": 873 + }, + { + "0": "92C5B50A-E46E-404D-9EFB-7043D6DD7C68", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:32:00", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "239.96", + "13": "239.96", + "14": "59.99", + "index": 874 + }, + { + "0": "FFF0CCE8-07E1-4100-9491-2853222482EF", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:44:10", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "123.97", + "13": "118.58", + "14": "5.39", + "index": 875 + }, + { + "0": "6DA73B9F-D74B-45A7-82F7-FD10B2840483", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 03:05:18", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "506.65999999999906", + "13": "495.8799999999991", + "14": "5.38999999999999", + "index": 876 + }, + { + "0": "0DF72AD1-2DFD-404E-88A8-965334D9F227", + "1": "A844427390246047", + "2": "5.39", + "3": "12.0", + "4": "2023-02-28 17:38:07", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "630.6299999999987", + "13": "291.0599999999996", + "14": "5.389999999999989", + "index": 877 + }, + { + "0": "9E41C0F4-5345-4439-B996-52841214F9FE", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:47:15", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "328.7899999999995", + "13": "318.00999999999954", + "14": "5.389999999999992", + "index": 878 + }, + { + "0": "EC2B7C43-96E8-4BD7-AE1B-1E4F5B513D29", + "1": "A306107899458824", + "2": "279.99", + "3": "8.0", + "4": "2023-01-09 12:15:52", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "279.99", + "13": "279.99", + "14": "279.99", + "index": 879 + }, + { + "0": "EC2B7C43-96E8-4BD7-AE1B-1E4F5B513D29", + "1": "A306107899458824", + "2": "279.99", + "3": "8.0", + "4": "2023-01-09 12:15:52", + "5": "279.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "279.99", + "13": "279.99", + "14": "279.99", + "index": 880 + }, + { + "0": "A0F3B9E3-5B99-4E62-99BC-3159F5F3C5D0", + "1": "A914800550439914", + "2": "157.07", + "3": "11.0", + "4": "2023-02-05 16:23:11", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "157.07", + "13": "157.07", + "14": "157.07", + "index": 881 + }, + { + "0": "A0F3B9E3-5B99-4E62-99BC-3159F5F3C5D0", + "1": "A914800550439914", + "2": "157.07", + "3": "11.0", + "4": "2023-02-05 16:23:11", + "5": "156.421301", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "157.07", + "13": "157.07", + "14": "157.07", + "index": 882 + }, + { + "0": "1580B155-E0E0-40CB-841D-E2A5D2DB0E7E", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:57:02", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "129.35999999999999", + "13": "118.58", + "14": "5.39", + "index": 883 + }, + { + "0": "00746053-49FB-4681-8AAA-10388C1D59E2", + "1": "A985157015268058", + "2": "4.99", + "3": "14.0", + "4": "2023-02-27 20:15:52", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "124.74999999999996", + "13": "124.74999999999996", + "14": "4.989999999999998", + "index": 884 + }, + { + "0": "1AE19EA1-54DF-4E2A-889F-E47C3AFE65AF", + "1": "A1899947009495910", + "2": "538.0", + "3": "21.0", + "4": "2023-03-14 13:11:13", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1076.0", + "13": "1076.0", + "14": "538.0", + "index": 885 + }, + { + "0": "E99493A6-78E3-434D-9AAB-D2B1E0AF1AD9", + "1": "A1759222088015940", + "2": "78750.0", + "3": "17.0", + "4": "2023-03-15 08:56:31", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "78750.0", + "13": "78750.0", + "14": "78750.0", + "index": 886 + }, + { + "0": "E99493A6-78E3-434D-9AAB-D2B1E0AF1AD9", + "1": "A1759222088015940", + "2": "78750.0", + "3": "17.0", + "4": "2023-03-15 08:56:31", + "5": "868.6125", + "6": "false", + "7": "3.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "78750.0", + "13": "78750.0", + "14": "78750.0", + "index": 887 + }, + { + "0": "1F9B9F18-4C20-46FD-8151-B8C6B463ACC0", + "1": "A1055521385546810", + "2": "148.74", + "3": "15.0", + "4": "2023-01-11 22:15:24", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "148.74", + "13": "148.74", + "14": "148.74", + "index": 888 + }, + { + "0": "1F9B9F18-4C20-46FD-8151-B8C6B463ACC0", + "1": "A1055521385546810", + "2": "148.74", + "3": "15.0", + "4": "2023-01-11 22:15:24", + "5": "148.74", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "148.74", + "13": "148.74", + "14": "148.74", + "index": 889 + }, + { + "0": "198674DC-ADFB-4FFE-94AB-E920AEA22B88", + "1": "A1829582414397910", + "2": "222.19", + "3": "14.0", + "4": "2023-01-15 19:38:34", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "222.19", + "13": "222.19", + "14": "222.19", + "index": 890 + }, + { + "0": "198674DC-ADFB-4FFE-94AB-E920AEA22B88", + "1": "A1829582414397910", + "2": "222.19", + "3": "14.0", + "4": "2023-01-15 19:38:34", + "5": "222.19", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "222.19", + "13": "222.19", + "14": "222.19", + "index": 891 + }, + { + "0": "8EC10EBC-F4BB-4148-9073-4B2BA93C9B34", + "1": "A985156981066925", + "2": "150.31", + "3": "8.0", + "4": "2023-01-03 14:11:15", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "150.31", + "13": "150.31", + "14": "150.31", + "index": 892 + }, + { + "0": "8EC10EBC-F4BB-4148-9073-4B2BA93C9B34", + "1": "A985156981066925", + "2": "150.31", + "3": "8.0", + "4": "2023-01-03 14:11:15", + "5": "150.31", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "150.31", + "13": "150.31", + "14": "150.31", + "index": 893 + }, + { + "0": "8CF41C6B-5E7A-44FD-B4F4-975432C25086", + "1": "A1829582519835540", + "2": "63.59", + "3": "23.0", + "4": "2023-02-17 08:15:04", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "127.18", + "13": "127.18", + "14": "63.59", + "index": 894 + }, + { + "0": "8CF41C6B-5E7A-44FD-B4F4-975432C25086", + "1": "A1829582519835540", + "2": "63.59", + "3": "23.0", + "4": "2023-02-17 08:15:04", + "5": "63.59", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "127.18", + "13": "127.18", + "14": "63.59", + "index": 895 + }, + { + "0": "702CD93B-73B6-4F45-8FE8-7F83EC633AA0", + "1": "A985157015268058", + "2": "4.99", + "3": "14.0", + "4": "2023-02-27 19:30:12", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "99.79999999999998", + "13": "99.79999999999998", + "14": "4.989999999999999", + "index": 896 + }, + { + "0": "6DCDA408-D527-4CC0-8ECD-BB1DD4C1B51B", + "1": "A1055520836257310", + "2": "5.04", + "3": "5.0", + "4": "2023-02-28 10:23:20", + "9": "1", + "10": "1555.0", + "11": "0.0", + "12": "10.08", + "13": "10.08", + "14": "5.04", + "index": 897 + }, + { + "0": "84F42387-D564-4878-8D22-760BCE34AD08", + "1": "A844428070993534", + "2": "1307.65", + "3": "10.0", + "4": "2023-03-07 17:10:15", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1307.65", + "13": "1307.65", + "14": "1307.65", + "index": 898 + }, + { + "0": "84F42387-D564-4878-8D22-760BCE34AD08", + "1": "A844428070993534", + "2": "1307.65", + "3": "10.0", + "4": "2023-03-07 17:10:15", + "5": "1307.65", + "6": "false", + "7": "0.0", + "8": "2.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1307.65", + "13": "1307.65", + "14": "1307.65", + "index": 899 + }, + { + "0": "A645B1E3-E62B-40EB-8201-F5ED545697E9", + "1": "A985157023797738", + "2": "281.37", + "3": "22.0", + "4": "2023-03-09 06:18:54", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "281.37", + "13": "281.37", + "14": "281.37", + "index": 900 + }, + { + "0": "A645B1E3-E62B-40EB-8201-F5ED545697E9", + "1": "A985157023797738", + "2": "281.37", + "3": "22.0", + "4": "2023-03-09 06:18:54", + "5": "280.207942", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "281.37", + "13": "281.37", + "14": "281.37", + "index": 901 + }, + { + "0": "81D69AD5-E46F-46A4-8317-14C6F2908E0D", + "1": "A1688853657886190", + "2": "53.99", + "3": "13.0", + "4": "2023-01-03 18:32:17", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1133.79", + "13": "1133.79", + "14": "53.989999999999995", + "index": 902 + }, + { + "0": "5AFF55FE-4D1D-4FFA-892D-AB911971CFFE", + "1": "A1899946873142120", + "2": "149.97", + "3": "15.0", + "4": "2023-01-03 20:52:47", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "8108.380000000004", + "13": "8108.380000000004", + "14": "147.42509090909098", + "index": 903 + }, + { + "0": "5AFF55FE-4D1D-4FFA-892D-AB911971CFFE", + "1": "A1899946873142120", + "2": "149.97", + "3": "15.0", + "4": "2023-01-03 20:52:47", + "5": "149.97", + "6": "false", + "7": "3.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "8108.380000000004", + "13": "8108.380000000004", + "14": "147.42509090909098", + "index": 904 + }, + { + "0": "BF43B590-100C-49DE-8DE2-F4F0462CC9CC", + "1": "A844428061406186", + "2": "1091.15", + "3": "8.0", + "4": "2023-02-23 14:56:14", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1091.15", + "13": "1091.15", + "14": "1091.15", + "index": 905 + }, + { + "0": "BF43B590-100C-49DE-8DE2-F4F0462CC9CC", + "1": "A844428061406186", + "2": "1091.15", + "3": "8.0", + "4": "2023-02-23 14:56:14", + "5": "1091.15", + "6": "false", + "7": "0.0", + "8": "2.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1091.15", + "13": "1091.15", + "14": "1091.15", + "index": 906 + }, + { + "0": "2B17E512-6E72-4890-87BD-3C122AA8604E", + "1": "A844427390246047", + "2": "5.39", + "3": "12.0", + "4": "2023-02-28 17:32:02", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "619.8499999999988", + "13": "280.27999999999963", + "14": "5.389999999999989", + "index": 907 + }, + { + "0": "2B17E512-6E72-4890-87BD-3C122AA8604E", + "1": "A844427390246047", + "2": "5.39", + "3": "12.0", + "4": "2023-02-28 17:32:02", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "619.8499999999988", + "13": "280.27999999999963", + "14": "5.389999999999989", + "index": 908 + }, + { + "0": "7C52F75A-B38D-4E3A-8C91-83F9FC04A0FB", + "1": "A1829582583894660", + "2": "59.99", + "3": "15.0", + "4": "2023-02-15 20:21:36", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "59.99", + "13": "59.99", + "14": "59.99", + "index": 909 + }, + { + "0": "7C52F75A-B38D-4E3A-8C91-83F9FC04A0FB", + "1": "A1829582583894660", + "2": "59.99", + "3": "15.0", + "4": "2023-02-15 20:21:36", + "5": "59.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "59.99", + "13": "59.99", + "14": "59.99", + "index": 910 + }, + { + "0": "D81F2077-E5A4-4DCC-85CB-5D37243F3386", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 02:53:36", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "425.80999999999926", + "13": "415.0299999999993", + "14": "5.389999999999991", + "index": 911 + }, + { + "0": "1ACA02AF-1E19-429B-9C7E-B62584B5F770", + "1": "A914801018475755", + "2": "149.93", + "3": "18.0", + "4": "2023-02-07 01:48:31", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "149.93", + "13": "149.93", + "14": "149.93", + "index": 912 + }, + { + "0": "1ACA02AF-1E19-429B-9C7E-B62584B5F770", + "1": "A914801018475755", + "2": "149.93", + "3": "18.0", + "4": "2023-02-07 01:48:31", + "5": "149.93", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "149.93", + "13": "149.93", + "14": "149.93", + "index": 913 + }, + { + "0": "1E0E93F8-6B15-40BA-ACE4-77CF9B527E0C", + "1": "A1899946944829860", + "2": "59.99", + "3": "7.0", + "4": "2023-02-16 13:16:34", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.98", + "13": "119.98", + "14": "59.99", + "index": 914 + }, + { + "0": "1E0E93F8-6B15-40BA-ACE4-77CF9B527E0C", + "1": "A1899946944829860", + "2": "59.99", + "3": "7.0", + "4": "2023-02-16 13:16:34", + "5": "59.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.98", + "13": "119.98", + "14": "59.99", + "index": 915 + }, + { + "0": "925E5659-FF7E-42E9-B91C-9C629D7F2BBA", + "1": "A1055521388773990", + "2": "108.24", + "3": "20.0", + "4": "2023-01-15 03:03:53", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "227.3", + "13": "227.3", + "14": "113.65", + "index": 916 + }, + { + "0": "925E5659-FF7E-42E9-B91C-9C629D7F2BBA", + "1": "A1055521388773990", + "2": "108.24", + "3": "20.0", + "4": "2023-01-15 03:03:53", + "5": "108.24", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "227.3", + "13": "227.3", + "14": "113.65", + "index": 917 + }, + { + "0": "DABB8679-0A5B-46D1-9421-D443A45907F8", + "1": "A1899946895455190", + "2": "19.99", + "3": "13.0", + "4": "2023-01-13 18:48:21", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "99.94999999999999", + "13": "99.94999999999999", + "14": "19.99", + "index": 918 + }, + { + "0": "A6A32094-B81A-4B70-B184-7B74C5B694CB", + "1": "A1829582189343980", + "2": "129.34", + "3": "2.0", + "4": "2023-02-17 07:51:54", + "9": "1", + "10": "985.0", + "11": "0.0", + "12": "258.68", + "13": "258.68", + "14": "129.34", + "index": 919 + }, + { + "0": "A6A32094-B81A-4B70-B184-7B74C5B694CB", + "1": "A1829582189343980", + "2": "129.34", + "3": "2.0", + "4": "2023-02-17 07:51:54", + "5": "129.34", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "985.0", + "11": "0.0", + "12": "258.68", + "13": "258.68", + "14": "129.34", + "index": 920 + }, + { + "0": "F0A25208-F9BB-401D-A840-36823FB1B0A8", + "1": "A844427390246047", + "2": "5.39", + "3": "12.0", + "4": "2023-02-28 17:34:16", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "625.2399999999988", + "13": "285.6699999999996", + "14": "5.389999999999989", + "index": 921 + }, + { + "0": "051BDF69-D526-4951-A7E0-9A933A9899FF", + "1": "A844427390246047", + "2": "5.39", + "3": "11.0", + "4": "2023-02-28 17:16:57", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "614.4599999999988", + "13": "274.88999999999965", + "14": "5.389999999999989", + "index": 922 + }, + { + "0": "A53C943B-A88C-4EB6-9A34-C386E9E8879C", + "1": "A844427390246047", + "2": "5.39", + "3": "11.0", + "4": "2023-02-28 17:14:53", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "609.0699999999988", + "13": "269.49999999999966", + "14": "5.389999999999989", + "index": 923 + }, + { + "0": "FF63B43E-F5B7-4CFD-81FD-AFBFE1BDDFA0", + "1": "A985157015268058", + "2": "4.99", + "3": "15.0", + "4": "2023-02-27 20:51:59", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "144.70999999999998", + "13": "144.70999999999998", + "14": "4.989999999999999", + "index": 924 + }, + { + "0": "4A729E60-7E0A-4080-88C8-A81656F18A24", + "1": "A1829582358242680", + "2": "239.51", + "3": "9.0", + "4": "2023-02-23 14:49:26", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "239.51", + "13": "239.51", + "14": "239.51", + "index": 925 + }, + { + "0": "C4F83897-54F9-4208-987E-DDE9D20F0B4B", + "1": "A1688853657869890", + "2": "52.99", + "3": "11.0", + "4": "2023-01-03 17:27:59", + "5": "52.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "476.91", + "13": "476.91", + "14": "52.99", + "index": 926 + }, + { + "0": "BD6E876C-4420-4359-B25A-35BE542F82C0", + "1": "A362840681200346", + "2": "159.85", + "3": "16.0", + "4": "2023-02-15 20:30:03", + "5": "159.189819", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "159.85", + "13": "159.85", + "14": "159.85", + "index": 927 + }, + { + "0": "66F28A11-228E-4CF9-9872-0677EF57CCCD", + "1": "A985156921982186", + "2": "50.49", + "3": "15.0", + "4": "2023-02-15 20:50:09", + "9": "1", + "10": "425.0", + "11": "0.0", + "12": "100.98", + "13": "100.98", + "14": "50.49", + "index": 928 + }, + { + "0": "F815E0BF-EDEA-40BF-9CA7-E529C895BA5E", + "1": "A985156554634689", + "2": "116.86", + "3": "14.0", + "4": "2023-02-17 19:24:44", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "233.72", + "13": "233.72", + "14": "116.86", + "index": 929 + }, + { + "0": "0550F138-938B-4710-83ED-00EC64D186E3", + "1": "A844427390246047", + "2": "5.39", + "3": "21.0", + "4": "2023-02-26 03:04:17", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "495.8799999999991", + "13": "485.0999999999991", + "14": "5.38999999999999", + "index": 930 + }, + { + "0": "7CD47312-9A89-4118-A977-62919D932541", + "1": "A985157015268058", + "2": "4.99", + "3": "10.0", + "4": "2023-02-27 15:37:33", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "54.890000000000015", + "13": "54.890000000000015", + "14": "4.990000000000001", + "index": 931 + }, + { + "0": "45775ADF-C0C1-4AB2-97A6-BEE6F012632F", + "1": "A985157015268058", + "2": "4.99", + "3": "10.0", + "4": "2023-02-27 15:36:29", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "49.90000000000001", + "13": "49.90000000000001", + "14": "4.990000000000001", + "index": 932 + }, + { + "0": "7CD47312-9A89-4118-A977-62919D932541", + "1": "A985157015268058", + "2": "4.99", + "3": "10.0", + "4": "2023-02-27 15:37:33", + "5": "4.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "367.0", + "11": "0.0", + "12": "54.890000000000015", + "13": "54.890000000000015", + "14": "4.990000000000001", + "index": 933 + }, + { + "0": "A45AA627-25B8-40C5-BA84-8581AEA31D28", + "1": "A1829582571162030", + "2": "219.99", + "3": "22.0", + "4": "2023-02-28 06:34:01", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "219.99", + "13": "219.99", + "14": "219.99", + "index": 934 + }, + { + "0": "A45AA627-25B8-40C5-BA84-8581AEA31D28", + "1": "A1829582571162030", + "2": "219.99", + "3": "22.0", + "4": "2023-02-28 06:34:01", + "5": "219.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "219.99", + "13": "219.99", + "14": "219.99", + "index": 935 + }, + { + "0": "65EA39D7-E9AC-4E55-8F4E-0A3C932688B0", + "1": "A985157032078551", + "2": "699.0", + "3": "17.0", + "4": "2023-03-19 01:27:21", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "699.0", + "13": "699.0", + "14": "699.0", + "index": 936 + }, + { + "0": "65EA39D7-E9AC-4E55-8F4E-0A3C932688B0", + "1": "A985157032078551", + "2": "699.0", + "3": "17.0", + "4": "2023-03-19 01:27:21", + "5": "112.30134", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "699.0", + "13": "699.0", + "14": "699.0", + "index": 937 + }, + { + "0": "06CA7673-9504-44D4-A9B1-49EC29233AD5", + "1": "A844428040495230", + "2": "73.11", + "3": "13.0", + "4": "2023-01-19 18:43:29", + "9": "1", + "10": "366.0", + "11": "1.0", + "12": "148.69", + "13": "148.69", + "14": "74.345", + "index": 938 + }, + { + "0": "077961F4-BD88-4A14-9607-D267E3882119", + "1": "A1688853596363060", + "2": "60.59", + "3": "6.0", + "4": "2023-02-16 11:57:34", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "60.59", + "13": "60.59", + "14": "60.59", + "index": 939 + }, + { + "0": "8D778823-BB51-4CA8-9CEC-84F4D48E035A", + "1": "A1899947010059410", + "2": "73080.0", + "3": "23.0", + "4": "2023-03-07 14:24:12", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "146160.0", + "13": "146160.0", + "14": "73080.0", + "index": 940 + }, + { + "0": "5977650F-EE3E-450F-AD0B-7C103B35B4F5", + "1": "A844428017843376", + "2": "119.98", + "3": "15.0", + "4": "2023-01-03 20:36:42", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "455.0", + "13": "455.0", + "14": "113.75", + "index": 941 + }, + { + "0": "5977650F-EE3E-450F-AD0B-7C103B35B4F5", + "1": "A844428017843376", + "2": "119.98", + "3": "15.0", + "4": "2023-01-03 20:36:42", + "5": "119.98", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "455.0", + "13": "455.0", + "14": "113.75", + "index": 942 + }, + { + "0": "BB496ECE-16ED-448A-BE0D-272C234653B5", + "1": "A1759222234549860", + "2": "62580.0", + "3": "8.0", + "4": "2023-03-02 23:38:37", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "62580.0", + "13": "62580.0", + "14": "62580.0", + "index": 943 + }, + { + "0": "BB496ECE-16ED-448A-BE0D-272C234653B5", + "1": "A1759222234549860", + "2": "62580.0", + "3": "8.0", + "4": "2023-03-02 23:38:37", + "5": "690.2574", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "62580.0", + "13": "62580.0", + "14": "62580.0", + "index": 944 + }, + { + "0": "A9A9B9C3-90F1-4BD3-9217-0EA2828D65B2", + "1": "A914800654351337", + "2": "148.74", + "3": "9.0", + "4": "2023-02-20 15:56:57", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "148.74", + "13": "148.74", + "14": "148.74", + "index": 945 + }, + { + "0": "A9A9B9C3-90F1-4BD3-9217-0EA2828D65B2", + "1": "A914800654351337", + "2": "148.74", + "3": "9.0", + "4": "2023-02-20 15:56:57", + "5": "148.74", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "148.74", + "13": "148.74", + "14": "148.74", + "index": 946 + }, + { + "0": "2EB5E726-5854-45B4-A674-FBCFD891AE9A", + "1": "A362221882887902", + "2": "680.89", + "4": "2023-03-06 18:12:12", + "9": "1", + "10": "1971.0", + "11": "0.0", + "12": "680.89", + "13": "680.89", + "14": "340.445", + "index": 947 + }, + { + "0": "2EB5E726-5854-45B4-A674-FBCFD891AE9A", + "1": "A362221882887902", + "2": "680.89", + "4": "2023-03-06 18:12:12", + "5": "680.89", + "6": "false", + "7": "1.0", + "8": "1.0", + "9": "1", + "10": "1971.0", + "11": "0.0", + "12": "680.89", + "13": "680.89", + "14": "340.445", + "index": 948 + }, + { + "0": "3E6BEDBD-7B2A-40CF-87FC-AE161EA47713", + "1": "A1899946865209040", + "2": "79380.0", + "3": "9.0", + "4": "2023-03-11 00:57:49", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "79380.0", + "13": "79380.0", + "14": "79380.0", + "index": 949 + }, + { + "0": "B3FFE8F1-6D4D-49FF-9DC6-97E3F78B18E1", + "1": "A1829582189343980", + "2": "129.34", + "3": "2.0", + "4": "2023-02-17 07:49:50", + "9": "1", + "10": "985.0", + "11": "0.0", + "12": "129.34", + "13": "129.34", + "14": "129.34", + "index": 950 + }, + { + "0": "0E1A2979-7A26-4C95-AFDE-E391961B3467", + "1": "A1899946781631740", + "2": "233.74", + "3": "6.0", + "4": "2023-02-22 12:26:38", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "233.74", + "13": "233.74", + "14": "233.74", + "index": 951 + }, + { + "0": "0E1A2979-7A26-4C95-AFDE-E391961B3467", + "1": "A1899946781631740", + "2": "233.74", + "3": "6.0", + "4": "2023-02-22 12:26:38", + "5": "233.74", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "233.74", + "13": "233.74", + "14": "233.74", + "index": 952 + }, + { + "0": "A25BC911-EAA9-47D1-B8D2-4086F6CC94CB", + "1": "A1829582580801010", + "2": "59.99", + "3": "15.0", + "4": "2023-01-03 20:35:29", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "419.93", + "13": "419.93", + "14": "59.99", + "index": 953 + }, + { + "0": "59ACE4B3-BD23-4241-B303-4D37EA2DFEE1", + "1": "A844427390246047", + "2": "5.39", + "3": "6.0", + "4": "2023-02-25 12:19:19", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "247.93999999999969", + "13": "237.1599999999997", + "14": "5.3899999999999935", + "index": 954 + }, + { + "0": "D1C8D053-633E-457E-AAE3-2CC1801EC80B", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:22:13", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "264.1099999999997", + "13": "253.32999999999967", + "14": "5.3899999999999935", + "index": 955 + }, + { + "0": "59ACE4B3-BD23-4241-B303-4D37EA2DFEE1", + "1": "A844427390246047", + "2": "5.39", + "3": "6.0", + "4": "2023-02-25 12:19:19", + "5": "5.39", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "247.93999999999969", + "13": "237.1599999999997", + "14": "5.3899999999999935", + "index": 956 + }, + { + "0": "5F4BFC0E-B20F-4310-8971-6D3B8E7C7EF8", + "1": "A914801030385624", + "2": "79.99", + "3": "15.0", + "4": "2023-02-24 21:24:27", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "79.99", + "13": "79.99", + "14": "79.99", + "index": 957 + }, + { + "0": "5F4BFC0E-B20F-4310-8971-6D3B8E7C7EF8", + "1": "A914801030385624", + "2": "79.99", + "3": "15.0", + "4": "2023-02-24 21:24:27", + "5": "79.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "79.99", + "13": "79.99", + "14": "79.99", + "index": 958 + }, + { + "0": "630E3459-B5AA-4D4C-A2E4-31E4D86BDD5B", + "1": "A985156290472668", + "2": "5.34", + "3": "20.0", + "4": "2023-02-26 02:11:24", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "16.02", + "13": "16.02", + "14": "5.34", + "index": 959 + }, + { + "0": "630E3459-B5AA-4D4C-A2E4-31E4D86BDD5B", + "1": "A985156290472668", + "2": "5.34", + "3": "20.0", + "4": "2023-02-26 02:11:24", + "5": "5.34", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "16.02", + "13": "16.02", + "14": "5.34", + "index": 960 + }, + { + "0": "9E012F96-E7AA-4046-8F24-0C85FBB36CF5", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 19:07:57", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1959.6100000000001", + "13": "1959.6100000000001", + "14": "139.97214285714287", + "index": 961 + }, + { + "0": "17DA4A53-7EDF-4FE4-A997-3C9AF9255294", + "1": "A844427390246047", + "2": "5.39", + "3": "7.0", + "4": "2023-02-25 12:42:04", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "312.61999999999955", + "13": "301.8399999999996", + "14": "5.389999999999993", + "index": 962 + }, + { + "0": "473551AD-AFD4-49DE-B182-623E23AE5E46", + "1": "A1055521108927870", + "2": "219.99", + "3": "13.0", + "4": "2023-02-27 20:23:30", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "219.99", + "13": "219.99", + "14": "219.99", + "index": 963 + }, + { + "0": "473551AD-AFD4-49DE-B182-623E23AE5E46", + "1": "A1055521108927870", + "2": "219.99", + "3": "13.0", + "4": "2023-02-27 20:23:30", + "5": "219.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "219.99", + "13": "219.99", + "14": "219.99", + "index": 964 + }, + { + "0": "E4BA8082-355D-4EA7-B2C8-1D9E07046F30", + "1": "A985157025448796", + "2": "73080.0", + "3": "21.0", + "4": "2023-03-11 12:47:25", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 965 + }, + { + "0": "E4BA8082-355D-4EA7-B2C8-1D9E07046F30", + "1": "A985157025448796", + "2": "73080.0", + "3": "21.0", + "4": "2023-03-11 12:47:25", + "5": "806.0724", + "6": "false", + "7": "2.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 966 + }, + { + "0": "2EA5AE02-F407-41D5-98D6-EBC2C4BF9DD2", + "1": "A1055521007937570", + "2": "1154.4", + "3": "10.0", + "4": "2023-02-14 18:35:02", + "9": "1", + "10": "1138.0", + "11": "0.0", + "12": "1154.4", + "13": "1154.4", + "14": "1154.4", + "index": 967 + }, + { + "0": "2EA5AE02-F407-41D5-98D6-EBC2C4BF9DD2", + "1": "A1055521007937570", + "2": "1154.4", + "3": "10.0", + "4": "2023-02-14 18:35:02", + "5": "1154.4", + "6": "false", + "7": "0.0", + "8": "3.0", + "9": "1", + "10": "1138.0", + "11": "0.0", + "12": "1154.4", + "13": "1154.4", + "14": "1154.4", + "index": 968 + }, + { + "0": "0A282803-01E1-4193-B72A-F135B850DCB5", + "1": "A844427390246047", + "2": "5.39", + "3": "15.0", + "4": "2023-02-24 20:32:12", + "9": "1", + "10": "2365.0", + "11": "3.0", + "12": "86.24", + "13": "86.24", + "14": "5.39", + "index": 969 + }, + { + "0": "25C5DCA0-AACA-4FF2-870E-7A08EC230EF6", + "1": "A1055521399136000", + "2": "5.4", + "3": "23.0", + "4": "2023-02-27 04:51:23", + "5": "5.4", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "21.6", + "13": "21.6", + "14": "5.4", + "index": 970 + }, + { + "0": "34E50410-3939-4466-BCE5-6207661FAF5C", + "1": "A1899946865208980", + "2": "73080.0", + "3": "0.0", + "4": "2023-03-09 16:20:26", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "73080.0", + "13": "73080.0", + "14": "73080.0", + "index": 971 + }, + { + "0": "BD1D07BF-A461-47A3-8938-D785B38A0E7D", + "1": "A914801001917388", + "2": "698.99", + "3": "8.0", + "4": "2023-01-15 07:32:32", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "698.99", + "13": "698.99", + "14": "698.99", + "index": 972 + }, + { + "0": "BD1D07BF-A461-47A3-8938-D785B38A0E7D", + "1": "A914801001917388", + "2": "698.99", + "3": "8.0", + "4": "2023-01-15 07:32:32", + "5": "942.0987220000001", + "6": "false", + "7": "0.0", + "8": "2.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "698.99", + "13": "698.99", + "14": "698.99", + "index": 973 + }, + { + "0": "985F137B-2E34-46E7-9AB6-EBF9D2C220F4", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 20:06:48", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "5108.979999999999", + "13": "5108.979999999999", + "14": "145.9708571428571", + "index": 974 + }, + { + "0": "2FF854D4-3A50-4F9B-9AF9-861612051389", + "1": "A1899946873142120", + "2": "149.97", + "3": "15.0", + "4": "2023-01-03 20:33:06", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "6908.620000000002", + "13": "6908.620000000002", + "14": "146.99191489361706", + "index": 975 + }, + { + "0": "8F4A2E5B-152F-45DB-B0E1-77EB964422F4", + "1": "A844428050423122", + "2": "64.49", + "3": "7.0", + "4": "2023-02-07 12:22:26", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "64.49", + "13": "64.49", + "14": "64.49", + "index": 976 + }, + { + "0": "8F4A2E5B-152F-45DB-B0E1-77EB964422F4", + "1": "A844428050423122", + "2": "64.49", + "3": "7.0", + "4": "2023-02-07 12:22:26", + "5": "64.49", + "6": "false", + "7": "0.0", + "8": "1.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "64.49", + "13": "64.49", + "14": "64.49", + "index": 977 + }, + { + "0": "4D150B63-9F3D-4A5E-A899-FECAF11AA4FE", + "1": "A985156107272519", + "2": "118.79", + "3": "11.0", + "4": "2023-02-09 17:02:14", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "118.79", + "13": "118.79", + "14": "118.79", + "index": 978 + }, + { + "0": "4D150B63-9F3D-4A5E-A899-FECAF11AA4FE", + "1": "A985156107272519", + "2": "118.79", + "3": "11.0", + "4": "2023-02-09 17:02:14", + "5": "118.79", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "2365.0", + "11": "0.0", + "12": "118.79", + "13": "118.79", + "14": "118.79", + "index": 979 + }, + { + "0": "A44E3875-069E-472A-B3FB-5ADC3A7CDF66", + "1": "A1055521435204170", + "2": "286.35", + "3": "18.0", + "4": "2023-03-29 23:51:16", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "286.35", + "13": "286.35", + "14": "286.35", + "index": 980 + }, + { + "0": "68D83F37-50D4-484B-8652-EAA245BFD48D", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 19:33:26", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "3009.3999999999987", + "13": "3009.3999999999987", + "14": "143.30476190476185", + "index": 981 + }, + { + "0": "ECADF883-D7AA-4373-99FB-358A35302900", + "1": "A1688853652289450", + "2": "1499.0", + "3": "14.0", + "4": "2023-01-08 21:20:27", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1499.0", + "13": "1499.0", + "14": "1499.0", + "index": 982 + }, + { + "0": "ECADF883-D7AA-4373-99FB-358A35302900", + "1": "A1688853652289450", + "2": "1499.0", + "3": "14.0", + "4": "2023-01-08 21:20:27", + "5": "118.002779", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1499.0", + "13": "1499.0", + "14": "1499.0", + "index": 983 + }, + { + "0": "13A9B365-CFF1-44F7-A1EB-19327EDE18C2", + "1": "A1688853647393240", + "2": "295.38", + "3": "8.0", + "4": "2023-01-25 16:49:33", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "443.07", + "13": "443.07", + "14": "221.535", + "index": 984 + }, + { + "0": "B1992BA4-6A40-477F-99FF-2C9AC26688DF", + "1": "A1688853662172620", + "2": "569.97", + "3": "23.0", + "4": "2023-03-19 15:17:07", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "569.97", + "13": "569.97", + "14": "569.97", + "index": 985 + }, + { + "0": "B1992BA4-6A40-477F-99FF-2C9AC26688DF", + "1": "A1688853662172620", + "2": "569.97", + "3": "23.0", + "4": "2023-03-19 15:17:07", + "5": "768.205566", + "6": "false", + "7": "3.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "569.97", + "13": "569.97", + "14": "569.97", + "index": 986 + }, + { + "0": "A92EA0F2-90D5-413B-A2FE-8A91F3DA1255", + "1": "A1759222219189020", + "2": "222.19", + "3": "3.0", + "4": "2023-01-28 08:50:57", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "222.19", + "13": "222.19", + "14": "222.19", + "index": 987 + }, + { + "0": "ABE168A6-3636-4202-9389-95E44E65881E", + "1": "A1688853657869890", + "2": "52.99", + "3": "10.0", + "4": "2023-01-03 17:14:56", + "5": "52.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "0", + "10": "366.0", + "11": "0.0", + "12": "423.92", + "13": "423.92", + "14": "52.99", + "index": 988 + }, + { + "0": "9B2DBE0F-7C5E-48F1-B184-2066C7CE0AC4", + "1": "A1899946871435580", + "2": "281.37", + "3": "13.0", + "4": "2023-01-20 18:56:34", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "281.37", + "13": "281.37", + "14": "281.37", + "index": 989 + }, + { + "0": "9B2DBE0F-7C5E-48F1-B184-2066C7CE0AC4", + "1": "A1899946871435580", + "2": "281.37", + "3": "13.0", + "4": "2023-01-20 18:56:34", + "5": "280.207942", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "281.37", + "13": "281.37", + "14": "281.37", + "index": 990 + }, + { + "0": "C5A162B3-E2A9-451F-8A02-FE6A939B43A4", + "1": "A985156979906180", + "2": "99.99", + "3": "14.0", + "4": "2023-01-07 22:49:51", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "99.99", + "13": "99.99", + "14": "99.99", + "index": 991 + }, + { + "0": "C5A162B3-E2A9-451F-8A02-FE6A939B43A4", + "1": "A985156979906180", + "2": "99.99", + "3": "14.0", + "4": "2023-01-07 22:49:51", + "5": "99.99", + "6": "false", + "7": "1.0", + "8": "0.0", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "99.99", + "13": "99.99", + "14": "99.99", + "index": 992 + }, + { + "0": "47A9F4BA-03C8-4900-BEF0-BADCF3C21D99", + "1": "A1688853662172620", + "2": "569.97", + "3": "23.0", + "4": "2023-03-19 15:19:14", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1139.94", + "13": "1139.94", + "14": "569.97", + "index": 993 + }, + { + "0": "51729D46-986A-4AD6-927B-959AA1FF1749", + "1": "A1688853657886190", + "2": "53.99", + "3": "13.0", + "4": "2023-01-03 18:35:19", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1241.77", + "13": "1241.77", + "14": "53.99", + "index": 994 + }, + { + "0": "F15CE4DA-A189-42BF-931E-66398ED48CA6", + "1": "A1899946873142120", + "2": "149.97", + "3": "14.0", + "4": "2023-01-03 19:21:51", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "2559.4899999999993", + "13": "2559.4899999999993", + "14": "142.19388888888886", + "index": 995 + }, + { + "0": "4C5EC030-CD2E-4097-B706-42BE9D808509", + "1": "A1899946873142120", + "2": "149.97", + "3": "13.0", + "4": "2023-01-03 19:05:37", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "1809.64", + "13": "1809.64", + "14": "139.20307692307694", + "index": 996 + }, + { + "0": "27B1F6C4-E881-408C-A29E-CA13AD07997B", + "1": "A1899946895455190", + "2": "19.99", + "3": "13.0", + "4": "2023-01-13 18:49:35", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "119.93999999999998", + "13": "119.93999999999998", + "14": "19.99", + "index": 997 + }, + { + "0": "DE53E28B-69C9-4C7D-AF79-E725235C87F4", + "1": "A1899946895455190", + "2": "19.99", + "3": "14.0", + "4": "2023-01-13 19:31:56", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "259.87", + "13": "259.87", + "14": "19.990000000000002", + "index": 998 + }, + { + "0": "1935138A-D934-4B52-B3F5-FA99C47F03AC", + "1": "A1688853596241210", + "2": "65.31", + "3": "22.0", + "4": "2023-02-17 03:40:57", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "190.61", + "13": "190.61", + "14": "63.53666666666667", + "index": 999 + }, + { + "0": "CDAFFE95-3687-4886-9668-96EB7645063F", + "1": "A1829582586398540", + "2": "786.79", + "3": "10.0", + "4": "2023-01-20 09:25:50", + "9": "1", + "10": "366.0", + "11": "0.0", + "12": "905.79", + "13": "905.79", + "14": "452.895", + "index": 1000 + } + ], + "schema": [ + { + "key": "0", + "name": "transactionID", + "type": "string" + }, + { + "key": "1", + "name": "accountID", + "type": "string" + }, + { + "key": "2", + "name": "transactionAmount", + "type": "double" + }, + { + "key": "3", + "name": "localHour", + "type": "double" + }, + { + "key": "4", + "name": "timestamp", + "type": "timestamp" + }, + { + "key": "5", + "name": "transactionAmountUSD", + "type": "double" + }, + { + "key": "6", + "name": "isProxyIP", + "type": "boolean" + }, + { + "key": "7", + "name": "digitalItemCount", + "type": "double" + }, + { + "key": "8", + "name": "physicalItemCount", + "type": "double" + }, + { + "key": "9", + "name": "is_fraud", + "type": "bigint" + }, + { + "key": "10", + "name": "accountAge", + "type": "double" + }, + { + "key": "11", + "name": "numPaymentRejects1dPerUser", + "type": "double" + }, + { + "key": "12", + "name": "transaction_amount_7d_sum", + "type": "double" + }, + { + "key": "13", + "name": "transaction_amount_3d_sum", + "type": "double" + }, + { + "key": "14", + "name": "transaction_amount_7d_avg", + "type": "double" + } + ], + "truncated": false + }, + "isSummary": false, + "language": "scala" + }, + "persist_state": { + "view": { + "type": "details", + "tableOptions": {}, + "chartOptions": { + "chartType": "bar", + "categoryFieldKeys": [ + "0" + ], + "seriesFieldKeys": [ + "10" + ], + "aggregationType": "sum", + "isStacked": false + } + } + } + }, + "9a6fcf39-abcf-44bd-98f3-19b607186f26": { + "type": "Synapse.DataFrame", + "sync_state": { + "table": { + "rows": [ + { + "0": "A1055520426185580", + "1": "2021-12-31 00:00:00", + "2": "GB", + "3": "true", + "4": "0.0", + "5": "2000.0", + "index": 1 + }, + { + "0": "A1055520426191820", + "1": "2021-12-31 00:00:00", + "2": "US", + "3": "true", + "4": "0.0", + "5": "1.0", + "index": 2 + }, + { + "0": "A1055520426549020", + "1": "2021-12-31 00:00:00", + "2": "AU", + "3": "true", + "4": "0.0", + "5": "1.0", + "index": 3 + }, + { + "0": "A1055520426719380", + "1": "2021-12-31 00:00:00", + "2": "US", + "3": "true", + "4": "0.0", + "5": "2000.0", + "index": 4 + }, + { + "0": "A1055520426806680", + "1": "2021-12-31 00:00:00", + "2": "GB", + "3": "true", + "4": "1.0", + "5": "2000.0", + "index": 5 + } + ], + "schema": [ + { + "key": "0", + "name": "accountID", + "type": "string" + }, + { + "key": "1", + "name": "timestamp", + "type": "timestamp" + }, + { + "key": "2", + "name": "accountCountry", + "type": "string" + }, + { + "key": "3", + "name": "isUserRegistered", + "type": "boolean" + }, + { + "key": "4", + "name": "numPaymentRejects1dPerUser", + "type": "double" + }, + { + "key": "5", + "name": "accountAge", + "type": "double" + } + ], + "truncated": false + }, + "isSummary": false, + "language": "scala" + }, + "persist_state": { + "view": { + "type": "details", + "tableOptions": {}, + "chartOptions": { + "chartType": "bar", + "categoryFieldKeys": [ + "0" + ], + "seriesFieldKeys": [ + "5" + ], + "aggregationType": "sum", + "isStacked": false + } + } + } + } + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file diff --git a/sdk/python/featurestore_sample/notebooks/sdk_only/3. Enable recurrent materialization and run batch inference.ipynb b/sdk/python/featurestore_sample/notebooks/sdk_only/3. Enable recurrent materialization and run batch inference.ipynb new file mode 100644 index 0000000000..813069d2e3 --- /dev/null +++ b/sdk/python/featurestore_sample/notebooks/sdk_only/3. Enable recurrent materialization and run batch inference.ipynb @@ -0,0 +1,620 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "# Tutorial: Enable recurrent materialization and run batch inference" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "_Managed feature store is in private preview, which is subject to the [Supplemental Terms of Use for Microsoft Azure Previews](https://azure.microsoft.com/en-us/support/legal/preview-supplemental-terms/)_" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "In this tutorial series you will experience how features seamlessly integrates all the phases of ML lifecycle: Prototyping features, training and operationalizing.\n", + "\n", + "In the previous part of the tutorial you learnt to experiment with features, train the model and register the model along with the feature-retrieval spec. In this tutorial you will learn how to run batch inference for the registered model.\n", + "\n", + "You will perform the following:\n", + "- Enable recurrent materialization for the `transactions` feature set\n", + "- Run batch inference pipeline on the registered model" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "# Prerequisites\n", + "1. Please ensure you have executed the previous parts of this tutorial series" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "# Setup" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Configure Azure ML spark notebook\n", + "\n", + "1. In the \"Compute\" dropdown in the top nav, select \"Serverless Spark Compute\". \n", + "1. Click on \"configure session\" in top status bar -> click on \"Python packages\" -> click on \"upload conda file\" -> select the file azureml-examples/sdk/python/featurestore-sample/project/env/conda.yml from your local machine; Also increase the session time out (idle time) if you want to avoid running the prerequisites frequently\n", + "\n", + "\n" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Start spark session" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "# run this cell to start the spark session (any code block will start the session ). This can take around 10 mins.\n", + "print(\"start spark session\")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696552142635 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "start-spark-session", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Setup root directory for the samples" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "import os\n", + "\n", + "# please update the dir to ./Users/ (or any custom directory you uploaded the samples to).\n", + "# You can find the name from the directory structure in the left nav\n", + "root_dir = \"./Users//featurestore_sample\"\n", + "\n", + "if os.path.isdir(root_dir):\n", + " print(\"The folder exists.\")\n", + "else:\n", + " print(\"The folder does not exist. Please create or fix the path\")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696552223358 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "root-dir", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Initialize the project workspace CRUD client\n", + "This is the current workspace where you will be running the tutorial notebook from" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "### Initialize the MLClient of this project workspace\n", + "import os\n", + "from azure.ai.ml import MLClient\n", + "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", + "\n", + "project_ws_sub_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", + "project_ws_rg = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", + "project_ws_name = os.environ[\"AZUREML_ARM_WORKSPACE_NAME\"]\n", + "version = \"\"\n", + "\n", + "# connect to the project workspace\n", + "ws_client = MLClient(\n", + " AzureMLOnBehalfOfCredential(), project_ws_sub_id, project_ws_rg, project_ws_name\n", + ")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696552235806 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "init-ws-crud-client", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Initialize the feature store CRUD client\n", + "Ensure you update the `featurestore_name` to reflect what you created in part 1 of this tutorial" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "from azure.ai.ml import MLClient\n", + "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", + "\n", + "# feature store\n", + "featurestore_name = \"my-featurestore\" # use the same name from part #1 of the tutorial\n", + "featurestore_subscription_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", + "featurestore_resource_group_name = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", + "\n", + "# feature store ml client\n", + "fs_client = MLClient(\n", + " AzureMLOnBehalfOfCredential(),\n", + " featurestore_subscription_id,\n", + " featurestore_resource_group_name,\n", + " featurestore_name,\n", + ")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696552265737 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "init-fs-crud-client", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Initialize the feature store core sdk client" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "# feature store client\n", + "from azureml.featurestore import FeatureStoreClient\n", + "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", + "\n", + "featurestore = FeatureStoreClient(\n", + " credential=AzureMLOnBehalfOfCredential(),\n", + " subscription_id=featurestore_subscription_id,\n", + " resource_group_name=featurestore_resource_group_name,\n", + " name=featurestore_name,\n", + ")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696552271317 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "init-fs-core-sdk", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "## Step 1: Enable recurrent materialization on the `transactions` featureset\n", + "\n", + "In part 2 of this tutorial you enabled materialization and performed backfill on the transactions feature set. Backfill is an ondemand one-time operation to compute and store feature values in the materialization store. However when you want to perform inference of the model in production, you might want to keep the materilization store upto date by setting up recurrent materialization jobs. These jobs run on user defined schedule\n", + "The recurrent job schedule works in the following way: \n", + "- A window is defined by the interval and frequency. E.g., interval = 3 and frequency = Hour define a 3-hour window\n", + "- The first window starts at the start_time defined in the RecurenceTrigger, and so on.\n", + "- The first recurrent job will be submitted at the begining of the next window after the update time.\n", + "- Later recurrent jobs will be submitted at every window after the first job.\n", + "\n", + "As explained in the previous parts of the tutorials, once data is materialized (backfill/recurrent materialization), feature retrieval will use the materialized data by default." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "from datetime import datetime\n", + "from azure.ai.ml.entities import RecurrenceTrigger\n", + "\n", + "transactions_fset_config = fs_client.feature_sets.get(\n", + " name=\"transactions\", version=version\n", + ")\n", + "\n", + "# create a schedule that runs the materialization job every 3 hours\n", + "transactions_fset_config.materialization_settings.schedule = RecurrenceTrigger(\n", + " interval=3, frequency=\"Hour\", start_time=datetime(2023, 4, 15, 0, 4, 10, 0)\n", + ")\n", + "\n", + "fs_poller = fs_client.feature_sets.begin_create_or_update(transactions_fset_config)\n", + "\n", + "print(fs_poller.result())" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696552294321 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "enable-recurrent-mat-txns-fset", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### (Optional) Save the feature set asset yaml with the updated settings" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "## uncomment and run\n", + "# transactions_fset_config.dump(root_dir + \"/featurestore/featuresets/transactions/featureset_asset_offline_enabled_with_schedule.yaml\")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1681791896733 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "dump-txn-fset-with-mat-yaml", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Track status of the recurrent materialization jobs in the feature store studio UI\n", + "This job will every three hours. \n", + "\n", + "__Action__:\n", + "\n", + "1. Feel free to execute the next step for now (batch inference).\n", + "1. In three hours check the recurrent job status via the UI" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "## Step 2: Run the batch-inference pipeline\n", + "\n", + "In this step you will manually trigger the batch inference pipeline. In a production scenario, this could be trigerred by a ci/cd pipeline based on model registration/approval.\n", + "\n", + "The batch-inference has the following steps:\n", + "\n", + "1. Feature retrieval step: This use the same built-in feature retrieval component that we used in the training pipeline in the part 3 of the tutorial. Incase of training pipeline, we provided feature retreival spec as an input to the component. However in case of batch inference we will pass the registered model as the input and the component will look for feature retrieval spec in the model artifact. Another difference is that in case of training, the observation data had the target variable, however incase of batch inference it will not be present. The feature retrieval step will join the observation data with the features and output the data for batch inference.\n", + "1. Batch inference: This step uses the batch inference input data from previous step, runs inference on the model and outputs the data by appending the predicted value.\n", + "\n", + "__Note:__ In this example we use a job for batch inference. You can also use Azure ML's batch endpoints." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "from azure.ai.ml import load_job # will be used later\n", + "\n", + "# set the batch inference pipeline path\n", + "batch_inference_pipeline_path = (\n", + " root_dir + \"/project/fraud_model/pipelines/batch_inference_pipeline.yaml\"\n", + ")\n", + "batch_inference_pipeline_definition = load_job(source=batch_inference_pipeline_path)\n", + "\n", + "# run the training pipeline\n", + "batch_inference_pipeline_job = ws_client.jobs.create_or_update(\n", + " batch_inference_pipeline_definition\n", + ")\n", + "\n", + "# stream the run logs\n", + "ws_client.jobs.stream(batch_inference_pipeline_job.name)" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1683430315364 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "run-batch-inf-pipeline", + "nteract": { + "transient": { + "deleting": false + } + }, + "tags": [ + "active-ipynb" + ] + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "#### Inspect the batch inference output data\n", + "1. In the pipeline view, double click on `inference_step` -> in `outputs` card, copy the `Data` field. It will be something like `azureml_995abbc2-3171-461e-8214-c3c5d17ede83_output_data_data_with_prediction:1`. \n", + "1. Paste it in the below cell with name and version separately (notice that the last character is the version, separated by a `:`).\n", + "1. You will see the `predict_is_fraud` column generated by the batch inference pipeline\n", + "\n", + "Explanation: Since we did not provide a `name` and `version` in the `outputs` of the `inference_step` in the batch inference pipeline (`/project/fraud_mode/pipelines/batch_inference_pipeline.yaml`), the system created an untracked data asset with a guid as name and version as 1. In the next cell we will be getting the data path from the asset and displaying it." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "inf_data_output = ws_client.data.get(\n", + " name=\"azureml_1c106662-aa5e-4354-b5f9-57c1b0fdb3a7_output_data_data_with_prediction\",\n", + " version=\"1\",\n", + ")\n", + "inf_output_df = spark.read.parquet(inf_data_output.path)\n", + "display(inf_output_df.head(5))" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1681446888800 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "inspect-batch-inf-output-data", + "nteract": { + "transient": { + "deleting": false + } + }, + "tags": [ + "active-ipynb" + ] + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "## Cleanup\n", + "If you created a resource group for the tutorial, you can delete the resource group to delete all the resources associated with this tutorial.\n", + "\n", + "Otherwise, you can delete the resources individually:\n", + "\n", + "* Delete the feature store: Go to the resource group in the azure portal, select the feature store and delete it\n", + "* Follow the instructions [here](https://review.learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-manage-user-assigned-managed-identities?pivots=identity-mi-methods-azp&view=azureml-api-2#delete-a-user-assigned-managed-identity) to delete the user assigned managed identity\n", + "* Delete the offline store (storage account): Go to the resource group in the azure portal, select the storage you created and delete it" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + } + ], + "metadata": { + "celltoolbar": "Edit Metadata", + "kernel_info": { + "name": "synapse_pyspark" + }, + "kernelspec": { + "name": "synapse_pyspark", + "language": "Python", + "display_name": "Synapse PySpark" + }, + "language_info": { + "name": "python", + "version": "3.8.0", + "mimetype": "text/x-python", + "file_extension": ".py", + "pygments_lexer": "ipython", + "codemirror_mode": "ipython", + "nbconvert_exporter": "python" + }, + "microsoft": { + "host": { + "AzureML": { + "notebookHasBeenCompleted": true + } + }, + "ms_spell_check": { + "ms_spell_check_language": "en" + } + }, + "nteract": { + "version": "nteract-front-end@1.0.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file diff --git a/sdk/python/featurestore_sample/notebooks/sdk_only/3. Experiment and train models using features.ipynb b/sdk/python/featurestore_sample/notebooks/sdk_only/3. Experiment and train models using features.ipynb deleted file mode 100644 index ae6bcbb32e..0000000000 --- a/sdk/python/featurestore_sample/notebooks/sdk_only/3. Experiment and train models using features.ipynb +++ /dev/null @@ -1,1201 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "# Tutorial #3: Experiment and train models using features" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "In this tutorial series you will experience how features seamlessly integrates all the phases of ML lifecycle: Prototyping features, training and operationalizing.\n", - "\n", - "In part 1 of the tutorial you learnt how to create a feature set spec with custom transformations. In part 2 of the tutorial you learnt how to enable materialization and perform backfill. In this tutorial you will will learn how to experiment with features to improve model performance. You will see how feature store increasing agility in the experimentation and training flows. \n", - "\n", - "You will perform the following:\n", - "- Prototype a create new `acccounts` feature set spec using existing precomputed values as features, unlike part 1 of the tutorial where we created feature set that had custom transformations. You will then Register the local feature set spec as a feature set in the feature store\n", - "- Select features for the model: You will select features from the `transactions` and `accounts` feature sets and save them as a feature-retrieval spec\n", - "- Run training pipeline that uses the Feature retrieval spec to train a new model. This pipeline will use the built in feature-retrieval component to generate the training data" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Important\n", - "\n", - "This feature is currently in public preview. This preview version is provided without a service-level agreement, and it's not recommended for production workloads. Certain features might not be supported or might have constrained capabilities. For more information, see [Supplemental Terms of Use for Microsoft Azure Previews](https://azure.microsoft.com/support/legal/preview-supplemental-terms/)." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "# Prerequisites\n", - "1. Please ensure you have executed part 1 and 2 of the tutorial" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "# Setup" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Configure Azure ML spark notebook\n", - "\n", - "1. In the \"Compute\" dropdown in the top nav, select \"Serverless Spark Compute\". \n", - "1. Click on \"configure session\" in top status bar -> click on \"Python packages\" -> click on \"upload conda file\" -> select the file azureml-examples/sdk/python/featurestore-sample/project/env/conda.yml from your local machine; Also increase the session time out (idle time) if you want to avoid running the prerequisites frequently\n", - "\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Start spark session" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683423408899 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "start-spark-session", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# run this cell to start the spark session (any code block will start the session ). This can take around 10 mins.\n", - "print(\"start spark session\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Setup root directory for the samples" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683423941098 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "root-dir", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "import os\n", - "\n", - "# please update the dir to ./Users/{your-alias} (or any custom directory you uploaded the samples to).\n", - "# You can find the name from the directory structure inm the left nav\n", - "root_dir = \"./Users//featurestore_sample\"\n", - "\n", - "if os.path.isdir(root_dir):\n", - " print(\"The folder exists.\")\n", - "else:\n", - " print(\"The folder does not exist. Please create or fix the path\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Initialize the project workspace CRUD client\n", - "This is the current workspace where you will be running the tutorial notebook from" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683423983149 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "init-ws-crud-client", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "### Initialize the MLClient of this project workspace\n", - "import os\n", - "from azure.ai.ml import MLClient\n", - "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", - "\n", - "project_ws_sub_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", - "project_ws_rg = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", - "project_ws_name = os.environ[\"AZUREML_ARM_WORKSPACE_NAME\"]\n", - "version = \"\"\n", - "\n", - "# connect to the project workspace\n", - "ws_client = MLClient(\n", - " AzureMLOnBehalfOfCredential(), project_ws_sub_id, project_ws_rg, project_ws_name\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Initialize the feature store CRUD client\n", - "Ensure you update the `featurestore_name` to reflect what you created in part 1 of this tutorial" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683423998492 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "init-fs-crud-client", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.ai.ml import MLClient\n", - "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", - "\n", - "# feature store\n", - "featurestore_name = \"my-featurestore\" # use the same name from part #1 of the tutorial\n", - "featurestore_subscription_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", - "featurestore_resource_group_name = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", - "\n", - "# feature store ml client\n", - "fs_client = MLClient(\n", - " AzureMLOnBehalfOfCredential(),\n", - " featurestore_subscription_id,\n", - " featurestore_resource_group_name,\n", - " featurestore_name,\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Initialize the feature store core sdk client" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683424037990 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "init-fs-core-sdk", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# feature store client\n", - "from azureml.featurestore import FeatureStoreClient\n", - "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", - "\n", - "featurestore = FeatureStoreClient(\n", - " credential=AzureMLOnBehalfOfCredential(),\n", - " subscription_id=featurestore_subscription_id,\n", - " resource_group_name=featurestore_resource_group_name,\n", - " name=featurestore_name,\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Create compute cluster with name `cpu-cluster` in the project workspace\n", - "This will be needed when we run training/batch inference jobs" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683424077800 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "create-compute-cluster", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.ai.ml.entities import AmlCompute\n", - "\n", - "cluster_basic = AmlCompute(\n", - " name=\"cpu-cluster-fs\",\n", - " type=\"amlcompute\",\n", - " size=\"STANDARD_F4S_V2\", # you can replace it with other supported VM SKUs\n", - " location=ws_client.workspaces.get(ws_client.workspace_name).location,\n", - " min_instances=0,\n", - " max_instances=1,\n", - " idle_time_before_scale_down=360,\n", - ")\n", - "ws_client.begin_create_or_update(cluster_basic).result()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Step 1: Create accounts featureset locally from precomputed data\n", - "In tutorial part 1, we created a transactions featureset that had custom transformations. Now we will create an accounts featureset that will use precomputed values. \n", - "\n", - "For onboarding precomputed features, you can create a featureset spec without writing any transformation code. Featureset spec is a specification to develop and test a featureset in a fully local/dev environment without connecting to any featurestore. In this step you will create the feature set spec locally and sample the values from it. If you want to get managed featurestore capabilities, you need to register the featureset spec with a feature store using a feature asset definition (a future step in this tutorial)." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Step 1a: Explore the source data for accounts\n", - "\n", - "##### Note\n", - " Note that the sample data used in this notebook is hosted in a public accessible blob container. It can only be read in Spark via `wasbs` driver. When you create feature sets using your own source data, please host them in adls gen2 account and use `abfss` driver in the data path. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683424121263 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "explore-accts-fset-src-data", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "accounts_data_path = \"wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/datasources/accounts-precalculated/*.parquet\"\n", - "accounts_df = spark.read.parquet(accounts_data_path)\n", - "\n", - "display(accounts_df.head(5))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Step 1b: Create `accounts` feature set spec in local from these precomputed features\n", - "Note that we do not need any transformation code here since we are referencing precomputed features." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683424234184 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "create-accts-fset-spec", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azureml.featurestore import create_feature_set_spec, FeatureSetSpec\n", - "from azureml.featurestore.contracts import (\n", - " DateTimeOffset,\n", - " FeatureSource,\n", - " TransformationCode,\n", - " Column,\n", - " ColumnType,\n", - " SourceType,\n", - " TimestampColumn,\n", - ")\n", - "\n", - "\n", - "accounts_featureset_spec = create_feature_set_spec(\n", - " source=FeatureSource(\n", - " type=SourceType.parquet,\n", - " path=\"wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/datasources/accounts-precalculated/*.parquet\",\n", - " timestamp_column=TimestampColumn(name=\"timestamp\"),\n", - " ),\n", - " index_columns=[Column(name=\"accountID\", type=ColumnType.string)],\n", - " # account profiles in the source are updated once a year. set temporal_join_lookback to 365 days\n", - " temporal_join_lookback=DateTimeOffset(days=365, hours=0, minutes=0),\n", - " infer_schema=True,\n", - ")\n", - "# Generate a spark dataframe from the feature set specification\n", - "accounts_fset_df = accounts_featureset_spec.to_spark_dataframe()\n", - "# display few records\n", - "display(accounts_fset_df.head(5))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Step 1c: Export as feature set spec\n", - "In order to register the feature set spec with the feature store, it needs to be saved in a specific format. \n", - "Action: After running the below cell, please inspect the generated `accounts` FeatureSetSpec: Open this file from the file tree to see the spec: `featurestore/featuresets/accounts/spec/FeatureSetSpec.yaml`\n", - "\n", - "Spec contains these important elements:\n", - "\n", - "1. `source`: reference to a storage. In this case a parquet file in a blob storage.\n", - "1. `features`: list of features and their datatypes. If you provide transformation code (see Day 2 section), the code has to return a dataframe that maps to the features and datatypes. In case where you do not provide transformation code (in this case of `accounts` because it is precomputed), the system will build the query to to map these to the source \n", - "1. `index_columns`: the join keys required to access values from the feature set\n", - "\n", - "Learn more about it in the [top level feature store entities document](fs-concepts-todo) and the [feature set spec yaml reference](reference-yaml-featureset-spec.md).\n", - "\n", - "The additional benefit of persisting it is that it can be source controlled." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683424300893 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "dump-accts-fset-spec", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "import os\n", - "\n", - "# create a new folder to dump the feature set spec\n", - "accounts_featureset_spec_folder = root_dir + \"/featurestore/featuresets/accounts/spec\"\n", - "\n", - "# check if the folder exists, create one if not\n", - "if not os.path.exists(accounts_featureset_spec_folder):\n", - " os.makedirs(accounts_featureset_spec_folder)\n", - "\n", - "accounts_featureset_spec.dump(accounts_featureset_spec_folder)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Step 2: Experiment with unregistered features locally and register with feature store when ready\n", - "When you are developing features, you might want to test/validate locally before registering with the feature store or running training pipelines in the cloud. In this step you will generate training data for the ML model from combination of features from a local unregistered feature set (`accounts`) and feature set registered in the feature store (`transactions`)." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Step 2a: Select features for model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683424463146 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "select-unreg-features-for-model", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# get the registered transactions feature set, version 1\n", - "transactions_featureset = featurestore.feature_sets.get(\"transactions\", version)\n", - "# Notice that account feature set spec is in your local dev environment (this notebook): not registered with feature store yet\n", - "features = [\n", - " accounts_featureset_spec.get_feature(\"accountAge\"),\n", - " accounts_featureset_spec.get_feature(\"numPaymentRejects1dPerUser\"),\n", - " transactions_featureset.get_feature(\"transaction_amount_7d_sum\"),\n", - " transactions_featureset.get_feature(\"transaction_amount_3d_sum\"),\n", - " transactions_featureset.get_feature(\"transaction_amount_7d_avg\"),\n", - "]" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Step 2b: Generate training data locally\n", - "In this step we generate training data for illustrative purpose. You can optionally train models locally with this. In the upcoming steps in this tutorial, you will train a model in the cloud." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683424551556 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "gen-training-data-locally", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azureml.featurestore import get_offline_features\n", - "\n", - "# Load the observation data. To understand observatio ndata, refer to part 1 of this tutorial\n", - "observation_data_path = \"wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/observation_data/train/*.parquet\"\n", - "observation_data_df = spark.read.parquet(observation_data_path)\n", - "obs_data_timestamp_column = \"timestamp\"\n", - "\n", - "# generate training dataframe by using feature data and observation data\n", - "training_df = get_offline_features(\n", - " features=features,\n", - " observation_data=observation_data_df,\n", - " timestamp_column=obs_data_timestamp_column,\n", - ")\n", - "\n", - "# Ignore the message that says feature set is not materialized (materialization is optional). We will enable materialization in the next part of the tutorial.\n", - "display(training_df)\n", - "# Note: display(training_df.head(5)) displays the timestamp column in a different format. You can can call training_df.show() to see correctly formatted value" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Step 2c: Register the `accounts` featureset with the featurestore\n", - "Once you have experimented with different feature definitions locally and sanity tested it, you can register it with the feature store.\n", - "For this you will register a featureset asset definition with the feature store.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683424692142 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "reg-accts-fset", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.ai.ml.entities import FeatureSet, FeatureSetSpecification\n", - "\n", - "accounts_fset_config = FeatureSet(\n", - " name=\"accounts\",\n", - " version=version,\n", - " description=\"accounts featureset\",\n", - " entities=[f\"azureml:account:{version}\"],\n", - " stage=\"Development\",\n", - " specification=FeatureSetSpecification(path=accounts_featureset_spec_folder),\n", - " tags={\"data_type\": \"nonPII\"},\n", - ")\n", - "\n", - "poller = fs_client.feature_sets.begin_create_or_update(accounts_fset_config)\n", - "print(poller.result())" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Step 2d: Get registered featureset and sanity test" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683424718158 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "sample-accts-fset-data", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# look up the featureset by providing name and version\n", - "accounts_featureset = featurestore.feature_sets.get(\"accounts\", version)\n", - "# get access to the feature data\n", - "accounts_feature_df = accounts_featureset.to_spark_dataframe()\n", - "display(accounts_feature_df.head(5))\n", - "# Note: Please ignore this warning: Failure while loading azureml_run_type_providers. Failed to load entrypoint azureml.scriptrun" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Step 3: Run training experiment\n", - "In this step you will select a list of features, run a training pipeline, and register the model. You can repeat this step till you are happy with the model performance." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### (Optional) Step 3a: Discover features from Feature Store UI\n", - "You have already done this in part 1 of the tutorial after registering the `transactions` feature set. Since you also have `accounts` featureset, you can browse the available features:\n", - "* Goto the [Azure ML global landing page](https://ml.azure.com/home?flight=FeatureStores).\n", - "* Click on `Feature stores` in the left nav\n", - "* You will see the list of feature stores that you have access to. Click on the feature store that you created above.\n", - "\n", - "You can see the feature sets and entity that you created. Click on the feature sets to browse the feature definitions. You can also search for feature sets across feature stores by using the global search box." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### (Optional) Step 3b: Discover features from SDK" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683424900729 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "discover-features-from-sdk", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# List available feature sets\n", - "all_featuresets = featurestore.feature_sets.list()\n", - "for fs in all_featuresets:\n", - " print(fs)\n", - "\n", - "# List of versions for transactions feature set\n", - "all_transactions_featureset_versions = featurestore.feature_sets.list(\n", - " name=\"transactions\"\n", - ")\n", - "for fs in all_transactions_featureset_versions:\n", - " print(fs)\n", - "\n", - "# See properties of the transactions featureset including list of features\n", - "featurestore.feature_sets.get(name=\"transactions\", version=version).features" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Step 3c: Select features for the model and export it as a feature-retrieval spec\n", - "In the previous steps, you selected features from a combination unregistered and registered feature sets for local experimentation and testing. Now you are ready to experiment in the cloud. Saving the selected features as a feature-retrieval spec and using it in the mlops/cicd flow for training/inference increases your agility in shipping models." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "Select features for the model" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683424978050 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "select-reg-features", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# you can select features in pythonic way\n", - "features = [\n", - " accounts_featureset.get_feature(\"accountAge\"),\n", - " transactions_featureset.get_feature(\"transaction_amount_7d_sum\"),\n", - " transactions_featureset.get_feature(\"transaction_amount_3d_sum\"),\n", - "]\n", - "\n", - "# you can also specify features in string form: featurestore:featureset:version:feature\n", - "more_features = [\n", - " f\"accounts:{version}:numPaymentRejects1dPerUser\",\n", - " f\"transactions:{version}:transaction_amount_7d_avg\",\n", - "]\n", - "\n", - "more_features = featurestore.resolve_feature_uri(more_features)\n", - "\n", - "features.extend(more_features)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "Export selected features as a feature-retrieval spec\n", - "\n", - "#### Note\n", - "Feature retrieval spec is a portable definition of list of features associated with a model. This can help streamline ML model development and operationalizing.This will be an input to the training pipeline (used to generate the training data), then will be packaged along with the model, and will be used during inference to lookup the features. It will be a glue that integrates all phases of the ML lifecycle. Changes to training/inference pipeline can be kept minimal as you experiment and deploy. \n", - "\n", - "Using feature retrieval spec and the built-in feature retrieval component is optional: you can directly use `get_offline_features()` api as shown above.\n", - "\n", - "Note that the name of the spec should be `feature_retrieval_spec.yaml` when it is packaged with the model for the system to recognize it." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683425334483 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "export-as-frspec", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# Create feature retrieval spec\n", - "feature_retrieval_spec_folder = root_dir + \"/project/fraud_model/feature_retrieval_spec\"\n", - "\n", - "# check if the folder exists, create one if not\n", - "if not os.path.exists(feature_retrieval_spec_folder):\n", - " os.makedirs(feature_retrieval_spec_folder)\n", - "\n", - "featurestore.generate_feature_retrieval_spec(feature_retrieval_spec_folder, features)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Step 4: Train in the cloud using pipelines and register model if satisfactory\n", - "In this step you will manually trigger the training pipeline. In a production scenario, this could be triggered by a ci/cd pipeline based on changes to the feature-retrieval spec in the source repository." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Step 4a: Run the training pipeline\n", - "The training pipeline has the following steps:\n", - "\n", - "1. Feature retrieval step: This is a built-in component takes as input the feature retrieval spec, the observation data and timestamp column name. It then generates the training data as output. It runs this as a managed spark job.\n", - "1. Training step: This step trains the model based on the training data and generates a model (not registered yet)\n", - "1. Evaluation step: This step validates whether model performance/quailty is within threshold (in our case it is a placeholder/dummy step for illustration purpose)\n", - "1. Register model step: This step registers the model\n", - "\n", - "Note: In part 2 of this tutorial you ran a backfill job to materialize data for `transactions` feature set. Feature retrieval step will read feature values from offline store for this feature set. The behavior will same even if you use `get_offline_features()` api." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683429020656 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "run-training-pipeline", - "nteract": { - "transient": { - "deleting": false - } - }, - "tags": [ - "active-ipynb" - ] - }, - "outputs": [], - "source": [ - "from azure.ai.ml import load_job # will be used later\n", - "\n", - "training_pipeline_path = (\n", - " root_dir + \"/project/fraud_model/pipelines/training_pipeline.yaml\"\n", - ")\n", - "training_pipeline_definition = load_job(source=training_pipeline_path)\n", - "training_pipeline_job = ws_client.jobs.create_or_update(training_pipeline_definition)\n", - "ws_client.jobs.stream(training_pipeline_job.name)\n", - "# Note: First time it runs, each step in pipeline can take ~ 15 mins. However subsequent runs can be faster (assuming spark pool is warm - default timeout is 30 mins)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Inspect the training pipeline and the model\n", - "Open the above pipeline run \"web view\" in new window to see the steps in the pipeline.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Step 4b: Notice the feature retrieval spec in the model artifacts\n", - "1. In the left nav of the current workspace -> right click on `Models` -> Open in new tab or window\n", - "1. Click on `fraud_model`\n", - "1. Click on `Artifacts` in the top nav\n", - "\n", - "You can notice that the feature retrieval spec is packaged along with the model. The model registration step in the training pipeline has done this. You created feature retrieval spec during experimentation, now it has become part of the model definition. In the next tutorial you will see how this will be used during inferencing.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Step 5: View the feature set and model dependencies" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Step 5a: View the list of feature sets associated with the model\n", - "In the same models page, click on the `feature sets` tab. Here you can see both `transactions` and `accounts` featuresets that this model depends on." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Step 5b: View the list of models using the feature sets\n", - "1. Open the feature store UI (expalined in a previous step in this tutorial)\n", - "1. Click on `Feature sets` on the left nav\n", - "1. Click on any of the feature set -> click on `Models` tab\n", - "\n", - "You can see the list of models that are using the feature sets (determined from the feature retrieval spec when the model was registered)." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Cleanup\n", - "\n", - "Part 4 of the tutorial has instructions for deleting the resources" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Next steps\n", - "* Part 4 of tutorial: Enable recurrent materialization and run batch inference" - ] - } - ], - "metadata": { - "celltoolbar": "Edit Metadata", - "kernel_info": { - "name": "synapse_pyspark" - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - }, - "microsoft": { - "host": { - "AzureML": { - "notebookHasBeenCompleted": true - } - }, - "ms_spell_check": { - "ms_spell_check_language": "en" - } - }, - "nteract": { - "version": "nteract-front-end@1.0.0" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/sdk/python/featurestore_sample/notebooks/sdk_only/4. Enable online store and run online inference.ipynb b/sdk/python/featurestore_sample/notebooks/sdk_only/4. Enable online store and run online inference.ipynb new file mode 100644 index 0000000000..2e39e5d801 --- /dev/null +++ b/sdk/python/featurestore_sample/notebooks/sdk_only/4. Enable online store and run online inference.ipynb @@ -0,0 +1,1328 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "# Tutorial: Enable online materialization and run online inference\n", + "So far you have learned how to develop features, materialize them to offline materialization store, perform training, and perform batch inference. In this tutorial you will learn how to use feature store for online/realtime inference use cases.\n", + "\n", + "You will perform the following steps:\n", + "\n", + "1. Setup Azure Cache for Redis.\n", + "1. Attach the cache to feature store as the online materialization store and grant necessary permissions.\n", + "1. Materialize feature sets to the online store.\n", + "1. Test online deployment with mock data.\n" + ], + "metadata": {} + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "# Prerequisites\n", + "1. Before proceeding, please ensure that you have already completed previous four turorials of this tutorial series. We will be reusing feature store and some other resources created in the previous tutorials." + ], + "metadata": {} + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "## Prepare the notebook environment for development\n", + "Note: This tutorial uses Azure Machine Learning notebook with **Serverless Spark Compute**.\n", + "\n", + "1. Clone the examples repository to your local machine: To run the tutorial, first clone the [examples repository - (azureml-examples)](https://github.com/azure/azureml-examples) with this command:\n", + "\n", + " `git clone --depth 1 https://github.com/Azure/azureml-examples`\n", + "\n", + " You can also download a zip file from the [examples repository (azureml-examples)](https://github.com/azure/azureml-examples). At this page, first select the `code` dropdown, and then select `Download ZIP`. Then, unzip the contents into a folder on your local device.\n", + "\n", + "2. Running the tutorial:\n", + "* Option 1: Create a new notebook, and execute the instructions in this document step by step. \n", + "* Option 2: Open the existing notebook `featurestore_sample/notebooks/sdk_only/5. Enable online store and run online inference.ipynb`. You may keep this document open and refer to it for additional explanation and documentation links.\n", + "\n", + " 1. Select **Serverless Spark Compute** in the top navigation **Compute** dropdown. This operation might take one to two minutes. Wait for a status bar in the top to display **Configure session**.\n", + " 2. Select **Configure session** in the top status bar.\n", + " 3. Select **Python packages**.\n", + " 4. Select **Upload conda file**.\n", + " 5. Select file `azureml-examples/sdk/python/featurestore-sample/project/env/online.yml` located on your local device.\n", + " 6. (Optional) Increase the session time-out (idle time in minutes) to reduce the serverless spark cluster startup time." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "# Set up" + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Start Spark session\n", + "Execute the following code cell to start the Spark session. It wil take approximately 10 minutes to install all dependencies and start the Spark session." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "# Run this cell to start the spark session (any code block will start the session ). This can take approximately 10 mins.\n", + "print(\"start spark session\")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696553374079 + }, + "name": "start-spark-session" + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Setup root directory for the samples" + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "import os\n", + "\n", + "# Please update the dir to ./Users/ (or any custom directory you uploaded the samples to).\n", + "# You can find the name from the directory structure in the left navigation panel.\n", + "root_dir = \"./Users//featurestore_sample\"\n", + "\n", + "if os.path.isdir(root_dir):\n", + " print(\"The folder exists.\")\n", + "else:\n", + " print(\"The folder does not exist. Please create or fix the path\")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696553404071 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "root-dir", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Initialize the project workspace CRUD client\n", + "The `MLClient` for the current workspace, where you are running this tutorial notebook, will be used for create, read, update, and delete (CRUD) operations." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "import os\n", + "from azure.ai.ml import MLClient\n", + "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", + "\n", + "project_ws_sub_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", + "project_ws_rg = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", + "project_ws_name = os.environ[\"AZUREML_ARM_WORKSPACE_NAME\"]\n", + "version = \"\"\n", + "\n", + "# Connect to the project workspace\n", + "ws_client = MLClient(\n", + " AzureMLOnBehalfOfCredential(), project_ws_sub_id, project_ws_rg, project_ws_name\n", + ")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696553434418 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "init-prj-ws-client", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Initialize the CRUD client of the feature store workspace\n", + "The `MLClient` for the feature store workspace for create, read, update, and delete (CRUD) operations on feature store workspace." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "from azure.ai.ml import MLClient\n", + "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", + "\n", + "# Feature store\n", + "featurestore_name = \"my-featurestore\" # use the same name from part #1 of the tutorial\n", + "featurestore_subscription_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", + "featurestore_resource_group_name = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", + "\n", + "# Feature store MLClient\n", + "fs_client = MLClient(\n", + " AzureMLOnBehalfOfCredential(),\n", + " featurestore_subscription_id,\n", + " featurestore_resource_group_name,\n", + " featurestore_name,\n", + ")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "name": "init-fs-ws-client", + "gather": { + "logged": 1696553467100 + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Initialize the feature store core SDK client\n", + "This tutorial uses the Python feature store core SDK (`azureml-featurestore`). The SDK client initialized here is used for create, read, update, and delete (CRUD) operations, on feature stores, feature sets, and feature store entities." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "from azureml.featurestore import FeatureStoreClient\n", + "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", + "\n", + "featurestore = FeatureStoreClient(\n", + " credential=AzureMLOnBehalfOfCredential(),\n", + " subscription_id=featurestore_subscription_id,\n", + " resource_group_name=featurestore_resource_group_name,\n", + " name=featurestore_name,\n", + ")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "name": "init-fs-core-sdk", + "gather": { + "logged": 1696553483336 + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "## Setup Azure cache for Redis\n", + "This tutorial uses Azure Cache for Redis as the online materialization store. You can either create a new Redis instance or reuse an existing one." + ], + "metadata": {} + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Set values for the Azure Cache for Redis that will be used as online materialization store\n", + "In the following code cell, define the name of the Azure Cache for Redis that you want to create or reuse. Optionally, you can override other default settings." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "ws_location = ws_client.workspaces.get(ws_client.workspace_name).location\n", + "\n", + "redis_subscription_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", + "redis_resource_group_name = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", + "redis_name = \"redis1\"\n", + "redis_location = ws_location" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696553534519 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "redis-settings", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Azure Cache for Redis (option 1): create new Redis instance\n", + "You can select the Redis cache tier (basic, standard, premium, or enterprise). You should choose a SKU family that is available for the selected cache tier. See this documentation page to learn more about [how selecting different tiers may affect cache performance](https://learn.microsoft.com/azure/azure-cache-for-redis/cache-best-practices-performance). See this link learn more about [pricing for different SKU tiers and families of Azure Cache for Redis](https://azure.microsoft.com/en-us/pricing/details/cache/).\n", + "\n", + "Execute the following code cell to create an Azure Cache for Redis with premium tier, SKU family `P` and cache capacity 2. It may take approximately 5-10 minutes to provision the Redis instance." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "from azure.mgmt.redis import RedisManagementClient\n", + "from azure.mgmt.redis.models import RedisCreateParameters, Sku, SkuFamily, SkuName\n", + "\n", + "management_client = RedisManagementClient(\n", + " AzureMLOnBehalfOfCredential(), redis_subscription_id\n", + ")\n", + "\n", + "# It usually takes about 5 - 10 min to finish the provision of the Redis instance.\n", + "# If the following begin_create() call still hangs for longer than that,\n", + "# please check the status of the Redis instance on the Azure portal and cancel the cell if the provision has completed.\n", + "# This sample uses a PREMIUM tier Redis SKU from family P, which may cost more than a STANDARD tier SKU from family C.\n", + "# Please choose the SKU tier and family according to your performance and pricing requirements.\n", + "\n", + "redis_arm_id = (\n", + " management_client.redis.begin_create(\n", + " resource_group_name=redis_resource_group_name,\n", + " name=redis_name,\n", + " parameters=RedisCreateParameters(\n", + " location=redis_location,\n", + " sku=Sku(name=SkuName.PREMIUM, family=SkuFamily.P, capacity=2),\n", + " ),\n", + " )\n", + " .result()\n", + " .id\n", + ")\n", + "\n", + "print(redis_arm_id)" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696554100442 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "provision-redis", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Azure Cache for Redis (option 2): use existing Redis instance\n", + "Optionally, you can reuse an existing Redis instance with the previously defined name by executing the following code." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "redis_arm_id = \"/subscriptions/{sub_id}/resourceGroups/{rg}/providers/Microsoft.Cache/Redis/{name}\".format(\n", + " sub_id=redis_subscription_id,\n", + " rg=redis_resource_group_name,\n", + " name=redis_name,\n", + ")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696554530800 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "reuse-redis", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Retrieve the user-assigned managed identity (UAI) used for feature store for materialization\n", + "This code cell retrieves the principal ID, client ID, and ARM ID property values for the UAI that will be used by the feature store for data materialization." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "from azure.mgmt.msi import ManagedServiceIdentityClient\n", + "\n", + "uai_arm_id = fs_client.feature_stores.get(\n", + " featurestore_name\n", + ").materialization_identity.resource_id\n", + "uai_principal_id = fs_client.feature_stores.get(\n", + " featurestore_name\n", + ").materialization_identity.principal_id\n", + "uai_client_id = fs_client.feature_stores.get(\n", + " featurestore_name\n", + ").materialization_identity.client_id\n", + "\n", + "print(\"uai_principal_id:\" + uai_principal_id)\n", + "print(\"uai_client_id:\" + uai_client_id)\n", + "print(\"uai_arm_id:\" + uai_arm_id)" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1696554548087 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "retrieve-uai", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "# Step 1: Attach online materialization store to the feature store\n", + "Attach the Azure Cache for Redis to the feature store to be used as the online materialization store." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "from azure.ai.ml.entities import (\n", + " ManagedIdentityConfiguration,\n", + " FeatureStore,\n", + " MaterializationStore,\n", + ")\n", + "\n", + "online_store = MaterializationStore(type=\"redis\", target=redis_arm_id)\n", + "\n", + "materialization_identity1 = ManagedIdentityConfiguration(\n", + " client_id=uai_client_id, principal_id=uai_principal_id, resource_id=uai_arm_id\n", + ")\n", + "\n", + "\n", + "ml_client = MLClient(\n", + " AzureMLOnBehalfOfCredential(),\n", + " subscription_id=featurestore_subscription_id,\n", + " resource_group_name=featurestore_resource_group_name,\n", + ")\n", + "\n", + "fs = FeatureStore(\n", + " name=featurestore_name,\n", + " online_store=online_store,\n", + " materialization_identity=materialization_identity1,\n", + ")\n", + "\n", + "fs_poller = ml_client.feature_stores.begin_create(fs, update_dependent_resources=True)\n", + "print(fs_poller.result())" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1684887054700 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "attach-online-store", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "# Step 2: Materialize `accounts` feature set data to online store" + ], + "metadata": {} + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Enable materialization on the `accounts` feature set\n", + "In the previous parts of the tutorial series, we did **not** materialize the accounts feature set since it had precomputed features and was used only for batch inference scenarios. In this step we will enable online materialization so that the features are available in the online store with low latency access. We will also enable offline materialization for consistency. Enabling offline materialization is optional." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "from azure.ai.ml.entities import (\n", + " MaterializationSettings,\n", + " MaterializationComputeResource,\n", + ")\n", + "\n", + "# Turn on both offline and online materialization on the \"accounts\" featureset.\n", + "\n", + "accounts_fset_config = fs_client._featuresets.get(name=\"accounts\", version=version)\n", + "\n", + "accounts_fset_config.materialization_settings = MaterializationSettings(\n", + " offline_enabled=True,\n", + " online_enabled=True,\n", + " resource=MaterializationComputeResource(instance_type=\"standard_e8s_v3\"),\n", + " spark_configuration={\n", + " \"spark.driver.cores\": 4,\n", + " \"spark.driver.memory\": \"36g\",\n", + " \"spark.executor.cores\": 4,\n", + " \"spark.executor.memory\": \"36g\",\n", + " \"spark.executor.instances\": 2,\n", + " },\n", + " schedule=None,\n", + ")\n", + "\n", + "fs_poller = fs_client.feature_sets.begin_create_or_update(accounts_fset_config)\n", + "print(fs_poller.result())" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1685121352342 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "enable-accounts-material", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Backfill the `account` feature set\n", + "`backfill` command backfills data to all the materialization stores that are enabled for this feature set. In this case both offline and online materialization is enabled. Therefore `backfill` will be performed on both offline and online materialization stores." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "from datetime import datetime, timedelta\n", + "\n", + "# Trigger backfill on the \"accounts\" feature set.\n", + "# Backfill from 01/01/2023 to all the way to 3 hours ago.\n", + "\n", + "st = datetime(2020, 1, 1, 0, 0, 0, 0)\n", + "ed = datetime.now() - timedelta(hours=3)\n", + "\n", + "poller = fs_client.feature_sets.begin_backfill(\n", + " name=\"accounts\",\n", + " version=version,\n", + " feature_window_start_time=st,\n", + " feature_window_end_time=ed,\n", + ")\n", + "print(poller.result().job_id)" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "name": "start-accounts-backfill" + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "The following code cell tracks completion of the backfill job. Using the premium tier Azure Cache for Redis provisioned earlier, this step may take approximately 10 minutes to complete." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "code", + "source": [ + "# Get the job URL, and stream the job logs.\n", + "# With PREMIUM Redis SKU, SKU family \"P\", and cache capacity 2,\n", + "# it takes approximately 10 minutes to complete.\n", + "fs_client.jobs.stream(poller.result().job_id)" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "name": "track-accounts-backfill", + "tags": [ + "active-ipynb" + ] + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "# Step 3: Materialize `transactions` feature set data to the online store\n", + "\n", + "In the previous tutorials, we materialized data of the `transactions` feature set to the offline materialization store. In this step we will:\n", + "\n", + "1. Enable online materilization for the `transactions` feature set." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "# Enable materialization to online store for the \"transactions\" feature set.\n", + "\n", + "transactions_fset_config = fs_client._featuresets.get(\n", + " name=\"transactions\", version=version\n", + ")\n", + "transactions_fset_config.materialization_settings.online_enabled = True\n", + "\n", + "fs_poller = fs_client.feature_sets.begin_create_or_update(transactions_fset_config)\n", + "print(fs_poller.result())" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1684887083625 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "enable-transact-material", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "markdown", + "source": [ + "2. Backfill the data to both the online and offline materialization store to ensure that both have the latest data. Note that recurrent materialization job, which was setup earlier in the tutorial 2 of this series, will now materialize data to both online and offline materialization stores." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "# Trigger backfill on the \"transactions\" feature set to fill in the online/offline store.\n", + "# Backfill from 01/01/2023 to all the way to 3 hours ago.\n", + "\n", + "from datetime import datetime, timedelta\n", + "\n", + "st = datetime(2020, 1, 1, 0, 0, 0, 0)\n", + "ed = datetime.now() - timedelta(hours=3)\n", + "\n", + "\n", + "poller = fs_client.feature_sets.begin_backfill(\n", + " name=\"transactions\",\n", + " version=version,\n", + " feature_window_start_time=st,\n", + " feature_window_end_time=ed,\n", + ")\n", + "print(poller.result().job_id)" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1685571817460 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "start-transact-material", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "markdown", + "source": [ + "The following code cell tracks completion of the backfill job. Using the premium tier Azure Cache for Redis provisioned earlier, this step may take approximately 5 minutes to complete." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "# Get the job URL, and stream the job logs.\n", + "# With PREMIUM Redis SKU, SKU family \"P\", and cache capacity 2,\n", + "# it takes approximately 5 minutes to complete.\n", + "fs_client.jobs.stream(poller.result().job_id)" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1685572796715 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "track-transact-material", + "nteract": { + "transient": { + "deleting": false + } + }, + "tags": [ + "active-ipynb" + ] + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "# Step 4: Test locally\n", + "In this step we will use our development environment (i.e. this notebook) to lookup features from online materialization store. " + ], + "metadata": {} + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "First, we will parse the list of features from the existing feature retrieval specification:" + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "# Parse the list of features from the existing feature retrieval specification.\n", + "feature_retrieval_spec_folder = root_dir + \"/project/fraud_model/feature_retrieval_spec\"\n", + "\n", + "features = featurestore.resolve_feature_retrieval_spec(feature_retrieval_spec_folder)\n", + "\n", + "features" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1685132938320 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "parse-feat-list", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "Next, we will get feature values from the online materialization store:" + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "from azureml.featurestore import init_online_lookup\n", + "import time\n", + "\n", + "# Initialize the online store client.\n", + "init_online_lookup(features, AzureMLOnBehalfOfCredential())" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1685132960042 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "init-online-lookup", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "markdown", + "source": [ + "Now, we will prepare some observation data for testing and use it to lookup features from the online materialization store. During online lookup, it may happen that the keys (`accountID`) defined in the observation sample data do not exist in the Redis (due to `TTL`). If this happens:\n", + "1. Open Azure portal.\n", + "2. Navigate to the Redis instance. \n", + "3. Open console for the Redis instance and check for existing keys using command `KEYS *`.\n", + "4. Replace `accountID` values in the sample observation data with the existing keys." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "import pyarrow\n", + "from azureml.featurestore import get_online_features\n", + "\n", + "# Prepare test observation data\n", + "obs = pyarrow.Table.from_pydict(\n", + " {\"accountID\": [\"A985156952816816\", \"A1055521248929430\", \"A914800935560176\"]}\n", + ")\n", + "\n", + "# Online lookup:\n", + "# It may happen that the keys defined in the observation sample data above does not exist in the Redis (due to TTL).\n", + "# If this happens, go to Azure portal and navigate to the Redis instance, open its console and check for existing keys using command \"KEYS *\"\n", + "# and replace the sample observation data with the existing keys.\n", + "df = get_online_features(features, obs)\n", + "df" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1685132964129 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "online-feat-loockup", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "Now that we have successfully looked up features from the online store, we will test online features using Azure Machine Learning managed online endpoint." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "# Step 5: Test online features from Azure Machine Learning managed online endpoint\n", + "Managed online endpoint provide capability for deploying and scoring models for online/realtime inference. Optionally, you can use any inference technology of your choice (like kubernetes).\n", + "\n", + "As a part of this step, we will perform the following actions:\n", + "\n", + "1. Create an Azure Machine Learning managed online endpoint.\n", + "1. Grant required role-based access control (RBAC) permissions.\n", + "1. Deploy the model that we trained in the tutorial 3 of this tutorial series. The scoring script used in this step will have the code to lookup online features.\n", + "2. Perform scoring of the model with sample data. You will see that the online features are looked up and model scoring is completed successfully." + ], + "metadata": {} + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "## Create Azure Machine Learning managed online endpoint\n", + "You can learn more about managed online endpoints [here](https://learn.microsoft.com/azure/machine-learning/how-to-deploy-online-endpoints?view=azureml-api-2&tabs=azure-cli). Note that using managed feature store API, you can also lookup online features from other inference platforms based on your need.\n", + "\n", + "Following code defines a managed online endpoint with name `fraud-model`." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "from azure.ai.ml.entities import (\n", + " ManagedOnlineDeployment,\n", + " ManagedOnlineEndpoint,\n", + " Model,\n", + " CodeConfiguration,\n", + " Environment,\n", + ")\n", + "\n", + "\n", + "endpoint_name = \"fraud-model\"\n", + "\n", + "endpoint = ManagedOnlineEndpoint(name=endpoint_name, auth_mode=\"key\")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1685155956798 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "define-endpoint", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "markdown", + "source": [ + "Excute the following code cell to create the managed online endpoint defined in the previous code cell." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "ws_client.online_endpoints.begin_create_or_update(endpoint).result()" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1685156110582 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "create-endpoint", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "## Grant required RBAC permissions\n", + "In this step, we will grant required RBAC permissions to the managed online endpoint on the Redis instance and feature store. The scoring code in the model deployment will need these RBAC permissions to successfully lookup features from the online store using the managed feature store API." + ], + "metadata": { + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Get managed identity of the managed online endpoint" + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "# Get managed identity of the managed online endpoint.\n", + "endpoint = ws_client.online_endpoints.get(endpoint_name)\n", + "\n", + "model_endpoint_msi_principal_id = endpoint.identity.principal_id\n", + "model_endpoint_msi_principal_id" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1685156114744 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "get-endpoint-identity", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Grant `Contributor` role to the online endpoint managed identity on the Azure Cache for Redis \n", + "We will grant `Contributor` role to the online endpoint managed identity on the Redis instance. This RBAC permission is needed to materialize data into the Redis online store." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "from azure.core.exceptions import ResourceExistsError\n", + "from azure.mgmt.msi import ManagedServiceIdentityClient\n", + "from azure.mgmt.msi.models import Identity\n", + "from azure.mgmt.authorization import AuthorizationManagementClient\n", + "from azure.mgmt.authorization.models import RoleAssignmentCreateParameters\n", + "from uuid import uuid4\n", + "\n", + "auth_client = AuthorizationManagementClient(\n", + " AzureMLOnBehalfOfCredential(), redis_subscription_id\n", + ")\n", + "\n", + "scope = f\"/subscriptions/{redis_subscription_id}/resourceGroups/{redis_resource_group_name}/providers/Microsoft.Cache/Redis/{redis_name}\"\n", + "\n", + "\n", + "# The role definition ID for the \"contributor\" role on the redis cache\n", + "# You can find other built-in role definition IDs in the Azure documentation\n", + "role_definition_id = f\"/subscriptions/{redis_subscription_id}/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c\"\n", + "\n", + "# Generate a random UUID for the role assignment name\n", + "role_assignment_name = str(uuid4())\n", + "\n", + "# Set up the role assignment creation parameters\n", + "role_assignment_params = RoleAssignmentCreateParameters(\n", + " principal_id=model_endpoint_msi_principal_id,\n", + " role_definition_id=role_definition_id,\n", + " principal_type=\"ServicePrincipal\",\n", + ")\n", + "\n", + "# Create the role assignment\n", + "try:\n", + " # Create the role assignment\n", + " result = auth_client.role_assignments.create(\n", + " scope, role_assignment_name, role_assignment_params\n", + " )\n", + " print(\n", + " f\"Redis RBAC granted to managed identity '{model_endpoint_msi_principal_id}'.\"\n", + " )\n", + "except ResourceExistsError:\n", + " print(\n", + " f\"Redis RBAC already exists for managed identity '{model_endpoint_msi_principal_id}'.\"\n", + " )" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1685156142743 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "endpoint-redis-rbac", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Grant `AzureML Data Scientist` role to the online endpoint managed identity on the feature store\n", + "We will grant `AzureML Data Scientist` role to the online endpoint managed identity on the feature store. This RBAC permission is required for successful deployment of the model to the online endpoint." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "auth_client = AuthorizationManagementClient(\n", + " AzureMLOnBehalfOfCredential(), featurestore_subscription_id\n", + ")\n", + "\n", + "scope = f\"/subscriptions/{featurestore_subscription_id}/resourceGroups/{featurestore_resource_group_name}/providers/Microsoft.MachineLearningServices/workspaces/{featurestore_name}\"\n", + "\n", + "# The role definition ID for the \"AzureML Data Scientist\" role.\n", + "# You can find other built-in role definition IDs in the Azure documentation.\n", + "role_definition_id = f\"/subscriptions/{featurestore_subscription_id}/providers/Microsoft.Authorization/roleDefinitions/f6c7c914-8db3-469d-8ca1-694a8f32e121\"\n", + "\n", + "# Generate a random UUID for the role assignment name.\n", + "role_assignment_name = str(uuid4())\n", + "\n", + "# Set up the role assignment creation parameters.\n", + "role_assignment_params = RoleAssignmentCreateParameters(\n", + " principal_id=model_endpoint_msi_principal_id,\n", + " role_definition_id=role_definition_id,\n", + " principal_type=\"ServicePrincipal\",\n", + ")\n", + "\n", + "# Create the role assignment\n", + "try:\n", + " # Create the role assignment\n", + " result = auth_client.role_assignments.create(\n", + " scope, role_assignment_name, role_assignment_params\n", + " )\n", + " print(\n", + " f\"Feature store RBAC granted to managed identity '{model_endpoint_msi_principal_id}'.\"\n", + " )\n", + "except ResourceExistsError:\n", + " print(\n", + " f\"Feature store RBAC already exists for managed identity '{model_endpoint_msi_principal_id}'.\"\n", + " )" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1685156168113 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "endpoint-fs-rbac", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Deploy the model to the online endpoint\n", + "First, inspect the scoring script `project/fraud_model/online_inference/src/scoring.py`. The scoring script performs the following tasks:\n", + "\n", + "1. Load the feature metadata from the feature retrieval specification that was packaged along with the model during model training (tutorial 3 of this tutorial series). This specification has features from both `transactions` and `accounts` feature sets.\n", + "2. When an input inference request is received, the scoring code looks up the online features using the index keys from the request. In this case for both feature sets, the index column is the `accountID`.\n", + "3. Passes the features to the model to perform inference and returs the response, a boolean value representing the variable `is_fraud`.\n", + "\n", + "First, create managed online deployment definition for model deployment by executing the following code cell:" + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "deployment = ManagedOnlineDeployment(\n", + " name=\"green\",\n", + " endpoint_name=endpoint_name,\n", + " model=\"azureml:fraud_model:1\",\n", + " code_configuration=CodeConfiguration(\n", + " code=root_dir + \"/project/fraud_model/online_inference/src/\",\n", + " scoring_script=\"scoring.py\",\n", + " ),\n", + " environment=Environment(\n", + " conda_file=root_dir + \"/project/fraud_model/online_inference/conda.yml\",\n", + " image=\"mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04\",\n", + " ),\n", + " instance_type=\"Standard_DS3_v2\",\n", + " instance_count=1,\n", + ")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1685156215970 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "define-online-deployment", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "cell_type": "markdown", + "source": [ + "Next, deploy the model to online enpoint by executing the following code cell. Note that it may take approximately 4-5 minutes to deploy the model." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "# Model deployment to online enpoint may take 4-5 minutes.\n", + "ws_client.online_deployments.begin_create_or_update(deployment).result()" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1685156672789 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "begin-online-deployment", + "nteract": { + "transient": { + "deleting": false + } + } + } + }, + { + "attachments": {}, + "cell_type": "markdown", + "source": [ + "### Test online deployment with mock data\n", + "Finally, execute the following code to test the online deployment using the mock data. You should see `0` or `1` as the output of this cell." + ], + "metadata": {} + }, + { + "cell_type": "code", + "source": [ + "# Test the online deployment using the mock data.\n", + "sample_data = root_dir + \"/project/fraud_model/online_inference/test.json\"\n", + "ws_client.online_endpoints.invoke(\n", + " endpoint_name=endpoint_name, request_file=sample_data, deployment_name=\"green\"\n", + ")" + ], + "outputs": [], + "execution_count": null, + "metadata": { + "gather": { + "logged": 1685157485313 + }, + "jupyter": { + "outputs_hidden": false, + "source_hidden": false + }, + "name": "test-online-deployment", + "nteract": { + "transient": { + "deleting": false + } + } + } + } + ], + "metadata": { + "celltoolbar": "Edit Metadata", + "kernel_info": { + "name": "synapse_pyspark" + }, + "kernelspec": { + "name": "synapse_pyspark", + "language": "Python", + "display_name": "Synapse PySpark" + }, + "language_info": { + "name": "python", + "version": "3.8.0", + "mimetype": "text/x-python", + "file_extension": ".py", + "pygments_lexer": "ipython", + "codemirror_mode": "ipython", + "nbconvert_exporter": "python" + }, + "microsoft": { + "host": { + "AzureML": { + "notebookHasBeenCompleted": true + } + }, + "ms_spell_check": { + "ms_spell_check_language": "en" + } + }, + "nteract": { + "version": "nteract-front-end@1.0.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file diff --git a/sdk/python/featurestore_sample/notebooks/sdk_only/4. Enable recurrent materialization and run batch inference.ipynb b/sdk/python/featurestore_sample/notebooks/sdk_only/4. Enable recurrent materialization and run batch inference.ipynb deleted file mode 100644 index db6c92ec1a..0000000000 --- a/sdk/python/featurestore_sample/notebooks/sdk_only/4. Enable recurrent materialization and run batch inference.ipynb +++ /dev/null @@ -1,623 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "# Tutorial #4: Enable recurrent materialization and run batch inference" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "_Managed feature store is in private preview, which is subject to the [Supplemental Terms of Use for Microsoft Azure Previews](https://azure.microsoft.com/en-us/support/legal/preview-supplemental-terms/)_" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "In this tutorial series you will experience how features seamlessly integrates all the phases of ML lifecycle: Prototyping features, training and operationalizing.\n", - "\n", - "In the previous part of the tutorial you learnt to experiment with features, train the model and register the model along with the feature-retrieval spec. In this tutorial you will learn how to run batch inference for the registered model.\n", - "\n", - "You will perform the following:\n", - "- Enable recurrent materialization for the `transactions` feature set\n", - "- Run batch inference pipeline on the registered model" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "# Prerequisites\n", - "1. Please ensure you have executed the previous parts of this tutorial series" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "# Setup" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Configure Azure ML spark notebook\n", - "\n", - "1. In the \"Compute\" dropdown in the top nav, select \"Serverless Spark Compute\". \n", - "1. Click on \"configure session\" in top status bar -> click on \"Python packages\" -> click on \"upload conda file\" -> select the file azureml-examples/sdk/python/featurestore-sample/project/env/conda.yml from your local machine; Also increase the session time out (idle time) if you want to avoid running the prerequisites frequently\n", - "\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Start spark session" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683429713573 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "start-spark-session", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# run this cell to start the spark session (any code block will start the session ). This can take around 10 mins.\n", - "print(\"start spark session\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Setup root directory for the samples" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683430082276 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "root-dir", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "import os\n", - "\n", - "# please update the dir to ./Users/{your-alias} (or any custom directory you uploaded the samples to).\n", - "# You can find the name from the directory structure inm the left nav\n", - "root_dir = \"./Users//featurestore_sample\"\n", - "\n", - "if os.path.isdir(root_dir):\n", - " print(\"The folder exists.\")\n", - "else:\n", - " print(\"The folder does not exist. Please create or fix the path\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Initialize the project workspace CRUD client\n", - "This is the current workspace where you will be running the tutorial notebook from" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683430126255 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "init-ws-crud-client", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "### Initialize the MLClient of this project workspace\n", - "import os\n", - "from azure.ai.ml import MLClient\n", - "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", - "\n", - "project_ws_sub_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", - "project_ws_rg = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", - "project_ws_name = os.environ[\"AZUREML_ARM_WORKSPACE_NAME\"]\n", - "version = \"\"\n", - "\n", - "# connect to the project workspace\n", - "ws_client = MLClient(\n", - " AzureMLOnBehalfOfCredential(), project_ws_sub_id, project_ws_rg, project_ws_name\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Initialize the feature store CRUD client\n", - "Ensure you update the `featurestore_name` to reflect what you created in part 1 of this tutorial" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683430135866 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "init-fs-crud-client", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.ai.ml import MLClient\n", - "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", - "\n", - "# feature store\n", - "featurestore_name = \"my-featurestore\" # use the same name from part #1 of the tutorial\n", - "featurestore_subscription_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", - "featurestore_resource_group_name = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", - "\n", - "# feature store ml client\n", - "fs_client = MLClient(\n", - " AzureMLOnBehalfOfCredential(),\n", - " featurestore_subscription_id,\n", - " featurestore_resource_group_name,\n", - " featurestore_name,\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Initialize the feature store core sdk client" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683430153396 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "init-fs-core-sdk", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# feature store client\n", - "from azureml.featurestore import FeatureStoreClient\n", - "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", - "\n", - "featurestore = FeatureStoreClient(\n", - " credential=AzureMLOnBehalfOfCredential(),\n", - " subscription_id=featurestore_subscription_id,\n", - " resource_group_name=featurestore_resource_group_name,\n", - " name=featurestore_name,\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Step 1: Enable recurrent materialization on the `transactions` featureset\n", - "\n", - "In part 2 of this tutorial you enabled materialization and performed backfill on the transactions feature set. Backfill is an ondemand one-time operation to compute and store feature values in the materialization store. However when you want to perform inference of the model in production, you might want to keep the materilization store upto date by setting up recurrent materialization jobs. These jobs run on user defined schedule\n", - "The recurrent job schedule works in the following way: \n", - "- A window is defined by the interval and frequency. E.g., interval = 3 and frequency = Hour define a 3-hour window\n", - "- The first window starts at the start_time defined in the RecurenceTrigger, and so on.\n", - "- The first recurrent job will be submitted at the begining of the next window after the update time.\n", - "- Later recurrent jobs will be submitted at every window after the first job.\n", - "\n", - "As explained in the previous parts of the tutorials, once data is materialized (backfill/recurrent materialization), feature retrieval will use the materialized data by default." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683430218931 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "enable-recurrent-mat-txns-fset", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from datetime import datetime\n", - "from azure.ai.ml.entities import RecurrenceTrigger\n", - "\n", - "transactions_fset_config = fs_client.feature_sets.get(\n", - " name=\"transactions\", version=version\n", - ")\n", - "\n", - "# create a schedule that runs the materialization job every 3 hours\n", - "transactions_fset_config.materialization_settings.schedule = RecurrenceTrigger(\n", - " interval=3, frequency=\"Hour\", start_time=datetime(2023, 4, 15, 0, 4, 10, 0)\n", - ")\n", - "\n", - "fs_poller = fs_client.feature_sets.begin_create_or_update(transactions_fset_config)\n", - "\n", - "print(fs_poller.result())" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### (Optional) Save the feature set asset yaml with the updated settings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1681791896733 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "dump-txn-fset-with-mat-yaml", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "## uncomment and run\n", - "# transactions_fset_config.dump(root_dir + \"/featurestore/featuresets/transactions/featureset_asset_offline_enabled_with_schedule.yaml\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Track status of the recurrent materialization jobs in the feature store studio UI\n", - "This job will every three hours. \n", - "\n", - "__Action__:\n", - "\n", - "1. Feel free to execute the next step for now (batch inference).\n", - "1. In three hours check the recurrent job status via the UI" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Step 2: Run the batch-inference pipeline\n", - "\n", - "In this step you will manually trigger the batch inference pipeline. In a production scenario, this could be trigerred by a ci/cd pipeline based on model registration/approval.\n", - "\n", - "The batch-inference has the following steps:\n", - "\n", - "1. Feature retrieval step: This use the same built-in feature retrieval component that we used in the training pipeline in the part 3 of the tutorial. Incase of training pipeline, we provided feature retreival spec as an input to the component. However in case of batch inference we will pass the registered model as the input and the component will look for feature retrieval spec in the model artifact. Another difference is that in case of training, the observation data had the target variable, however incase of batch inference it will not be present. The feature retrieval step will join the observation data with the features and output the data for batch inference.\n", - "1. Batch inference: This step uses the batch inference input data from previous step, runs inference on the model and outputs the data by appending the predicted value.\n", - "\n", - "__Note:__ In this example we use a job for batch inference. You can also use Azure ML's batch endpoints." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1683430315364 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "run-batch-inf-pipeline", - "nteract": { - "transient": { - "deleting": false - } - }, - "tags": [ - "active-ipynb" - ] - }, - "outputs": [], - "source": [ - "from azure.ai.ml import load_job # will be used later\n", - "\n", - "# set the batch inference pipeline path\n", - "batch_inference_pipeline_path = (\n", - " root_dir + \"/project/fraud_model/pipelines/batch_inference_pipeline.yaml\"\n", - ")\n", - "batch_inference_pipeline_definition = load_job(source=batch_inference_pipeline_path)\n", - "\n", - "# run the training pipeline\n", - "batch_inference_pipeline_job = ws_client.jobs.create_or_update(\n", - " batch_inference_pipeline_definition\n", - ")\n", - "\n", - "# stream the run logs\n", - "ws_client.jobs.stream(batch_inference_pipeline_job.name)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "#### Inspect the batch inference output data\n", - "1. In the pipeline view, double click on `inference_step` -> in `outputs` card, copy the `Data` field. It will be something like `azureml_995abbc2-3171-461e-8214-c3c5d17ede83_output_data_data_with_prediction:1`. \n", - "1. Paste it in the below cell with name and version separately (notice that the last character is the version, separated by a `:`).\n", - "1. You will see the `predict_is_fraud` column generated by the batch inference pipeline\n", - "\n", - "Explanation: Since we did not provide a `name` and `version` in the `outputs` of the `inference_step` in the batch inference pipeline (`/project/fraud_mode/pipelines/batch_inference_pipeline.yaml`), the system created an untracked data asset with a guid as name and version as 1. In the next cell we will be getting the data path from the asset and displaying it." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1681446888800 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "inspect-batch-inf-output-data", - "nteract": { - "transient": { - "deleting": false - } - }, - "tags": [ - "active-ipynb" - ] - }, - "outputs": [], - "source": [ - "inf_data_output = ws_client.data.get(\n", - " name=\"azureml_1c106662-aa5e-4354-b5f9-57c1b0fdb3a7_output_data_data_with_prediction\",\n", - " version=\"1\",\n", - ")\n", - "inf_output_df = spark.read.parquet(inf_data_output.path)\n", - "display(inf_output_df.head(5))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Cleanup\n", - "If you created a resource group for the tutorial, you can delete the resource group to delete all the resources associated with this tutorial.\n", - "\n", - "Otherwise, you can delete the resources individually:\n", - "\n", - "* Delete the feature store: Go to the resource group in the azure portal, select the feature store and delete it\n", - "* Follow the instructions [here](https://review.learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-manage-user-assigned-managed-identities?pivots=identity-mi-methods-azp&view=azureml-api-2#delete-a-user-assigned-managed-identity) to delete the user assigned managed identity\n", - "* Delete the offline store (storage account): Go to the resource group in the azure portal, select the storage you created and delete it" - ] - } - ], - "metadata": { - "celltoolbar": "Edit Metadata", - "kernel_info": { - "name": "synapse_pyspark" - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - }, - "microsoft": { - "host": { - "AzureML": { - "notebookHasBeenCompleted": true - } - }, - "ms_spell_check": { - "ms_spell_check_language": "en" - } - }, - "nteract": { - "version": "nteract-front-end@1.0.0" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/sdk/python/featurestore_sample/notebooks/sdk_only/5. Enable online store and run online inference.ipynb b/sdk/python/featurestore_sample/notebooks/sdk_only/5. Enable online store and run online inference.ipynb deleted file mode 100644 index 1251cb2421..0000000000 --- a/sdk/python/featurestore_sample/notebooks/sdk_only/5. Enable online store and run online inference.ipynb +++ /dev/null @@ -1,1393 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Tutorial #5: Enable online materialization and run online inference\n", - "So far you have learned how to develop features, materialize them to offline materialization store, perform training, and perform batch inference. In this tutorial you will learn how to use feature store for online/realtime inference use cases.\n", - "\n", - "You will perform the following steps:\n", - "\n", - "1. Setup Azure Cache for Redis.\n", - "1. Attach the cache to feature store as the online materialization store and grant necessary permissions.\n", - "1. Materialize feature sets to the online store.\n", - "1. Test online deployment with mock data.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Prerequisites\n", - "1. Before proceeding, please ensure that you have already completed previous four turorials of this tutorial series. We will be reusing feature store and some other resources created in the previous tutorials." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Prepare the notebook environment for development\n", - "Note: This tutorial uses Azure Machine Learning notebook with **Serverless Spark Compute**.\n", - "\n", - "1. Clone the examples repository to your local machine: To run the tutorial, first clone the [examples repository - (azureml-examples)](https://github.com/azure/azureml-examples) with this command:\n", - "\n", - " `git clone --depth 1 https://github.com/Azure/azureml-examples`\n", - "\n", - " You can also download a zip file from the [examples repository (azureml-examples)](https://github.com/azure/azureml-examples). At this page, first select the `code` dropdown, and then select `Download ZIP`. Then, unzip the contents into a folder on your local device.\n", - "\n", - "2. Running the tutorial:\n", - "* Option 1: Create a new notebook, and execute the instructions in this document step by step. \n", - "* Option 2: Open the existing notebook `featurestore_sample/notebooks/sdk_only/5. Enable online store and run online inference.ipynb`. You may keep this document open and refer to it for additional explanation and documentation links.\n", - "\n", - " 1. Select **Serverless Spark Compute** in the top navigation **Compute** dropdown. This operation might take one to two minutes. Wait for a status bar in the top to display **Configure session**.\n", - " 2. Select **Configure session** in the top status bar.\n", - " 3. Select **Python packages**.\n", - " 4. Select **Upload conda file**.\n", - " 5. Select file `azureml-examples/sdk/python/featurestore-sample/project/env/online.yml` located on your local device.\n", - " 6. (Optional) Increase the session time-out (idle time in minutes) to reduce the serverless spark cluster startup time." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "# Set up" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Start Spark session\n", - "Execute the following code cell to start the Spark session. It wil take approximately 10 minutes to install all dependencies and start the Spark session." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685571267325 - }, - "name": "start-spark-session" - }, - "outputs": [], - "source": [ - "# Run this cell to start the spark session (any code block will start the session ). This can take approximately 10 mins.\n", - "print(\"start spark session\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Setup root directory for the samples" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685571691922 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "root-dir", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "import os\n", - "\n", - "# Please update the dir to ./Users/{your-alias} (or any custom directory you uploaded the samples to).\n", - "# You can find the name from the directory structure inm the left navigation panel.\n", - "root_dir = \"./Users//featurestore_sample\"\n", - "\n", - "if os.path.isdir(root_dir):\n", - " print(\"The folder exists.\")\n", - "else:\n", - " print(\"The folder does not exist. Please create or fix the path\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Initialize the project workspace CRUD client\n", - "The `MLClient` for the current workspace, where you are running this tutorial notebook, will be used for create, read, update, and delete (CRUD) operations." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685571719727 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "init-prj-ws-client", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "import os\n", - "from azure.ai.ml import MLClient\n", - "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", - "\n", - "project_ws_sub_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", - "project_ws_rg = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", - "project_ws_name = os.environ[\"AZUREML_ARM_WORKSPACE_NAME\"]\n", - "version = \"\"\n", - "\n", - "# Connect to the project workspace\n", - "ws_client = MLClient(\n", - " AzureMLOnBehalfOfCredential(), project_ws_sub_id, project_ws_rg, project_ws_name\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Initialize the CRUD client of the feature store workspace\n", - "The `MLClient` for the feature store workspace for create, read, update, and delete (CRUD) operations on feature store workspace." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "name": "init-fs-ws-client" - }, - "outputs": [], - "source": [ - "from azure.ai.ml import MLClient\n", - "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", - "\n", - "# Feature store\n", - "featurestore_name = \"my-featurestore\" # use the same name from part #1 of the tutorial\n", - "featurestore_subscription_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", - "featurestore_resource_group_name = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", - "\n", - "# Feature store MLClient\n", - "fs_client = MLClient(\n", - " AzureMLOnBehalfOfCredential(),\n", - " featurestore_subscription_id,\n", - " featurestore_resource_group_name,\n", - " featurestore_name,\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Initialize the feature store core SDK client\n", - "This tutorial uses the Python feature store core SDK (`azureml-featurestore`). The SDK client initialized here is used for create, read, update, and delete (CRUD) operations, on feature stores, feature sets, and feature store entities." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "name": "init-fs-core-sdk" - }, - "outputs": [], - "source": [ - "from azureml.featurestore import FeatureStoreClient\n", - "from azure.ai.ml.identity import AzureMLOnBehalfOfCredential\n", - "\n", - "featurestore = FeatureStoreClient(\n", - " credential=AzureMLOnBehalfOfCredential(),\n", - " subscription_id=featurestore_subscription_id,\n", - " resource_group_name=featurestore_resource_group_name,\n", - " name=featurestore_name,\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Setup Azure cache for Redis\n", - "This tutorial uses Azure Cache for Redis as the online materialization store. You can either create a new Redis instance or reuse an existing one." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Set values for the Azure Cache for Redis that will be used as online materialization store\n", - "In the following code cell, define the name of the Azure Cache for Redis that you want to create or reuse. Optionally, you can override other default settings." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685571729309 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "redis-settings", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "ws_location = ws_client.workspaces.get(ws_client.workspace_name).location\n", - "\n", - "redis_subscription_id = os.environ[\"AZUREML_ARM_SUBSCRIPTION\"]\n", - "redis_resource_group_name = os.environ[\"AZUREML_ARM_RESOURCEGROUP\"]\n", - "redis_name = \"\"\n", - "redis_location = ws_location" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Azure Cache for Redis (option 1): create new Redis instance\n", - "You can select the Redis cache tier (basic, standard, premium, or enterprise). You should choose a SKU family that is available for the selected cache tier. See this documentation page to learn more about [how selecting different tiers may affect cache performance](https://learn.microsoft.com/azure/azure-cache-for-redis/cache-best-practices-performance). See this link learn more about [pricing for different SKU tiers and families of Azure Cache for Redis](https://azure.microsoft.com/en-us/pricing/details/cache/).\n", - "\n", - "Execute the following code cell to create an Azure Cache for Redis with premium tier, SKU family `P` and cache capacity 2. It may take approximately 5-10 minutes to provision the Redis instance." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685571734517 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "provision-redis", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.mgmt.redis import RedisManagementClient\n", - "from azure.mgmt.redis.models import RedisCreateParameters, Sku, SkuFamily, SkuName\n", - "\n", - "management_client = RedisManagementClient(\n", - " AzureMLOnBehalfOfCredential(), redis_subscription_id\n", - ")\n", - "\n", - "# It usually takes about 5 - 10 min to finish the provision of the Redis instance.\n", - "# If the following begin_create() call still hangs for longer than that,\n", - "# please check the status of the Redis instance on the Azure portal and cancel the cell if the provision has completed.\n", - "# This sample uses a PREMIUM tier Redis SKU from family P, which may cost more than a STANDARD tier SKU from family C.\n", - "# Please choose the SKU tier and family according to your performance and pricing requirements.\n", - "\n", - "redis_arm_id = (\n", - " management_client.redis.begin_create(\n", - " resource_group_name=redis_resource_group_name,\n", - " name=redis_name,\n", - " parameters=RedisCreateParameters(\n", - " location=redis_location,\n", - " sku=Sku(name=SkuName.PREMIUM, family=SkuFamily.P, capacity=2),\n", - " ),\n", - " )\n", - " .result()\n", - " .id\n", - ")\n", - "\n", - "print(redis_arm_id)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Azure Cache for Redis (option 2): use existing Redis instance\n", - "Optionally, you can reuse an existing Redis instance with the previously defined name by executing the following code." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1684886695973 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "reuse-redis", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "redis_arm_id = \"/subscriptions/{sub_id}/resourceGroups/{rg}/providers/Microsoft.Cache/Redis/{name}\".format(\n", - " sub_id=redis_subscription_id,\n", - " rg=redis_resource_group_name,\n", - " name=redis_name,\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Retrieve the user-assigned managed identity (UAI) used for feature store for materialization\n", - "This code cell retrieves the principal ID, client ID, and ARM ID property values for the UAI that will be used by the feature store for data materialization." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685571749076 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "retrieve-uai", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.mgmt.msi import ManagedServiceIdentityClient\n", - "\n", - "uai_arm_id = fs_client.feature_stores.get(\n", - " featurestore_name\n", - ").materialization_identity.resource_id\n", - "uai_principal_id = fs_client.feature_stores.get(\n", - " featurestore_name\n", - ").materialization_identity.principal_id\n", - "uai_client_id = fs_client.feature_stores.get(\n", - " featurestore_name\n", - ").materialization_identity.client_id\n", - "\n", - "print(\"uai_principal_id:\" + uai_principal_id)\n", - "print(\"uai_client_id:\" + uai_client_id)\n", - "print(\"uai_arm_id:\" + uai_arm_id)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Grant `Contributor` role to the UAI on the Azure Cache for Redis\n", - "The following code grant `Contributor` role to the UAI on the Azure Cache for Redis. This is required to write data into Redis during materialization." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1684886991067 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "uai-redis-rbac", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.core.exceptions import ResourceExistsError\n", - "from azure.mgmt.msi import ManagedServiceIdentityClient\n", - "from azure.mgmt.msi.models import Identity\n", - "from azure.mgmt.authorization import AuthorizationManagementClient\n", - "from azure.mgmt.authorization.models import RoleAssignmentCreateParameters\n", - "from uuid import uuid4\n", - "\n", - "auth_client = AuthorizationManagementClient(\n", - " AzureMLOnBehalfOfCredential(), redis_subscription_id\n", - ")\n", - "\n", - "scope = f\"/subscriptions/{redis_subscription_id}/resourceGroups/{redis_resource_group_name}/providers/Microsoft.Cache/Redis/{redis_name}\"\n", - "\n", - "\n", - "# The role definition ID for the \"contributor\" role on the redis cache\n", - "# You can find other built-in role definition IDs in the Azure documentation\n", - "role_definition_id = f\"/subscriptions/{redis_subscription_id}/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c\"\n", - "\n", - "# Generate a random UUID for the role assignment name\n", - "role_assignment_name = str(uuid4())\n", - "\n", - "# Set up the role assignment creation parameters\n", - "role_assignment_params = RoleAssignmentCreateParameters(\n", - " principal_id=uai_principal_id,\n", - " role_definition_id=role_definition_id,\n", - " principal_type=\"ServicePrincipal\",\n", - ")\n", - "\n", - "# Create the role assignment\n", - "try:\n", - " # Create the role assignment\n", - " result = auth_client.role_assignments.create(\n", - " scope, role_assignment_name, role_assignment_params\n", - " )\n", - " print(f\"redis RBAC granted to managed identity '{uai_principal_id}'.\")\n", - "except ResourceExistsError:\n", - " print(f\"redis RBAC already exists for managed identity '{uai_principal_id}'.\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Step 1: Attach online materialization store to the feature store\n", - "Attach the Azure Cache for Redis to the feature store to be used as the online materialization store." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1684887054700 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "attach-online-store", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.ai.ml.entities import (\n", - " ManagedIdentityConfiguration,\n", - " FeatureStore,\n", - " MaterializationStore,\n", - ")\n", - "\n", - "online_store = MaterializationStore(type=\"redis\", target=redis_arm_id)\n", - "\n", - "materialization_identity1 = ManagedIdentityConfiguration(\n", - " client_id=uai_client_id, principal_id=uai_principal_id, resource_id=uai_arm_id\n", - ")\n", - "\n", - "\n", - "ml_client = MLClient(\n", - " AzureMLOnBehalfOfCredential(),\n", - " subscription_id=featurestore_subscription_id,\n", - " resource_group_name=featurestore_resource_group_name,\n", - ")\n", - "\n", - "fs = FeatureStore(\n", - " name=featurestore_name,\n", - " online_store=online_store,\n", - " materialization_identity=materialization_identity1,\n", - ")\n", - "\n", - "fs_poller = ml_client.feature_stores.begin_create(fs, update_dependent_resources=True)\n", - "print(fs_poller.result())" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Step 2: Materialize `accounts` feature set data to online store" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Enable materialization on the `accounts` feature set\n", - "In the previous parts of the tutorial series, we did **not** materialize the accounts feature set since it had precomputed features and was used only for batch inference scenarios. In this step we will enable online materialization so that the features are available in the online store with low latency access. We will also enable offline materialization for consistency. Enabling offline materialization is optional." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685121352342 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "enable-accounts-material", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.ai.ml.entities import (\n", - " MaterializationSettings,\n", - " MaterializationComputeResource,\n", - ")\n", - "\n", - "# Turn on both offline and online materialization on the \"accounts\" featureset.\n", - "\n", - "accounts_fset_config = fs_client._featuresets.get(name=\"accounts\", version=version)\n", - "\n", - "accounts_fset_config.materialization_settings = MaterializationSettings(\n", - " offline_enabled=True,\n", - " online_enabled=True,\n", - " resource=MaterializationComputeResource(instance_type=\"standard_e8s_v3\"),\n", - " spark_configuration={\n", - " \"spark.driver.cores\": 4,\n", - " \"spark.driver.memory\": \"36g\",\n", - " \"spark.executor.cores\": 4,\n", - " \"spark.executor.memory\": \"36g\",\n", - " \"spark.executor.instances\": 2,\n", - " },\n", - " schedule=None,\n", - ")\n", - "\n", - "fs_poller = fs_client.feature_sets.begin_create_or_update(accounts_fset_config)\n", - "print(fs_poller.result())" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "### Backfill the `account` feature set\n", - "`backfill` command backfills data to all the materialization stores that are enabled for this feature set. In this case both offline and online materialization is enabled. Therefore `backfill` will be performed on both offline and online materialization stores." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "name": "start-accounts-backfill" - }, - "outputs": [], - "source": [ - "from datetime import datetime, timedelta\n", - "\n", - "# Trigger backfill on the \"accounts\" feature set.\n", - "# Backfill from 01/01/2023 to all the way to 3 hours ago.\n", - "\n", - "st = datetime(2020, 1, 1, 0, 0, 0, 0)\n", - "ed = datetime.now() - timedelta(hours=3)\n", - "\n", - "poller = fs_client.feature_sets.begin_backfill(\n", - " name=\"accounts\",\n", - " version=version,\n", - " feature_window_start_time=st,\n", - " feature_window_end_time=ed,\n", - ")\n", - "print(poller.result().job_id)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "The following code cell tracks completion of the backfill job. Using the premium tier Azure Cache for Redis provisioned earlier, this step may take approximately 10 minutes to complete." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "name": "track-accounts-backfill", - "tags": [ - "active-ipynb" - ] - }, - "outputs": [], - "source": [ - "# Get the job URL, and stream the job logs.\n", - "# With PREMIUM Redis SKU, SKU family \"P\", and cache capacity 2,\n", - "# it takes approximately 10 minutes to complete.\n", - "fs_client.jobs.stream(poller.result().job_id)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Step 3: Materialize `transactions` feature set data to the online store\n", - "\n", - "In the previous tutorials, we materialized data of the `transactions` feature set to the offline materialization store. In this step we will:\n", - "\n", - "1. Enable online materilization for the `transactions` feature set." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1684887083625 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "enable-transact-material", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# Enable materialization to online store for the \"transactions\" feature set.\n", - "\n", - "transactions_fset_config = fs_client._featuresets.get(\n", - " name=\"transactions\", version=version\n", - ")\n", - "transactions_fset_config.materialization_settings.online_enabled = True\n", - "\n", - "fs_poller = fs_client.feature_sets.begin_create_or_update(transactions_fset_config)\n", - "print(fs_poller.result())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2. Backfill the data to both the online and offline materialization store to ensure that both have the latest data. Note that recurrent materialization job, which was setup earlier in the tutorial 2 of this series, will now materialize data to both online and offline materialization stores." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685571817460 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "start-transact-material", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# Trigger backfill on the \"transactions\" feature set to fill in the online/offline store.\n", - "# Backfill from 01/01/2023 to all the way to 3 hours ago.\n", - "\n", - "from datetime import datetime, timedelta\n", - "\n", - "st = datetime(2020, 1, 1, 0, 0, 0, 0)\n", - "ed = datetime.now() - timedelta(hours=3)\n", - "\n", - "\n", - "poller = fs_client.feature_sets.begin_backfill(\n", - " name=\"transactions\",\n", - " version=version,\n", - " feature_window_start_time=st,\n", - " feature_window_end_time=ed,\n", - ")\n", - "print(poller.result().job_id)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The following code cell tracks completion of the backfill job. Using the premium tier Azure Cache for Redis provisioned earlier, this step may take approximately 5 minutes to complete." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685572796715 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "track-transact-material", - "nteract": { - "transient": { - "deleting": false - } - }, - "tags": [ - "active-ipynb" - ] - }, - "outputs": [], - "source": [ - "# Get the job URL, and stream the job logs.\n", - "# With PREMIUM Redis SKU, SKU family \"P\", and cache capacity 2,\n", - "# it takes approximately 5 minutes to complete.\n", - "fs_client.jobs.stream(poller.result().job_id)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Step 4: Test locally\n", - "In this step we will use our development environment (i.e. this notebook) to lookup features from online materialization store. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First, we will parse the list of features from the existing feature retrieval specification:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685132938320 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "parse-feat-list", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# Parse the list of features from the existing feature retrieval specification.\n", - "feature_retrieval_spec_folder = root_dir + \"/project/fraud_model/feature_retrieval_spec\"\n", - "\n", - "features = featurestore.resolve_feature_retrieval_spec(feature_retrieval_spec_folder)\n", - "\n", - "features" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, we will get feature values from the online materialization store:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685132960042 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "init-online-lookup", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azureml.featurestore import init_online_lookup\n", - "import time\n", - "\n", - "# Initialize the online store client.\n", - "init_online_lookup(features, AzureMLOnBehalfOfCredential())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, we will prepare some observation data for testing and use it to lookup features from the online materialization store. During online lookup, it may happen that the keys (`accountID`) defined in the observation sample data do not exist in the Redis (due to `TTL`). If this happens:\n", - "1. Open Azure portal.\n", - "2. Navigate to the Redis instance. \n", - "3. Open console for the Redis instance and check for existing keys using command `KEYS *`.\n", - "4. Replace `accountID` values in the sample observation data with the existing keys." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685132964129 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "online-feat-loockup", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "import pyarrow\n", - "from azureml.featurestore import get_online_features\n", - "\n", - "# Prepare test observation data\n", - "obs = pyarrow.Table.from_pydict(\n", - " {\"accountID\": [\"A985156952816816\", \"A1055521248929430\", \"A914800935560176\"]}\n", - ")\n", - "\n", - "# Online lookup:\n", - "# It may happen that the keys defined in the observation sample data above does not exist in the Redis (due to TTL).\n", - "# If this happens, go to Azure portal and navigate to the Redis instance, open its console and check for existing keys using command \"KEYS *\"\n", - "# and replace the sample observation data with the existing keys.\n", - "df = get_online_features(features, obs)\n", - "df" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "Now that we have successfully looked up features from the online store, we will test online features using Azure Machine Learning managed online endpoint." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Step 5: Test online features from Azure Machine Learning managed online endpoint\n", - "Managed online endpoint provide capability for deploying and scoring models for online/realtime inference. Optionally, you can use any inference technology of your choice (like kubernetes).\n", - "\n", - "As a part of this step, we will perform the following actions:\n", - "\n", - "1. Create an Azure Machine Learning managed online endpoint.\n", - "1. Grant required role-based access control (RBAC) permissions.\n", - "1. Deploy the model that we trained in the tutorial 3 of this tutorial series. The scoring script used in this step will have the code to lookup online features.\n", - "2. Perform scoring of the model with sample data. You will see that the online features are looked up and model scoring is completed successfully." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create Azure Machine Learning managed online endpoint\n", - "You can learn more about managed online endpoints [here](https://learn.microsoft.com/azure/machine-learning/how-to-deploy-online-endpoints?view=azureml-api-2&tabs=azure-cli). Note that using managed feature store API, you can also lookup online features from other inference platforms based on your need.\n", - "\n", - "Following code defines a managed online endpoint with name `fraud-model`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685155956798 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "define-endpoint", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.ai.ml.entities import (\n", - " ManagedOnlineDeployment,\n", - " ManagedOnlineEndpoint,\n", - " Model,\n", - " CodeConfiguration,\n", - " Environment,\n", - ")\n", - "\n", - "\n", - "endpoint_name = \"fraud-model\"\n", - "\n", - "endpoint = ManagedOnlineEndpoint(name=endpoint_name, auth_mode=\"key\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Excute the following code cell to create the managed online endpoint defined in the previous code cell." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685156110582 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "create-endpoint", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "ws_client.online_endpoints.begin_create_or_update(endpoint).result()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Grant required RBAC permissions\n", - "In this step, we will grant required RBAC permissions to the managed online endpoint on the Redis instance and feature store. The scoring code in the model deployment will need these RBAC permissions to successfully lookup features from the online store using the managed feature store API." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Get managed identity of the managed online endpoint" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685156114744 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "get-endpoint-identity", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# Get managed identity of the managed online endpoint.\n", - "endpoint = ws_client.online_endpoints.get(endpoint_name)\n", - "\n", - "model_endpoint_msi_principal_id = endpoint.identity.principal_id\n", - "model_endpoint_msi_principal_id" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Grant `Contributor` role to the online endpoint managed identity on the Azure Cache for Redis \n", - "We will grant `Contributor` role to the online endpoint managed identity on the Redis instance. This RBAC permission is needed to materialize data into the Redis online store." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685156142743 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "endpoint-redis-rbac", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "from azure.core.exceptions import ResourceExistsError\n", - "from azure.mgmt.msi import ManagedServiceIdentityClient\n", - "from azure.mgmt.msi.models import Identity\n", - "from azure.mgmt.authorization import AuthorizationManagementClient\n", - "from azure.mgmt.authorization.models import RoleAssignmentCreateParameters\n", - "from uuid import uuid4\n", - "\n", - "auth_client = AuthorizationManagementClient(\n", - " AzureMLOnBehalfOfCredential(), redis_subscription_id\n", - ")\n", - "\n", - "scope = f\"/subscriptions/{redis_subscription_id}/resourceGroups/{redis_resource_group_name}/providers/Microsoft.Cache/Redis/{redis_name}\"\n", - "\n", - "\n", - "# The role definition ID for the \"contributor\" role on the redis cache\n", - "# You can find other built-in role definition IDs in the Azure documentation\n", - "role_definition_id = f\"/subscriptions/{redis_subscription_id}/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c\"\n", - "\n", - "# Generate a random UUID for the role assignment name\n", - "role_assignment_name = str(uuid4())\n", - "\n", - "# Set up the role assignment creation parameters\n", - "role_assignment_params = RoleAssignmentCreateParameters(\n", - " principal_id=model_endpoint_msi_principal_id,\n", - " role_definition_id=role_definition_id,\n", - " principal_type=\"ServicePrincipal\",\n", - ")\n", - "\n", - "# Create the role assignment\n", - "try:\n", - " # Create the role assignment\n", - " result = auth_client.role_assignments.create(\n", - " scope, role_assignment_name, role_assignment_params\n", - " )\n", - " print(\n", - " f\"Redis RBAC granted to managed identity '{model_endpoint_msi_principal_id}'.\"\n", - " )\n", - "except ResourceExistsError:\n", - " print(\n", - " f\"Redis RBAC already exists for managed identity '{model_endpoint_msi_principal_id}'.\"\n", - " )" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Grant `AzureML Data Scientist` role to the online endpoint managed identity on the feature store\n", - "We will grant `AzureML Data Scientist` role to the online endpoint managed identity on the feature store. This RBAC permission is required for successful deployment of the model to the online endpoint." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685156168113 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "endpoint-fs-rbac", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "auth_client = AuthorizationManagementClient(\n", - " AzureMLOnBehalfOfCredential(), featurestore_subscription_id\n", - ")\n", - "\n", - "scope = f\"/subscriptions/{featurestore_subscription_id}/resourceGroups/{featurestore_resource_group_name}/providers/Microsoft.MachineLearningServices/workspaces/{featurestore_name}\"\n", - "\n", - "# The role definition ID for the \"AzureML Data Scientist\" role.\n", - "# You can find other built-in role definition IDs in the Azure documentation.\n", - "role_definition_id = f\"/subscriptions/{featurestore_subscription_id}/providers/Microsoft.Authorization/roleDefinitions/f6c7c914-8db3-469d-8ca1-694a8f32e121\"\n", - "\n", - "# Generate a random UUID for the role assignment name.\n", - "role_assignment_name = str(uuid4())\n", - "\n", - "# Set up the role assignment creation parameters.\n", - "role_assignment_params = RoleAssignmentCreateParameters(\n", - " principal_id=model_endpoint_msi_principal_id,\n", - " role_definition_id=role_definition_id,\n", - " principal_type=\"ServicePrincipal\",\n", - ")\n", - "\n", - "# Create the role assignment\n", - "try:\n", - " # Create the role assignment\n", - " result = auth_client.role_assignments.create(\n", - " scope, role_assignment_name, role_assignment_params\n", - " )\n", - " print(\n", - " f\"Feature store RBAC granted to managed identity '{model_endpoint_msi_principal_id}'.\"\n", - " )\n", - "except ResourceExistsError:\n", - " print(\n", - " f\"Feature store RBAC already exists for managed identity '{model_endpoint_msi_principal_id}'.\"\n", - " )" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Deploy the model to the online endpoint\n", - "First, inspect the scoring script `project/fraud_model/online_inference/src/scoring.py`. The scoring script performs the following tasks:\n", - "\n", - "1. Load the feature metadata from the feature retrieval specification that was packaged along with the model during model training (tutorial 3 of this tutorial series). This specification has features from both `transactions` and `accounts` feature sets.\n", - "2. When an input inference request is received, the scoring code looks up the online features using the index keys from the request. In this case for both feature sets, the index column is the `accountID`.\n", - "3. Passes the features to the model to perform inference and returs the response, a boolean value representing the variable `is_fraud`.\n", - "\n", - "First, create managed online deployment definition for model deployment by executing the following code cell:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685156215970 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "define-online-deployment", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "deployment = ManagedOnlineDeployment(\n", - " name=\"green\",\n", - " endpoint_name=endpoint_name,\n", - " model=\"azureml:fraud_model:1\",\n", - " code_configuration=CodeConfiguration(\n", - " code=root_dir + \"/project/fraud_model/online_inference/src/\",\n", - " scoring_script=\"scoring.py\",\n", - " ),\n", - " environment=Environment(\n", - " conda_file=root_dir + \"/project/fraud_model/online_inference/conda.yml\",\n", - " image=\"mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04\",\n", - " ),\n", - " instance_type=\"Standard_DS3_v2\",\n", - " instance_count=1,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, deploy the model to online enpoint by executing the following code cell. Note that it may take approximately 4-5 minutes to deploy the model." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685156672789 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "begin-online-deployment", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# Model deployment to online enpoint may take 4-5 minutes.\n", - "ws_client.online_deployments.begin_create_or_update(deployment).result()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Test online deployment with mock data\n", - "Finally, execute the following code to test the online deployment using the mock data. You should see `0` or `1` as the output of this cell." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1685157485313 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "name": "test-online-deployment", - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# Test the online deployment using the mock data.\n", - "sample_data = root_dir + \"/project/fraud_model/online_inference/test.json\"\n", - "ws_client.online_endpoints.invoke(\n", - " endpoint_name=endpoint_name, request_file=sample_data, deployment_name=\"green\"\n", - ")" - ] - } - ], - "metadata": { - "celltoolbar": "Edit Metadata", - "kernel_info": { - "name": "synapse_pyspark" - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.13" - }, - "microsoft": { - "host": { - "AzureML": { - "notebookHasBeenCompleted": true - } - }, - "ms_spell_check": { - "ms_spell_check_language": "en" - } - }, - "nteract": { - "version": "nteract-front-end@1.0.0" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/sdk/python/featurestore_sample/project/env/conda.yml b/sdk/python/featurestore_sample/project/env/conda.yml index b76c0c4292..269a426d8e 100644 --- a/sdk/python/featurestore_sample/project/env/conda.yml +++ b/sdk/python/featurestore_sample/project/env/conda.yml @@ -5,7 +5,7 @@ dependencies: # Protobuf is needed to avoid conflict with managed spark - protobuf==3.19.6 # Feature store core SDK - - azureml-featurestore==0.1.0b3 + - azureml-featurestore==0.1.0b5 # This is needed if you want to execute the Part 2 of the "SDK" track or execute "SDK+CLI" track in the docs tutorial - azure-cli diff --git a/sdk/python/featurestore_sample/setup-resources.sh b/sdk/python/featurestore_sample/setup-resources.sh index 6906c140f6..85540ba7ce 100644 --- a/sdk/python/featurestore_sample/setup-resources.sh +++ b/sdk/python/featurestore_sample/setup-resources.sh @@ -11,20 +11,18 @@ USER_ID="36b5b70a-a2b2-45e6-a496-df3c2ffde085" RAND_NUM=$RANDOM UAI_NAME=fstoreuai${RAND_NUM} REDIS_NAME=${RESOURCE_GROUP}rds -VERSION=$(((RANDOM%10)+1)) +VERSION=$(((RANDOM%1000)+1)) # # NOTEBOOK_1="notebooks/sdk_only/1. Develop a feature set and register with managed feature store" -NOTEBOOK_2="notebooks/sdk_only/2. Enable materialization and backfill feature data" -NOTEBOOK_3="notebooks/sdk_only/3. Experiment and train models using features" -NOTEBOOK_4="notebooks/sdk_only/4. Enable recurrent materialization and run batch inference" -NOTEBOOK_5="notebooks/sdk_only/5. Enable online store and run online inference" +NOTEBOOK_2="notebooks/sdk_only/2. Experiment and train models using features" +NOTEBOOK_3="notebooks/sdk_only/3. Enable recurrent materialization and run batch inference" +NOTEBOOK_4="notebooks/sdk_only/4. Enable online store and run online inference" jupytext --to py "${NOTEBOOK_1}.ipynb" jupytext --to py "${NOTEBOOK_2}.ipynb" jupytext --to py "${NOTEBOOK_3}.ipynb" jupytext --to py "${NOTEBOOK_4}.ipynb" -jupytext --to py "${NOTEBOOK_5}.ipynb" # # @@ -36,14 +34,9 @@ sed -i "s//$SUBSCRIPTION_ID/g; sed -i "s/display/$OUTPUT_COMMAND/g;s/.\/Users\/\/featurestore_sample/.\//g; s//$VERSION/g;" "${NOTEBOOK_1}.py" sed -i "s/display/$OUTPUT_COMMAND/g;s/.\/Users\/\/featurestore_sample/.\//g; - s//$FEATURE_STORAGE_ACCOUNT_NAME/g; - s//$USER_ID/g - s//$VERSION/g;; - s//$UAI_NAME/g;" "${NOTEBOOK_2}.py" + s//$VERSION/g;" "${NOTEBOOK_2}.py" sed -i "s/display/$OUTPUT_COMMAND/g;s/.\/Users\/\/featurestore_sample/.\//g; s//$VERSION/g;" "${NOTEBOOK_3}.py" -sed -i "s/display/$OUTPUT_COMMAND/g;s/.\/Users\/\/featurestore_sample/.\//g; - s//$VERSION/g;" "${NOTEBOOK_4}.py" sed -i "s/display/$OUTPUT_COMMAND/g;s/.\/Users\/\/featurestore_sample/.\//g; s//$REDIS_NAME/g; - s//$VERSION/g;" "${NOTEBOOK_5}.py" \ No newline at end of file + s//$VERSION/g;" "${NOTEBOOK_4}.py" \ No newline at end of file