﻿<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/css' href='https://stocksharp.com/css/style.css'?>
<?xml-stylesheet type='text/css' href='https://stocksharp.com/css/bbeditor.css'?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html">Community. StockSharp</title>
  <id>https://stocksharp.com/handlers/atom.ashx?category=community&amp;page=7</id>
  <rights type="text">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  <updated>2026-04-11T20:10:57Z</updated>
  <logo>https://stocksharp.com/images/logo.png</logo>
  <link href="https://stocksharp.com/handlers/atom.ashx?category=community&amp;page=7" rel="self" type="application/rss+xml" />
  <entry>
    <id>https://stocksharp.com/topic/25630/</id>
    <title type="text">Mastering Uniswap V3: Advanced Strategies for Exchange Pool Liquidity (Part 1)</title>
    <published>2024-03-26T09:17:00Z</published>
    <updated>2024-03-26T09:17:00Z</updated>
    <author>
      <name>FMZQuant</name>
      <uri>https://stocksharp.com/users/185759/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#strategy" />
    <category term="#code" />
    <category term="#fmz" />
    <category term="#contract" />
    <category term="#crypto" />
    <category term="#position" />
    <category term="#exhange" />
    <category term="#uniswapV3" />
    <category term="#token" />
    <content type="html">&lt;b&gt;NonfungiblePositionManager Contract in Uniswap V3&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;When we add liquidity to the Uniswap V3 liquidity pool (trading pair pool), the NonfungiblePositionManager contract returns a minted NFT to us as proof of the liquidity addition.&lt;br /&gt;&lt;br /&gt;The first step is to use the router contract to get the address of the corresponding NonfungiblePositionManager contract, and then use the balanceOf method of the NonfungiblePositionManager contract to get the number of position NFTs for the specified wallet address.&lt;br /&gt;&lt;br /&gt;Then use the tokenOfOwnerByIndex method to get the tokenId of these position NFTs, with these tokenId, you can use the positions method to continue to query the specific details of these positions.&lt;br /&gt;&lt;br /&gt;The following test code:&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;// Uniswap ABI&lt;br /&gt;const ABI_UniswapV3Router = `[{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;_factoryV2&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;factoryV3&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;_positionManager&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;_WETH9&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;nonpayable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;constructor&amp;quot;},{&amp;quot;inputs&amp;quot;:[],&amp;quot;name&amp;quot;:&amp;quot;WETH9&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;approveMax&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;approveMaxMinusOne&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;approveZeroThenMax&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;approveZeroThenMaxMinusOne&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;data&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;callPositionManager&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;result&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes[]&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;paths&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes[]&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint128[]&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amounts&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint128[]&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint24&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;maximumTickDivergence&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint24&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;secondsAgo&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint32&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;checkOracleSlippage&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;path&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint24&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;maximumTickDivergence&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint24&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;secondsAgo&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint32&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;checkOracleSlippage&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;components&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;path&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;recipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountIn&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountOutMinimum&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;internalType&amp;quot;:&amp;quot;struct IV3SwapRouter.ExactInputParams&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;params&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;tuple&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;exactInput&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountOut&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;components&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenIn&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenOut&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint24&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;fee&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint24&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;recipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountIn&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountOutMinimum&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint160&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;sqrtPriceLimitX96&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint160&amp;quot;}],&amp;quot;internalType&amp;quot;:&amp;quot;struct IV3SwapRouter.ExactInputSingleParams&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;params&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;tuple&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;exactInputSingle&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountOut&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;components&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;path&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;recipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountOut&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountInMaximum&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;internalType&amp;quot;:&amp;quot;struct IV3SwapRouter.ExactOutputParams&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;params&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;tuple&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;exactOutput&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountIn&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;components&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenIn&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenOut&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint24&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;fee&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint24&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;recipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountOut&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountInMaximum&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint160&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;sqrtPriceLimitX96&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint160&amp;quot;}],&amp;quot;internalType&amp;quot;:&amp;quot;struct IV3SwapRouter.ExactOutputSingleParams&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;params&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;tuple&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;exactOutputSingle&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountIn&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[],&amp;quot;name&amp;quot;:&amp;quot;factory&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[],&amp;quot;name&amp;quot;:&amp;quot;factoryV2&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;getApprovalType&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;enum IApproveAndCall.ApprovalType&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint8&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;nonpayable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;components&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token0&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token1&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0Min&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1Min&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;internalType&amp;quot;:&amp;quot;struct IApproveAndCall.IncreaseLiquidityParams&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;params&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;tuple&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;increaseLiquidity&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;result&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;components&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token0&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token1&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint24&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;fee&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint24&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;int24&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tickLower&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;int24&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;int24&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tickUpper&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;int24&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0Min&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1Min&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;recipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;internalType&amp;quot;:&amp;quot;struct IApproveAndCall.MintParams&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;params&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;tuple&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;mint&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;result&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;previousBlockhash&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes[]&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;data&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes[]&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;multicall&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes[]&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes[]&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;deadline&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes[]&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;data&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes[]&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;multicall&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes[]&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes[]&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes[]&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;data&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes[]&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;multicall&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes[]&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;results&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes[]&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[],&amp;quot;name&amp;quot;:&amp;quot;positionManager&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;value&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;pull&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[],&amp;quot;name&amp;quot;:&amp;quot;refundETH&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;value&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;deadline&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint8&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;v&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint8&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;r&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;s&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;selfPermit&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;nonce&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;expiry&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint8&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;v&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint8&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;r&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;s&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;selfPermitAllowed&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;nonce&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;expiry&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint8&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;v&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint8&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;r&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;s&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;selfPermitAllowedIfNecessary&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;value&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;deadline&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint8&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;v&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint8&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;r&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;s&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;selfPermitIfNecessary&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountIn&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountOutMin&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address[]&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;path&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address[]&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;to&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;swapExactTokensForTokens&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountOut&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountOut&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountInMax&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address[]&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;path&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address[]&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;to&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;swapTokensForExactTokens&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountIn&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountMinimum&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;recipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;sweepToken&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountMinimum&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;sweepToken&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountMinimum&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;feeBips&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;feeRecipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;sweepTokenWithFee&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountMinimum&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;recipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;feeBips&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;feeRecipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;sweepTokenWithFee&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;int256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0Delta&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;int256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;int256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1Delta&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;int256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;_data&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;uniswapV3SwapCallback&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;nonpayable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountMinimum&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;recipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;unwrapWETH9&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountMinimum&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;unwrapWETH9&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountMinimum&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;recipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;feeBips&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;feeRecipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;unwrapWETH9WithFee&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountMinimum&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;feeBips&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;feeRecipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;unwrapWETH9WithFee&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;value&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;wrapETH&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;receive&amp;quot;}]`&lt;br /&gt;const ABI_NonfungiblePositionManager = `[{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;_factory&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;_WETH9&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;_tokenDescriptor_&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;nonpayable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;constructor&amp;quot;},{&amp;quot;anonymous&amp;quot;:false,&amp;quot;inputs&amp;quot;:[{&amp;quot;indexed&amp;quot;:true,&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;owner&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;indexed&amp;quot;:true,&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;approved&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;indexed&amp;quot;:true,&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;Approval&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;event&amp;quot;},{&amp;quot;anonymous&amp;quot;:false,&amp;quot;inputs&amp;quot;:[{&amp;quot;indexed&amp;quot;:true,&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;owner&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;indexed&amp;quot;:true,&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;operator&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;indexed&amp;quot;:false,&amp;quot;internalType&amp;quot;:&amp;quot;bool&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;approved&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bool&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;ApprovalForAll&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;event&amp;quot;},{&amp;quot;anonymous&amp;quot;:false,&amp;quot;inputs&amp;quot;:[{&amp;quot;indexed&amp;quot;:true,&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;indexed&amp;quot;:false,&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;recipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;indexed&amp;quot;:false,&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;indexed&amp;quot;:false,&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;Collect&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;event&amp;quot;},{&amp;quot;anonymous&amp;quot;:false,&amp;quot;inputs&amp;quot;:[{&amp;quot;indexed&amp;quot;:true,&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;indexed&amp;quot;:false,&amp;quot;internalType&amp;quot;:&amp;quot;uint128&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;liquidity&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint128&amp;quot;},{&amp;quot;indexed&amp;quot;:false,&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;indexed&amp;quot;:false,&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;DecreaseLiquidity&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;event&amp;quot;},{&amp;quot;anonymous&amp;quot;:false,&amp;quot;inputs&amp;quot;:[{&amp;quot;indexed&amp;quot;:true,&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;indexed&amp;quot;:false,&amp;quot;internalType&amp;quot;:&amp;quot;uint128&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;liquidity&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint128&amp;quot;},{&amp;quot;indexed&amp;quot;:false,&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;indexed&amp;quot;:false,&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;IncreaseLiquidity&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;event&amp;quot;},{&amp;quot;anonymous&amp;quot;:false,&amp;quot;inputs&amp;quot;:[{&amp;quot;indexed&amp;quot;:true,&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;from&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;indexed&amp;quot;:true,&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;to&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;indexed&amp;quot;:true,&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;Transfer&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;event&amp;quot;},{&amp;quot;inputs&amp;quot;:[],&amp;quot;name&amp;quot;:&amp;quot;DOMAIN_SEPARATOR&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[],&amp;quot;name&amp;quot;:&amp;quot;PERMIT_TYPEHASH&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[],&amp;quot;name&amp;quot;:&amp;quot;WETH9&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;to&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;approve&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;nonpayable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;owner&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;balanceOf&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[],&amp;quot;name&amp;quot;:&amp;quot;baseURI&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;string&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;pure&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;burn&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;components&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;recipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint128&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0Max&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint128&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint128&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1Max&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint128&amp;quot;}],&amp;quot;internalType&amp;quot;:&amp;quot;struct INonfungiblePositionManager.CollectParams&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;params&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;tuple&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;collect&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token0&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token1&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint24&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;fee&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint24&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint160&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;sqrtPriceX96&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint160&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;createAndInitializePoolIfNecessary&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;pool&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;components&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint128&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;liquidity&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint128&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0Min&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1Min&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;deadline&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;internalType&amp;quot;:&amp;quot;struct INonfungiblePositionManager.DecreaseLiquidityParams&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;params&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;tuple&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;decreaseLiquidity&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[],&amp;quot;name&amp;quot;:&amp;quot;factory&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;getApproved&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;components&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0Desired&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1Desired&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0Min&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1Min&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;deadline&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;internalType&amp;quot;:&amp;quot;struct INonfungiblePositionManager.IncreaseLiquidityParams&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;params&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;tuple&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;increaseLiquidity&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint128&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;liquidity&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint128&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;owner&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;operator&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;isApprovedForAll&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bool&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bool&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;components&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token0&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token1&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint24&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;fee&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint24&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;int24&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tickLower&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;int24&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;int24&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tickUpper&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;int24&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0Desired&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1Desired&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0Min&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1Min&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;recipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;deadline&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;internalType&amp;quot;:&amp;quot;struct INonfungiblePositionManager.MintParams&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;params&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;tuple&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;mint&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint128&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;liquidity&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint128&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes[]&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;data&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes[]&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;multicall&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes[]&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;results&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes[]&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[],&amp;quot;name&amp;quot;:&amp;quot;name&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;string&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;ownerOf&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;spender&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;deadline&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint8&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;v&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint8&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;r&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;s&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;permit&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;positions&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint96&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;nonce&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint96&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;operator&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token0&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token1&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint24&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;fee&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint24&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;int24&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tickLower&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;int24&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;int24&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tickUpper&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;int24&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint128&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;liquidity&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint128&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;feeGrowthInside0LastX128&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;feeGrowthInside1LastX128&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint128&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokensOwed0&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint128&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint128&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokensOwed1&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint128&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[],&amp;quot;name&amp;quot;:&amp;quot;refundETH&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;from&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;to&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;safeTransferFrom&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;nonpayable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;from&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;to&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;_data&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;safeTransferFrom&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;nonpayable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;value&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;deadline&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint8&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;v&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint8&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;r&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;s&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;selfPermit&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;nonce&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;expiry&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint8&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;v&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint8&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;r&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;s&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;selfPermitAllowed&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;nonce&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;expiry&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint8&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;v&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint8&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;r&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;s&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;selfPermitAllowedIfNecessary&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;value&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;deadline&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint8&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;v&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint8&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;r&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes32&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;s&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes32&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;selfPermitIfNecessary&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;operator&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bool&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;approved&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bool&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;setApprovalForAll&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;nonpayable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bytes4&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;interfaceId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes4&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;supportsInterface&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;bool&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bool&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;token&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountMinimum&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;recipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;sweepToken&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[],&amp;quot;name&amp;quot;:&amp;quot;symbol&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;string&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;index&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;tokenByIndex&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;owner&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;index&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;tokenOfOwnerByIndex&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;tokenURI&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;string&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;string&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[],&amp;quot;name&amp;quot;:&amp;quot;totalSupply&amp;quot;,&amp;quot;outputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;stateMutability&amp;quot;:&amp;quot;view&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;from&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;to&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;tokenId&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;transferFrom&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;nonpayable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount0Owed&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amount1Owed&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;bytes&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;data&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;bytes&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;uniswapV3MintCallback&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;nonpayable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;inputs&amp;quot;:[{&amp;quot;internalType&amp;quot;:&amp;quot;uint256&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;amountMinimum&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;uint256&amp;quot;},{&amp;quot;internalType&amp;quot;:&amp;quot;address&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;recipient&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;address&amp;quot;}],&amp;quot;name&amp;quot;:&amp;quot;unwrapWETH9&amp;quot;,&amp;quot;outputs&amp;quot;:[],&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;function&amp;quot;},{&amp;quot;stateMutability&amp;quot;:&amp;quot;payable&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;receive&amp;quot;}]`&lt;br /&gt;const ABI_Pool = &amp;#39;[{\&amp;quot;inputs\&amp;quot;:[],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;nonpayable\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;constructor\&amp;quot;},{\&amp;quot;anonymous\&amp;quot;:false,\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;owner\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickLower\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickUpper\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;Burn\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;event\&amp;quot;},{\&amp;quot;anonymous\&amp;quot;:false,\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;owner\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;recipient\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickLower\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickUpper\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;Collect\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;event\&amp;quot;},{\&amp;quot;anonymous\&amp;quot;:false,\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;sender\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;recipient\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;CollectProtocol\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;event\&amp;quot;},{\&amp;quot;anonymous\&amp;quot;:false,\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;sender\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;recipient\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;paid0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;paid1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;Flash\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;event\&amp;quot;},{\&amp;quot;anonymous\&amp;quot;:false,\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint16\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;observationCardinalityNextOld\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint16\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint16\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;observationCardinalityNextNew\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint16\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;IncreaseObservationCardinalityNext\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;event\&amp;quot;},{\&amp;quot;anonymous\&amp;quot;:false,\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint160\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;sqrtPriceX96\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint160\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tick\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;Initialize\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;event\&amp;quot;},{\&amp;quot;anonymous\&amp;quot;:false,\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;sender\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;owner\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickLower\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickUpper\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;Mint\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;event\&amp;quot;},{\&amp;quot;anonymous\&amp;quot;:false,\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint8\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;feeProtocol0Old\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint8\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint8\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;feeProtocol1Old\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint8\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint8\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;feeProtocol0New\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint8\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint8\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;feeProtocol1New\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint8\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;SetFeeProtocol\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;event\&amp;quot;},{\&amp;quot;anonymous\&amp;quot;:false,\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;sender\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;recipient\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;int256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int256\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;int256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int256\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint160\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;sqrtPriceX96\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint160\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;liquidity\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tick\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;Swap\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;event\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickLower\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickUpper\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;burn\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;nonpayable\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;recipient\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickLower\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickUpper\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount0Requested\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount1Requested\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;collect\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;nonpayable\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;recipient\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount0Requested\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount1Requested\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;collectProtocol\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;nonpayable\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[],\&amp;quot;name\&amp;quot;:\&amp;quot;factory\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[],\&amp;quot;name\&amp;quot;:\&amp;quot;fee\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint24\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[],\&amp;quot;name\&amp;quot;:\&amp;quot;feeGrowthGlobal0X128\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[],\&amp;quot;name\&amp;quot;:\&amp;quot;feeGrowthGlobal1X128\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;recipient\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;bytes\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;data\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;bytes\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;flash\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;nonpayable\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint16\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;observationCardinalityNext\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint16\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;increaseObservationCardinalityNext\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;nonpayable\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint160\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;sqrtPriceX96\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint160\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;initialize\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;nonpayable\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[],\&amp;quot;name\&amp;quot;:\&amp;quot;liquidity\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[],\&amp;quot;name\&amp;quot;:\&amp;quot;maxLiquidityPerTick\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;recipient\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickLower\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickUpper\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;bytes\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;data\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;bytes\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;mint\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;nonpayable\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;observations\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint32\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;blockTimestamp\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint32\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int56\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickCumulative\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int56\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint160\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;secondsPerLiquidityCumulativeX128\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint160\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;bool\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;initialized\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;bool\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint32[]\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;secondsAgos\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint32[]\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;observe\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int56[]\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickCumulatives\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int56[]\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint160[]\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;secondsPerLiquidityCumulativeX128s\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint160[]\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;bytes32\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;bytes32\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;positions\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;liquidity\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;feeGrowthInside0LastX128\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;feeGrowthInside1LastX128\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tokensOwed0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tokensOwed1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[],\&amp;quot;name\&amp;quot;:\&amp;quot;protocolFees\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;token0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;token1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint8\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;feeProtocol0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint8\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint8\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;feeProtocol1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint8\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;setFeeProtocol\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;nonpayable\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[],\&amp;quot;name\&amp;quot;:\&amp;quot;slot0\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint160\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;sqrtPriceX96\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint160\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tick\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint16\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;observationIndex\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint16\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint16\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;observationCardinality\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint16\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint16\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;observationCardinalityNext\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint16\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint8\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;feeProtocol\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint8\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;bool\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;unlocked\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;bool\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickLower\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickUpper\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;snapshotCumulativesInside\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int56\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickCumulativeInside\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int56\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint160\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;secondsPerLiquidityInsideX128\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint160\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint32\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;secondsInside\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint32\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;recipient\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;bool\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;zeroForOne\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;bool\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amountSpecified\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int256\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint160\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;sqrtPriceLimitX96\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint160\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;bytes\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;data\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;bytes\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;swap\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int256\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;amount1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int256\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;nonpayable\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int16\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int16\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;tickBitmap\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[],\&amp;quot;name\&amp;quot;:\&amp;quot;tickSpacing\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;ticks\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;liquidityGross\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint128\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int128\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;liquidityNet\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int128\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;feeGrowthOutside0X128\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint256\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;feeGrowthOutside1X128\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint256\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int56\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickCumulativeOutside\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int56\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint160\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;secondsPerLiquidityOutsideX128\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint160\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint32\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;secondsOutside\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint32\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;bool\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;initialized\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;bool\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[],\&amp;quot;name\&amp;quot;:\&amp;quot;token0\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[],\&amp;quot;name\&amp;quot;:\&amp;quot;token1\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;}]&amp;#39;&lt;br /&gt;const ABI_Factory = &amp;#39;[{\&amp;quot;inputs\&amp;quot;:[],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;nonpayable\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;constructor\&amp;quot;},{\&amp;quot;anonymous\&amp;quot;:false,\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;fee\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint24\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickSpacing\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;FeeAmountEnabled\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;event\&amp;quot;},{\&amp;quot;anonymous\&amp;quot;:false,\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;oldOwner\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;newOwner\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;OwnerChanged\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;event\&amp;quot;},{\&amp;quot;anonymous\&amp;quot;:false,\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;token0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;token1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:true,\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;fee\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint24\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickSpacing\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;},{\&amp;quot;indexed\&amp;quot;:false,\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;pool\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;PoolCreated\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;event\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tokenA\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tokenB\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;fee\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint24\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;createPool\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;pool\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;nonpayable\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;fee\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint24\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickSpacing\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;enableFeeAmount\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;nonpayable\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint24\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;feeAmountTickSpacing\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint24\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;getPool\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[],\&amp;quot;name\&amp;quot;:\&amp;quot;owner\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[],\&amp;quot;name\&amp;quot;:\&amp;quot;parameters\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;factory\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;token0\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;token1\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;uint24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;fee\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;uint24\&amp;quot;},{\&amp;quot;internalType\&amp;quot;:\&amp;quot;int24\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;tickSpacing\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;int24\&amp;quot;}],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;view\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;},{\&amp;quot;inputs\&amp;quot;:[{\&amp;quot;internalType\&amp;quot;:\&amp;quot;address\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;_owner\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;address\&amp;quot;}],\&amp;quot;name\&amp;quot;:\&amp;quot;setOwner\&amp;quot;,\&amp;quot;outputs\&amp;quot;:[],\&amp;quot;stateMutability\&amp;quot;:\&amp;quot;nonpayable\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;function\&amp;quot;}]&amp;#39;&lt;br /&gt;&lt;br /&gt;// Uniswap contract address&lt;br /&gt;const UniswapV3RouterAddress = &amp;quot;0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45&amp;quot;&lt;br /&gt;const ContractV3Factory = &amp;quot;0x1F98431c8aD98523631AE4a59f267346ea31F984&amp;quot;&lt;br /&gt;&lt;br /&gt;// common constant&lt;br /&gt;const TWO = BigInt(2)&lt;br /&gt;const Q192 = (TWO ** BigInt(96)) ** TWO&lt;br /&gt;const Q96 = (TWO ** BigInt(96))&lt;br /&gt;&lt;br /&gt;// Convert to readable amount&lt;br /&gt;function toAmount(s, decimals) {&lt;br /&gt;    return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Reverse conversion from readable amount to amount used for passing parameters and calculations&lt;br /&gt;function toInnerAmount(n, decimals) {&lt;br /&gt;    return (BigDecimal(n) * BigDecimal(Math.pow(10, decimals))).toFixed(0)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function main(){&lt;br /&gt;    // The address of the wallet to be searched&lt;br /&gt;    // const walletAddress = exchange.IO(&amp;quot;address&amp;quot;)&lt;br /&gt;    const walletAddress = &amp;quot;0x28df8b987BE232bA33FdFB8Fc5058C1592A3db26&amp;quot;&lt;br /&gt;&lt;br /&gt;    // Get the address of Uniswap V3&amp;#39;s positionManager contract&lt;br /&gt;    exchange.IO(&amp;quot;abi&amp;quot;, UniswapV3RouterAddress, ABI_UniswapV3Router)&lt;br /&gt;    const NonfungiblePositionManagerAddress = exchange.IO(&amp;quot;api&amp;quot;, UniswapV3RouterAddress, &amp;quot;positionManager&amp;quot;)&lt;br /&gt;    Log(&amp;quot;NonfungiblePositionManagerAddress:&amp;quot;, NonfungiblePositionManagerAddress)&lt;br /&gt;&lt;br /&gt;    // Register ABI for positionManager contracts&lt;br /&gt;    exchange.IO(&amp;quot;abi&amp;quot;, NonfungiblePositionManagerAddress, ABI_NonfungiblePositionManager)&lt;br /&gt;&lt;br /&gt;    // Query the number of Uniswap V3 positions NFT owned by the current account&lt;br /&gt;    var nftBalance = exchange.IO(&amp;quot;api&amp;quot;, NonfungiblePositionManagerAddress, &amp;quot;balanceOf&amp;quot;, walletAddress)&lt;br /&gt;    Log(&amp;quot;nftBalance:&amp;quot;, nftBalance)&lt;br /&gt;    &lt;br /&gt;    // Query the TokenId of these NFTs&lt;br /&gt;    var nftTokenIds = []&lt;br /&gt;    for (var i = 0 ; i &amp;lt; nftBalance; i++) {&lt;br /&gt;        var nftTokenId = exchange.IO(&amp;quot;api&amp;quot;, NonfungiblePositionManagerAddress, &amp;quot;tokenOfOwnerByIndex&amp;quot;, walletAddress, i)&lt;br /&gt;        nftTokenIds.push(nftTokenId)&lt;br /&gt;        Log(&amp;quot;nftTokenId:&amp;quot;, nftTokenId)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // Query liquidity position details based on the tokenId of the positions NFT&lt;br /&gt;    var positions = []&lt;br /&gt;    for (var i = 0; i &amp;lt; nftTokenIds.length; i++) {&lt;br /&gt;        var pos = exchange.IO(&amp;quot;api&amp;quot;, NonfungiblePositionManagerAddress, &amp;quot;positions&amp;quot;, nftTokenIds[i])        &lt;br /&gt;        Log(&amp;quot;pos:&amp;quot;, pos)&lt;br /&gt;&lt;br /&gt;        // Parsing position data&lt;br /&gt;        positions.push(parsePosData(pos))&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    var tbl = {&lt;br /&gt;        type : &amp;quot;table&amp;quot;,&lt;br /&gt;        title : &amp;quot;LP&amp;quot;,&lt;br /&gt;        cols : [&amp;quot;range(token0 valuation)&amp;quot;, &amp;quot;token0&amp;quot;, &amp;quot;token1&amp;quot;, &amp;quot;fee&amp;quot;, &amp;quot;lowerPrice(tickLower)&amp;quot;, &amp;quot;upperPrice(tickUpper)&amp;quot;, &amp;quot;liquidity&amp;quot;, &amp;quot;amount0&amp;quot;, &amp;quot;amount1&amp;quot;],&lt;br /&gt;        rows : positions&lt;br /&gt;    }&lt;br /&gt;    LogStatus(&amp;quot;`&amp;quot; + JSON.stringify(tbl) + &amp;quot;`&amp;quot;)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Record information about tokens queried through coingecko.com&lt;br /&gt;var tokens = []&lt;br /&gt;function init() {&lt;br /&gt;    // When initializing, get information about all tokens to query the&lt;br /&gt;    var res = JSON.parse(HttpQuery(&amp;quot;https://tokens.coingecko.com/uniswap/all.json&amp;quot;))&lt;br /&gt;    Log(&amp;quot;fetch&amp;quot;, res.tokens.length, &amp;quot;tokens from&amp;quot;, res.name)&lt;br /&gt;    _.each(res.tokens, function(token) {&lt;br /&gt;        tokens.push({&lt;br /&gt;            name : token.name,&lt;br /&gt;            symbol : token.symbol,&lt;br /&gt;            decimals : token.decimals,&lt;br /&gt;            address : token.address&lt;br /&gt;        })&lt;br /&gt;    })&lt;br /&gt;    Log(&amp;quot;tokens:&amp;quot;, tokens)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function parsePosData(posData) {&lt;br /&gt;    /*&lt;br /&gt;    {&lt;br /&gt;        &amp;quot;nonce&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;        &amp;quot;operator&amp;quot;: &amp;quot;0x0000000000000000000000000000000000000000&amp;quot;,&lt;br /&gt;        &amp;quot;token1&amp;quot;: &amp;quot;0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2&amp;quot;,&lt;br /&gt;        &amp;quot;fee&amp;quot;: &amp;quot;3000&amp;quot;,&lt;br /&gt;        &amp;quot;feeGrowthInside0LastX128&amp;quot;: &amp;quot;552824104363438506727784685971981736468&amp;quot;,&lt;br /&gt;        &amp;quot;feeGrowthInside1LastX128&amp;quot;: &amp;quot;2419576808699564757520565912733367379&amp;quot;,&lt;br /&gt;        &amp;quot;tokensOwed0&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;        &amp;quot;tokensOwed1&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;        &amp;quot;token0&amp;quot;: &amp;quot;0x1f9840a85d5af5bf1d1762f925bdaddc4201f984&amp;quot;,&lt;br /&gt;        &amp;quot;tickLower&amp;quot;: &amp;quot;-62160&amp;quot;,&lt;br /&gt;        &amp;quot;tickUpper&amp;quot;: &amp;quot;-41280&amp;quot;,&lt;br /&gt;        &amp;quot;liquidity&amp;quot;: &amp;quot;19090316141441365693&amp;quot;&lt;br /&gt;    }&lt;br /&gt;    */&lt;br /&gt;    &lt;br /&gt;    var token0Symbol = null&lt;br /&gt;    var token1Symbol = null&lt;br /&gt;    // Determine the token according to the address of the token, record the information about the token&lt;br /&gt;    for (var i in tokens) {&lt;br /&gt;        if (tokens[i].address.toLowerCase() == posData.token0.toLowerCase()) {&lt;br /&gt;            token0Symbol = tokens[i]&lt;br /&gt;        } else if (tokens[i].address.toLowerCase() == posData.token1.toLowerCase()) {&lt;br /&gt;            token1Symbol = tokens[i]&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    if (!token0Symbol || !token1Symbol) {&lt;br /&gt;    	Log(&amp;quot;token0Symbol:&amp;quot;, token0Symbol, &amp;quot;, token1Symbol:&amp;quot;, token1Symbol)&lt;br /&gt;        throw &amp;quot;token not found&amp;quot;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // get Pool , obtaining data about the exchange pool&lt;br /&gt;    var poolInfo = getPool(token0Symbol.address, token1Symbol.address, posData.fee)&lt;br /&gt;    Log(&amp;quot;poolInfo:&amp;quot;, poolInfo)&lt;br /&gt;    /* Data examples&lt;br /&gt;    {&lt;br /&gt;        &amp;quot;slot0&amp;quot;:{&lt;br /&gt;            &amp;quot;sqrtPriceX96&amp;quot;:&amp;quot;4403124416947951698847768103&amp;quot;,&amp;quot;tick&amp;quot;:&amp;quot;-57804&amp;quot;,&amp;quot;observationIndex&amp;quot;:136,&amp;quot;observationCardinality&amp;quot;:300,&lt;br /&gt;            &amp;quot;observationCardinalityNext&amp;quot;:300,&amp;quot;feeProtocol&amp;quot;:0,&amp;quot;unlocked&amp;quot;:true&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    */&lt;br /&gt;    &lt;br /&gt;    // Calculate token0Amount, token1Amount&lt;br /&gt;    var currentTick = parseInt(poolInfo.slot0.tick)&lt;br /&gt;    var lowerPrice = 1.0001 ** posData.tickLower&lt;br /&gt;    var upperPrice = 1.0001 ** posData.tickUpper&lt;br /&gt;    var sqrtRatioA = Math.sqrt(lowerPrice)&lt;br /&gt;    var sqrtRatioB = Math.sqrt(upperPrice)&lt;br /&gt;    var sqrtPrice = Number(BigFloat(poolInfo.slot0.sqrtPriceX96) / Q96)&lt;br /&gt;    &lt;br /&gt;    var amount0wei = 0&lt;br /&gt;    var amount1wei = 0&lt;br /&gt;    if (currentTick &amp;lt;= posData.tickLower) {&lt;br /&gt;        amount0wei = Math.floor(posData.liquidity * ((sqrtRatioB - sqrtRatioA) / (sqrtRatioA * sqrtRatioB)))&lt;br /&gt;    } else if (currentTick &amp;gt; posData.tickUpper) {&lt;br /&gt;        amount1wei = Math.floor(posData.liquidity * (sqrtRatioB - sqrtRatioA))&lt;br /&gt;    } else if (currentTick &amp;gt;= posData.tickLower &amp;amp;&amp;amp; currentTick &amp;lt; posData.tickUpper) {&lt;br /&gt;        amount0wei = Math.floor(posData.liquidity * ((sqrtRatioB - sqrtPrice) / (sqrtPrice * sqrtRatioB)))&lt;br /&gt;        amount1wei = Math.floor(posData.liquidity * (sqrtPrice - sqrtRatioA))&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    var rangeToken0 = (1.0001 ** -posData.tickUpper) + &amp;quot; ~ &amp;quot; + (1.0001 ** -posData.tickLower)&lt;br /&gt;    var amount0 = toAmount(amount0wei, token0Symbol.decimals)&lt;br /&gt;    var amount1 = toAmount(amount1wei, token1Symbol.decimals)&lt;br /&gt;&lt;br /&gt;    return [rangeToken0, token0Symbol.symbol, token1Symbol.symbol, posData.fee / 10000 + &amp;quot;%&amp;quot;, &lt;br /&gt;        `${lowerPrice}(tickLower:${posData.tickLower})`, `${upperPrice}(tickUpper:${posData.tickUpper})`, posData.liquidity, &lt;br /&gt;            amount0, amount1]&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function getPool(token0Address, token1Address, fee) {&lt;br /&gt;    if (BigInt(token0Address) &amp;gt; BigInt(token1Address)) {&lt;br /&gt;        var tmp = token0Address&lt;br /&gt;        token0Address = token1Address&lt;br /&gt;        token1Address = tmp&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    // Calculating the contract address of an exchange pool using Uniswap&amp;#39;s factory contract&lt;br /&gt;    exchange.IO(&amp;quot;abi&amp;quot;, ContractV3Factory, ABI_Factory)&lt;br /&gt;    var poolAddress = exchange.IO(&amp;quot;api&amp;quot;, ContractV3Factory, &amp;quot;getPool&amp;quot;, token0Address, token1Address, fee)&lt;br /&gt;    if (!poolAddress) {&lt;br /&gt;        throw &amp;quot;getPool failed&amp;quot;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    // ABI for registered pool contracts&lt;br /&gt;    exchange.IO(&amp;quot;abi&amp;quot;, poolAddress, ABI_Pool)&lt;br /&gt;    &lt;br /&gt;    // Call the pool contract&amp;#39;s slot0 method to query the current exchange pool&amp;#39;s data&lt;br /&gt;    var slot0 = exchange.IO(&amp;quot;api&amp;quot;, poolAddress, &amp;quot;slot0&amp;quot;)&lt;br /&gt;    if (!slot0) {&lt;br /&gt;    	throw &amp;quot;get slot0 failed&amp;quot;&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    return {&lt;br /&gt;    	&amp;quot;slot0&amp;quot;: slot0&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;The retrieved liquidity position information (which needs further parsing):&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;{&lt;br /&gt;	&amp;quot;nonce&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;	&amp;quot;operator&amp;quot;: &amp;quot;0x0000000000000000000000000000000000000000&amp;quot;,&lt;br /&gt;	&amp;quot;token1&amp;quot;: &amp;quot;0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2&amp;quot;,&lt;br /&gt;	&amp;quot;fee&amp;quot;: &amp;quot;3000&amp;quot;,&lt;br /&gt;	&amp;quot;feeGrowthInside0LastX128&amp;quot;: &amp;quot;552824104363438506727784685971981736468&amp;quot;,&lt;br /&gt;	&amp;quot;feeGrowthInside1LastX128&amp;quot;: &amp;quot;2419576808699564757520565912733367379&amp;quot;,&lt;br /&gt;	&amp;quot;tokensOwed0&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;	&amp;quot;tokensOwed1&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;	&amp;quot;token0&amp;quot;: &amp;quot;0x1f9840a85d5af5bf1d1762f925bdaddc4201f984&amp;quot;,&lt;br /&gt;	&amp;quot;tickLower&amp;quot;: &amp;quot;-62160&amp;quot;,&lt;br /&gt;	&amp;quot;tickUpper&amp;quot;: &amp;quot;-41280&amp;quot;,&lt;br /&gt;	&amp;quot;liquidity&amp;quot;: &amp;quot;19090316141441365693&amp;quot;&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Parsing Liquidity Holdings for Market Making Ranges&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The positions method of Uniswap&amp;#39;s NonfungiblePositionManager contract returns tickLower and tickUpper in the liquidity position data. In Uniswap V3, liquidity can be specified within a range, whereas the initial design of Uniswap had uniform distribution of liquidity. The specification of a liquidity range in subsequent versions is aimed at improving the utilization of liquidity capital.&lt;br /&gt;&lt;br /&gt;&amp;gt; tickLower: The lower end of the tick range for the position&lt;br /&gt;&amp;gt; tickUpper: The higher end of the tick range for the position&lt;br /&gt;&lt;br /&gt;tickLower and tickUpper represent the upper and lower limits of the liquidity. Referring to the Uniswap documentation and its complex formulas, tickLower and tickUpper are essentially price boundaries recorded in exponential form. So, how can we calculate the price range for market-making from these &amp;quot;exponential boundaries&amp;quot;?&lt;br /&gt;&lt;br /&gt;It&amp;#39;s quite simple. Uniswap uses a base of ```1.0001```. Lower price: ```lowerPrice = 1.0001 ** tickLower```; Upper price: ```upperPrice = 1.0001 ** tickUpper```. The ```**``` operator represents exponentiation. For example, ```1.0001 ** 100``` calculates 1.0001 raised to the power of 100.&lt;br /&gt;&lt;br /&gt;This calculated price range is denominated in token1. But what if we want to see the price range denominated in token0?&lt;br /&gt;&lt;br /&gt;It can be calculated as follows:&lt;br /&gt;Lower price: 1.0001 ** -tickUpper&lt;br /&gt;Upper price: 1.0001 ** -tickLower&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149684
" title="https://stocksharp.com/file/149684
"&gt;https://stocksharp.com/file/149684
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Compare this to the NFT position we looked up on the chain:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149685
" title="https://stocksharp.com/file/149685
"&gt;https://stocksharp.com/file/149685
&lt;/a&gt;&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149686
" title="https://stocksharp.com/file/149686
"&gt;https://stocksharp.com/file/149686
&lt;/a&gt;&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149687
" title="https://stocksharp.com/file/149687
"&gt;https://stocksharp.com/file/149687
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Parsing the Asset Value in the Current Liquidity Position&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In addition to tickUpper and tickLower, the positions method of Uniswap&amp;#39;s NonfungiblePositionManager contract returns another important data: liquidity.&lt;br /&gt;&lt;br /&gt;By combining the liquidity, tickUpper, tickLower data from the position information with the current price data in the exchange pool, we can calculate the asset value in the current liquidity position.&lt;br /&gt;&lt;br /&gt;You may wonder why we need to know the current price in the exchange pool to make the calculation.&lt;br /&gt;&lt;br /&gt;This is because once you add liquidity, any price changes within the effective range of your liquidity position imply that your assets have been exchanged. If the current exchange price is not within the effective range of your liquidity provision, there won&amp;#39;t be any changes. Therefore, there are three scenarios to consider when calculating:&lt;br /&gt;&lt;br /&gt;- The tick of the current price is less than tickLower.&lt;br /&gt;- The tick of the current price is greater than tickUpper.&lt;br /&gt;- The tick of the current price is within the range of tickLower to tickUpper.&lt;br /&gt;&lt;br /&gt;This corresponds to the following calculation and processing in the code:&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;    if (currentTick &amp;lt;= posData.tickLower) {&lt;br /&gt;        amount0wei = Math.floor(posData.liquidity * ((sqrtRatioB - sqrtRatioA) / (sqrtRatioA * sqrtRatioB)))&lt;br /&gt;    } else if (currentTick &amp;gt; posData.tickUpper) {&lt;br /&gt;        amount1wei = Math.floor(posData.liquidity * (sqrtRatioB - sqrtRatioA))&lt;br /&gt;    } else if (currentTick &amp;gt;= posData.tickLower &amp;amp;&amp;amp; currentTick &amp;lt; posData.tickUpper) {&lt;br /&gt;        amount0wei = Math.floor(posData.liquidity * ((sqrtRatioB - sqrtPrice) / (sqrtPrice * sqrtRatioB)))&lt;br /&gt;        amount1wei = Math.floor(posData.liquidity * (sqrtPrice - sqrtRatioA))&lt;br /&gt;    }&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;To perform the above calculations, we need to obtain the tick of the current price, which can be obtained directly from the pool contract. To get the address of the pool contract, we can use the getPool method of Uniswap&amp;#39;s factory contract. By using the ```slot0``` method of the pool contract, we can retrieve the current price information, including the tick value we need.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149688
" title="https://stocksharp.com/file/149688
"&gt;https://stocksharp.com/file/149688
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y6x6iLLUqIMFJAk1dYxX-PKODE2xLmQn5pc1B_afih5X8YEwANTJSRfvIDDF9IQbcJWCPI-QGIvuoune2CBaw7e3WRpW5WimOlsXMnXhuqcv5LhUdCfs_gock8XjlwRdMqQ" title="https://blog.mathquant.com/2023/07/21/fmz-quant-uniswap-v3-exchange-pool-liquidity-related-operations-guide-part-1.html"&gt;https://blog.mathquant.c...ations-guide-part-1.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25629/</id>
    <title type="text">Thoughts on High-Frequency Trading Strategies (5)</title>
    <published>2024-03-26T07:20:05Z</published>
    <updated>2024-03-26T07:20:05Z</updated>
    <author>
      <name>FMZQuant</name>
      <uri>https://stocksharp.com/users/185759/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#strategy" />
    <category term="#data" />
    <category term="#market" />
    <category term="#fmz" />
    <category term="#exchange" />
    <category term="#highfrequency" />
    <category term="#parameter" />
    <category term="#crypto" />
    <category term="#order" />
    <content type="html">In the previous article, various methods for calculating mid-price were introduced, and a revised mid-price was proposed. In this article, we will delve deeper into this topic.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Data Required&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;We need order flow data and depth data for the top ten levels of the order book, collected from live trading with an update frequency of 100ms. For the sake of simplicity, we will not include real-time updates for the bid and ask prices. To reduce the data size, we have kept only 100,000 rows of depth data and separated the tick-by-tick market data into individual columns.&lt;br /&gt;&lt;br /&gt;In [1]:&lt;br /&gt;```&lt;br /&gt;from datetime import date,datetime&lt;br /&gt;import time&lt;br /&gt;import pandas as pd&lt;br /&gt;import numpy as np&lt;br /&gt;import matplotlib.pyplot as plt&lt;br /&gt;import ast&lt;br /&gt;%matplotlib inline&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [2]:&lt;br /&gt;```&lt;br /&gt;tick_size = 0.0001&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [3]:&lt;br /&gt;```&lt;br /&gt;trades = pd.read_csv(&amp;#39;YGGUSDT_aggTrade.csv&amp;#39;,names=[&amp;#39;type&amp;#39;,&amp;#39;event_time&amp;#39;, &amp;#39;agg_trade_id&amp;#39;,&amp;#39;symbol&amp;#39;, &amp;#39;price&amp;#39;, &amp;#39;quantity&amp;#39;, &amp;#39;first_trade_id&amp;#39;, &amp;#39;last_trade_id&amp;#39;,&lt;br /&gt;       &amp;#39;transact_time&amp;#39;, &amp;#39;is_buyer_maker&amp;#39;])&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [4]:&lt;br /&gt;```&lt;br /&gt;trades = trades.groupby([&amp;#39;transact_time&amp;#39;,&amp;#39;is_buyer_maker&amp;#39;]).agg({&lt;br /&gt;    &amp;#39;transact_time&amp;#39;:&amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;agg_trade_id&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;price&amp;#39;: &amp;#39;first&amp;#39;,&lt;br /&gt;    &amp;#39;quantity&amp;#39;: &amp;#39;sum&amp;#39;,&lt;br /&gt;    &amp;#39;first_trade_id&amp;#39;: &amp;#39;first&amp;#39;,&lt;br /&gt;    &amp;#39;last_trade_id&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;is_buyer_maker&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;})&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [5]:&lt;br /&gt;```&lt;br /&gt;trades.index = pd.to_datetime(trades[&amp;#39;transact_time&amp;#39;], unit=&amp;#39;ms&amp;#39;)&lt;br /&gt;trades.index.rename(&amp;#39;time&amp;#39;, inplace=True)&lt;br /&gt;trades[&amp;#39;interval&amp;#39;] = trades[&amp;#39;transact_time&amp;#39;] - trades[&amp;#39;transact_time&amp;#39;].shift()&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [6]:&lt;br /&gt;```&lt;br /&gt;depths = pd.read_csv(&amp;#39;YGGUSDT_depth.csv&amp;#39;,names=[&amp;#39;type&amp;#39;,&amp;#39;event_time&amp;#39;, &amp;#39;transact_time&amp;#39;,&amp;#39;symbol&amp;#39;, &amp;#39;u1&amp;#39;, &amp;#39;u2&amp;#39;, &amp;#39;u3&amp;#39;, &amp;#39;bids&amp;#39;,&amp;#39;asks&amp;#39;])&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [7]:&lt;br /&gt;```&lt;br /&gt;depths = depths.iloc[:100000]&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [8]:&lt;br /&gt;```&lt;br /&gt;depths[&amp;#39;bids&amp;#39;] = depths[&amp;#39;bids&amp;#39;].apply(ast.literal_eval).copy()&lt;br /&gt;depths[&amp;#39;asks&amp;#39;] = depths[&amp;#39;asks&amp;#39;].apply(ast.literal_eval).copy()&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [9]:&lt;br /&gt;```&lt;br /&gt;def expand_bid(bid_data):&lt;br /&gt;    expanded = {}&lt;br /&gt;    for j, (price, quantity) in enumerate(bid_data):&lt;br /&gt;        expanded[f&amp;#39;bid_{j}_price&amp;#39;] = float(price)&lt;br /&gt;        expanded[f&amp;#39;bid_{j}_quantity&amp;#39;] = float(quantity)&lt;br /&gt;    return pd.Series(expanded)&lt;br /&gt;def expand_ask(ask_data):&lt;br /&gt;    expanded = {}&lt;br /&gt;    for j, (price, quantity) in enumerate(ask_data):&lt;br /&gt;        expanded[f&amp;#39;ask_{j}_price&amp;#39;] = float(price)&lt;br /&gt;        expanded[f&amp;#39;ask_{j}_quantity&amp;#39;] = float(quantity)&lt;br /&gt;    return pd.Series(expanded)&lt;br /&gt;# Apply to each line to get a new df&lt;br /&gt;expanded_df_bid = depths[&amp;#39;bids&amp;#39;].apply(expand_bid)&lt;br /&gt;expanded_df_ask = depths[&amp;#39;asks&amp;#39;].apply(expand_ask)&lt;br /&gt;# Expansion on the original df&lt;br /&gt;depths = pd.concat([depths, expanded_df_bid, expanded_df_ask], axis=1)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [10]:&lt;br /&gt;```&lt;br /&gt;depths.index = pd.to_datetime(depths[&amp;#39;transact_time&amp;#39;], unit=&amp;#39;ms&amp;#39;)&lt;br /&gt;depths.index.rename(&amp;#39;time&amp;#39;, inplace=True);&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [11]:&lt;br /&gt;```&lt;br /&gt;trades = trades[trades[&amp;#39;transact_time&amp;#39;] &amp;lt; depths[&amp;#39;transact_time&amp;#39;].iloc[-1]]&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Take a look at the distribution of the market in these 20 levels. It is in line with expectations, with more orders placed the further away from the market price. Additionally, buy orders and sell orders are roughly symmetrical.&lt;br /&gt;&lt;br /&gt;In [14]:&lt;br /&gt;```&lt;br /&gt;bid_mean_list = []&lt;br /&gt;ask_mean_list = []&lt;br /&gt;for i in range(20):&lt;br /&gt;    bid_mean_list.append(round(depths[f&amp;#39;bid_{i}_quantity&amp;#39;].mean(),0))&lt;br /&gt;    ask_mean_list.append(round(depths[f&amp;#39;ask_{i}_quantity&amp;#39;].mean(),0))&lt;br /&gt;plt.figure(figsize=(10, 5))&lt;br /&gt;plt.plot(bid_mean_list);&lt;br /&gt;plt.plot(ask_mean_list);&lt;br /&gt;plt.grid(True)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[14]:&lt;br /&gt;&lt;br /&gt;/upload/asset/28d4e2581a36fd970d055.png&lt;br /&gt;&lt;br /&gt;Merge the depth data with the transaction data to facilitate the evaluation of prediction accuracy. Ensure that the transaction data is later than the depth data. Without considering latency, directly calculate the mean squared error between the predicted value and the actual transaction price. This is used to measure the accuracy of the prediction.&lt;br /&gt;&lt;br /&gt;From the results, the error is highest for the average value of the bid and ask prices (mid_price). However, when changed to the weighted mid_price, the error immediately decreases significantly. Further improvement is observed by using the adjusted weighted mid_price. After receiving feedback on using I^3/2 only, it was checked and found that the results were better. Upon reflection, this is likely due to the different frequencies of events. When I is close to -1 and 1, it represents low probability events. In order to correct for these low probability events, the accuracy of predicting high-frequency events is compromised. Therefore, to prioritize high-frequency events, some adjustments were made (these parameters were purely trial-and-error and have limited practical significance in live trading).&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149678
" title="https://stocksharp.com/file/149678
"&gt;https://stocksharp.com/file/149678
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The results have improved slightly. As mentioned in the previous article, strategies should rely on more data for prediction. With the availability of more depth and order transaction data, the improvement gained from focusing on the order book is already weak.&lt;br /&gt;&lt;br /&gt;In [15]:&lt;br /&gt;```&lt;br /&gt;df = pd.merge_asof(trades, depths, on=&amp;#39;transact_time&amp;#39;, direction=&amp;#39;backward&amp;#39;)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [17]:&lt;br /&gt;```&lt;br /&gt;df[&amp;#39;spread&amp;#39;] = round(df[&amp;#39;ask_0_price&amp;#39;] - df[&amp;#39;bid_0_price&amp;#39;],4)&lt;br /&gt;df[&amp;#39;mid_price&amp;#39;] = (df[&amp;#39;bid_0_price&amp;#39;]+ df[&amp;#39;ask_0_price&amp;#39;]) / 2&lt;br /&gt;df[&amp;#39;I&amp;#39;] = (df[&amp;#39;bid_0_quantity&amp;#39;] - df[&amp;#39;ask_0_quantity&amp;#39;]) / (df[&amp;#39;bid_0_quantity&amp;#39;] + df[&amp;#39;ask_0_quantity&amp;#39;])&lt;br /&gt;df[&amp;#39;weight_mid_price&amp;#39;] = df[&amp;#39;mid_price&amp;#39;] + df[&amp;#39;spread&amp;#39;]*df[&amp;#39;I&amp;#39;]/2&lt;br /&gt;df[&amp;#39;adjust_mid_price&amp;#39;] = df[&amp;#39;mid_price&amp;#39;] + df[&amp;#39;spread&amp;#39;]*(df[&amp;#39;I&amp;#39;])*(df[&amp;#39;I&amp;#39;]**8+1)/4&lt;br /&gt;df[&amp;#39;adjust_mid_price_2&amp;#39;] = df[&amp;#39;mid_price&amp;#39;] + df[&amp;#39;spread&amp;#39;]*df[&amp;#39;I&amp;#39;]*(df[&amp;#39;I&amp;#39;]**2+1)/4&lt;br /&gt;df[&amp;#39;adjust_mid_price_3&amp;#39;] = df[&amp;#39;mid_price&amp;#39;] + df[&amp;#39;spread&amp;#39;]*df[&amp;#39;I&amp;#39;]**3/2&lt;br /&gt;df[&amp;#39;adjust_mid_price_4&amp;#39;] = df[&amp;#39;mid_price&amp;#39;] + df[&amp;#39;spread&amp;#39;]*(df[&amp;#39;I&amp;#39;]+0.3)*(df[&amp;#39;I&amp;#39;]**4+0.7)/3.8&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [18]:&lt;br /&gt;```&lt;br /&gt;print(&amp;#39;Mean value     Error in mid_price:&amp;#39;, ((df[&amp;#39;price&amp;#39;]-df[&amp;#39;mid_price&amp;#39;])**2).sum())&lt;br /&gt;print(&amp;#39;Error of pending order volume weighted mid_price:&amp;#39;, ((df[&amp;#39;price&amp;#39;]-df[&amp;#39;weight_mid_price&amp;#39;])**2).sum())&lt;br /&gt;print(&amp;#39;The error of the adjusted mid_price:&amp;#39;, ((df[&amp;#39;price&amp;#39;]-df[&amp;#39;adjust_mid_price&amp;#39;])**2).sum())&lt;br /&gt;print(&amp;#39;The error of the adjusted mid_price_2:&amp;#39;, ((df[&amp;#39;price&amp;#39;]-df[&amp;#39;adjust_mid_price_2&amp;#39;])**2).sum())&lt;br /&gt;print(&amp;#39;The error of the adjusted mid_price_3:&amp;#39;, ((df[&amp;#39;price&amp;#39;]-df[&amp;#39;adjust_mid_price_3&amp;#39;])**2).sum())&lt;br /&gt;print(&amp;#39;The error of the adjusted mid_price_4:&amp;#39;, ((df[&amp;#39;price&amp;#39;]-df[&amp;#39;adjust_mid_price_4&amp;#39;])**2).sum())&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[18]:&lt;br /&gt;&lt;br /&gt;Mean value     Error in mid_price: 0.0048751924999999845&lt;br /&gt;Error of pending order volume weighted mid_price: 0.0048373440193987035&lt;br /&gt;The error of the adjusted mid_price: 0.004803654771638586&lt;br /&gt;The error of the adjusted mid_price_2: 0.004808216498329721&lt;br /&gt;The error of the adjusted mid_price_3: 0.004794984755260528&lt;br /&gt;The error of the adjusted mid_price_4: 0.0047909595497071375&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Consider the Second Level of Depth&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;We can follow the approach from the previous article to examine different ranges of a parameter and measure its contribution to the mid_price based on the changes in transaction price. Similar to the first level of depth, as I increases, the transaction price is more likely to increase, indicating a positive contribution from I.&lt;br /&gt;&lt;br /&gt;Applying the same approach to the second level of depth, we find that although the effect is slightly smaller than the first level, it is still significant and should not be ignored. The third level of depth also shows a weak contribution, but with less monotonicity. Deeper depths have little reference value.&lt;br /&gt;&lt;br /&gt;Based on the different contributions, we assign different weights to these three levels of imbalance parameters. By examining different calculation methods, we observe further reduction in prediction errors.&lt;br /&gt;&lt;br /&gt;In [19]:&lt;br /&gt;```&lt;br /&gt;bins = np.linspace(-1, 1, 50)&lt;br /&gt;df[&amp;#39;change&amp;#39;] = (df[&amp;#39;price&amp;#39;].pct_change().shift(-1))/tick_size&lt;br /&gt;df[&amp;#39;I_bins&amp;#39;] = pd.cut(df[&amp;#39;I&amp;#39;], bins, labels=bins[1:])&lt;br /&gt;df[&amp;#39;I_2&amp;#39;] = (df[&amp;#39;bid_1_quantity&amp;#39;] - df[&amp;#39;ask_1_quantity&amp;#39;]) / (df[&amp;#39;bid_1_quantity&amp;#39;] + df[&amp;#39;ask_1_quantity&amp;#39;])&lt;br /&gt;df[&amp;#39;I_2_bins&amp;#39;] = pd.cut(df[&amp;#39;I_2&amp;#39;], bins, labels=bins[1:])&lt;br /&gt;df[&amp;#39;I_3&amp;#39;] = (df[&amp;#39;bid_2_quantity&amp;#39;] - df[&amp;#39;ask_2_quantity&amp;#39;]) / (df[&amp;#39;bid_2_quantity&amp;#39;] + df[&amp;#39;ask_2_quantity&amp;#39;])&lt;br /&gt;df[&amp;#39;I_3_bins&amp;#39;] = pd.cut(df[&amp;#39;I_3&amp;#39;], bins, labels=bins[1:])&lt;br /&gt;df[&amp;#39;I_4&amp;#39;] = (df[&amp;#39;bid_3_quantity&amp;#39;] - df[&amp;#39;ask_3_quantity&amp;#39;]) / (df[&amp;#39;bid_3_quantity&amp;#39;] + df[&amp;#39;ask_3_quantity&amp;#39;])&lt;br /&gt;df[&amp;#39;I_4_bins&amp;#39;] = pd.cut(df[&amp;#39;I_4&amp;#39;], bins, labels=bins[1:])&lt;br /&gt;fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(8, 5))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;axes[0][0].plot(df.groupby(&amp;#39;I_bins&amp;#39;)[&amp;#39;change&amp;#39;].mean())&lt;br /&gt;axes[0][0].set_title(&amp;#39;I&amp;#39;)&lt;br /&gt;axes[0][0].grid(True)&lt;br /&gt;&lt;br /&gt;axes[0][1].plot(df.groupby(&amp;#39;I_2_bins&amp;#39;)[&amp;#39;change&amp;#39;].mean())&lt;br /&gt;axes[0][1].set_title(&amp;#39;I 2&amp;#39;)&lt;br /&gt;axes[0][1].grid(True)&lt;br /&gt;&lt;br /&gt;axes[1][0].plot(df.groupby(&amp;#39;I_3_bins&amp;#39;)[&amp;#39;change&amp;#39;].mean())&lt;br /&gt;axes[1][0].set_title(&amp;#39;I 3&amp;#39;)&lt;br /&gt;axes[1][0].grid(True)&lt;br /&gt;&lt;br /&gt;axes[1][1].plot(df.groupby(&amp;#39;I_4_bins&amp;#39;)[&amp;#39;change&amp;#39;].mean())&lt;br /&gt;axes[1][1].set_title(&amp;#39;I 4&amp;#39;)&lt;br /&gt;axes[1][1].grid(True)&lt;br /&gt;plt.tight_layout();&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[19]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149683
" title="https://stocksharp.com/file/149683
"&gt;https://stocksharp.com/file/149683
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [20]:&lt;br /&gt;```&lt;br /&gt;df[&amp;#39;adjust_mid_price_4&amp;#39;] = df[&amp;#39;mid_price&amp;#39;] + df[&amp;#39;spread&amp;#39;]*(df[&amp;#39;I&amp;#39;]+0.3)*(df[&amp;#39;I&amp;#39;]**4+0.7)/3.8&lt;br /&gt;df[&amp;#39;adjust_mid_price_5&amp;#39;] = df[&amp;#39;mid_price&amp;#39;] + df[&amp;#39;spread&amp;#39;]*(0.7*df[&amp;#39;I&amp;#39;]+0.3*df[&amp;#39;I_2&amp;#39;])/2&lt;br /&gt;df[&amp;#39;adjust_mid_price_6&amp;#39;] = df[&amp;#39;mid_price&amp;#39;] + df[&amp;#39;spread&amp;#39;]*(0.7*df[&amp;#39;I&amp;#39;]+0.3*df[&amp;#39;I_2&amp;#39;])**3/2&lt;br /&gt;df[&amp;#39;adjust_mid_price_7&amp;#39;] = df[&amp;#39;mid_price&amp;#39;] + df[&amp;#39;spread&amp;#39;]*(0.7*df[&amp;#39;I&amp;#39;]+0.3*df[&amp;#39;I_2&amp;#39;]+0.3)*((0.7*df[&amp;#39;I&amp;#39;]+0.3*df[&amp;#39;I_2&amp;#39;])**4+0.7)/3.8&lt;br /&gt;df[&amp;#39;adjust_mid_price_8&amp;#39;] = df[&amp;#39;mid_price&amp;#39;] + df[&amp;#39;spread&amp;#39;]*(0.7*df[&amp;#39;I&amp;#39;]+0.2*df[&amp;#39;I_2&amp;#39;]+0.1*df[&amp;#39;I_3&amp;#39;]+0.3)*((0.7*df[&amp;#39;I&amp;#39;]+0.3*df[&amp;#39;I_2&amp;#39;]+0.1*df[&amp;#39;I_3&amp;#39;])**4+0.7)/3.8&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [21]:&lt;br /&gt;```&lt;br /&gt;print(&amp;#39;The error of the adjusted mid_price_4:&amp;#39;, ((df[&amp;#39;price&amp;#39;]-df[&amp;#39;adjust_mid_price_4&amp;#39;])**2).sum())&lt;br /&gt;print(&amp;#39;The error of the adjusted mid_price_5:&amp;#39;, ((df[&amp;#39;price&amp;#39;]-df[&amp;#39;adjust_mid_price_5&amp;#39;])**2).sum())&lt;br /&gt;print(&amp;#39;The error of the adjusted mid_price_6:&amp;#39;, ((df[&amp;#39;price&amp;#39;]-df[&amp;#39;adjust_mid_price_6&amp;#39;])**2).sum())&lt;br /&gt;print(&amp;#39;The error of the adjusted mid_price_7:&amp;#39;, ((df[&amp;#39;price&amp;#39;]-df[&amp;#39;adjust_mid_price_7&amp;#39;])**2).sum())&lt;br /&gt;print(&amp;#39;The error of the adjusted mid_price_8:&amp;#39;, ((df[&amp;#39;price&amp;#39;]-df[&amp;#39;adjust_mid_price_8&amp;#39;])**2).sum())&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[21]:&lt;br /&gt;&lt;br /&gt;The error of the adjusted mid_price_4: 0.0047909595497071375&lt;br /&gt;The error of the adjusted mid_price_5: 0.0047884350488318714&lt;br /&gt;The error of the adjusted mid_price_6: 0.0047778319053133735&lt;br /&gt;The error of the adjusted mid_price_7: 0.004773578540592192&lt;br /&gt;The error of the adjusted mid_price_8: 0.004771415189297518&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Considering the Transaction Data&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Transaction data directly reflects the extent of long and short positions. After all, transactions involve real money, while placing orders has much lower costs and can even involve intentional deception. Therefore, when predicting the mid_price, strategies should focus on the transaction data.&lt;br /&gt;&lt;br /&gt;In terms of form, we can define the imbalance of the average order arrival quantity as VI, with Vb and Vs representing the average quantity of buy and sell orders within a unit time interval, respectively.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149679
" title="https://stocksharp.com/file/149679
"&gt;https://stocksharp.com/file/149679
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The results show that the arrival quantity in a short period of time has the most significant impact on price change prediction. When VI is between 0.1 and 0.9, it is negatively correlated with price, while outside this range, it is positively correlated with price. This suggests that when the market is not extreme and mainly oscillates, the price tends to revert to the mean. However, in extreme market conditions, such as when there are a large number of buy orders overwhelming sell orders, a trend emerges. Even without considering these low probability scenarios, assuming a negative linear relationship between the trend and VI significantly reduces the prediction error of the mid_price. The coefficient &amp;quot;a&amp;quot; represents the weight of this relationship in the equation.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149681
" title="https://stocksharp.com/file/149681
"&gt;https://stocksharp.com/file/149681
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [22]:&lt;br /&gt;```&lt;br /&gt;alpha=0.1&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [23]:&lt;br /&gt;```&lt;br /&gt;df[&amp;#39;avg_buy_interval&amp;#39;] = None&lt;br /&gt;df[&amp;#39;avg_sell_interval&amp;#39;] = None&lt;br /&gt;df.loc[df[&amp;#39;is_buyer_maker&amp;#39;] == True, &amp;#39;avg_buy_interval&amp;#39;] = df[df[&amp;#39;is_buyer_maker&amp;#39;] == True][&amp;#39;transact_time&amp;#39;].diff().ewm(alpha=alpha).mean()&lt;br /&gt;df.loc[df[&amp;#39;is_buyer_maker&amp;#39;] == False, &amp;#39;avg_sell_interval&amp;#39;] = df[df[&amp;#39;is_buyer_maker&amp;#39;] == False][&amp;#39;transact_time&amp;#39;].diff().ewm(alpha=alpha).mean()&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [24]:&lt;br /&gt;```&lt;br /&gt;df[&amp;#39;avg_buy_quantity&amp;#39;] = None&lt;br /&gt;df[&amp;#39;avg_sell_quantity&amp;#39;] = None&lt;br /&gt;df.loc[df[&amp;#39;is_buyer_maker&amp;#39;] == True, &amp;#39;avg_buy_quantity&amp;#39;] = df[df[&amp;#39;is_buyer_maker&amp;#39;] == True][&amp;#39;quantity&amp;#39;].ewm(alpha=alpha).mean()&lt;br /&gt;df.loc[df[&amp;#39;is_buyer_maker&amp;#39;] == False, &amp;#39;avg_sell_quantity&amp;#39;] = df[df[&amp;#39;is_buyer_maker&amp;#39;] == False][&amp;#39;quantity&amp;#39;].ewm(alpha=alpha).mean()&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [25]:&lt;br /&gt;```&lt;br /&gt;df[&amp;#39;avg_buy_quantity&amp;#39;] = df[&amp;#39;avg_buy_quantity&amp;#39;].fillna(method=&amp;#39;ffill&amp;#39;)&lt;br /&gt;df[&amp;#39;avg_sell_quantity&amp;#39;] = df[&amp;#39;avg_sell_quantity&amp;#39;].fillna(method=&amp;#39;ffill&amp;#39;)&lt;br /&gt;df[&amp;#39;avg_buy_interval&amp;#39;] = df[&amp;#39;avg_buy_interval&amp;#39;].fillna(method=&amp;#39;ffill&amp;#39;)&lt;br /&gt;df[&amp;#39;avg_sell_interval&amp;#39;] = df[&amp;#39;avg_sell_interval&amp;#39;].fillna(method=&amp;#39;ffill&amp;#39;)&lt;br /&gt;&lt;br /&gt;df[&amp;#39;avg_buy_rate&amp;#39;] = 1000 / df[&amp;#39;avg_buy_interval&amp;#39;]&lt;br /&gt;df[&amp;#39;avg_sell_rate&amp;#39;] =1000 / df[&amp;#39;avg_sell_interval&amp;#39;]&lt;br /&gt;&lt;br /&gt;df[&amp;#39;avg_buy_volume&amp;#39;] = df[&amp;#39;avg_buy_rate&amp;#39;]*df[&amp;#39;avg_buy_quantity&amp;#39;]&lt;br /&gt;df[&amp;#39;avg_sell_volume&amp;#39;] = df[&amp;#39;avg_sell_rate&amp;#39;]*df[&amp;#39;avg_sell_quantity&amp;#39;]&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [26]:&lt;br /&gt;```&lt;br /&gt;df[&amp;#39;I&amp;#39;] = (df[&amp;#39;bid_0_quantity&amp;#39;]- df[&amp;#39;ask_0_quantity&amp;#39;]) / (df[&amp;#39;bid_0_quantity&amp;#39;] + df[&amp;#39;ask_0_quantity&amp;#39;])&lt;br /&gt;df[&amp;#39;OI&amp;#39;] = (df[&amp;#39;avg_buy_rate&amp;#39;]-df[&amp;#39;avg_sell_rate&amp;#39;]) / (df[&amp;#39;avg_buy_rate&amp;#39;] + df[&amp;#39;avg_sell_rate&amp;#39;])&lt;br /&gt;df[&amp;#39;QI&amp;#39;] = (df[&amp;#39;avg_buy_quantity&amp;#39;]-df[&amp;#39;avg_sell_quantity&amp;#39;]) / (df[&amp;#39;avg_buy_quantity&amp;#39;] + df[&amp;#39;avg_sell_quantity&amp;#39;])&lt;br /&gt;df[&amp;#39;VI&amp;#39;] = (df[&amp;#39;avg_buy_volume&amp;#39;]-df[&amp;#39;avg_sell_volume&amp;#39;]) / (df[&amp;#39;avg_buy_volume&amp;#39;] + df[&amp;#39;avg_sell_volume&amp;#39;])&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [27]:&lt;br /&gt;```&lt;br /&gt;bins = np.linspace(-1, 1, 50)&lt;br /&gt;df[&amp;#39;VI_bins&amp;#39;] = pd.cut(df[&amp;#39;VI&amp;#39;], bins, labels=bins[1:])&lt;br /&gt;plt.plot(df.groupby(&amp;#39;VI_bins&amp;#39;)[&amp;#39;change&amp;#39;].mean());&lt;br /&gt;plt.grid(True)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[27]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149680
" title="https://stocksharp.com/file/149680
"&gt;https://stocksharp.com/file/149680
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [28]:&lt;br /&gt;```&lt;br /&gt;df[&amp;#39;adjust_mid_price&amp;#39;] = df[&amp;#39;mid_price&amp;#39;] + df[&amp;#39;spread&amp;#39;]*df[&amp;#39;I&amp;#39;]/2&lt;br /&gt;df[&amp;#39;adjust_mid_price_9&amp;#39;] = df[&amp;#39;mid_price&amp;#39;] + df[&amp;#39;spread&amp;#39;]*(-df[&amp;#39;OI&amp;#39;])*2&lt;br /&gt;df[&amp;#39;adjust_mid_price_10&amp;#39;] = df[&amp;#39;mid_price&amp;#39;] + df[&amp;#39;spread&amp;#39;]*(-df[&amp;#39;VI&amp;#39;])*1.4&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [29]:&lt;br /&gt;```&lt;br /&gt;print(&amp;#39;The error of the adjusted mid_price:&amp;#39;, ((df[&amp;#39;price&amp;#39;]-df[&amp;#39;adjust_mid_price&amp;#39;])**2).sum())&lt;br /&gt;print(&amp;#39;The error of the adjusted mid_price_9:&amp;#39;, ((df[&amp;#39;price&amp;#39;]-df[&amp;#39;adjust_mid_price_9&amp;#39;])**2).sum())&lt;br /&gt;print(&amp;#39;The error of the adjusted mid_price_10:&amp;#39;, ((df[&amp;#39;price&amp;#39;]-df[&amp;#39;adjust_mid_price_10&amp;#39;])**2).sum())&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[29]:&lt;br /&gt;&lt;br /&gt;The error of the adjusted mid_price: 0.0048373440193987035&lt;br /&gt;The error of the adjusted mid_price_9: 0.004629586542840461&lt;br /&gt;The error of the adjusted mid_price_10: 0.004401790287167206&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Comprehensive Mid-price&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Considering that both order book imbalance and transaction data are helpful for predicting the mid_price, we can combine these two parameters together. The assignment of weights in this case is arbitrary and does not take into account boundary conditions. In extreme cases, the predicted mid_price may not fall between the bid and ask prices. However, as long as the prediction error can be reduced, these details are not of great concern.&lt;br /&gt;&lt;br /&gt;In the end, the prediction error is reduced from 0.00487 to 0.0043. At this point, we will not delve further into the topic. There are still many aspects to explore when it comes to predicting the mid_price, as it is essentially predicting the price itself. Everyone is encouraged to try their own approaches and techniques.&lt;br /&gt;&lt;br /&gt;In [30]:&lt;br /&gt;```&lt;br /&gt;#Note that the VI needs to be delayed by one to use&lt;br /&gt;df[&amp;#39;CI&amp;#39;] = -1.5*df[&amp;#39;VI&amp;#39;].shift()+0.7*(0.7*df[&amp;#39;I&amp;#39;]+0.2*df[&amp;#39;I_2&amp;#39;]+0.1*df[&amp;#39;I_3&amp;#39;])**3 &lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [31]:&lt;br /&gt;```&lt;br /&gt;df[&amp;#39;adjust_mid_price_11&amp;#39;] = df[&amp;#39;mid_price&amp;#39;] + df[&amp;#39;spread&amp;#39;]*(df[&amp;#39;CI&amp;#39;])&lt;br /&gt;print(&amp;#39;The error of the adjusted mid_price_11:&amp;#39;, ((df[&amp;#39;price&amp;#39;]-df[&amp;#39;adjust_mid_price_11&amp;#39;])**2).sum())&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[31]:&lt;br /&gt;&lt;br /&gt;The error of the adjusted mid_price_11: 0.0043001941412563575&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The article combines depth data and transaction data to further improve the calculation method of the mid-price. It provides a method to measure accuracy and improves the accuracy of price change prediction. Overall, the parameters are not rigorous and are for reference only. With a more accurate mid-price, the next step is to conduct backtesting using the mid-price in practical applications. This part of the content is extensive, so updates will be paused for a period of time.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y67qq0yhtjdH5OJdvZRK-DU65XMv9S5xjTGa2LUWYX_21frTV3Cpue8TTeNEtAxk5cUFyLveinbFYypTvDTfSrvI" title="https://blog.mathquant.com/2023/08/10/thoughts-on-high-frequency-trading-strategies-5.html"&gt;https://blog.mathquant.c...rading-strategies-5.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25628/</id>
    <title type="text">Thoughts on High-Frequency Trading Strategies (4)</title>
    <published>2024-03-26T05:11:42Z</published>
    <updated>2024-03-26T05:11:42Z</updated>
    <author>
      <name>FMZQuant</name>
      <uri>https://stocksharp.com/users/185759/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#strategy" />
    <category term="#code" />
    <category term="#data" />
    <category term="#market" />
    <category term="#binance" />
    <category term="#highfrequency" />
    <category term="#parameter" />
    <category term="#FMZQuant" />
    <category term="#quote" />
    <content type="html">The previous article demonstrated the need for dynamically adjusting parameters and how to evaluate the quality of estimates by studying the order arrival intervals. This article will focus on depth data and study the mid-price (also known as fair-price or micro-price).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Depth Data&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Binance provides historical data downloads for best_bid_price (the highest buying price), best_bid_quantity (the quantity at the best bid price), best_ask_price (the lowest selling price), best_ask_quantity (the quantity at the best ask price), and transaction_time. This data does not include the second or deeper order book levels. The analysis in this article is based on the YGG market on August 7th, which experienced significant volatility with over 9 million data points.&lt;br /&gt;&lt;br /&gt;First, let&amp;#39;s take a look at the market conditions on that day. There were large fluctuations, and the order book volume changed significantly along with the market volatility. The spread, particularly, indicated the extent of market fluctuations, which is the difference between the best ask and bid prices. In the statistics of the YGG market on that day, the spread was larger than one tick for 20% of the time. In this era of various trading bots competing in the order book, such situations are becoming increasingly rare.&lt;br /&gt;&lt;br /&gt;In [1]:&lt;br /&gt;```&lt;br /&gt;from datetime import date,datetime&lt;br /&gt;import time&lt;br /&gt;import pandas as pd&lt;br /&gt;import numpy as np&lt;br /&gt;import matplotlib.pyplot as plt&lt;br /&gt;%matplotlib inline&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [2]:&lt;br /&gt;```&lt;br /&gt;books = pd.read_csv(&amp;#39;YGGUSDT-bookTicker-2023-08-07.csv&amp;#39;)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [3]:&lt;br /&gt;```&lt;br /&gt;tick_size = 0.0001&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [4]:&lt;br /&gt;```&lt;br /&gt;books[&amp;#39;date&amp;#39;] = pd.to_datetime(books[&amp;#39;transaction_time&amp;#39;], unit=&amp;#39;ms&amp;#39;)&lt;br /&gt;books.index = books[&amp;#39;date&amp;#39;]&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [5]:&lt;br /&gt;```&lt;br /&gt;books[&amp;#39;spread&amp;#39;] = round(books[&amp;#39;best_ask_price&amp;#39;] - books[&amp;#39;best_bid_price&amp;#39;],4)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [6]:&lt;br /&gt;```&lt;br /&gt;books[&amp;#39;best_bid_price&amp;#39;][::10].plot(figsize=(10,5),grid=True);&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[6]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149672
" title="https://stocksharp.com/file/149672
"&gt;https://stocksharp.com/file/149672
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [7]:&lt;br /&gt;```&lt;br /&gt;books[&amp;#39;best_bid_qty&amp;#39;][::10].rolling(10000).mean().plot(figsize=(10,5),grid=True);&lt;br /&gt;books[&amp;#39;best_ask_qty&amp;#39;][::10].rolling(10000).mean().plot(figsize=(10,5),grid=True);&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[7]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149677
" title="https://stocksharp.com/file/149677
"&gt;https://stocksharp.com/file/149677
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [8]:&lt;br /&gt;```&lt;br /&gt;(books[&amp;#39;spread&amp;#39;][::10]/tick_size).rolling(10000).mean().plot(figsize=(10,5),grid=True);&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[8]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149675
" title="https://stocksharp.com/file/149675
"&gt;https://stocksharp.com/file/149675
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [9]:&lt;br /&gt;```&lt;br /&gt;books[&amp;#39;spread&amp;#39;].value_counts()[books[&amp;#39;spread&amp;#39;].value_counts()&amp;gt;500]/books[&amp;#39;spread&amp;#39;].value_counts().sum()&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[9]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149667
" title="https://stocksharp.com/file/149667
"&gt;https://stocksharp.com/file/149667
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Imbalanced Quotes&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Imbalanced quotes are observed from the significant difference in the order book volumes between the buy and sell orders most of the time. This difference has a strong predictive effect on short-term market trends, similar to the reason mentioned earlier that a decrease in buy order volume often leads to a decline. If one side of the order book is significantly smaller than the other, assuming the active buying and selling orders are similar in volume, there is a greater likelihood of the smaller side being consumed, thereby driving price changes. Imbalanced quotes are represented by the letter &amp;quot;I&amp;quot;.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149671
" title="https://stocksharp.com/file/149671
"&gt;https://stocksharp.com/file/149671
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Where Q_b represents the amount of pending buy orders (best_bid_qty) and Q_a represents the amount of pending sell orders (best_ask_qty).&lt;br /&gt;&lt;br /&gt;Define mid-price:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149674
" title="https://stocksharp.com/file/149674
"&gt;https://stocksharp.com/file/149674
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The graph below shows the relationship between the rate of change of mid-price over the next 1 interval and the imbalance I. As expected, the more likely the price is to increase as I increases and the closer it gets to 1, the more the price change accelerates. In high-frequency trading, the introduction of the intermediate price is to better predict future price changes, that is, and the future price difference is smaller, the better the intermediate price is defined. Obviously the imbalance of pending orders provides additional information for the prediction of the strategy, with this in mind, defining the weighted mid-price:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149668
" title="https://stocksharp.com/file/149668
"&gt;https://stocksharp.com/file/149668
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [10]:&lt;br /&gt;```&lt;br /&gt;books[&amp;#39;I&amp;#39;] = books[&amp;#39;best_bid_qty&amp;#39;] / (books[&amp;#39;best_bid_qty&amp;#39;] + books[&amp;#39;best_ask_qty&amp;#39;])&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [11]:&lt;br /&gt;```&lt;br /&gt;books[&amp;#39;mid_price&amp;#39;] = (books[&amp;#39;best_ask_price&amp;#39;] + books[&amp;#39;best_bid_price&amp;#39;])/2&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [12]:&lt;br /&gt;```&lt;br /&gt;bins = np.linspace(0, 1, 51)&lt;br /&gt;books[&amp;#39;I_bins&amp;#39;] = pd.cut(books[&amp;#39;I&amp;#39;], bins, labels=bins[1:])&lt;br /&gt;books[&amp;#39;price_change&amp;#39;] = (books[&amp;#39;mid_price&amp;#39;].pct_change()/tick_size).shift(-1)&lt;br /&gt;avg_change = books.groupby(&amp;#39;I_bins&amp;#39;)[&amp;#39;price_change&amp;#39;].mean()&lt;br /&gt;plt.figure(figsize=(8,5))&lt;br /&gt;plt.plot(avg_change)&lt;br /&gt;plt.xlabel(&amp;#39;I Value Range&amp;#39;)&lt;br /&gt;plt.ylabel(&amp;#39;Average Mid Price Change Rate&amp;#39;);&lt;br /&gt;plt.grid(True)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[12]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149663
" title="https://stocksharp.com/file/149663
"&gt;https://stocksharp.com/file/149663
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [13]:&lt;br /&gt;```&lt;br /&gt;books[&amp;#39;weighted_mid_price&amp;#39;] = books[&amp;#39;mid_price&amp;#39;] + books[&amp;#39;spread&amp;#39;]*books[&amp;#39;I&amp;#39;]/2&lt;br /&gt;bins = np.linspace(-1, 1, 51)&lt;br /&gt;books[&amp;#39;I_bins&amp;#39;] = pd.cut(books[&amp;#39;I&amp;#39;], bins, labels=bins[1:])&lt;br /&gt;books[&amp;#39;weighted_price_change&amp;#39;] = (books[&amp;#39;weighted_mid_price&amp;#39;].pct_change()/tick_size).shift(-1)&lt;br /&gt;avg_change = books.groupby(&amp;#39;I_bins&amp;#39;)[&amp;#39;weighted_price_change&amp;#39;].mean()&lt;br /&gt;plt.figure(figsize=(8,5))&lt;br /&gt;plt.plot(avg_change)&lt;br /&gt;plt.xlabel(&amp;#39;I Value Range&amp;#39;)&lt;br /&gt;plt.ylabel(&amp;#39;Weighted Average Mid Price Change Rate&amp;#39;);&lt;br /&gt;plt.grid(True)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[13]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149670
" title="https://stocksharp.com/file/149670
"&gt;https://stocksharp.com/file/149670
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Adjust Weighted Mid-Price:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;From the graph, it can be observed that the weighted mid-price shows smaller variations compared to different values of I, indicating that it is a better fit. However, there are still some deviations, particularly around 0.2 and 0.8. This suggests that I still provides additional information. The assumption of a completely linear relationship between the price correction term and I, as implied by the weighted mid-price, does not align with reality. It can be seen from the graph that the deviation speed increases when I approaches 0 and 1, indicating a non-linear relationship.&lt;br /&gt;&lt;br /&gt;To provide a more intuitive representation, here is a redefinition of I:&lt;br /&gt;&lt;br /&gt;Revised definition of I:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149666
" title="https://stocksharp.com/file/149666
"&gt;https://stocksharp.com/file/149666
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;At this point:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149673
" title="https://stocksharp.com/file/149673
"&gt;https://stocksharp.com/file/149673
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Upon observation, it can be noticed that the weighted mid-price is a correction to the average mid-price, where the correction term is multiplied by the spread. The correction term is a function of I, and the weighted mid-price assumes a simple relationship of I/2. In this case, the advantage of the adjusted I distribution (-1, 1) becomes apparent, as I is symmetric around the origin, making it convenient to find a fitting relationship for the function. By examining the graph, it appears that this function should satisfy odd powers of I, as it aligns with the rapid growth on both sides and symmetry around the origin. Additionally, it can be observed that values near the origin are close to linear. Furthermore, when I is 0, the function result is 0, and when I is 1, the function result is 0.5. Therefore, it is speculated that the function is of the form:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149665
" title="https://stocksharp.com/file/149665
"&gt;https://stocksharp.com/file/149665
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here N is a positive even number, after actual testing, it is better when N is 8. So far this paper presents the modified weighted mid-price:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149664
" title="https://stocksharp.com/file/149664
"&gt;https://stocksharp.com/file/149664
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;At this point, the prediction of mid-price changes is no longer significantly related to I. Although this result is slightly better than the simple weighted mid-price, it is still not applicable in real trading scenarios. This is just a proposed approach. In a 2017 article by S Stoikov, the concept of [Micro-Price](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2970694) is introduced using a Markov chain approach, and related code is provided. Researchers can explore this approach further.&lt;br /&gt;&lt;br /&gt;In [14]:&lt;br /&gt;```&lt;br /&gt;books[&amp;#39;I&amp;#39;] = (books[&amp;#39;best_bid_qty&amp;#39;] - books[&amp;#39;best_ask_qty&amp;#39;]) / (books[&amp;#39;best_bid_qty&amp;#39;] + books[&amp;#39;best_ask_qty&amp;#39;])&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [15]:&lt;br /&gt;```&lt;br /&gt;books[&amp;#39;weighted_mid_price&amp;#39;] = books[&amp;#39;mid_price&amp;#39;] + books[&amp;#39;spread&amp;#39;]*books[&amp;#39;I&amp;#39;]/2&lt;br /&gt;bins = np.linspace(-1, 1, 51)&lt;br /&gt;books[&amp;#39;I_bins&amp;#39;] = pd.cut(books[&amp;#39;I&amp;#39;], bins, labels=bins[1:])&lt;br /&gt;books[&amp;#39;weighted_price_change&amp;#39;] = (books[&amp;#39;weighted_mid_price&amp;#39;].pct_change()/tick_size).shift(-1)&lt;br /&gt;avg_change = books.groupby(&amp;#39;I_bins&amp;#39;)[&amp;#39;weighted_price_change&amp;#39;].mean()&lt;br /&gt;plt.figure(figsize=(8,5))&lt;br /&gt;plt.plot(avg_change)&lt;br /&gt;plt.xlabel(&amp;#39;I Value Range&amp;#39;)&lt;br /&gt;plt.ylabel(&amp;#39;Weighted Average Mid Price Change Rate&amp;#39;);&lt;br /&gt;plt.grid(True)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[15]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149669
" title="https://stocksharp.com/file/149669
"&gt;https://stocksharp.com/file/149669
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [16]:&lt;br /&gt;```&lt;br /&gt;books[&amp;#39;adjust_mid_price&amp;#39;] = books[&amp;#39;mid_price&amp;#39;] + books[&amp;#39;spread&amp;#39;]*books[&amp;#39;I&amp;#39;]*(books[&amp;#39;I&amp;#39;]**8+1)/4&lt;br /&gt;bins = np.linspace(-1, 1, 51)&lt;br /&gt;books[&amp;#39;I_bins&amp;#39;] = pd.cut(books[&amp;#39;I&amp;#39;], bins, labels=bins[1:])&lt;br /&gt;books[&amp;#39;adjust_mid_price&amp;#39;] = (books[&amp;#39;adjust_mid_price&amp;#39;].pct_change()/tick_size).shift(-1)&lt;br /&gt;avg_change = books.groupby(&amp;#39;I_bins&amp;#39;)[&amp;#39;adjust_mid_price&amp;#39;].mean()&lt;br /&gt;plt.figure(figsize=(8,5))&lt;br /&gt;plt.plot(avg_change)&lt;br /&gt;plt.xlabel(&amp;#39;I Value Range&amp;#39;)&lt;br /&gt;plt.ylabel(&amp;#39;Weighted Average Mid Price Change Rate&amp;#39;);&lt;br /&gt;plt.grid(True)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[16]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149676
" title="https://stocksharp.com/file/149676
"&gt;https://stocksharp.com/file/149676
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The mid-price is crucial for high-frequency strategies as it serves as a prediction of short-term future prices. Therefore, it is important for the mid-price to be as accurate as possible. The mid-price approaches discussed earlier are based on order book data, as only the top level of the order book is utilized in the analysis. In live trading, strategies should aim to utilize all available data, including trade data, to validate mid-price predictions against actual transaction prices. I recall Stoikov mentioning in a Twitter that the real mid-price should be a weighted average of the probabilities of the bid and ask prices being executed. This issue has been explored in the previous articles. Due to length constraints, further details on these topics will be discussed in the next article.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y67qq0yhtjdH5OJdvZRK-DU65XMv9S5xjTGa2LUWYX_21frTV3Cpue8TTeNEtAxk5cdHrubA_Wj4n1z7tWuaJLSw" title="https://blog.mathquant.com/2023/08/10/thoughts-on-high-frequency-trading-strategies-4.html"&gt;https://blog.mathquant.c...rading-strategies-4.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25627/</id>
    <title type="text">Thoughts on High-Frequency Trading Strategies (3)</title>
    <published>2024-03-26T03:09:54Z</published>
    <updated>2024-03-26T03:09:54Z</updated>
    <author>
      <name>FMZQuant</name>
      <uri>https://stocksharp.com/users/185759/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#strategy" />
    <category term="#code" />
    <category term="#data" />
    <category term="#market" />
    <category term="#fmz" />
    <category term="#highfrequency" />
    <category term="#crypto" />
    <category term="#order" />
    <category term="#BTC" />
    <content type="html">In the previous article, I introduced how to model cumulative trading volume and analyzed the phenomenon of price impact. In this article, I will continue to analyze the trades order data. YGG recently launched Binance U-based contracts, and the price fluctuations have been significant, with trading volume even surpassing BTC at one point. Today, I will analyze it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Order Time Intervals&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In general, it is assumed that the arrival time of orders follows a Poisson process. There is an article that introduces the [Poisson process](https://www.ruanyifeng.com/blog/2015/06/poisson-distribution.html) . Here, I will provide empirical evidence.&lt;br /&gt;&lt;br /&gt;I downloaded the aggTrades data for August 5th, which consists of 1,931,193 trades, which is quite significant. First, let&amp;#39;s take a look at the distribution of buy orders. We can see a non-smooth local peak around 100ms and 500ms, which is likely caused by iceberg orders placed by trading bots at regular intervals. This may also be one of the reasons for the unusual market conditions that day.&lt;br /&gt;&lt;br /&gt;The probability mass function (PMF) of the Poisson distribution is given by the following formula:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149661
" title="https://stocksharp.com/file/149661
"&gt;https://stocksharp.com/file/149661
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Where:&lt;br /&gt;&lt;br /&gt;- κ is the number of events we are interested in.&lt;br /&gt;- λ is the average rate of events occurring per unit time (or unit space).&lt;br /&gt;- &lt;a href="https://stocksharp.com/file/149657 " title="https://stocksharp.com/file/149657 "&gt;https://stocksharp.com/file/149657 &lt;/a&gt;represents the probability of exactly κ events occurring, given the average rate λ.&lt;br /&gt;&lt;br /&gt;In a Poisson process, the time intervals between events follow an exponential distribution. The probability density function (PDF) of the exponential distribution is given by the following formula:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149655
" title="https://stocksharp.com/file/149655
"&gt;https://stocksharp.com/file/149655
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The fitting results show that there is a significant difference between the observed data and the expected Poisson distribution. The Poisson process underestimates the frequency of long time intervals and overestimates the frequency of short time intervals. (The actual distribution of intervals is closer to a modified Pareto distribution)&lt;br /&gt;&lt;br /&gt;In [1]:&lt;br /&gt;```&lt;br /&gt;from datetime import date,datetime&lt;br /&gt;import time&lt;br /&gt;import pandas as pd&lt;br /&gt;import numpy as np&lt;br /&gt;import matplotlib.pyplot as plt&lt;br /&gt;%matplotlib inline&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [2]:&lt;br /&gt;```&lt;br /&gt;trades = pd.read_csv(&amp;#39;YGGUSDT-aggTrades-2023-08-05.csv&amp;#39;)&lt;br /&gt;trades[&amp;#39;date&amp;#39;] = pd.to_datetime(trades[&amp;#39;transact_time&amp;#39;], unit=&amp;#39;ms&amp;#39;)&lt;br /&gt;trades.index = trades[&amp;#39;date&amp;#39;]&lt;br /&gt;buy_trades = trades[trades[&amp;#39;is_buyer_maker&amp;#39;]==False].copy()&lt;br /&gt;buy_trades = buy_trades.groupby(&amp;#39;transact_time&amp;#39;).agg({&lt;br /&gt;    &amp;#39;agg_trade_id&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;price&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;quantity&amp;#39;: &amp;#39;sum&amp;#39;,&lt;br /&gt;    &amp;#39;first_trade_id&amp;#39;: &amp;#39;first&amp;#39;,&lt;br /&gt;    &amp;#39;last_trade_id&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;is_buyer_maker&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;date&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;transact_time&amp;#39;:&amp;#39;last&amp;#39;&lt;br /&gt;})&lt;br /&gt;buy_trades[&amp;#39;interval&amp;#39;]=buy_trades[&amp;#39;transact_time&amp;#39;] - buy_trades[&amp;#39;transact_time&amp;#39;].shift()&lt;br /&gt;buy_trades.index = buy_trades[&amp;#39;date&amp;#39;]&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [10]:&lt;br /&gt;```&lt;br /&gt;buy_trades[&amp;#39;interval&amp;#39;][buy_trades[&amp;#39;interval&amp;#39;]&amp;lt;1000].plot.hist(bins=200,figsize=(10, 5));&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[10]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149656
" title="https://stocksharp.com/file/149656
"&gt;https://stocksharp.com/file/149656
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [20]:&lt;br /&gt;```&lt;br /&gt;Intervals = np.array(range(0, 1000, 5))&lt;br /&gt;mean_intervals = buy_trades[&amp;#39;interval&amp;#39;].mean()&lt;br /&gt;buy_rates = 1000/mean_intervals&lt;br /&gt;probabilities = np.array([np.mean(buy_trades[&amp;#39;interval&amp;#39;] &amp;gt; interval)  for interval in Intervals])&lt;br /&gt;probabilities_s = np.array([np.e**(-buy_rates*interval/1000) for interval in Intervals])&lt;br /&gt;&lt;br /&gt;plt.figure(figsize=(10, 5))&lt;br /&gt;plt.plot(Intervals, probabilities)&lt;br /&gt;plt.plot(Intervals, probabilities_s)&lt;br /&gt;plt.xlabel(&amp;#39;Intervals&amp;#39;)&lt;br /&gt;plt.ylabel(&amp;#39;Probability&amp;#39;)&lt;br /&gt;plt.grid(True)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[20]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149659
" title="https://stocksharp.com/file/149659
"&gt;https://stocksharp.com/file/149659
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;When comparing the distribution of the number of order occurrences within 1 second with the Poisson distribution, the difference is also significant. The Poisson distribution significantly underestimates the frequency of rare events. Possible reasons for this are:&lt;br /&gt;&lt;br /&gt;- Non-constant rate of occurrence: The Poisson process assumes that the average rate of events occurring within any given time interval is constant. If this assumption does not hold, then the distribution of the data will deviate from the Poisson distribution.&lt;br /&gt;- Interactions between processes: Another fundamental assumption of the Poisson process is that events are independent of each other. If events in the real world interact with each other, their distribution may deviate from the Poisson distribution.&lt;br /&gt;&lt;br /&gt;In other words, in a real-world environment, the frequency of order occurrences is non-constant, and it needs to be updated in real-time. There may also be an incentive effect, where more orders within a fixed time period stimulate more orders. This makes strategies unable to rely on a single fixed parameter.&lt;br /&gt;&lt;br /&gt;In [190]:&lt;br /&gt;```&lt;br /&gt;result_df = buy_trades.resample(&amp;#39;1S&amp;#39;).agg({ &lt;br /&gt;    &amp;#39;price&amp;#39;: &amp;#39;count&amp;#39;,&lt;br /&gt;    &amp;#39;quantity&amp;#39;: &amp;#39;sum&amp;#39;&lt;br /&gt;}).rename(columns={&amp;#39;price&amp;#39;: &amp;#39;order_count&amp;#39;, &amp;#39;quantity&amp;#39;: &amp;#39;quantity_sum&amp;#39;})&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [219]:&lt;br /&gt;```&lt;br /&gt;count_df = result_df[&amp;#39;order_count&amp;#39;].value_counts().sort_index()[result_df[&amp;#39;order_count&amp;#39;].value_counts()&amp;gt;20]&lt;br /&gt;(count_df/count_df.sum()).plot(figsize=(10,5),grid=True,label=&amp;#39;sample pmf&amp;#39;);&lt;br /&gt;&lt;br /&gt;from scipy.stats import poisson&lt;br /&gt;prob_values = poisson.pmf(count_df.index, 1000/mean_intervals) &lt;br /&gt;&lt;br /&gt;plt.plot(count_df.index, prob_values,label=&amp;#39;poisson pmf&amp;#39;);&lt;br /&gt;plt.legend() ;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[219]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149662
" title="https://stocksharp.com/file/149662
"&gt;https://stocksharp.com/file/149662
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Real-time Parameter Updating&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;From the analysis of order intervals earlier, it can be concluded that fixed parameters are not suitable for the real market conditions, and the key parameters describing the market in the strategy need to be updated in real-time. The most straightforward solution is to use a sliding window moving average. The two graphs below show the frequency of buy orders within 1 second and the mean of trading volume with a window size of 1000. It can be observed that there is a clustering phenomenon in trading, where the frequency of orders is significantly higher than usual for a period of time, and the volume also increases synchronously. Here, the mean of the previous values is used to predict the latest value, and the mean absolute error of the residuals is used to measure the quality of the prediction.&lt;br /&gt;&lt;br /&gt;From the graphs, we can also understand why the order frequency deviates so much from the Poisson distribution. Although the mean number of orders per second is only 8.5, extreme cases deviate significantly from this value.&lt;br /&gt;&lt;br /&gt;It is found that using the mean of the previous two seconds to predict yields the smallest residual error, and it is much better than simply using the mean for prediction results.&lt;br /&gt;&lt;br /&gt;In [221]:&lt;br /&gt;```&lt;br /&gt;result_df[&amp;#39;order_count&amp;#39;].rolling(1000).mean().plot(figsize=(10,5),grid=True);&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[221]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149660
" title="https://stocksharp.com/file/149660
"&gt;https://stocksharp.com/file/149660
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [193]:&lt;br /&gt;```&lt;br /&gt;result_df[&amp;#39;quantity_sum&amp;#39;].rolling(1000).mean().plot(figsize=(10,5),grid=True);&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[193]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149658
" title="https://stocksharp.com/file/149658
"&gt;https://stocksharp.com/file/149658
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [195]:&lt;br /&gt;```&lt;br /&gt;(result_df[&amp;#39;order_count&amp;#39;] - result_df[&amp;#39;mean_count&amp;#39;].mean()).abs().mean()&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[195]:&lt;br /&gt;&lt;br /&gt;6.985628185332997&lt;br /&gt;&lt;br /&gt;In [205]:&lt;br /&gt;```&lt;br /&gt;result_df[&amp;#39;mean_count&amp;#39;] = result_df[&amp;#39;order_count&amp;#39;].rolling(2).mean()&lt;br /&gt;(result_df[&amp;#39;order_count&amp;#39;] - result_df[&amp;#39;mean_count&amp;#39;].shift()).abs().mean()&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[205]:&lt;br /&gt;&lt;br /&gt;3.091737586730269&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This article briefly explains the reasons for the deviation of order time intervals from the Poisson process, mainly due to the variation of parameters over time. In order to accurately predict the market, strategies need to make real-time forecasts of the fundamental parameters of the market. Residuals can be used to measure the quality of the predictions. The example provided above is a simple demonstration, and there is extensive research on specific time series analysis, volatility clustering, and other related topics, the above demonstration can be further improved.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y62klVQmZvlTo3phT-rCTmYIUCcEqFi5p8AtLvJFlMhEKyo02EnHxnu9As9UjtJ-CA_YNXwP8GEd9W9Nox_6TYXY" title="https://blog.mathquant.com/2023/08/08/thoughts-on-high-frequency-trading-strategies-3.html"&gt;https://blog.mathquant.c...rading-strategies-3.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25626/</id>
    <title type="text">Thoughts on High-Frequency Trading Strategies (2)</title>
    <published>2024-03-26T01:19:48Z</published>
    <updated>2024-03-26T01:19:48Z</updated>
    <author>
      <name>FMZQuant</name>
      <uri>https://stocksharp.com/users/185759/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#strategy" />
    <category term="#code" />
    <category term="#data" />
    <category term="#fmz" />
    <category term="#exchange" />
    <category term="#highfrequency" />
    <category term="#crypto" />
    <category term="#position" />
    <category term="#chart" />
    <content type="html">&lt;b&gt;Accumulated Trading Amount Modeling&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In the previous article, we derived an expression for the probability of a single trade amount being greater than a certain value.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149650
" title="https://stocksharp.com/file/149650
"&gt;https://stocksharp.com/file/149650
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We are also interested in the distribution of trading amount over a period of time, which intuitively should be related to the individual trade amount and order frequency. Below, we process the data in fixed intervals and plot its distribution, similar to what was done in the previous section.&lt;br /&gt;&lt;br /&gt;In [1]:&lt;br /&gt;```&lt;br /&gt;from datetime import date,datetime&lt;br /&gt;import time&lt;br /&gt;import pandas as pd&lt;br /&gt;import numpy as np&lt;br /&gt;import matplotlib.pyplot as plt&lt;br /&gt;%matplotlib inline&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [2]:&lt;br /&gt;```&lt;br /&gt;trades = pd.read_csv(&amp;#39;HOOKUSDT-aggTrades-2023-01-27.csv&amp;#39;)&lt;br /&gt;trades[&amp;#39;date&amp;#39;] = pd.to_datetime(trades[&amp;#39;transact_time&amp;#39;], unit=&amp;#39;ms&amp;#39;)&lt;br /&gt;trades.index = trades[&amp;#39;date&amp;#39;]&lt;br /&gt;buy_trades = trades[trades[&amp;#39;is_buyer_maker&amp;#39;]==False].copy()&lt;br /&gt;buy_trades = buy_trades.groupby(&amp;#39;transact_time&amp;#39;).agg({&lt;br /&gt;    &amp;#39;agg_trade_id&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;price&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;quantity&amp;#39;: &amp;#39;sum&amp;#39;,&lt;br /&gt;    &amp;#39;first_trade_id&amp;#39;: &amp;#39;first&amp;#39;,&lt;br /&gt;    &amp;#39;last_trade_id&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;is_buyer_maker&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;date&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;transact_time&amp;#39;:&amp;#39;last&amp;#39;&lt;br /&gt;})&lt;br /&gt;buy_trades[&amp;#39;interval&amp;#39;]=buy_trades[&amp;#39;transact_time&amp;#39;] - buy_trades[&amp;#39;transact_time&amp;#39;].shift()&lt;br /&gt;buy_trades.index = buy_trades[&amp;#39;date&amp;#39;]&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;We combine the individual trade amounts at intervals of 1 second to obtain the aggregated trading amount, excluding periods with no trading activity. We then fit this aggregated amount using the distribution derived from the single trade amount analysis mentioned earlier. The results show a good fit when considering each trade within the 1-second interval as a single trade, effectively solving the problem. However, when the time interval is extended relative to the trading frequency, we observe an increase in errors. Further research reveals that this error is caused by the correction term introduced by the Pareto distribution. This suggests that as the time interval lengthens and includes more individual trades, the aggregation of multiple trades approaches the Pareto distribution more closely, necessitating the removal of the correction term.&lt;br /&gt;&lt;br /&gt;In [3]:&lt;br /&gt;```&lt;br /&gt;df_resampled = buy_trades[&amp;#39;quantity&amp;#39;].resample(&amp;#39;1S&amp;#39;).sum()&lt;br /&gt;df_resampled = df_resampled.to_frame(name=&amp;#39;quantity&amp;#39;)&lt;br /&gt;df_resampled = df_resampled[df_resampled[&amp;#39;quantity&amp;#39;]&amp;gt;0]&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [4]:&lt;br /&gt;```&lt;br /&gt;# Cumulative distribution in 1s&lt;br /&gt;depths = np.array(range(0, 3000, 5))&lt;br /&gt;probabilities = np.array([np.mean(df_resampled[&amp;#39;quantity&amp;#39;] &amp;gt; depth) for depth in depths])&lt;br /&gt;mean = df_resampled[&amp;#39;quantity&amp;#39;].mean()&lt;br /&gt;alpha = np.log(np.mean(df_resampled[&amp;#39;quantity&amp;#39;] &amp;gt; mean))/np.log(2.05)&lt;br /&gt;probabilities_s = np.array([((1+20**(-depth/mean))*depth/mean+1)**(alpha) for depth in depths])&lt;br /&gt;&lt;br /&gt;plt.figure(figsize=(10, 5))&lt;br /&gt;plt.plot(depths, probabilities)&lt;br /&gt;plt.plot(depths, probabilities_s)&lt;br /&gt;plt.xlabel(&amp;#39;Depth&amp;#39;)&lt;br /&gt;plt.ylabel(&amp;#39;Probability of execution&amp;#39;)&lt;br /&gt;plt.title(&amp;#39;Execution probability at different depths&amp;#39;)&lt;br /&gt;plt.grid(True)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[4]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149653
" title="https://stocksharp.com/file/149653
"&gt;https://stocksharp.com/file/149653
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [5]:&lt;br /&gt;```&lt;br /&gt;df_resampled = buy_trades[&amp;#39;quantity&amp;#39;].resample(&amp;#39;30S&amp;#39;).sum()&lt;br /&gt;df_resampled = df_resampled.to_frame(name=&amp;#39;quantity&amp;#39;)&lt;br /&gt;df_resampled = df_resampled[df_resampled[&amp;#39;quantity&amp;#39;]&amp;gt;0]&lt;br /&gt;depths = np.array(range(0, 12000, 20))&lt;br /&gt;probabilities = np.array([np.mean(df_resampled[&amp;#39;quantity&amp;#39;] &amp;gt; depth) for depth in depths])&lt;br /&gt;mean = df_resampled[&amp;#39;quantity&amp;#39;].mean()&lt;br /&gt;alpha = np.log(np.mean(df_resampled[&amp;#39;quantity&amp;#39;] &amp;gt; mean))/np.log(2.05)&lt;br /&gt;probabilities_s = np.array([((1+20**(-depth/mean))*depth/mean+1)**(alpha) for depth in depths])&lt;br /&gt;alpha = np.log(np.mean(df_resampled[&amp;#39;quantity&amp;#39;] &amp;gt; mean))/np.log(2)&lt;br /&gt;probabilities_s_2 = np.array([(depth/mean+1)**alpha for depth in depths]) # No amendment&lt;br /&gt;&lt;br /&gt;plt.figure(figsize=(10, 5))&lt;br /&gt;plt.plot(depths, probabilities,label=&amp;#39;Probabilities (True)&amp;#39;)&lt;br /&gt;plt.plot(depths, probabilities_s, label=&amp;#39;Probabilities (Simulation 1)&amp;#39;)&lt;br /&gt;plt.plot(depths, probabilities_s_2, label=&amp;#39;Probabilities (Simulation 2)&amp;#39;)&lt;br /&gt;plt.xlabel(&amp;#39;Depth&amp;#39;)&lt;br /&gt;plt.ylabel(&amp;#39;Probability of execution&amp;#39;)&lt;br /&gt;plt.title(&amp;#39;Execution probability at different depths&amp;#39;)&lt;br /&gt;plt.legend() &lt;br /&gt;plt.grid(True)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[5]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149654
" title="https://stocksharp.com/file/149654
"&gt;https://stocksharp.com/file/149654
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now summarize a general formula for the distribution of accumulated trading amount for different time periods, using the distribution of single transaction amount to fit, instead of separately calculating each time. Here is the formula:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149652
" title="https://stocksharp.com/file/149652
"&gt;https://stocksharp.com/file/149652
&lt;/a&gt;&lt;br /&gt;Here, avg_interval represents the average interval of single transactions, and avg_interval_T represents the average interval of the interval that needs to be estimated. It may sound a bit confusing. If we want to estimate the trading amount for 1 second, we need to calculate the average interval between events containing transactions within 1 second. If the arrival probability of orders follows a Poisson distribution, it should be directly estimable. However, in reality, there is a significant deviation, but I won&amp;#39;t elaborate on it here.&lt;br /&gt;&lt;br /&gt;Note that the probability of trading amount exceeding a specific value within a certain interval of time and the actual probability of trading at that position in the depth should be quite different. As the waiting time increases, the possibility of changes in the order book increases, and trading also leads to changes in the depth. Therefore, the probability of trading at the same depth position changes in real-time as the data updates.&lt;br /&gt;&lt;br /&gt;In [6]:&lt;br /&gt;```&lt;br /&gt;df_resampled = buy_trades[&amp;#39;quantity&amp;#39;].resample(&amp;#39;2S&amp;#39;).sum()&lt;br /&gt;df_resampled = df_resampled.to_frame(name=&amp;#39;quantity&amp;#39;)&lt;br /&gt;df_resampled = df_resampled[df_resampled[&amp;#39;quantity&amp;#39;]&amp;gt;0]&lt;br /&gt;depths = np.array(range(0, 6500, 10))&lt;br /&gt;probabilities = np.array([np.mean(df_resampled[&amp;#39;quantity&amp;#39;] &amp;gt; depth) for depth in depths])&lt;br /&gt;mean = buy_trades[&amp;#39;quantity&amp;#39;].mean()&lt;br /&gt;adjust = buy_trades[&amp;#39;interval&amp;#39;].mean() / 2620&lt;br /&gt;alpha = np.log(np.mean(buy_trades[&amp;#39;quantity&amp;#39;] &amp;gt; mean))/0.7178397931503168&lt;br /&gt;probabilities_s = np.array([((1+20**(-depth*adjust/mean))*depth*adjust/mean+1)**(alpha) for depth in depths])&lt;br /&gt;&lt;br /&gt;plt.figure(figsize=(10, 5))&lt;br /&gt;plt.plot(depths, probabilities)&lt;br /&gt;plt.plot(depths, probabilities_s)&lt;br /&gt;plt.xlabel(&amp;#39;Depth&amp;#39;)&lt;br /&gt;plt.ylabel(&amp;#39;Probability of execution&amp;#39;)&lt;br /&gt;plt.title(&amp;#39;Execution probability at different depths&amp;#39;)&lt;br /&gt;plt.grid(True)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[6]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149651
" title="https://stocksharp.com/file/149651
"&gt;https://stocksharp.com/file/149651
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Single Trade Price Impact&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Trade data is valuable, and there is still a lot of data that can be mined. We should pay close attention to the impact of orders on prices, as this affects the positioning of strategies. Similarly, aggregating data based on transact_time, we calculate the difference between the last price and the first price. If there is only one order, the price difference is 0. Interestingly, there are a few data results that are negative, which may be due to the ordering of the data, but we won&amp;#39;t delve into it here.&lt;br /&gt;&lt;br /&gt;The results show that the proportion of trades that did not cause any impact is as high as 77%, while the proportion of trades causing a price movement of 1 tick is 16.5%, 2 ticks is 3.7%, 3 ticks is 1.2%, and more than 4 ticks is less than 1%. This basically follows the characteristics of an exponential function, but the fitting is not precise.&lt;br /&gt;&lt;br /&gt;The trade amount causing the corresponding price difference was also analyzed, excluding distortions caused by excessive impact. It shows a linear relationship, with approximately 1 tick of price fluctuation caused by every 1000 units of amount. This can also be understood as an average of around 1000 units of orders placed near each price level in the order book.&lt;br /&gt;&lt;br /&gt;In [7]:&lt;br /&gt;```&lt;br /&gt;diff_df = trades[trades[&amp;#39;is_buyer_maker&amp;#39;]==False].groupby(&amp;#39;transact_time&amp;#39;)[&amp;#39;price&amp;#39;].agg(lambda x: abs(round(x.iloc[-1] - x.iloc[0],3)) if len(x) &amp;gt; 1 else 0)&lt;br /&gt;buy_trades[&amp;#39;diff&amp;#39;] = buy_trades[&amp;#39;transact_time&amp;#39;].map(diff_df)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [8]:&lt;br /&gt;```&lt;br /&gt;diff_counts = buy_trades[&amp;#39;diff&amp;#39;].value_counts()&lt;br /&gt;diff_counts[diff_counts&amp;gt;10]/diff_counts.sum()&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[8]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149649
" title="https://stocksharp.com/file/149649
"&gt;https://stocksharp.com/file/149649
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [9]:&lt;br /&gt;```&lt;br /&gt;diff_group = buy_trades.groupby(&amp;#39;diff&amp;#39;).agg({&lt;br /&gt;    &amp;#39;quantity&amp;#39;: &amp;#39;mean&amp;#39;,&lt;br /&gt;    &amp;#39;diff&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;})&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [10]:&lt;br /&gt;```&lt;br /&gt;diff_group[&amp;#39;quantity&amp;#39;][diff_group[&amp;#39;diff&amp;#39;]&amp;gt;0][diff_group[&amp;#39;diff&amp;#39;]&amp;lt;0.01].plot(figsize=(10,5),grid=True);&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[10]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149648
" title="https://stocksharp.com/file/149648
"&gt;https://stocksharp.com/file/149648
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Fixed Interval Price Impact&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Let&amp;#39;s analyze the price impact within a 2-second interval. The difference here is that there may be negative values. However, since we are only considering buy orders, the impact on the symmetrical position would be one tick higher. Continuing to observe the relationship between trade amount and impact, we only consider results greater than 0. The conclusion is similar to that of a single order, showing an approximate linear relationship, with approximately 2000 units of amount needed for each tick.&lt;br /&gt;&lt;br /&gt;In [11]:&lt;br /&gt;```&lt;br /&gt;df_resampled = buy_trades.resample(&amp;#39;2S&amp;#39;).agg({ &lt;br /&gt;    &amp;#39;price&amp;#39;: [&amp;#39;first&amp;#39;, &amp;#39;last&amp;#39;, &amp;#39;count&amp;#39;],&lt;br /&gt;    &amp;#39;quantity&amp;#39;: &amp;#39;sum&amp;#39;&lt;br /&gt;})&lt;br /&gt;df_resampled[&amp;#39;price_diff&amp;#39;] = round(df_resampled[(&amp;#39;price&amp;#39;, &amp;#39;last&amp;#39;)] - df_resampled[(&amp;#39;price&amp;#39;, &amp;#39;first&amp;#39;)],3)&lt;br /&gt;df_resampled[&amp;#39;price_diff&amp;#39;] = df_resampled[&amp;#39;price_diff&amp;#39;].fillna(0)&lt;br /&gt;result_df_raw = pd.DataFrame({&lt;br /&gt;    &amp;#39;price_diff&amp;#39;: df_resampled[&amp;#39;price_diff&amp;#39;],&lt;br /&gt;    &amp;#39;quantity_sum&amp;#39;: df_resampled[(&amp;#39;quantity&amp;#39;, &amp;#39;sum&amp;#39;)],&lt;br /&gt;    &amp;#39;data_count&amp;#39;: df_resampled[(&amp;#39;price&amp;#39;, &amp;#39;count&amp;#39;)]&lt;br /&gt;})&lt;br /&gt;result_df = result_df_raw[result_df_raw[&amp;#39;price_diff&amp;#39;] != 0]&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [12]:&lt;br /&gt;```&lt;br /&gt;result_df[&amp;#39;price_diff&amp;#39;][abs(result_df[&amp;#39;price_diff&amp;#39;])&amp;lt;0.016].value_counts().sort_index().plot.bar(figsize=(10,5));&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[12]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149646
" title="https://stocksharp.com/file/149646
"&gt;https://stocksharp.com/file/149646
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [23]:&lt;br /&gt;```&lt;br /&gt;result_df[&amp;#39;price_diff&amp;#39;].value_counts()[result_df[&amp;#39;price_diff&amp;#39;].value_counts()&amp;gt;30]&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[23]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149645
" title="https://stocksharp.com/file/149645
"&gt;https://stocksharp.com/file/149645
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [14]:&lt;br /&gt;```&lt;br /&gt;diff_group = result_df.groupby(&amp;#39;price_diff&amp;#39;).agg({ &amp;#39;quantity_sum&amp;#39;: &amp;#39;mean&amp;#39;})&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [15]:&lt;br /&gt;```&lt;br /&gt;diff_group[(diff_group.index&amp;gt;0) &amp;amp; (diff_group.index&amp;lt;0.015)].plot(figsize=(10,5),grid=True);&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[15]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149647
" title="https://stocksharp.com/file/149647
"&gt;https://stocksharp.com/file/149647
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Trade Amount&amp;#39;s Price Impact&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Previously, we determined the trade amount required for a tick change, but it was not precise as it was based on the assumption that the impact had already occurred. Now, let&amp;#39;s reverse the perspective and examine the price impact caused by trade amount.&lt;br /&gt;&lt;br /&gt;In this analysis, the data is sampled every 1 second, with each step representing 100 units of amount. We then calculated the price changes within this amount range. Here are some valuable conclusions:&lt;br /&gt;&lt;br /&gt;1. When the buy order amount is below 500, the expected price change is a decrease, which is as expected since there are also sell orders impacting the price.&lt;br /&gt;2. At lower trade amounts, there is a linear relationship, meaning that the larger the trade amount, the greater the price increase.&lt;br /&gt;3. As the buy order amount increases, the price change becomes more significant. This often indicates a price breakthrough, which may later regress. Additionally, the fixed interval sampling adds to the data instability.&lt;br /&gt;4. It is important to pay attention to the upper part of the scatter plot, which corresponds to the increase in price with trade amount.&lt;br /&gt;5. For this specific trading pair, we provide a rough version of the relationship between trade amount and price change.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149642
" title="https://stocksharp.com/file/149642
"&gt;https://stocksharp.com/file/149642
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Where &amp;quot;C&amp;quot; represents the change in price and &amp;quot;Q&amp;quot; represents the amount of buy orders.&lt;br /&gt;&lt;br /&gt;In [16]:&lt;br /&gt;```&lt;br /&gt;df_resampled = buy_trades.resample(&amp;#39;1S&amp;#39;).agg({ &lt;br /&gt;    &amp;#39;price&amp;#39;: [&amp;#39;first&amp;#39;, &amp;#39;last&amp;#39;, &amp;#39;count&amp;#39;],&lt;br /&gt;    &amp;#39;quantity&amp;#39;: &amp;#39;sum&amp;#39;&lt;br /&gt;})&lt;br /&gt;df_resampled[&amp;#39;price_diff&amp;#39;] = round(df_resampled[(&amp;#39;price&amp;#39;, &amp;#39;last&amp;#39;)] - df_resampled[(&amp;#39;price&amp;#39;, &amp;#39;first&amp;#39;)],3)&lt;br /&gt;df_resampled[&amp;#39;price_diff&amp;#39;] = df_resampled[&amp;#39;price_diff&amp;#39;].fillna(0)&lt;br /&gt;result_df_raw = pd.DataFrame({&lt;br /&gt;    &amp;#39;price_diff&amp;#39;: df_resampled[&amp;#39;price_diff&amp;#39;],&lt;br /&gt;    &amp;#39;quantity_sum&amp;#39;: df_resampled[(&amp;#39;quantity&amp;#39;, &amp;#39;sum&amp;#39;)],&lt;br /&gt;    &amp;#39;data_count&amp;#39;: df_resampled[(&amp;#39;price&amp;#39;, &amp;#39;count&amp;#39;)]&lt;br /&gt;})&lt;br /&gt;result_df = result_df_raw[result_df_raw[&amp;#39;price_diff&amp;#39;] != 0]&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [24]:&lt;br /&gt;```&lt;br /&gt;df = result_df.copy()&lt;br /&gt;bins = np.arange(0, 30000, 100)  # &lt;br /&gt;labels = [f&amp;#39;{i}-{i+100-1}&amp;#39; for i in bins[:-1]]  &lt;br /&gt;df.loc[:, &amp;#39;quantity_group&amp;#39;] = pd.cut(df[&amp;#39;quantity_sum&amp;#39;], bins=bins, labels=labels)&lt;br /&gt;grouped = df.groupby(&amp;#39;quantity_group&amp;#39;)[&amp;#39;price_diff&amp;#39;].mean()&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [25]:&lt;br /&gt;```&lt;br /&gt;grouped_df = pd.DataFrame(grouped).reset_index()&lt;br /&gt;grouped_df[&amp;#39;quantity_group_center&amp;#39;] = grouped_df[&amp;#39;quantity_group&amp;#39;].apply(lambda x: (float(x.split(&amp;#39;-&amp;#39;)[0]) + float(x.split(&amp;#39;-&amp;#39;)[1])) / 2)&lt;br /&gt;&lt;br /&gt;plt.figure(figsize=(10,5))&lt;br /&gt;plt.scatter(grouped_df[&amp;#39;quantity_group_center&amp;#39;], grouped_df[&amp;#39;price_diff&amp;#39;],s=10)&lt;br /&gt;plt.plot(grouped_df[&amp;#39;quantity_group_center&amp;#39;], np.array(grouped_df[&amp;#39;quantity_group_center&amp;#39;].values)/2e6-0.000352,color=&amp;#39;red&amp;#39;)&lt;br /&gt;plt.xlabel(&amp;#39;quantity_group_center&amp;#39;)&lt;br /&gt;plt.ylabel(&amp;#39;average price_diff&amp;#39;)&lt;br /&gt;plt.title(&amp;#39;Scatter plot of average price_diff by quantity_group&amp;#39;)&lt;br /&gt;plt.grid(True)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[25]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149644
" title="https://stocksharp.com/file/149644
"&gt;https://stocksharp.com/file/149644
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In [19]:&lt;br /&gt;```&lt;br /&gt;grouped_df.head(10)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[19]:&lt;br /&gt;, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149643
" title="https://stocksharp.com/file/149643
"&gt;https://stocksharp.com/file/149643
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Preliminary Optimal Order Placement&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;With the modeling of trade amount and the rough model of price impact corresponding to trade amount, it seems possible to calculate the optimal order placement. Let&amp;#39;s make some assumptions and provide an irresponsible optimal price position.&lt;br /&gt;&lt;br /&gt;1. Assume that the price regresses to its original value after the impact (which is highly unlikely and would require further analysis of the price change after the impact).&lt;br /&gt;2. Assume that the distribution of trade amount and order frequency during this period follows a preset pattern (which is also inaccurate, as we are estimating based on one day&amp;#39;s data and trading exhibits clear clustering phenomena).&lt;br /&gt;3. Assume that only one sell order occurs during the simulated time and then is closed.&lt;br /&gt;4. Assume that after the order is executed, there are other buy orders that continue to push up the price, especially when the amount is very low. This effect is ignored here, and it is simply assumed that the price will regress.&lt;br /&gt;&lt;br /&gt;Let&amp;#39;s start by writing a simple expected return, which is the probability of cumulative buy orders exceeding Q within 1 second, multiplied by the expected return rate (i.e., the price impact).&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149640
" title="https://stocksharp.com/file/149640
"&gt;https://stocksharp.com/file/149640
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Based on the graph, the maximum expected return is approximately 2500, which is about 2.5 times the average trade amount. This suggests that the sell order should be placed at a price position of 2500. It is important to emphasize that the horizontal axis represents trade amount within 1 second and should not be equated with depth position. Additionally, this analysis is based on trades data and lacks important depth data.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;We have discovered that trade amount distribution at different time intervals is a simple scaling of the distribution of individual trade amounts. We have also developed a simple expected return model based on price impact and trade probability. The results of this model align with our expectations, showing that if the sell order amount is low, it indicates a price decrease, and a certain amount is needed for profit potential. The probability decreases as the trade amount increases, with an optimal size in between, which represents the optimal order placement strategy. However, this model is still too simplistic. In the next article, I will delve deeper into this topic.&lt;br /&gt;&lt;br /&gt;In [20]:&lt;br /&gt;```&lt;br /&gt;# Cumulative distribution in 1s&lt;br /&gt;df_resampled = buy_trades[&amp;#39;quantity&amp;#39;].resample(&amp;#39;1S&amp;#39;).sum()&lt;br /&gt;df_resampled = df_resampled.to_frame(name=&amp;#39;quantity&amp;#39;)&lt;br /&gt;df_resampled = df_resampled[df_resampled[&amp;#39;quantity&amp;#39;]&amp;gt;0]&lt;br /&gt;&lt;br /&gt;depths = np.array(range(0, 15000, 10))&lt;br /&gt;mean = df_resampled[&amp;#39;quantity&amp;#39;].mean()&lt;br /&gt;alpha = np.log(np.mean(df_resampled[&amp;#39;quantity&amp;#39;] &amp;gt; mean))/np.log(2.05)&lt;br /&gt;probabilities_s = np.array([((1+20**(-depth/mean))*depth/mean+1)**(alpha) for depth in depths])&lt;br /&gt;profit_s = np.array([depth/2e6-0.000352 for depth in depths])&lt;br /&gt;plt.figure(figsize=(10, 5))&lt;br /&gt;plt.plot(depths, probabilities_s*profit_s)&lt;br /&gt;plt.xlabel(&amp;#39;Q&amp;#39;)&lt;br /&gt;plt.ylabel(&amp;#39;Excpet profit&amp;#39;)&lt;br /&gt;plt.grid(True)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[20]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149641
" title="https://stocksharp.com/file/149641
"&gt;https://stocksharp.com/file/149641
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y65E87vDtvnJJc474NzmMzPPJN9Y6ZnGodgAgIvD-7H_bi-YS7AzPMc0hOvgIv-dIZK3J240VMWnZN8XmoOVCgHY" title="https://blog.mathquant.com/2023/08/04/thoughts-on-high-frequency-trading-strategies-2.html"&gt;https://blog.mathquant.c...rading-strategies-2.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25622/</id>
    <title type="text">Thoughts on High-Frequency Trading Strategies (1)</title>
    <published>2024-03-25T09:08:04Z</published>
    <updated>2024-03-25T09:08:04Z</updated>
    <author>
      <name>FMZQuant</name>
      <uri>https://stocksharp.com/users/185759/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#strategy" />
    <category term="#code" />
    <category term="#market" />
    <category term="#fmz" />
    <category term="#exchange" />
    <category term="#highfrequency" />
    <category term="#formula" />
    <category term="#crypto" />
    <category term="#order" />
    <content type="html">I have written two articles on high-frequency trading of digital currencies, namely &amp;quot;[Digital Currency High-Frequency Strategy Detailed Introduction](https://www.fmz.com/bbs-topic/10009)&amp;quot; and &amp;quot;[Earn 80 Times in 5 Days, the Power of High-frequency Strategy](https://www.fmz.com/bbs-topic/9750)&amp;quot;. However, these articles can only be considered as sharing experiences and provide a general overview. This time, I plan to write a series of articles to introduce the thought process behind high-frequency trading from scratch. I hope to keep it concise and clear, but due to my limited expertise, my understanding of high-frequency trading may not be very in-depth. This article should be seen as a starting point for discussion, and I welcome corrections and guidance from experts.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Source of High-Frequency Profits&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In my previous articles, I mentioned that high-frequency strategies are particularly suitable for markets with extremely volatile fluctuations. The price changes of a trading instrument within a short period of time consist of overall trends and oscillations. While it is indeed profitable if we can accurately predict trend changes, this is also the most challenging aspect. In this article, I will primarily focus on high-frequency maker strategies and will not delve into trend prediction. In oscillating markets, by placing bid and ask orders strategically, if the frequency of executions is high enough and the profit margin is significant, it can cover potential losses caused by trends. In this way, profitability can be achieved without predicting market movements. Currently, exchanges provide rebates for maker trades, which are also a component of profits. The more competitive the market, the higher the proportion of rebates should be.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Problems to be Addressed&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;1. The first problem in implementing a strategy that places both buy and sell orders is determining where to place these orders. The closer the orders are placed to the market depth, the higher the probability of execution. However, in highly volatile market conditions, the price at which an order is instantly executed may be far from the market depth, resulting in insufficient profit. On the other hand, placing orders too far away reduces the probability of execution. This is an optimization problem that needs to be addressed.&lt;br /&gt;&lt;br /&gt;2. Position control is crucial to manage risk. A strategy cannot accumulate excessive positions for extended periods. This can be addressed by controlling the distance and quantity of orders placed, as well as setting limits on overall positions.&lt;br /&gt;&lt;br /&gt;To achieve the above objectives, modeling and estimation are required for various aspects such as execution probabilities, profit from executions, and market estimation. There are numerous articles and papers available on this topic, using keywords such as &amp;quot;High-Frequency Trading&amp;quot; and &amp;quot;Orderbook.&amp;quot; Many recommendations can also be found online, although further elaboration is beyond the scope of this article. Additionally, it is advisable to establish a reliable and fast backtesting system. Although high-frequency strategies can easily be validated through live trading, backtesting provides additional insights and helps reduce the cost of trial and error.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Required Data&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Binance provides [downloadable data](https://www.binance.com/en/landing/data) for individual trades and best bid/ask orders. Depth data can be downloaded through their API by being whitelisted, or it can be collected manually. For backtesting purposes, aggregated trade data is sufficient. In this article, we will use the example of HOOKUSDT-aggTrades-2023-01-27 data.&lt;br /&gt;&lt;br /&gt;In [1]:&lt;br /&gt;```&lt;br /&gt;from datetime import date,datetime&lt;br /&gt;import time&lt;br /&gt;import pandas as pd&lt;br /&gt;import numpy as np&lt;br /&gt;import matplotlib.pyplot as plt&lt;br /&gt;%matplotlib inline&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;The individual trade data includes the followings:&lt;br /&gt;&lt;br /&gt;1. agg_trade_id: The ID of the aggregated trade.&lt;br /&gt;2. price: The price at which the trade was executed.&lt;br /&gt;3. quantity: The quantity of the trade.&lt;br /&gt;4. first_trade_id: In cases where multiple trades are aggregated, this represents the ID of the first trade.&lt;br /&gt;5. last_trade_id: The ID of the last trade in the aggregation.&lt;br /&gt;6. transact_time: The timestamp of the trade execution.&lt;br /&gt;7. is_buyer_maker: Indicates the direction of the trade. &amp;quot;True&amp;quot; represents a buy order executed as a maker, while a sell order is executed as a taker.&lt;br /&gt;&lt;br /&gt;It can be seen that there were 660,000 trades executed on that day, indicating a highly active market. The CSV file will be attached in the comments section.&lt;br /&gt;&lt;br /&gt;In [4]:&lt;br /&gt;```&lt;br /&gt;trades = pd.read_csv(&amp;#39;COMPUSDT-aggTrades-2023-07-02.csv&amp;#39;)&lt;br /&gt;trades&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[4]:&lt;br /&gt;, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149605
" title="https://stocksharp.com/file/149605
"&gt;https://stocksharp.com/file/149605
&lt;/a&gt;&lt;br /&gt;664475 rows &amp;#215; 7 columns&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Modeling Individual Trade Amount&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;First, the data is processed by dividing the original trades into two groups: buy orders executed as makers and sell orders executed as takers. Additionally, the original aggregated trade data combines trades executed at the same time, at the same price, and in the same direction into a single data point. For example, if there is a single buy order with a volume of 100, it may be split into two trades with volumes of 60 and 40, respectively, if the prices are different. This can affect the estimation of buy order volumes. Therefore, it is necessary to aggregate the data again based on the transact_time. After this second aggregation, the data volume is reduced by 140,000 records.&lt;br /&gt;&lt;br /&gt;In [6]:&lt;br /&gt;```&lt;br /&gt;trades[&amp;#39;date&amp;#39;] = pd.to_datetime(trades[&amp;#39;transact_time&amp;#39;], unit=&amp;#39;ms&amp;#39;)&lt;br /&gt;trades.index = trades[&amp;#39;date&amp;#39;]&lt;br /&gt;buy_trades = trades[trades[&amp;#39;is_buyer_maker&amp;#39;]==False].copy()&lt;br /&gt;sell_trades = trades[trades[&amp;#39;is_buyer_maker&amp;#39;]==True].copy()&lt;br /&gt;buy_trades = buy_trades.groupby(&amp;#39;transact_time&amp;#39;).agg({&lt;br /&gt;    &amp;#39;agg_trade_id&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;price&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;quantity&amp;#39;: &amp;#39;sum&amp;#39;,&lt;br /&gt;    &amp;#39;first_trade_id&amp;#39;: &amp;#39;first&amp;#39;,&lt;br /&gt;    &amp;#39;last_trade_id&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;is_buyer_maker&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;date&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;transact_time&amp;#39;:&amp;#39;last&amp;#39;&lt;br /&gt;})&lt;br /&gt;sell_trades = sell_trades.groupby(&amp;#39;transact_time&amp;#39;).agg({&lt;br /&gt;    &amp;#39;agg_trade_id&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;price&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;quantity&amp;#39;: &amp;#39;sum&amp;#39;,&lt;br /&gt;    &amp;#39;first_trade_id&amp;#39;: &amp;#39;first&amp;#39;,&lt;br /&gt;    &amp;#39;last_trade_id&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;is_buyer_maker&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;date&amp;#39;: &amp;#39;last&amp;#39;,&lt;br /&gt;    &amp;#39;transact_time&amp;#39;:&amp;#39;last&amp;#39;&lt;br /&gt;})&lt;br /&gt;buy_trades[&amp;#39;interval&amp;#39;]=buy_trades[&amp;#39;transact_time&amp;#39;] - buy_trades[&amp;#39;transact_time&amp;#39;].shift()&lt;br /&gt;sell_trades[&amp;#39;interval&amp;#39;]=sell_trades[&amp;#39;transact_time&amp;#39;] - sell_trades[&amp;#39;transact_time&amp;#39;].shift()&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;In [10]:&lt;br /&gt;```&lt;br /&gt;print(trades.shape[0] - (buy_trades.shape[0]+sell_trades.shape[0]))&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out [10]:&lt;br /&gt;146181&lt;br /&gt;&lt;br /&gt;Take buy orders as an example, let&amp;#39;s first plot a histogram. It can be observed that there is a significant long-tail effect, with the majority of data concentrated towards the leftmost part of the histogram. However, there are also a few large trades distributed towards the tail end.&lt;br /&gt;&lt;br /&gt;In [36]:&lt;br /&gt;```&lt;br /&gt;buy_trades[&amp;#39;quantity&amp;#39;].plot.hist(bins=200,figsize=(10, 5));&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out [36]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149606
" title="https://stocksharp.com/file/149606
"&gt;https://stocksharp.com/file/149606
&lt;/a&gt;&lt;br /&gt;For easier observation, let&amp;#39;s trim the tail and analyze the data. It can be observed that as the trade amount increases, the frequency of occurrence decreases, and the rate of decrease becomes faster.&lt;br /&gt;&lt;br /&gt;In [37]:&lt;br /&gt;```&lt;br /&gt;buy_trades[&amp;#39;quantity&amp;#39;][buy_trades[&amp;#39;quantity&amp;#39;]&amp;lt;200].plot.hist(bins=200,figsize=(10, 5));&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out [37]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149607
" title="https://stocksharp.com/file/149607
"&gt;https://stocksharp.com/file/149607
&lt;/a&gt;&lt;br /&gt;There have been numerous studies on the distribution of trade amounts. It has been found that trade amounts follow a power-law distribution, also known as a Pareto distribution, which is a common probability distribution in statistical physics and social sciences. In a power-law distribution, the probability of an event&amp;#39;s size (or frequency) is proportional to a negative exponent of that event&amp;#39;s size. The main characteristic of this distribution is that the frequency of large events (i.e., those far from the average) is higher than expected in many other distributions. This is precisely the characteristic of trade amount distribution. The form of the Pareto distribution is given by P(x) = Cx^(-α). Let&amp;#39;s empirically verify this.&lt;br /&gt;&lt;br /&gt;The following graph represents the probability of trade amounts exceeding a certain value. The blue line represents the actual probability, while the orange line represents the simulated probability. Please note that we won&amp;#39;t go into the specific parameters at this point. It can be observed that the distribution indeed follows a Pareto distribution. Since the probability of trade amounts being greater than zero is 1, and in order to satisfy normalization, the distribution equation should be as follows:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149608
" title="https://stocksharp.com/file/149608
"&gt;https://stocksharp.com/file/149608
&lt;/a&gt;&lt;br /&gt;Here, N is the parameter for normalization. We will choose the average trade amount, M, and set alpha to -2.06. The specific estimation of alpha can be obtained by calculating the P-value when D=N. Specifically, alpha = log(P(d&amp;gt;M))/log(2). The choice of different points may result in slight differences in the value of alpha.&lt;br /&gt;&lt;br /&gt;In [55]:&lt;br /&gt;```&lt;br /&gt;depths = range(0, 250, 2)&lt;br /&gt;probabilities = np.array([np.mean(buy_trades[&amp;#39;quantity&amp;#39;] &amp;gt; depth) for depth in depths])&lt;br /&gt;alpha = np.log(np.mean(buy_trades[&amp;#39;quantity&amp;#39;] &amp;gt; mean_quantity))/np.log(2)&lt;br /&gt;mean_quantity = buy_trades[&amp;#39;quantity&amp;#39;].mean()&lt;br /&gt;probabilities_s = np.array([(1+depth/mean_quantity)**alpha for depth in depths])&lt;br /&gt;&lt;br /&gt;plt.figure(figsize=(10, 5))&lt;br /&gt;plt.plot(depths, probabilities)&lt;br /&gt;plt.plot(depths, probabilities_s)&lt;br /&gt;plt.xlabel(&amp;#39;Depth&amp;#39;)&lt;br /&gt;plt.ylabel(&amp;#39;Probability of execution&amp;#39;)&lt;br /&gt;plt.title(&amp;#39;Execution probability at different depths&amp;#39;)&lt;br /&gt;plt.grid(True)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[55]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149613
" title="https://stocksharp.com/file/149613
"&gt;https://stocksharp.com/file/149613
&lt;/a&gt;&lt;br /&gt;In [56]:&lt;br /&gt;```&lt;br /&gt;plt.figure(figsize=(10, 5))&lt;br /&gt;plt.grid(True)&lt;br /&gt;plt.title(&amp;#39;Diff&amp;#39;)&lt;br /&gt;plt.plot(depths, probabilities_s-probabilities);&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[56]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149610
" title="https://stocksharp.com/file/149610
"&gt;https://stocksharp.com/file/149610
&lt;/a&gt;&lt;br /&gt;However, this estimation is only approximate, as shown in the graph where we plot the difference between the simulated and actual values. When the trade amount is small, the deviation is significant, even approaching 10%. Although selecting different points during parameter estimation may improve the accuracy of that specific point&amp;#39;s probability, it does not solve the deviation issue as a whole. This discrepancy arises from the difference between the power-law distribution and the actual distribution. To obtain more accurate results, the equation of the power-law distribution needs to be modified. The specific process is not elaborated here, but in summary, after a moment of insight, it is found that the actual equation should be as follows:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149612
" title="https://stocksharp.com/file/149612
"&gt;https://stocksharp.com/file/149612
&lt;/a&gt;&lt;br /&gt;To simplify, let&amp;#39;s use r = q/M to represent the normalized trade amount. We can estimate the parameters using the same method as before. The following graph shows that after the modification, the maximum deviation is no more than 2%. In theory, further adjustments can be made, but this level of accuracy is already sufficient.&lt;br /&gt;&lt;br /&gt;In [52]:&lt;br /&gt;```&lt;br /&gt;depths = range(0, 250, 2)&lt;br /&gt;probabilities = np.array([np.mean(buy_trades[&amp;#39;quantity&amp;#39;] &amp;gt; depth) for depth in depths])&lt;br /&gt;mean = buy_trades[&amp;#39;quantity&amp;#39;].mean()&lt;br /&gt;alpha = np.log(np.mean(buy_trades[&amp;#39;quantity&amp;#39;] &amp;gt; mean))/np.log(2.05)&lt;br /&gt;probabilities_s = np.array([(((1+20**(-depth/mean))*depth+mean)/mean)**alpha for depth in depths])&lt;br /&gt;&lt;br /&gt;plt.figure(figsize=(10, 5))&lt;br /&gt;plt.plot(depths, probabilities)&lt;br /&gt;plt.plot(depths, probabilities_s)&lt;br /&gt;plt.xlabel(&amp;#39;Depth&amp;#39;)&lt;br /&gt;plt.ylabel(&amp;#39;Probability of execution&amp;#39;)&lt;br /&gt;plt.title(&amp;#39;Execution probability at different depths&amp;#39;)&lt;br /&gt;plt.grid(True)&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[52]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149609
" title="https://stocksharp.com/file/149609
"&gt;https://stocksharp.com/file/149609
&lt;/a&gt;&lt;br /&gt;In [53]:&lt;br /&gt;```&lt;br /&gt;plt.figure(figsize=(10, 5))&lt;br /&gt;plt.grid(True)&lt;br /&gt;plt.title(&amp;#39;Diff&amp;#39;)&lt;br /&gt;plt.plot(depths, probabilities_s-probabilities);&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;Out[53]:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149611
" title="https://stocksharp.com/file/149611
"&gt;https://stocksharp.com/file/149611
&lt;/a&gt;&lt;br /&gt;With the estimated equation for the trade amount distribution, it is important to note that the probabilities in the equation are not the actual probabilities, but conditional probabilities. At this point, we can answer the question: What is the probability that the next order will be greater than a certain value? We can also determine the probability of orders at different depths being executed (in an ideal scenario, without considering order additions, cancellations, and queueing at the same depth).&lt;br /&gt;&lt;br /&gt;At this point, the length of the text is already quite long, and there are still many questions that need to be answered. The following series of articles will attempt to provide answers.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y65E87vDtvnJJc474NzmMzPPJN9Y6ZnGodgAgIvD-7H_bi-YS7AzPMc0hOvgIv-dIZMVywi_S3WoczZm2nla8u14" title="https://blog.mathquant.com/2023/08/04/thoughts-on-high-frequency-trading-strategies-1.html"&gt;https://blog.mathquant.c...rading-strategies-1.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25621/</id>
    <title type="text">Empower Your Quantitative Trading: Unleashing the Potential of FMZ Mobile App Trading Terminal</title>
    <published>2024-03-25T08:01:20Z</published>
    <updated>2024-03-25T08:03:06Z</updated>
    <author>
      <name>FMZQuant</name>
      <uri>https://stocksharp.com/users/185759/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#code" />
    <category term="#terminal" />
    <category term="#program" />
    <category term="#market" />
    <category term="#crypto" />
    <category term="#asset" />
    <category term="#FMZQuant" />
    <category term="#plugin" />
    <category term="#tool" />
    <content type="html">In the field of quantitative trading, simple and easy-to-use quantitative trading tools have always been one of the keys to achieving wealth growth and risk management. However, with increasing market competition, traditional trading tools are no longer sufficient to meet rapidly changing market demands. To maintain a competitive edge for quantitative traders in the constantly evolving digital asset world, FMZ Mobile App has added a significant new feature: Trading Terminal. This feature will not only improve your trading efficiency, but also empower you through custom plugin programs to assist in trading, injecting new vitality into your trading career.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size:140%"&gt;Beginner&amp;amp;#39;s Guide to Trading Terminal:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;What is the FMZ Mobile APP Trading Terminal?&lt;/b&gt;&lt;br /&gt;On the FMZ Quant Trading Platform, you can download the FMZ Quant Mobile APP from the [Mobile App download page](https://www.fmz.com/mobile). After downloading and installing, open the FMZ mobile app and log in with your FMZ account.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149582
" title="https://stocksharp.com/file/149582
"&gt;https://stocksharp.com/file/149582
&lt;/a&gt;&lt;br /&gt;Please note that FMZ Quant is divided into FMZ.COM international site and FMZ.CN China domestic site (supporting different markets). When logging in, you need to choose the corresponding site. Accounts for different sites are independent and not interchangeable.&lt;br /&gt;&lt;br /&gt;The FMZ Quantitative Trading Platform mobile APP trading terminal is a quantitative trading tool that encapsulates APIs from major exchanges. It allows quick switching between various exchanges, and with the help of various features of the FMZ platform, it can perform data capture analysis, real-time data monitoring, program-assisted trading, semi-automatic/manual trading operations etc.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How to access and enable the trading terminal function?&lt;/b&gt;&lt;br /&gt;After logging into the FMZ Quant Mobile APP, you can see the &amp;amp;quot;Trading Terminal&amp;amp;quot; function on the main interface. Click to enter the trading terminal interface.&lt;br /&gt;&lt;br /&gt;Before FMZ launched its mobile APP trading terminal, FMZ&amp;amp;#39;s web version had already launched this feature quite early. Whether it is a web-based trading terminal or a mobile APP-based one, **at least one docker program must be deployed**.&lt;br /&gt;This is because all actual requests sent to exchanges are executed from the docker, not on the mobile app, which is safer. It also avoids disadvantages such as API KEY binding IP addresses and inability to use when mobile IP changes.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149581
" title="https://stocksharp.com/file/149581
"&gt;https://stocksharp.com/file/149581
&lt;/a&gt;&lt;br /&gt;&lt;b&gt;Detailed Explanation of Trading Terminal Interface&lt;/b&gt;&lt;br /&gt;**1. Main Interface of the Trading Terminal:**&lt;br /&gt;&lt;br /&gt;After opening the trading terminal, you can see the main interface of the trading terminal. Clicking on the area in red frame will open up &amp;amp;quot;Docker&amp;amp;quot;, &amp;amp;quot;Exchange&amp;amp;quot;, and &amp;amp;quot;Markets&amp;amp;quot; configuration interfaces.&lt;br /&gt;&lt;br /&gt;- Docker: All docker programs deployed under your current FMZ account will be listed here for selection.&lt;br /&gt;- Exchange: The exchange objects (configured with API KEY information etc.) created in your current FMZ account will also appear in corresponding lists for specific operation selections.&lt;br /&gt;- Markets: Set up the trading pair or contract that this trading terminal is going to operate. The input box widget for trading pairs will display selectable trading pairs/contracts based on entered information.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149583
" title="https://stocksharp.com/file/149583
"&gt;https://stocksharp.com/file/149583
&lt;/a&gt;&lt;br /&gt;**2. Trading Zone:**&lt;br /&gt;&lt;br /&gt;The Trading Zone displays market depth data;&lt;br /&gt;Trading widgets can be set with order price, order quantity, order direction, leverage and other settings.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149577
" title="https://stocksharp.com/file/149577
"&gt;https://stocksharp.com/file/149577
&lt;/a&gt;&lt;br /&gt;The bottom tabs of the main interface display information such as &amp;amp;quot;Orders&amp;amp;quot;, &amp;amp;quot;Assets&amp;amp;quot;, making your funds, and orders clear at a glance.&lt;br /&gt;&lt;br /&gt;**3. K-line Chart:**&lt;br /&gt;&lt;br /&gt;If you wish to view the K-line chart while placing an order, a thoughtful design has been implemented here - a collapsible display widget that unfolds the mini K-line chart of the current product.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149578
" title="https://stocksharp.com/file/149578
"&gt;https://stocksharp.com/file/149578
&lt;/a&gt;&lt;br /&gt;If you wish to view the K-line chart in a larger area, display market transaction records, depth information and more, you can click on this K-line icon to jump to the professional K-line chart page.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149576
" title="https://stocksharp.com/file/149576
"&gt;https://stocksharp.com/file/149576
&lt;/a&gt;&lt;br /&gt;The professional K-line chart interface:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149580
" title="https://stocksharp.com/file/149580
"&gt;https://stocksharp.com/file/149580
&lt;/a&gt;&lt;br /&gt;The professional K-line chart interface can also be displayed in landscape mode:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149579
" title="https://stocksharp.com/file/149579
"&gt;https://stocksharp.com/file/149579
&lt;/a&gt;&lt;br /&gt;&lt;b&gt;Trading Plugin&lt;/b&gt;&lt;br /&gt;What can a trading terminal plugin do?&lt;br /&gt;&lt;br /&gt;- Real-time market data calculation and display.&lt;br /&gt;- Order placement and order management.&lt;br /&gt;- Implement risk management.&lt;br /&gt;- Semi-automatic auxiliary trading strategies.&lt;br /&gt;&lt;br /&gt;Which programming languages and tools are used to develop plugins?&lt;br /&gt;&lt;br /&gt;- python&lt;br /&gt;- javascript&lt;br /&gt;- c++&lt;br /&gt;&lt;br /&gt;What can you get?&lt;br /&gt;&lt;br /&gt;- Share your plugin with the community for mutual learning with developers.&lt;br /&gt;- Learn from other developers and get inspired.&lt;br /&gt;- Interact with other quantitative trading enthusiasts.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Give an Example Based on a Real-life Application Scenario:&lt;/b&gt;&lt;br /&gt;In the FMZ community, a user has put forward such a request:&lt;br /&gt;&lt;br /&gt;&amp;amp;gt; Use js to traverse all U contract currencies of the Binance exchange, and open a position of 10u (long) for each currency. How is this code written?&lt;br /&gt;&lt;br /&gt;This requirement scenario can be implemented with trading terminal plugins actually, and running plugin strategies on the trading terminal is free of charge. Compared to long-term live trading strategies, using trading terminal plugins as an aid is undoubtedly a good choice.&lt;br /&gt;&lt;br /&gt;Let&amp;amp;#39;s see how to design and implement the user&amp;amp;#39;s request.&lt;br /&gt;&lt;br /&gt;Firstly, we need to create a trading terminal plugin and add three parameters to its strategy:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149592
" title="https://stocksharp.com/file/149592
"&gt;https://stocksharp.com/file/149592
&lt;/a&gt;&lt;br /&gt;Then start writing the plugin program:&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;function main() {&lt;br /&gt;    let exName = exchange.GetName()&lt;br /&gt;    if (exName != &amp;amp;quot;Futures_Binance&amp;amp;quot;) {&lt;br /&gt;        return &amp;amp;quot;not support!&amp;amp;quot;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    let apiBase = &amp;amp;quot;https://fapi.binance.com&amp;amp;quot;&lt;br /&gt;    if (isSimulate) {&lt;br /&gt;        apiBase = &amp;amp;quot;https://testnet.binancefuture.com&amp;amp;quot;        &lt;br /&gt;        Log(&amp;amp;quot;Switch base address:&amp;amp;quot;, apiBase)&lt;br /&gt;    }&lt;br /&gt;    exchange.SetBase(apiBase)&lt;br /&gt;    &lt;br /&gt;    try {&lt;br /&gt;        var obj = JSON.parse(HttpQuery(apiBase + &amp;amp;quot;/fapi/v1/exchangeInfo&amp;amp;quot;))&lt;br /&gt;    } catch (e) {&lt;br /&gt;        Log(e)&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    let pairs = []&lt;br /&gt;    for (var i in obj.symbols) {&lt;br /&gt;        if (obj.symbols[i][&amp;amp;quot;status&amp;amp;quot;] !== &amp;amp;quot;TRADING&amp;amp;quot; || obj.symbols[i][&amp;amp;quot;quoteAsset&amp;amp;quot;] !== &amp;amp;quot;USDT&amp;amp;quot;) {&lt;br /&gt;            continue&lt;br /&gt;        }&lt;br /&gt;        let = pair = obj.symbols[i][&amp;amp;quot;baseAsset&amp;amp;quot;] + &amp;amp;quot;_&amp;amp;quot; + obj.symbols[i][&amp;amp;quot;quoteAsset&amp;amp;quot;]&lt;br /&gt;        pairs.push(pair)&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    let markets = _C(exchange.GetMarkets)&lt;br /&gt;    for (var i in pairs) {&lt;br /&gt;        // /*&lt;br /&gt;        // For testing purposes, only 10 varieties are opened here. If all varieties are needed, this comment content can be deleted.&lt;br /&gt;        if (i &amp;amp;gt;= 9) {&lt;br /&gt;            break&lt;br /&gt;        }&lt;br /&gt;        // */&lt;br /&gt;&lt;br /&gt;        let pair = pairs[i]&lt;br /&gt;        exchange.SetCurrency(pair)&lt;br /&gt;        exchange.SetContractType(&amp;amp;quot;swap&amp;amp;quot;)&lt;br /&gt;        let ticker = exchange.GetTicker()&lt;br /&gt;        if (!ticker) {&lt;br /&gt;            continue &lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        let = amountPrecision = markets[pair + &amp;amp;quot;.swap&amp;amp;quot;][&amp;amp;quot;AmountPrecision&amp;amp;quot;]&lt;br /&gt;        exchange.SetDirection(&amp;amp;quot;buy&amp;amp;quot;)&lt;br /&gt;        let amount = _N(qty / ticker.Last, amountPrecision)&lt;br /&gt;        if (amount &amp;amp;gt; 0) {&lt;br /&gt;            exchange.Buy(-1, amount)&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        Sleep(100)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // Obtain all positions&lt;br /&gt;    let pos = exchange.IO(&amp;amp;quot;api&amp;amp;quot;, &amp;amp;quot;GET&amp;amp;quot;, &amp;amp;quot;/fapi/v2/positionRisk&amp;amp;quot;)&lt;br /&gt;    if (!pos) {&lt;br /&gt;        return &lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    // View positions&lt;br /&gt;    return pos.filter(item =&amp;amp;gt; Number(item.positionAmt) != 0)&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;After the trading terminal plugin is written, it can be tested:&lt;br /&gt;&lt;br /&gt;In the trading terminal of the mobile APP, click on the &amp;amp;#39;...&amp;amp;#39; button to open the list of trading terminal plugins. All plugins in the strategy library of your current FMZ account will be displayed in this list for selection and use.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149593
" title="https://stocksharp.com/file/149593
"&gt;https://stocksharp.com/file/149593
&lt;/a&gt;&lt;br /&gt;After completing the operation on the mobile APP, we use the following code to query the position of Binance&amp;amp;#39;s simulation bot:&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;function main() {&lt;br /&gt;    let apiBase = &amp;amp;quot;https://testnet.binancefuture.com&amp;amp;quot;&lt;br /&gt;    exchange.SetBase(apiBase)&lt;br /&gt;&lt;br /&gt;    let pos = exchange.IO(&amp;amp;quot;api&amp;amp;quot;, &amp;amp;quot;GET&amp;amp;quot;, &amp;amp;quot;/fapi/v2/positionRisk&amp;amp;quot;)&lt;br /&gt;    if (!pos) {&lt;br /&gt;        return &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // View positions&lt;br /&gt;    return pos.filter(item =&amp;amp;gt; Number(item.positionAmt) != 0)&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;Data found:&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;[{&lt;br /&gt;	&amp;amp;quot;symbol&amp;amp;quot;: &amp;amp;quot;ETCUSDT&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;entryPrice&amp;amp;quot;: &amp;amp;quot;16.17&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;unRealizedProfit&amp;amp;quot;: &amp;amp;quot;0.08567881&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;positionSide&amp;amp;quot;: &amp;amp;quot;LONG&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;updateTime&amp;amp;quot;: 1698420908103,&lt;br /&gt;	&amp;amp;quot;isolated&amp;amp;quot;: false,&lt;br /&gt;	&amp;amp;quot;breakEvenPrice&amp;amp;quot;: &amp;amp;quot;16.176468&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;leverage&amp;amp;quot;: &amp;amp;quot;20&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;adlQuantile&amp;amp;quot;: 3,&lt;br /&gt;	&amp;amp;quot;positionAmt&amp;amp;quot;: &amp;amp;quot;0.65&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;markPrice&amp;amp;quot;: &amp;amp;quot;16.30181356&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;liquidationPrice&amp;amp;quot;: &amp;amp;quot;0&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;maxNotionalValue&amp;amp;quot;: &amp;amp;quot;400000&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;marginType&amp;amp;quot;: &amp;amp;quot;cross&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;notional&amp;amp;quot;: &amp;amp;quot;10.59617881&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isolatedMargin&amp;amp;quot;: &amp;amp;quot;0.00000000&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isAutoAddMargin&amp;amp;quot;: &amp;amp;quot;false&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isolatedWallet&amp;amp;quot;: &amp;amp;quot;0&amp;amp;quot;&lt;br /&gt;}, {&lt;br /&gt;	&amp;amp;quot;positionAmt&amp;amp;quot;: &amp;amp;quot;105&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;markPrice&amp;amp;quot;: &amp;amp;quot;0.09371526&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;liquidationPrice&amp;amp;quot;: &amp;amp;quot;0&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;leverage&amp;amp;quot;: &amp;amp;quot;20&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;maxNotionalValue&amp;amp;quot;: &amp;amp;quot;90000&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;positionSide&amp;amp;quot;: &amp;amp;quot;LONG&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isolatedWallet&amp;amp;quot;: &amp;amp;quot;0&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;symbol&amp;amp;quot;: &amp;amp;quot;TRXUSDT&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;updateTime&amp;amp;quot;: 1698420906668,&lt;br /&gt;	&amp;amp;quot;breakEvenPrice&amp;amp;quot;: &amp;amp;quot;0.094497784&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isolatedMargin&amp;amp;quot;: &amp;amp;quot;0.00000000&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isolated&amp;amp;quot;: false,&lt;br /&gt;	&amp;amp;quot;entryPrice&amp;amp;quot;: &amp;amp;quot;0.09446&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;adlQuantile&amp;amp;quot;: 1,&lt;br /&gt;	&amp;amp;quot;unRealizedProfit&amp;amp;quot;: &amp;amp;quot;-0.07819770&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isAutoAddMargin&amp;amp;quot;: &amp;amp;quot;false&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;notional&amp;amp;quot;: &amp;amp;quot;9.84010230&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;marginType&amp;amp;quot;: &amp;amp;quot;cross&amp;amp;quot;&lt;br /&gt;}, {&lt;br /&gt;	&amp;amp;quot;unRealizedProfit&amp;amp;quot;: &amp;amp;quot;-0.00974456&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isAutoAddMargin&amp;amp;quot;: &amp;amp;quot;false&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;notional&amp;amp;quot;: &amp;amp;quot;9.97449543&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isolatedWallet&amp;amp;quot;: &amp;amp;quot;0.50309216&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;updateTime&amp;amp;quot;: 1698420905377,&lt;br /&gt;	&amp;amp;quot;markPrice&amp;amp;quot;: &amp;amp;quot;67.85371047&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isolatedMargin&amp;amp;quot;: &amp;amp;quot;0.49334760&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;adlQuantile&amp;amp;quot;: 2,&lt;br /&gt;	&amp;amp;quot;symbol&amp;amp;quot;: &amp;amp;quot;LTCUSDT&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;entryPrice&amp;amp;quot;: &amp;amp;quot;67.92&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;liquidationPrice&amp;amp;quot;: &amp;amp;quot;64.91958163&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;maxNotionalValue&amp;amp;quot;: &amp;amp;quot;250000&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;positionSide&amp;amp;quot;: &amp;amp;quot;LONG&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isolated&amp;amp;quot;: true,&lt;br /&gt;	&amp;amp;quot;positionAmt&amp;amp;quot;: &amp;amp;quot;0.147&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;breakEvenPrice&amp;amp;quot;: &amp;amp;quot;67.947168&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;leverage&amp;amp;quot;: &amp;amp;quot;20&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;marginType&amp;amp;quot;: &amp;amp;quot;isolated&amp;amp;quot;&lt;br /&gt;}, {&lt;br /&gt;	&amp;amp;quot;liquidationPrice&amp;amp;quot;: &amp;amp;quot;1613.23261508&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;marginType&amp;amp;quot;: &amp;amp;quot;isolated&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isolated&amp;amp;quot;: true,&lt;br /&gt;	&amp;amp;quot;symbol&amp;amp;quot;: &amp;amp;quot;ETHUSDT&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;entryPrice&amp;amp;quot;: &amp;amp;quot;1784.27&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;markPrice&amp;amp;quot;: &amp;amp;quot;1783.35661952&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isAutoAddMargin&amp;amp;quot;: &amp;amp;quot;false&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;positionSide&amp;amp;quot;: &amp;amp;quot;LONG&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;notional&amp;amp;quot;: &amp;amp;quot;8.91678309&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;leverage&amp;amp;quot;: &amp;amp;quot;10&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;maxNotionalValue&amp;amp;quot;: &amp;amp;quot;30000000&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isolatedWallet&amp;amp;quot;: &amp;amp;quot;0.89551774&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;adlQuantile&amp;amp;quot;: 1,&lt;br /&gt;	&amp;amp;quot;positionAmt&amp;amp;quot;: &amp;amp;quot;0.005&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;breakEvenPrice&amp;amp;quot;: &amp;amp;quot;1784.983708&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;unRealizedProfit&amp;amp;quot;: &amp;amp;quot;-0.00456690&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isolatedMargin&amp;amp;quot;: &amp;amp;quot;0.89095084&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;updateTime&amp;amp;quot;: 1698420900362&lt;br /&gt;}, {&lt;br /&gt;	&amp;amp;quot;positionAmt&amp;amp;quot;: &amp;amp;quot;17.1&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;marginType&amp;amp;quot;: &amp;amp;quot;cross&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isolatedWallet&amp;amp;quot;: &amp;amp;quot;0&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;adlQuantile&amp;amp;quot;: 2,&lt;br /&gt;	&amp;amp;quot;liquidationPrice&amp;amp;quot;: &amp;amp;quot;0&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;maxNotionalValue&amp;amp;quot;: &amp;amp;quot;250000&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;positionSide&amp;amp;quot;: &amp;amp;quot;LONG&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isolated&amp;amp;quot;: false,&lt;br /&gt;	&amp;amp;quot;symbol&amp;amp;quot;: &amp;amp;quot;EOSUSDT&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;breakEvenPrice&amp;amp;quot;: &amp;amp;quot;0.6432572&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;updateTime&amp;amp;quot;: 1698420904257,&lt;br /&gt;	&amp;amp;quot;isolatedMargin&amp;amp;quot;: &amp;amp;quot;0.00000000&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isAutoAddMargin&amp;amp;quot;: &amp;amp;quot;false&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;notional&amp;amp;quot;: &amp;amp;quot;10.34550000&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;entryPrice&amp;amp;quot;: &amp;amp;quot;0.643&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;markPrice&amp;amp;quot;: &amp;amp;quot;0.60500000&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;unRealizedProfit&amp;amp;quot;: &amp;amp;quot;-0.64980000&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;leverage&amp;amp;quot;: &amp;amp;quot;20&amp;amp;quot;&lt;br /&gt;}, {&lt;br /&gt;	&amp;amp;quot;isolated&amp;amp;quot;: false,&lt;br /&gt;	&amp;amp;quot;adlQuantile&amp;amp;quot;: 1,&lt;br /&gt;	&amp;amp;quot;liquidationPrice&amp;amp;quot;: &amp;amp;quot;0&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;maxNotionalValue&amp;amp;quot;: &amp;amp;quot;10000000&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;notional&amp;amp;quot;: &amp;amp;quot;9.73993328&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;leverage&amp;amp;quot;: &amp;amp;quot;20&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;updateTime&amp;amp;quot;: 1698420901638,&lt;br /&gt;	&amp;amp;quot;symbol&amp;amp;quot;: &amp;amp;quot;BCHUSDT&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;entryPrice&amp;amp;quot;: &amp;amp;quot;250.0&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;markPrice&amp;amp;quot;: &amp;amp;quot;243.49833219&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isAutoAddMargin&amp;amp;quot;: &amp;amp;quot;false&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;positionSide&amp;amp;quot;: &amp;amp;quot;LONG&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;positionAmt&amp;amp;quot;: &amp;amp;quot;0.040&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;breakEvenPrice&amp;amp;quot;: &amp;amp;quot;250.1&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isolatedMargin&amp;amp;quot;: &amp;amp;quot;0.00000000&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;unRealizedProfit&amp;amp;quot;: &amp;amp;quot;-0.26006671&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;marginType&amp;amp;quot;: &amp;amp;quot;cross&amp;amp;quot;,&lt;br /&gt;	&amp;amp;quot;isolatedWallet&amp;amp;quot;: &amp;amp;quot;0&amp;amp;quot;&lt;br /&gt;}]&lt;br /&gt;```&lt;br /&gt;It can be seen that 6 positions have been opened, this is because when placing actual orders on the simulation bot, it&amp;amp;#39;s easy to trigger limit prices; in addition, due to the order amount of 10U, it&amp;amp;#39;s easy to trigger the minimum order amount limit of trading pairs; therefore a few trading pairs were not successfully ordered. &lt;br /&gt;If you need to use this in reality, more practical situations should be considered in order to optimize this plugin for better usage. The code here is only used for teaching and communication purposes.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Other Interesting Built-in Plugins on FMZ&lt;/b&gt;&lt;br /&gt;The FMZ Quant Trading Platform mobile app trading terminal has many interesting plugins. Come and explore together!&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAADHZKb-RfbDOdB_w3dJgQKt9xqN8kE5Kkn-fL4pSIl_5-9VqG_BAKkEzhNdGLTTMwnI5ljyUq5pbzTOWEMQ7bzY" title="https://www.fmz.com/upload/asset/16b436307a4ce5c246c2.mp4
"&gt;https://www.fmz.com/uplo...6b436307a4ce5c246c2.mp4
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The End&lt;/b&gt;&lt;br /&gt;The new trading terminal feature of the FMZ mobile app will become your powerful assistant in the digital asset market, allowing you to respond more flexibly to market fluctuations and opportunities. No longer limited to traditional trading strategies, through custom plugin programs, you can create smarter, more efficient trading strategies that are better adapted to the market. Let&amp;amp;#39;s start this exciting new chapter of quantitative trading together and enhance your trading skills and profits.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y63a22F2g41PdIIqGtgrMebs9U-8zB3jppLQsJFjxtN8exAtDhnKLxg8X28K29FII8kW57BT0P9cr7xn_l-OMDUnmcxtt9YY008hfWQnZtbHAy33nzd_Dc_PB_c9yUT16PA" title="https://blog.mathquant.com/2023/10/30/fmz-mobile-app-trading-terminal-empowering-your-quantitative-trading-experience.html"&gt;https://blog.mathquant.c...-trading-experience.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25619/</id>
    <title type="text">Navigating Position Risk: Unveiling VaR Method for Effective Measurement</title>
    <published>2024-03-25T05:16:19Z</published>
    <updated>2024-03-25T05:16:19Z</updated>
    <author>
      <name>FMZQuant</name>
      <uri>https://stocksharp.com/users/185759/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#market" />
    <category term="#fmz" />
    <category term="#risk" />
    <category term="#crypto" />
    <category term="#asset" />
    <category term="#algorithm" />
    <category term="#loss" />
    <category term="#position" />
    <category term="#VaR" />
    <content type="html">Controlling risk is a skill that every investor needs to learn. With the rapidly changing and evolving cryptocurrency market, algorithmic traders need to focus on risk management especially. This is because algorithmic trading often executes trades automatically based on historical data and statistical models, which may quickly become inaccurate in fast-moving markets. Therefore, effective risk management strategies are crucial for protecting investors&amp;#39; capital.&lt;br /&gt;&lt;br /&gt;Among many risk management tools, Value at Risk (VaR) is a widely used measure of risk. It can help investors predict the maximum loss that might occur under normal market conditions in their portfolio. VaR quantifies risk into a single number, simplifying the expression of risk and allowing investors to understand potential losses intuitively.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Role of VaR&lt;/b&gt;&lt;br /&gt;VaR, or &amp;quot;Value at Risk&amp;quot;, is used to quantify the maximum possible loss that can be endured within a certain period of time, according to a certain confidence level. In other words, it tells investors or risk managers: &amp;quot;Under normal market conditions, how much money is within the &amp;#39;safe&amp;#39; range and will not be lost tomorrow.&amp;quot; For example, if the 1-day 99% VaR of a cryptocurrency portfolio is $10,000, it means that in 99% of cases we expect the loss in one day will not exceed $10,000.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Advantages&lt;/b&gt;&lt;br /&gt;1. **Easy to understand** : For example, the 1-day 95% VaR of a digital currency portfolio is $5000, which means there is a 95% confidence that the loss of the portfolio within one day will not exceed $5000. Quantifying complex risks into an intuitive number makes it easy for non-professionals to understand. Of course, it&amp;#39;s inevitably to have some misleading aspects.&lt;br /&gt;&lt;br /&gt;2. **Relatively standard** : Suppose there are two portfolios A and B, with A&amp;#39;s 1-day 95% VaR being $3000 and B&amp;#39;s being $6000. This implies that under normal market conditions, A&amp;#39;s risk is lower than B&amp;#39;s. Even if these two portfolios contain different assets, we can compare their risk levels directly. Correspondingly, we can also judge the level of investment; if both strategies A and B have earned $6000 in the past month but A&amp;#39;s average and maximum VaR values are significantly lower than B&amp;#39;s, then we could consider strategy A as better, since it achieves higher returns at a lower risk level.&lt;br /&gt;&lt;br /&gt;3. **Decision-making tool** : Traders might use VaR to decide whether or not to add a new asset to their portfolio. If adding an asset increases the VaR value significantly, then it may suggest that the added asset&amp;#39;s risk does not match with the portfolio&amp;#39;s acceptable risk level.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Disadvantages&lt;/b&gt;&lt;br /&gt;1. **Ignoring tail risk** : If a portfolio&amp;#39;s 1-day 99% VaR is $10,000, the loss in the extreme 1% scenario could far exceed this value. In the field of digital currency, black swan events are frequent and extreme situations can exceed most people&amp;#39;s expectations, because VaR does not consider tail events.&lt;br /&gt;&lt;br /&gt;2. **Assumption limitations** : The parameter VaR often assumes that asset returns are normally distributed, which is rarely the case in real markets, especially in digital currency markets. For example, suppose a portfolio only contains Bitcoin. We use the parameter VaR and assume that Bitcoin&amp;#39;s return is normally distributed. However, in reality, Bitcoin&amp;#39;s rate of return may experience large jumps during certain periods and exhibit significant volatility clustering phenomena. If there has been high volatility over the past week, the probability of noticeable volatility in the following period will increase significantly. This can lead to an underestimation of risk by normal distribution models. Some models take this issue into account such as GARCH etc., but we won&amp;#39;t discuss them here.&lt;br /&gt;&lt;br /&gt;3. **Historical dependence** : The VaR model relies on historical data to predict future risks. However, past performance does not always indicate future situations, especially in rapidly changing markets like the digital currency market. For example, if Bitcoin has been very stable over the past year, a historical simulation might predict a very low VaR. However, if there is a sudden regulatory change or market crash, past data will no longer be an effective predictor of future risk.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Methods of Calculating VaR&lt;/b&gt;&lt;br /&gt;There are mainly three methods to calculate VaR: Parametric method (Variance-Covariance Method): This assumes that the rate of return follows a certain distribution (usually normal distribution), and we use the mean and standard deviation of the rate of return to calculate VaR. Historical Simulation Method: It makes no assumptions about the distribution of returns, but uses historical data directly to determine potential loss distributions. Monte Carlo Simulation: It uses randomly generated price paths to simulate asset prices and calculates VaR from them.&lt;br /&gt;&lt;br /&gt;The Historical Simulation Method utilizes past price changes directly to estimate possible future losses. It does not need any assumptions about profit distribution, making it suitable for assets with unknown or abnormal profit distributions, such as digital currencies.&lt;br /&gt;&lt;br /&gt;For example, if we want to calculate 1-day 95% VaR for a Bitcoin spot position, we can do this:&lt;br /&gt;&lt;br /&gt;1. Collect the daily returns of Bitcoin over a certain period (for example, 100 days).&lt;br /&gt;2. Calculate the portfolio return rate each day, which is the return rate of each asset multiplied by its weight in the portfolio.&lt;br /&gt;3. Sort these 100 days of portfolio returns from low to high.&lt;br /&gt;4. Find the data point at the 5% mark (because we are calculating 95% VaR). The point represents the loss rate on the best day out of worst five days in past 100 days.&lt;br /&gt;5. Multiply the return by total value held, and that&amp;#39;s your one-day 95% VaR.&lt;br /&gt;&lt;br /&gt;The following is a specific code that has obtained data from the past 1000 days, calculating that the current VaR for holding one BTC spot is 1980 USDT.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;import numpy as np&lt;br /&gt;import requests&lt;br /&gt;&lt;br /&gt;url = &amp;#39;https://api.binance.com/api/v3/klines?symbol=%s&amp;amp;interval=%s&amp;amp;limit=1000&amp;#39;%(&amp;#39;BTCUSDT&amp;#39;,&amp;#39;1d&amp;#39;)&lt;br /&gt;res = requests.get(url)&lt;br /&gt;data = res.json()&lt;br /&gt;&lt;br /&gt;confidence_level = 0.95&lt;br /&gt;closing_prices = [float(day[4]) for day in data]&lt;br /&gt;log_returns = np.diff(np.log(closing_prices))&lt;br /&gt;VaR = np.percentile(log_returns, (1 - confidence_level) * 100)&lt;br /&gt;money_at_risk = VaR * closing_prices[-1] * 1&lt;br /&gt;&lt;br /&gt;print(f&amp;quot;VaR at {confidence_level*100}% confidence level is {money_at_risk}&amp;quot;)&lt;br /&gt;```&lt;br /&gt;&lt;b&gt;Calculating VaR Considering Correlation&lt;/b&gt;&lt;br /&gt;When calculating the VaR of a portfolio containing multiple assets, we must consider the correlation between these assets. If there is a positive correlation in price changes between assets, then the risk of the portfolio will increase; if it&amp;#39;s negatively correlated, then the risk of the portfolio will decrease.&lt;br /&gt;&lt;br /&gt;When using historical simulation method to calculate VaR considering correlation, we need to collect not only each individual asset&amp;#39;s historical returns, but also consider their joint distribution. In practice, you can use the historical returns of your portfolio for sorting and calculation directly, because these returns already implicitly include inter-asset correlations. In cryptocurrency markets, correlation is especially important with BTC essentially leading market trends. If BTC rises bullishly, other cryptocurrencies are likely to rise as well; if BTC rapidly surges or plummets due to quickly changing market, this could cause significant short-term increases in correlation - something that is particularly common during extreme market events. Therefore, historical simulation method is a useful tool when considering digital currency investment portfolios&amp;#39; VaR calculations. It doesn&amp;#39;t require complex statistical models - just effective historical data - and naturally includes inter-asset correlations.&lt;br /&gt;&lt;br /&gt;For example: holding 1 long position on BTC and 10 short positions on ETH – following our previous method – we can calculate that 10 ETH short positions have a VaR of 1219 USDT. When combining these two types of assets into one portfolio, here&amp;#39;s how you would calculate its combined VaR:&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;confidence_level = 0.95&lt;br /&gt;btc_closing_prices = np.array([float(day[4]) for day in btc_data])&lt;br /&gt;eth_closing_prices = np.array([float(day[4]) for day in eth_data])&lt;br /&gt;btc_log_returns = np.diff(np.log(btc_closing_prices))&lt;br /&gt;eth_log_returns = np.diff(np.log(eth_closing_prices))&lt;br /&gt;&lt;br /&gt;log_returns = (1*btc_log_returns*btc_closing_prices[1:] - 10*eth_log_returns*eth_closing_prices[1:])/(1*btc_closing_prices[1:] + 10*eth_closing_prices[1:])&lt;br /&gt;VaR = np.percentile(log_returns, (1 - confidence_level) * 100)&lt;br /&gt;money_at_risk = VaR * (btc_closing_prices[-1] * 1 + eth_closing_prices[-1]*10)&lt;br /&gt;&lt;br /&gt;print(f&amp;quot;VaR at {confidence_level*100}% confidence level is {money_at_risk}&amp;quot;)&lt;br /&gt;```&lt;br /&gt;The result is 970 USDT, which means the risk of this combination is lower than holding the respective assets separately. This is because BTC and ETH markets have a high correlation, and the hedging effect of long-short position combinations serves to reduce risk.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;This article will introduce a highly adaptive risk assessment method, namely the application of Historical Simulation in calculating VaR, as well as how to consider asset correlations to optimize risk prediction. Through specific examples from the digital currency market, it explains how to use historical simulation to assess portfolio risks and discusses methods for calculating VaR when asset correlations are significant. With this method, algorithmic traders can not only estimate their maximum loss in most situations, but also be prepared for extreme market conditions. This allows them to trade more calmly and execute strategies accurately.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y6yFNy3NAma5skPNX7KdFj0RWQ__h8we_fnMRera2xT2iq6SFSaO1FaN1f00dhxbQf2dmlQD8eohKaz7Mp4XSXjTfkM4rtSJXvtnSP36nhko8" title="https://blog.mathquant.com/2023/11/03/how-to-measure-position-risk-an-introduction-to-the-var-method.html"&gt;https://blog.mathquant.c...n-to-the-var-method.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25618/</id>
    <title type="text">Exploring Unconventional Trading Techniques: The K-Line Area Trading Strategy</title>
    <published>2024-03-25T03:03:22Z</published>
    <updated>2024-03-25T03:03:22Z</updated>
    <author>
      <name>FMZQuant</name>
      <uri>https://stocksharp.com/users/185759/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#strategy" />
    <category term="#code" />
    <category term="#fmz" />
    <category term="#risk" />
    <category term="#Kline" />
    <category term="#indicator" />
    <category term="#crypto" />
    <category term="#price" />
    <category term="#trend" />
    <content type="html">Looking at a not-so-reliable trading idea -- the K-line area trading strategy, in this article, we will explore the concept and try to implement the script.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Main Idea of the K-Line Area Strategy&lt;/b&gt;&lt;br /&gt;The K-line area strategy is a trading strategy based on the area relationship between price K-lines and moving averages. Its main idea is to predict possible trends in stock prices by analyzing the magnitude and changes of price trends, as well as shifts in buying and selling sentiment, thereby determining when to open positions and exit. This strategy relies on the area between the K-line and moving averages, as well as values from the KDJ indicator, to generate long and short trading signals.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Principle of K-Line Area Strategy&lt;/b&gt;&lt;br /&gt;The area of the K-line refers to the spatial area between the price K-line and the moving average, calculated by subtracting the moving average value from each bar&amp;#39;s closing price and then summing it up. When there is a large increase in price over a long period of time, the K-line area will become larger, while during volatile markets or after volatility reversals, the K-line area is smaller. According to the principle of &amp;quot;what goes up must come down&amp;quot;, as an upward trend becomes larger and lasts longer, its corresponding K-line area also increases; thus increasing its probability for reversal - much like a spring that rebounds with greater force when stretched further. Therefore, setting a threshold for this K-line area can indicate when prices may have reached their peak and are likely to reverse.&lt;br /&gt;&lt;br /&gt;To further confirm an impending trend reversal, we introduce the use of KDJ indicators which help determine shifts in buying or selling sentiment. The thresholds for the strategy and values for these indicators can be adjusted according to specific circumstances and needs in order to enhance accuracy.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Advantages of K-Line Area Strategy&lt;/b&gt;&lt;br /&gt;The advantage of the K-line area strategy lies in its combination of the magnitude and changes of price trends, as well as the shift in buying and selling sentiment, providing a relatively complete quantitative trading strategy. Its advantages include:&lt;br /&gt;&lt;br /&gt;- It provides a simple and intuitive method to identify the possibility of trend reversal, helping traders better grasp market trends.&lt;br /&gt;- By combining the K-line area and KDJ indicator, it increases the reliability and accuracy of the strategy.&lt;br /&gt;- High flexibility allows for parameter adjustments according to market conditions to meet different trading needs.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Risk of K-line Area Strategy&lt;/b&gt;&lt;br /&gt;Although the K-line area strategy has certain advantages, it also carries some risks, including:&lt;br /&gt;&lt;br /&gt;- The setting of thresholds may require some experience and adjustment. If it set improperly, it could lead to misjudgment of market trends.&lt;br /&gt;- The accuracy of the KDJ indicator is affected by market fluctuations and noise, which may result in false signals.&lt;br /&gt;- The performance of the strategy may vary under different market conditions and needs constant optimization and adjustment.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Optimization Direction of K-line Area Strategy&lt;/b&gt;&lt;br /&gt;To optimize the K-line area strategy, consider the following directions:&lt;br /&gt;&lt;br /&gt;- Parameter optimization: Continuously adjust and optimize threshold values and KDJ indicator parameters to adapt to different market conditions and trading needs.&lt;br /&gt;- Risk management: Implement effective risk management strategies, including stop-loss and take-profit rules, to reduce loss risks.&lt;br /&gt;- Multi-strategy combination: Combine the K-line area strategy with other strategies to improve the performance of comprehensive trading strategies.&lt;br /&gt;- Real-time monitoring and adjustment: Regularly monitor the performance of strategies, adjusting and improving based on actual situations.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Implement the Strategy Using JavaScript&lt;/b&gt;&lt;br /&gt;- Calculate K-line Area&lt;br /&gt;&lt;br /&gt;- Long position opening signal:&lt;br /&gt;&lt;br /&gt;  (1) The &amp;quot;K-line area&amp;quot; of the downward trend reaches the threshold, it can be established beforehand.&lt;br /&gt;&lt;br /&gt;  (2) KDJ indicator value is greater than 80.&lt;br /&gt;&lt;br /&gt;- Short position opening signal:&lt;br /&gt;&lt;br /&gt;  (1) The &amp;quot;K-line area&amp;quot; of the upward trend reaches the threshold, it can be established beforehand.&lt;br /&gt;&lt;br /&gt;  (2) KDJ indicator value is less than 20.&lt;br /&gt;&lt;br /&gt;- Exit for Long/Short positions: ATR trailing stop loss and take profit.&lt;br /&gt;&lt;br /&gt;Code implementation&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;// Parameter&lt;br /&gt;var maPeriod = 30&lt;br /&gt;var threshold = 50000&lt;br /&gt;var amount = 0.1&lt;br /&gt;&lt;br /&gt;// Global variable&lt;br /&gt;let c = KLineChart({})&lt;br /&gt;let openPrice = 0&lt;br /&gt;let tradeState = &amp;quot;NULL&amp;quot;  // NULL BUY SELL&lt;br /&gt;&lt;br /&gt;function calculateKLineArea(r, ma) {&lt;br /&gt;    var lastCrossUpIndex = null&lt;br /&gt;    var lastCrossDownIndex = null&lt;br /&gt;    for (var i = r.length - 1 ; i &amp;gt;= 0 ; i--) {&lt;br /&gt;        if (ma[i] !== null &amp;amp;&amp;amp; r[i].Open &amp;lt; ma[i] &amp;amp;&amp;amp; r[i].Close &amp;gt; ma[i]) {&lt;br /&gt;            lastCrossUpIndex = i&lt;br /&gt;            break&lt;br /&gt;        } else if (ma[i] !== null &amp;amp;&amp;amp; r[i].Open &amp;gt; ma[i] &amp;amp;&amp;amp; r[i].Close &amp;lt; ma[i]) {&lt;br /&gt;            lastCrossDownIndex = i&lt;br /&gt;            break&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (i &amp;gt;= 1 &amp;amp;&amp;amp; ma[i] !== null &amp;amp;&amp;amp; ma[i - 1] !== null &amp;amp;&amp;amp; r[i - 1].Close &amp;lt; ma[i - 1] &amp;amp;&amp;amp; r[i].Close &amp;gt; ma[i]) {&lt;br /&gt;            lastCrossUpIndex = i&lt;br /&gt;            break&lt;br /&gt;        } else if (i &amp;gt;= 1 &amp;amp;&amp;amp; ma[i] !== null &amp;amp;&amp;amp; ma[i - 1] !== null &amp;amp;&amp;amp; r[i - 1].Close &amp;gt; ma[i - 1] &amp;amp;&amp;amp; r[i].Close &amp;lt; ma[i]) {&lt;br /&gt;            lastCrossDownIndex = i&lt;br /&gt;            break&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    var area = 0&lt;br /&gt;    if (lastCrossDownIndex !== null) {&lt;br /&gt;        for (var i = r.length - 1 ; i &amp;gt;= lastCrossDownIndex ; i--) {&lt;br /&gt;            area -= Math.abs(r[i].Close - ma[i])&lt;br /&gt;        }&lt;br /&gt;    } else if (lastCrossUpIndex !== null) {&lt;br /&gt;        for (var i = r.length - 1 ; i &amp;gt;= lastCrossUpIndex ; i--) {&lt;br /&gt;            area += Math.abs(r[i].Close - ma[i])&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return [area, lastCrossUpIndex, lastCrossDownIndex]&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function onTick() {&lt;br /&gt;    var r = _C(exchange.GetRecords)&lt;br /&gt;    if (r.length &amp;lt; maPeriod) {&lt;br /&gt;        LogStatus(_D(), &amp;quot;Insufficient number of K-line&amp;quot;)&lt;br /&gt;        return &lt;br /&gt;    }&lt;br /&gt;    var ma = TA.MA(r, maPeriod)&lt;br /&gt;    var atr = TA.ATR(r)&lt;br /&gt;    var kdj = TA.KDJ(r)&lt;br /&gt;    var lineK = kdj[0]&lt;br /&gt;    var lineD = kdj[1]&lt;br /&gt;    var lineJ = kdj[2]&lt;br /&gt;    var areaInfo = calculateKLineArea(r, ma)&lt;br /&gt;    var area = _N(areaInfo[0], 0)&lt;br /&gt;    var lastCrossUpIndex = areaInfo[1]&lt;br /&gt;    var lastCrossDownIndex = areaInfo[2]&lt;br /&gt;    &lt;br /&gt;    r.forEach(function(bar, index) {&lt;br /&gt;        c.begin(bar)&lt;br /&gt;        c.plotcandle(bar.Open, bar.High, bar.Low, bar.Close, {overlay: true})&lt;br /&gt;        let maLine = c.plot(ma[index], &amp;quot;ma&amp;quot;, {overlay: true})&lt;br /&gt;        let close = c.plot(bar.Close, &amp;#39;close&amp;#39;, {overlay: true})&lt;br /&gt;        c.fill(maLine, close, {color: bar.Close &amp;gt; ma[index] ? &amp;#39;rgba(255, 0, 0, 0.1)&amp;#39; : &amp;#39;rgba(0, 255, 0, 0.1)&amp;#39;})&lt;br /&gt;        if (lastCrossUpIndex !== null) {&lt;br /&gt;            c.plotchar(bar.Time, {char: &amp;#39;$:&amp;#39; + area, overlay: true})&lt;br /&gt;        } else if (lastCrossDownIndex !== null) {&lt;br /&gt;            c.plotchar(bar.Time, {char: &amp;#39;$:&amp;#39; + area, overlay: true})&lt;br /&gt;        }&lt;br /&gt;        c.plot(lineK[index], &amp;quot;K&amp;quot;)&lt;br /&gt;        c.plot(lineD[index], &amp;quot;D&amp;quot;)&lt;br /&gt;        c.plot(lineJ[index], &amp;quot;J&amp;quot;)&lt;br /&gt;&lt;br /&gt;        c.close()&lt;br /&gt;    })&lt;br /&gt;    &lt;br /&gt;    if (tradeState == &amp;quot;NULL&amp;quot; &amp;amp;&amp;amp; area &amp;lt; -threshold &amp;amp;&amp;amp; lineK[lineK.length - 1] &amp;gt; 70) {&lt;br /&gt;        // long&lt;br /&gt;        let tradeInfo = $.Buy(amount)&lt;br /&gt;        if (tradeInfo) {&lt;br /&gt;            openPrice = tradeInfo.price&lt;br /&gt;            tradeState = &amp;quot;BUY&amp;quot;&lt;br /&gt;        }&lt;br /&gt;    } else if (tradeState == &amp;quot;NULL&amp;quot; &amp;amp;&amp;amp; area &amp;gt; threshold &amp;amp;&amp;amp; lineK[lineK.length - 1] &amp;lt; 30) {&lt;br /&gt;        // short&lt;br /&gt;        let tradeInfo = $.Sell(amount)&lt;br /&gt;        if (tradeInfo) {&lt;br /&gt;            openPrice = tradeInfo.price&lt;br /&gt;            tradeState = &amp;quot;SELL&amp;quot;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    let stopBase = tradeState == &amp;quot;BUY&amp;quot; ? Math.max(openPrice, r[r.length - 2].Close) : Math.min(openPrice, r[r.length - 2].Close)&lt;br /&gt;    if (tradeState == &amp;quot;BUY&amp;quot; &amp;amp;&amp;amp; r[r.length - 1].Close &amp;lt; stopBase - atr[atr.length - 2]) {&lt;br /&gt;        // cover long&lt;br /&gt;        let tradeInfo = $.Sell(amount)&lt;br /&gt;        if (tradeInfo) {&lt;br /&gt;            tradeState = &amp;quot;NULL&amp;quot;&lt;br /&gt;            openPrice = 0&lt;br /&gt;        }        &lt;br /&gt;    } else if (tradeState == &amp;quot;SELL&amp;quot; &amp;amp;&amp;amp; r[r.length - 1].Close &amp;gt; stopBase + atr[atr.length - 2]) {&lt;br /&gt;        // cover short &lt;br /&gt;        let tradeInfo = $.Buy(amount)&lt;br /&gt;        if (tradeInfo) {&lt;br /&gt;            tradeState = &amp;quot;NULL&amp;quot;&lt;br /&gt;            openPrice = 0&lt;br /&gt;        }        &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    LogStatus(_D(), &amp;quot;area:&amp;quot;, area, &amp;quot;, lineK[lineK.length - 2]:&amp;quot;, lineK[lineK.length - 2])&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function main() {    &lt;br /&gt;    if (exchange.GetName().includes(&amp;quot;_Futures&amp;quot;)) {&lt;br /&gt;        throw &amp;quot;not support Futures&amp;quot;&lt;br /&gt;    }&lt;br /&gt;    while (true) {&lt;br /&gt;        onTick()&lt;br /&gt;        Sleep(1000)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;The strategy logic is very simple:&lt;br /&gt;&lt;br /&gt;1. First, some global variables and parameters are defined, including:&lt;br /&gt;&lt;br /&gt;Strategy parameters&lt;br /&gt;&lt;br /&gt;- maPeriod: The period of moving average.&lt;br /&gt;- threshold: A threshold used to determine the timing of buying or selling.&lt;br /&gt;- amount: The quantity for each transaction.&lt;br /&gt;&lt;br /&gt;Global variables&lt;br /&gt;&lt;br /&gt;- c: A K-line chart object, used for drawing charts.&lt;br /&gt;- openPrice: Records the opening price.&lt;br /&gt;- tradeState: Records the trading status, which can be &amp;quot;NULL&amp;quot; (empty position), &amp;quot;BUY&amp;quot; or &amp;quot;SELL&amp;quot;.&lt;br /&gt;&lt;br /&gt;Calculate function&lt;br /&gt;&lt;br /&gt;- calculateKLineArea function: It is used to calculate the area between the price and moving average line on a K-line chart over a certain period of time, and returns the area value, the index of the last upward crossing K-line, and the index of the last downward crossing K-line. These values are used in subsequent decisions to determine when to buy and sell.&lt;br /&gt;&lt;br /&gt;Main loop function&lt;br /&gt;&lt;br /&gt;- onTick function: It is the main strategy execution function, and here are the operations within the function:&lt;br /&gt;&lt;br /&gt;  a. Obtain the latest K-line data and ensure that the number of K-lines is not less than maPeriod, otherwise record status and return.&lt;br /&gt;&lt;br /&gt;  b. Calculate moving average line ma and ATR indicator atr, as well as KDJ indicator.&lt;br /&gt;&lt;br /&gt;  c. Get area information from areaInfo, last cross-over K-line index, and last cross-under K-line index.&lt;br /&gt;&lt;br /&gt;  d. Use K-line chart object c to draw K-lines and indicator lines while filling in different colors based on price&amp;#39;s relationship with moving average line.&lt;br /&gt;&lt;br /&gt;  e. Determine buying or selling timing according to conditions:&lt;br /&gt;&lt;br /&gt;  If tradeState is &amp;quot;NULL&amp;quot;, and the area is less than -threshold, and the K value of KDJ is greater than 70, execute a buy operation.&lt;br /&gt;  If tradeState is &amp;quot;NULL&amp;quot;, and the area is greater than threshold, and the K value of KDJ is less than 30, execute a sell operation.&lt;br /&gt;  f. Set stop loss and take profit conditions. If these conditions are met, close positions:&lt;br /&gt;&lt;br /&gt;  If it&amp;#39;s in buying state, when the price falls below the closing price of last trading day minus previous day&amp;#39;s ATR (Average True Range), close position.&lt;br /&gt;  If it&amp;#39;s in selling state, when the price rises above last trading day&amp;#39;s closing price plus previous day&amp;#39;s ATR (Average True Range), close position.&lt;br /&gt;&lt;br /&gt;  main function: This serves as main execution entry point. It checks if exchange name contains &amp;quot;_Futures&amp;quot;. If so, an exception will be thrown; otherwise it enters into an infinite loop where onTick function gets executed every second.&lt;br /&gt;&lt;br /&gt;In a word, this strategy mainly relies on K-line charts and technical indicators for making buying or selling decisions while also employing stop-loss &amp;amp; take-profit strategies to manage risk. Please note that this just serves as an example strategy which needs to be adjusted &amp;amp; optimized according to market situations &amp;amp; specific requirements during actual use.&lt;br /&gt;&lt;br /&gt;On FMZ.COM, using JavaScript language didn&amp;#39;t require many lines of code, instead, it implemented this model easily. And with help from KLineChart function graphical representation of K-line chart area was easily achieved, too. The strategy design caters towards cryptocurrency spot markets by utilizing &amp;#39;Digital Currency Spot Trading Library&amp;#39; template for placing orders through encapsulated functions within template, which makes it very simple &amp;amp; easy to understand and use.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Strategy Backtesting&lt;/b&gt;&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149572
" title="https://stocksharp.com/file/149572
"&gt;https://stocksharp.com/file/149572
&lt;/a&gt;&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149571
" title="https://stocksharp.com/file/149571
"&gt;https://stocksharp.com/file/149571
&lt;/a&gt;&lt;br /&gt;I selected a backtesting period randomly. Although I didn&amp;#39;t lose money, I didn&amp;#39;t accumulate profits continuously, either, and the drawdown issue is quite significant. There should be other directions and room for optimization for the strategy. Those who are interested can try to upgrade the strategy.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149569
" title="https://stocksharp.com/file/149569
"&gt;https://stocksharp.com/file/149569
&lt;/a&gt;&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149570
" title="https://stocksharp.com/file/149570
"&gt;https://stocksharp.com/file/149570
&lt;/a&gt;&lt;br /&gt;Through the strategy, we not only learned a rather unconventional trading idea, but also learned how to plot diagrams; representing the area enclosed by K-line and moving average line; ploting KDJ indicators etc.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;The K-line area strategy is a trading strategy based on price trend magnitude and the KDJ indicator. It helps traders predict market trends by analyzing the area between the K-line and moving averages, as well as shifts in buying and selling sentiment. Despite certain risks, this strategy can provide powerful trading tools through continuous optimization and adjustment, helping traders better cope with market fluctuations. Moreover, traders should adjust the parameters and rules of the strategy flexibly according to specific situations and market conditions to achieve better trading performance.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y64w0KH_McPil-CCmMm0S4csgQSlJDfYfZNqJ5KuaEFdOqAOE0PYwB0j_-adaAfZDxk8AgDet7R3RaJqt4wzHHixJP8KC83tqTfFB6E1dsCmj" title="https://blog.mathquant.com/2023/11/06/alternative-trading-ideas-k-line-area-trading-strategy.html"&gt;https://blog.mathquant.c...ea-trading-strategy.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25616/</id>
    <title type="text">High-Frequency Trading Strategy Analysis - Penny Jump</title>
    <published>2024-03-25T01:14:50Z</published>
    <updated>2024-03-25T01:14:50Z</updated>
    <author>
      <name>FMZQuant</name>
      <uri>https://stocksharp.com/users/185759/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#strategy" />
    <category term="#code" />
    <category term="#market" />
    <category term="#analysis" />
    <category term="#fmz" />
    <category term="#highfrequency" />
    <category term="#crypto" />
    <category term="#order" />
    <category term="#pennyJump" />
    <content type="html">High-frequency trading is a challenging and competitive field that relies on rapid trade execution and sensitive insights into the microstructure of the market. One notable strategy is Penny Jump, which focuses on exploiting &amp;quot;elephants&amp;quot; in the market to gain small but frequent profits. In this article, we will explain in detail how the Penny Jump strategy works, delving into the details of its code, so that beginners can understand how it operates.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Understanding the Penny Jump Strategy&lt;/b&gt;&lt;br /&gt;In the stock market, &amp;quot;elephants&amp;quot; usually refer to those institutional investors who wish to buy or sell a large number of shares but are unwilling to trade at market price. Instead, they choose to hang a large number of limit orders in the market, i.e., pending orders, to indicate their intentions. This behavior has attracted widespread attention in the market, because large transactions may have a significant impact on the market.&lt;br /&gt;&lt;br /&gt;For example, suppose the original depth of a stock&amp;#39;s market was like this: 200 | $1.01 x $1.03 | 200. Then an &amp;quot;elephant&amp;quot; enters and places a buy order for 3000 shares at $1.01 each. At this point, the depth of the market will change to 3,200 | $1.01 x $1.03 | 200 . This action is like introducing an &amp;quot;elephant&amp;quot;, which becomes the focus of other participants in the marketplace.&lt;br /&gt;&lt;br /&gt;- Competitive market&lt;br /&gt;  For high-frequency traders, their profits mainly come from the analysis of market microstructure to speculate on the intentions of other traders. Once a big player appears, high-frequency traders will establish positions quickly to capture minor price fluctuations. Their goal is to trade frequently in a short period of time and accumulate small but cumulative profits.&lt;br /&gt;&lt;br /&gt;- The Dilemma of the Elephant&lt;br /&gt;  Even though elephants might wish to operate on a large scale in the market, their actions also reveal their trading intentions, making them targets for high-frequency traders. High-frequency traders attempt to establish positions ahead of time and then profit from price fluctuations. The presence of elephants in the market could trigger reactions in competitive markets, thereby affecting their trading strategies.&lt;br /&gt;&lt;br /&gt;- Deception in the Market&lt;br /&gt;  In reality, large institutional investors usually do not place a large number of buy or sell orders in the market blatantly, as such behavior could lead other participants in the market to take countermeasures or even manipulate the market. Therefore, they may adopt strategies to create illusions, attract high-frequency traders into the field, and then quickly sell or buy to profit from price fluctuations.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Core Idea of the Penny Jump Strategy&lt;/b&gt;&lt;br /&gt;The core idea of the Penny Jump strategy is that once a &amp;quot;big player&amp;quot; appears in the market and supports a specific price (such as $1.01), high-frequency traders will quickly raise their bid by one cent, for instance, to $1.02. This is because high-frequency traders understand that the appearance of a big player means there&amp;#39;s strong buying support at this price level, so they try to follow closely in hopes of a price increase. When the price indeed rises to $1.03 x $1.05, high-frequency traders can sell quickly and earn a profit of $0.01.&lt;br /&gt;&lt;br /&gt;Not only that, but high-frequency traders can also make profits after purchasing even if the price doesn&amp;#39;t rise, because they know that the big player has supported the base price; hence they can swiftly sell their stocks to this big player and gain tiny arbitrage profits.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Analyzing Penny Jump Strategy Code&lt;/b&gt;&lt;br /&gt;Strategy source code: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAADHZKb-RfbDOdB_w3dJgQKtdiNZNpLtyGanWuMu3v9LM_2Yv3dlp98Wb2KYr6QeDwk" title="https://www.fmz.com/strategy/358
"&gt;https://www.fmz.com/strategy/358
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The strategy code provided above is an example, used to implement the Penny Jump strategy. Below is a detailed explanation of the code, enabling beginners to understand how it works:&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;var Counter = {&lt;br /&gt;    i: 0,&lt;br /&gt;    w: 0,&lt;br /&gt;    f: 0&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;// Variables&lt;br /&gt;var InitAccount = null;&lt;br /&gt;&lt;br /&gt;function CancelAll() {&lt;br /&gt;    while (true) {&lt;br /&gt;        var orders = _C(exchange.GetOrders);&lt;br /&gt;        if (orders.length == 0) {&lt;br /&gt;            break;&lt;br /&gt;        }&lt;br /&gt;        for (var i = 0; i &amp;lt; orders.length; i++) {&lt;br /&gt;            exchange.CancelOrder(orders[i].Id);&lt;br /&gt;        }&lt;br /&gt;        Sleep(Interval);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function updateStatus(msg) {&lt;br /&gt;    LogStatus(&amp;quot;Number of debugging sessions:&amp;quot;, Counter.i, &amp;quot;succeeded:&amp;quot;, Counter.w, &amp;quot;failed:&amp;quot;, Counter.f, &amp;quot;\n&amp;quot;+msg+&amp;quot;#0000ff\n&amp;quot;+new Date());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function main() {&lt;br /&gt;    if (DisableLog) {&lt;br /&gt;        EnableLog(false);&lt;br /&gt;    }&lt;br /&gt;    CancelAll();&lt;br /&gt;    InitAccount = _C(exchange.GetAccount);&lt;br /&gt;    Log(InitAccount);&lt;br /&gt;    var i = 0;&lt;br /&gt;    var locks = 0;&lt;br /&gt;    while (true) {&lt;br /&gt;        Sleep(Interval);&lt;br /&gt;        var depth = _C(exchange.GetDepth);&lt;br /&gt;        if (depth.Asks.length === 0 || depth.Bids.length === 0) {&lt;br /&gt;            continue;&lt;br /&gt;        }&lt;br /&gt;        updateStatus(&amp;quot;Searching within the elephant... Buy one: &amp;quot; + depth.Bids[0].Price + &amp;quot;,  Sell one:&amp;quot; + depth.Asks[0].Price + &amp;quot;, Lock times: &amp;quot; + locks);&lt;br /&gt;        var askPrice = 0;&lt;br /&gt;        for (i = 0; i &amp;lt; depth.Asks.length; i++) {&lt;br /&gt;            if (depth.Asks[i].Amount &amp;gt;= Lot) {&lt;br /&gt;                askPrice = depth.Asks[i].Price;&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        if (askPrice === 0) {&lt;br /&gt;            continue;&lt;br /&gt;        }&lt;br /&gt;        var elephant = null;&lt;br /&gt;        // skip Bids[0]&lt;br /&gt;        for (i = 1; i &amp;lt; depth.Bids.length; i++) {&lt;br /&gt;            if ((askPrice - depth.Bids[i].Price) &amp;gt; ElephantSpace) {&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;            if (depth.Bids[i].Amount &amp;gt;= ElephantAmount) {&lt;br /&gt;                elephant = depth.Bids[i];&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (!elephant) {&lt;br /&gt;            locks = 0;&lt;br /&gt;            continue;&lt;br /&gt;        }&lt;br /&gt;        locks++;&lt;br /&gt;        if (locks &amp;lt; LockCount) {&lt;br /&gt;            continue;&lt;br /&gt;        }&lt;br /&gt;        locks = 0;&lt;br /&gt;&lt;br /&gt;        updateStatus(&amp;quot;Debug the elephant... The elephant is in gear &amp;quot; + i + &amp;quot;, &amp;quot; + JSON.stringify(elephant));&lt;br /&gt;        exchange.Buy(elephant.Price + PennyTick, Lot, &amp;quot;Bids[&amp;quot; + i + &amp;quot;]&amp;quot;, elephant);&lt;br /&gt;        var ts = new Date().getTime();&lt;br /&gt;        while (true) {&lt;br /&gt;            Sleep(CheckInterval);&lt;br /&gt;            var orders = _C(exchange.GetOrders);&lt;br /&gt;            if (orders.length == 0) {&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;            if ((new Date().getTime() - ts) &amp;gt; WaitInterval) {&lt;br /&gt;                for (var i = 0; i &amp;lt; orders.length; i++) {&lt;br /&gt;                    exchange.CancelOrder(orders[i].Id);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        var account = _C(exchange.GetAccount);&lt;br /&gt;        var opAmount = _N(account.Stocks - InitAccount.Stocks);&lt;br /&gt;        if (opAmount &amp;lt; 0.001) {&lt;br /&gt;            Counter.f++;&lt;br /&gt;            Counter.i++;&lt;br /&gt;            continue;&lt;br /&gt;        }&lt;br /&gt;        updateStatus(&amp;quot;Successful payment: &amp;quot; + opAmount +&amp;quot;, Start taking action...&amp;quot;);&lt;br /&gt;        exchange.Sell(elephant.Price + (PennyTick * ProfitTick), opAmount);&lt;br /&gt;        var success = true;&lt;br /&gt;        while (true) {&lt;br /&gt;            var depth = _C(exchange.GetDepth);&lt;br /&gt;            if (depth.Bids.length &amp;gt; 0 &amp;amp;&amp;amp; depth.Bids[0].Price &amp;lt;= (elephant.Price-(STTick*PennyTick))) {&lt;br /&gt;                success = false;&lt;br /&gt;                updateStatus(&amp;quot;Didn&amp;#39;t get it, start to stop loss, currently buying one: &amp;quot; + depth.Bids[0].Price);&lt;br /&gt;                CancelAll();&lt;br /&gt;                account = _C(exchange.GetAccount);&lt;br /&gt;                var opAmount = _N(account.Stocks - InitAccount.Stocks);&lt;br /&gt;                if (opAmount &amp;lt; 0.001) {&lt;br /&gt;                    break;&lt;br /&gt;                }&lt;br /&gt;                exchange.Sell(depth.Bids[0].Price, opAmount);&lt;br /&gt;            }&lt;br /&gt;            var orders = _C(exchange.GetOrders);&lt;br /&gt;            if (orders.length === 0) {&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;            Sleep(CheckInterval);&lt;br /&gt;        }&lt;br /&gt;        if (success) {&lt;br /&gt;            Counter.w++;&lt;br /&gt;        } else {&lt;br /&gt;            Counter.f++;&lt;br /&gt;        }&lt;br /&gt;        Counter.i++;&lt;br /&gt;        var account = _C(exchange.GetAccount);&lt;br /&gt;        LogProfit(account.Balance - InitAccount.Balance, account);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;I will parse your provided strategy code line by line to help you understand its operation in detail.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;var Counter = {&lt;br /&gt;    i: 0,&lt;br /&gt;    w: 0,&lt;br /&gt;    f: 0&lt;br /&gt;};&lt;br /&gt;```&lt;br /&gt;This code initializes an object named Counter, which is used to track the trading statistical information of a strategy. Specifically, it includes three attributes:&lt;br /&gt;&lt;br /&gt;- i: Represents the total number of transactions.&lt;br /&gt;- w: Represents the number of successful transactions.&lt;br /&gt;- f: Represents the number of failed transactions.&lt;br /&gt;&lt;br /&gt;These attributes will be recorded and updated during the strategy execution process.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;var InitAccount = null;&lt;br /&gt;```&lt;br /&gt;This line of code initializes a variable named InitAccount, which will store account information when the strategy starts executing.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;function CancelAll() {&lt;br /&gt;    while (true) {&lt;br /&gt;        var orders = _C(exchange.GetOrders);&lt;br /&gt;        if (orders.length == 0) {&lt;br /&gt;            break;&lt;br /&gt;        }&lt;br /&gt;        for (var i = 0; i &amp;lt; orders.length; i++) {&lt;br /&gt;            exchange.CancelOrder(orders[i].Id);&lt;br /&gt;        }&lt;br /&gt;        Sleep(Interval);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;This is a function named ```CancelAll()```, its purpose is to cancel all unfulfilled orders in the market. Let&amp;#39;s explain its functions step by step:&lt;br /&gt;&lt;br /&gt;- ```while (true)```: This is an infinite loop, it will continue to run until there are no uncompleted orders.&lt;br /&gt;- ```var orders = _C(exchange.GetOrders)```: This line of code uses the exchange.GetOrders function to retrieve all pending orders in the current account and stores them in the orders variable.&lt;br /&gt;- ```if (orders.length == 0)```: This line of code checks for any unfinished orders. If the length of the orders array is 0, it means there are no unfinished orders and the loop will be interrupted (break).&lt;br /&gt;- ```for (var i = 0; i &amp;lt; orders.length; i++)```: This is a for loop that iterates through all uncompleted orders.&lt;br /&gt;- ```exchange.CancelOrder(orders[i].Id)```: This line of code uses the exchange.CancelOrder() function to cancel each order by its ID.&lt;br /&gt;- ```Sleep(Interval)```: This line of code introduces a waiting period, pausing for a certain amount of time (in milliseconds), to ensure that the operation of cancelling orders is not too frequent.&lt;br /&gt;&lt;br /&gt;This line of code introduces a waiting period, pausing for a certain amount of time (in milliseconds), to ensure that the operation of cancelling orders is not too frequent.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;function updateStatus(msg) {&lt;br /&gt;    LogStatus(&amp;quot;Number of debugging sessions:&amp;quot;, Counter.i, &amp;quot;succeeded:&amp;quot;, Counter.w, &amp;quot;failed:&amp;quot;, Counter.f, &amp;quot;\n&amp;quot; + msg + &amp;quot;#0000ff\n&amp;quot; + new Date());&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;This is a function named ```updateStatus(msg)```, which is used to update and record transaction status information. It accepts a msg parameter, which usually contains information about the current market status. The specific operations of the function include:&lt;br /&gt;&lt;br /&gt;Using the ```LogStatus()``` function to record the information displayed in the status bar during strategy execution. It displays text about trade counts, successful counts, and failure counts.&lt;br /&gt;The ```msg``` parameter is appended, which contains information about the current market status.&lt;br /&gt;The current timestamp (```new Date()```) is appended to display time information.&lt;br /&gt;The purpose of this function is to record and update transaction status information for monitoring and analysis during strategy execution.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;function main() {&lt;br /&gt;    if (DisableLog) {&lt;br /&gt;        EnableLog(false);&lt;br /&gt;    }&lt;br /&gt;    CancelAll();&lt;br /&gt;    InitAccount = _C(exchange.GetAccount);&lt;br /&gt;    Log(InitAccount);&lt;br /&gt;    var i = 0;&lt;br /&gt;    var locks = 0;&lt;br /&gt;    while (true) {&lt;br /&gt;        Sleep(Interval);&lt;br /&gt;        var depth = _C(exchange.GetDepth);&lt;br /&gt;        if (depth.Asks.length === 0 || depth.Bids.length === 0) {&lt;br /&gt;            continue;&lt;br /&gt;        }&lt;br /&gt;        updateStatus(&amp;quot;Searching within the elephant... Buy one: &amp;quot; + depth.Bids[0].Price + &amp;quot;,  Sell one:&amp;quot; + depth.Asks[0].Price + &amp;quot;, Lock times: &amp;quot; + locks);&lt;br /&gt;        var askPrice = 0;&lt;br /&gt;        for (i = 0; i &amp;lt; depth.Asks.length; i++) {&lt;br /&gt;            if (depth.Asks[i].Amount &amp;gt;= Lot) {&lt;br /&gt;                askPrice = depth.Asks[i].Price;&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        if (askPrice === 0) {&lt;br /&gt;            continue;&lt;br /&gt;        }&lt;br /&gt;        var elephant = null;&lt;br /&gt;        // skip Bids[0]&lt;br /&gt;        for (i = 1; i &amp;lt; depth.Bids.length; i++) {&lt;br /&gt;            if ((askPrice - depth.Bids[i].Price) &amp;gt; ElephantSpace) {&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;            if (depth.Bids[i].Amount &amp;gt;= ElephantAmount) {&lt;br /&gt;                elephant = depth.Bids[i];&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (!elephant) {&lt;br /&gt;            locks = 0;&lt;br /&gt;            continue;&lt;br /&gt;        }&lt;br /&gt;        locks++;&lt;br /&gt;        if (locks &amp;lt; LockCount) {&lt;br /&gt;            continue;&lt;br /&gt;        }&lt;br /&gt;        locks = 0;&lt;br /&gt;&lt;br /&gt;        updateStatus(&amp;quot;Debug the elephant... The elephant is in gear &amp;quot; + i + &amp;quot;, &amp;quot; + JSON.stringify(elephant));&lt;br /&gt;        exchange.Buy(elephant.Price + PennyTick, Lot, &amp;quot;Bids[&amp;quot; + i + &amp;quot;]&amp;quot;, elephant);&lt;br /&gt;        var ts = new Date().getTime();&lt;br /&gt;        while (true) {&lt;br /&gt;            Sleep(CheckInterval);&lt;br /&gt;            var orders = _C(exchange.GetOrders);&lt;br /&gt;            if (orders.length == 0) {&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;            if ((new Date().getTime() - ts) &amp;gt; WaitInterval) {&lt;br /&gt;                for (var i = 0; i &amp;lt; orders.length; i++) {&lt;br /&gt;                    exchange.CancelOrder(orders[i].Id);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        var account = _C(exchange.GetAccount);&lt;br /&gt;        var opAmount = _N(account.Stocks - InitAccount.Stocks);&lt;br /&gt;        if (opAmount &amp;lt; 0.001) {&lt;br /&gt;            Counter.f++;&lt;br /&gt;            Counter.i++;&lt;br /&gt;            continue;&lt;br /&gt;        }&lt;br /&gt;        updateStatus(&amp;quot;Successful payment: &amp;quot; + opAmount +&amp;quot;, Start taking action...&amp;quot;);&lt;br /&gt;        exchange.Sell(elephant.Price + (PennyTick * ProfitTick), opAmount);&lt;br /&gt;        var success = true;&lt;br /&gt;        while (true) {&lt;br /&gt;            var depth = _C(exchange.GetDepth);&lt;br /&gt;            if (depth.Bids.length &amp;gt; 0 &amp;amp;&amp;amp; depth.Bids[0].Price &amp;lt;= (elephant.Price-(STTick*PennyTick))) {&lt;br /&gt;                success = false;&lt;br /&gt;                updateStatus(&amp;quot;Didn&amp;#39;t get it, start to stop loss, currently buying one: &amp;quot; + depth.Bids[0].Price);&lt;br /&gt;                CancelAll();&lt;br /&gt;                account = _C(exchange.GetAccount);&lt;br /&gt;                var opAmount = _N(account.Stocks - InitAccount.Stocks);&lt;br /&gt;                if (opAmount &amp;lt; 0.001) {&lt;br /&gt;                    break;&lt;br /&gt;                }&lt;br /&gt;                exchange.Sell(depth.Bids[0].Price, opAmount);&lt;br /&gt;            }&lt;br /&gt;            var orders = _C(exchange.GetOrders);&lt;br /&gt;            if (orders.length === 0) {&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;            Sleep(CheckInterval);&lt;br /&gt;        }&lt;br /&gt;        if (success) {&lt;br /&gt;            Counter.w++;&lt;br /&gt;        } else {&lt;br /&gt;            Counter.f++;&lt;br /&gt;        }&lt;br /&gt;        Counter.i++;&lt;br /&gt;        var account = _C(exchange.GetAccount);&lt;br /&gt;        LogProfit(account.Balance - InitAccount.Balance, account);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;This is the main execution function ```main()``` of the strategy, which contains the core logic of the strategy. Let&amp;#39;s explain its operations line by line:&lt;br /&gt;&lt;br /&gt;- ```if (DisableLog)```: This line of code checks if the DisableLog variable is true, and if so, it will disable log recording. This is to ensure that unnecessary logs are not recorded by the strategy.&lt;br /&gt;&lt;br /&gt;- ```CancelAll()```: Call the previously explained CancelAll() function to ensure that there are no unfinished orders.&lt;br /&gt;&lt;br /&gt;- ```InitAccount = _C(exchange.GetAccount)```: This line of code retrieves the current account information and stores it in the InitAccount variable. This will be used to record the account status when the strategy starts executing.&lt;br /&gt;&lt;br /&gt;- ```var i = 0; ``` and ``` var locks = 0;```: Initialize two variables, i and locks, which will be used in the subsequent strategy logic.&lt;br /&gt;&lt;br /&gt;- ```while (true)```: This is an infinite loop, mainly used for the continuous execution of strategies.&lt;br /&gt;&lt;br /&gt;Next, we will explain the main strategy logic within the ```while (true)``` loop line by line.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;while (true) {&lt;br /&gt;    Sleep(Interval);&lt;br /&gt;    var depth = _C(exchange.GetDepth);&lt;br /&gt;    if (depth.Asks.length === 0 || depth.Bids.length === 0) {&lt;br /&gt;        continue;&lt;br /&gt;    }&lt;br /&gt;    updateStatus(&amp;quot;Searching within the elephant... Buy one: &amp;quot; + depth.Bids[0].Price + &amp;quot;,  Sell one:&amp;quot; + depth.Asks[0].Price + &amp;quot;, Lock times: &amp;quot; + locks);&lt;br /&gt;```&lt;br /&gt;- ```Sleep(Interval)```: This line of code allows the strategy to sleep for a period of time, in order to control the execution frequency of the strategy. The Interval parameter defines the sleep interval (in milliseconds).&lt;br /&gt;&lt;br /&gt;- ```var depth = _C(exchange.GetDepth)```: Obtain the current market depth information, including the prices and quantities of sell orders and buy orders. This information will be stored in the depth variable.&lt;br /&gt;&lt;br /&gt;- ```if (depth.Asks.length === 0 || depth.Bids.length === 0)```: This line of code checks the market depth information, ensuring that both sell orders and buy orders exist. If one of them does not exist, it indicates that the market may not have enough trading information, so the strategy will continue to wait.&lt;br /&gt;&lt;br /&gt;- ```updateStatus(&amp;quot;Searching within the elephant... Buy one: &amp;quot; + depth.Bids[0].Price + &amp;quot;, Sell one:&amp;quot; + depth.Asks[0].Price + &amp;quot;, Lock times: &amp;quot; + locks)```: This line of code calls the updateStatus function to update the status information of the strategy. It records the current market status, including the highest bid price, lowest ask price and previously locked times (locks).&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;    var askPrice = 0;&lt;br /&gt;    for (i = 0; i &amp;lt; depth.Asks.length; i++) {&lt;br /&gt;        if (depth.Asks[i].Amount &amp;gt;= Lot) {&lt;br /&gt;            askPrice = depth.Asks[i].Price;&lt;br /&gt;            break;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    if (askPrice === 0) {&lt;br /&gt;        continue;&lt;br /&gt;    }&lt;br /&gt;    var elephant = null;&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;- ```var askPrice = 0;```: Initialize the askPrice variable, it will be used to store the price of sell orders that meet the conditions.&lt;br /&gt;&lt;br /&gt;- ```for (i = 0; i &amp;lt; depth.Asks.length; i++)```: This is a for loop used to traverse the price and quantity information of market sell orders.&lt;br /&gt;&lt;br /&gt;- ```if (depth.Asks[i].Amount &amp;gt;= Lot)```: In the loop, check if the quantity of each sell order is greater than or equal to the specified Lot (hand count). If so, store the price of that sell order in askPrice and terminate the loop.&lt;br /&gt;&lt;br /&gt;- ```if (askPrice === 0)```: If no sell orders that meet the conditions are found (askPrice is still 0), the strategy will continue to wait and skip subsequent operations.&lt;br /&gt;&lt;br /&gt;- ```var elephant = null;```: Initialize the elephant variable, it will be used to store the buy order information identified as &amp;quot;elephant&amp;quot;.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;    for (i = 1; i &amp;lt; depth.Bids.length; i++) {&lt;br /&gt;        if ((askPrice - depth.Bids[i].Price) &amp;gt; ElephantSpace) {&lt;br /&gt;            break;&lt;br /&gt;        }&lt;br /&gt;        if (depth.Bids[i].Amount &amp;gt;= ElephantAmount) {&lt;br /&gt;            elephant = depth.Bids[i];&lt;br /&gt;            break;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    if (!elephant) {&lt;br /&gt;        locks = 0;&lt;br /&gt;        continue;&lt;br /&gt;    }&lt;br /&gt;    locks++;&lt;br /&gt;    if (locks &amp;lt; LockCount) {&lt;br /&gt;        continue;&lt;br /&gt;    }&lt;br /&gt;    locks = 0;&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;Continue to traverse the price and quantity information of market buy orders, skipping the first buy order (Bids[0]).&lt;br /&gt;&lt;br /&gt;- ```if ((askPrice - depth.Bids[i].Price) &amp;gt; ElephantSpace)```: Check whether the gap between the current bid price and askPrice is greater than ElephantSpace. If so, it indicates that it is far enough from the &amp;quot;elephant&amp;quot;, and the strategy will no longer continue to search.&lt;br /&gt;&lt;br /&gt;- ```if (depth.Bids[i].Amount &amp;gt;= ElephantAmount)```: Check if the quantity of the current buy order is greater than or equal to ElephantAmount. If so, store the buy order information in the elephant variable.&lt;br /&gt;&lt;br /&gt;- ```if (!elephant)```: If the &amp;quot;elephant&amp;quot; is not found, reset the lock count to 0 and continue waiting.&lt;br /&gt;&lt;br /&gt;- ```locks++```: If the &amp;quot;elephant&amp;quot; is found, increment the lock count. This is to ensure that the strategy is executed only after confirming the existence of the &amp;quot;elephant&amp;quot; multiple times over a period of time.&lt;br /&gt;&lt;br /&gt;- ```if (locks &amp;lt; LockCount)```: Check whether the number of lock times has met the requirement (LockCount). If it hasn&amp;#39;t, continue to wait.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;    updateStatus(&amp;quot;Debug the elephant... The elephant is in gear &amp;quot; + i + &amp;quot;, &amp;quot; + JSON.stringify(elephant));&lt;br /&gt;    exchange.Buy(elephant.Price + PennyTick, Lot, &amp;quot;Bids[&amp;quot; + i + &amp;quot;]&amp;quot;, elephant);&lt;br /&gt;    var ts = new Date().getTime();&lt;br /&gt;    while (true) {&lt;br /&gt;        Sleep(CheckInterval);&lt;br /&gt;        var orders = _C(exchange.GetOrders);&lt;br /&gt;        if (orders.length == 0) {&lt;br /&gt;            break;&lt;br /&gt;        }&lt;br /&gt;        if ((new Date().getTime() - ts) &amp;gt; WaitInterval) {&lt;br /&gt;            for (var i = 0; i &amp;lt; orders.length; i++) {&lt;br /&gt;                exchange.CancelOrder(orders[i].Id);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;- ```updateStatus(&amp;quot;Debug the elephant... The elephant is in gear &amp;quot; + i + &amp;quot;, &amp;quot; + JSON.stringify(elephant))```: Call the updateStatus function to record the current status of the strategy, including the gear position of the &amp;quot;elephant&amp;quot; found and related information. This will be displayed in the status bar of the strategy.&lt;br /&gt;&lt;br /&gt;- ```exchange.Buy(elephant.Price + PennyTick, Lot, &amp;quot;Bids[&amp;quot; + i + &amp;quot;]&amp;quot;, elephant)```: Use the exchange.Buy function to purchase the found &amp;quot;elephant&amp;quot;. The purchase price is elephant.Price + PennyTick, the purchase quantity is Lot, and describe the purchase operation as &amp;quot;Bids[&amp;quot; + i + &amp;quot;]&amp;quot;.&lt;br /&gt;&lt;br /&gt;- ```var ts = new Date().getTime()```: Obtain the timestamp of the current time for subsequent calculation of time intervals.&lt;br /&gt;&lt;br /&gt;- ```while (true)```: Enter a new infinite loop, used to wait for the execution of &amp;quot;elephant&amp;quot; buy orders.&lt;br /&gt;&lt;br /&gt;- ```Sleep(CheckInterval)```: The strategy sleeps for a while to control the frequency of checking order status.&lt;br /&gt;&lt;br /&gt;- ```var orders = _C(exchange.GetOrders)```: Obtain all order information of the current account.&lt;br /&gt;&lt;br /&gt;- ```if (orders.length == 0)```: Check if there are any unfinished orders, if not, break the loop.&lt;br /&gt;&lt;br /&gt;- ```(new Date().getTime() - ts) &amp;gt; WaitInterval```: Calculate the time interval between the current time and when the &amp;quot;elephant&amp;quot; was purchased. If it exceeds WaitInterval, it means that the waiting has timed out.&lt;br /&gt;&lt;br /&gt;- ```for (var i = 0; i &amp;lt; orders.length; i++)```: Traverse through all uncompleted orders.&lt;br /&gt;&lt;br /&gt;- ```exchange.CancelOrder(orders[i].Id)```: Use the exchange.CancelOrder function to cancel each unfinished order.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;    var account = _C(exchange.GetAccount);&lt;br /&gt;    var opAmount = _N(account.Stocks - InitAccount.Stocks);&lt;br /&gt;    if (opAmount &amp;lt; 0.001) {&lt;br /&gt;        Counter.f++;&lt;br /&gt;        Counter.i++;&lt;br /&gt;        continue;&lt;br /&gt;    }&lt;br /&gt;    updateStatus(&amp;quot;Successful payment: &amp;quot; + opAmount + &amp;quot;, Start taking action...&amp;quot;);&lt;br /&gt;    exchange.Sell(elephant.Price + (PennyTick * ProfitTick), opAmount);&lt;br /&gt;    var success = true;&lt;br /&gt;    while (true) {&lt;br /&gt;        var depth = _C(exchange.GetDepth);&lt;br /&gt;        if (depth.Bids.length &amp;gt; 0 &amp;amp;&amp;amp; depth.Bids[0].Price &amp;lt;= (elephant.Price - (STTick * PennyTick))) {&lt;br /&gt;            success = false;&lt;br /&gt;            updateStatus(&amp;quot;Didn&amp;#39;t get it, start to stop loss, currently buying one: &amp;quot; + depth.Bids[0].Price);&lt;br /&gt;            CancelAll();&lt;br /&gt;            account = _C(exchange.GetAccount);&lt;br /&gt;            var opAmount = _N(account.Stocks - InitAccount.Stocks);&lt;br /&gt;            if (opAmount &amp;lt; 0.001) {&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;            exchange.Sell(depth.Bids[0].Price, opAmount);&lt;br /&gt;        }&lt;br /&gt;        var orders = _C(exchange.GetOrders);&lt;br /&gt;        if (orders.length === 0) {&lt;br /&gt;            break;&lt;br /&gt;        }&lt;br /&gt;        Sleep(CheckInterval);&lt;br /&gt;    }&lt;br /&gt;    if (success) {&lt;br /&gt;        Counter.w++;&lt;br /&gt;    } else {&lt;br /&gt;        Counter.f++;&lt;br /&gt;    }&lt;br /&gt;    Counter.i++;&lt;br /&gt;    var account = _C(exchange.GetAccount);&lt;br /&gt;    LogProfit(account.Balance - InitAccount.Balance, account);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;- ```var account = _C(exchange.GetAccount)```: Obtain current account information.&lt;br /&gt;&lt;br /&gt;- ```var opAmount = _N(account.Stocks - InitAccount.Stocks)```: Calculate the change in account assets after purchasing the &amp;quot;elephant&amp;quot;. If the change is less than 0.001, it indicates that the purchase has failed, increase the number of failures and continue to the next loop.&lt;br /&gt;&lt;br /&gt;- ```updateStatus(&amp;quot;Successful payment: &amp;quot; + opAmount + &amp;quot;, Start taking action...&amp;quot;)```: Record the successful purchase information of &amp;quot;elephant&amp;quot;, including the quantity purchased.&lt;br /&gt;&lt;br /&gt;- ```exchange.Sell(elephant.Price + (PennyTick * ProfitTick), opAmount)```: Use the exchange.Sell function to sell the successfully purchased &amp;quot;elephant&amp;quot; for profit. The selling price is elephant.Price + (PennyTick * ProfitTick).&lt;br /&gt;&lt;br /&gt;Enter a new infinite loop, used to wait for the execution of sell orders.&lt;br /&gt;&lt;br /&gt;- ```var depth = _C(exchange.GetDepth)```: Obtain market depth information.&lt;br /&gt;&lt;br /&gt;- ```if (depth.Bids.length &amp;gt; 0 &amp;amp;&amp;amp; depth.Bids[0].Price &amp;lt;= (elephant.Price - (STTick * PennyTick)))```: Check the market depth information, if the market price has already fallen to the stop-loss level, then execute the stop-loss operation.&lt;br /&gt;&lt;br /&gt;- ```CancelAll()```: Call the CancelAll() function to cancel all uncompleted orders, in order to avoid position risk.&lt;br /&gt;&lt;br /&gt;- ```if (opAmount &amp;lt; 0.001)```: Check the purchase quantity again, if it&amp;#39;s less than 0.001, it indicates that the purchase has failed, break out of the loop.&lt;br /&gt;&lt;br /&gt;- ```exchange.Sell(depth.Bids[0].Price, opAmount)```: Execute a stop-loss operation, sell the remaining assets at the current market&amp;#39;s lowest price.&lt;br /&gt;&lt;br /&gt;Finally, update the number of successful and failed transactions based on whether the transaction was successful or not, and record the trading profits.&lt;br /&gt;&lt;br /&gt;This is a line-by-line explanation of the entire strategy. The core idea of this strategy is to find &amp;quot;elephants&amp;quot; (large buy orders) in the market, buy and sell them to gain small profits. It includes several important parameters, such as Lot, error retry interval (Interval), ElephantAmount, ElephantSpace, etc., to adjust the strategy.&lt;br /&gt;&lt;br /&gt;In general, this strategy is a high-frequency trading strategy aimed at utilizing market depth information to identify large buy orders and carry out buying and selling transactions in a short period. It needs constant monitoring of the market and execution of buying and selling operations to quickly gain small profits. However, it&amp;#39;s also a high-risk strategy, because it requires quick responses to market fluctuations while considering risk management and stop-loss mechanisms to avoid significant losses.&lt;br /&gt;&lt;br /&gt;Please note that the strategy is based on specific markets and trading platforms. For different markets and exchanges, appropriate adjustments and optimizations may be needed. In practical application, investors need to carefully test and evaluate the performance of the strategy to ensure it aligns with their investment goals and risk tolerance.&lt;br /&gt;&lt;br /&gt;As you continue to execute the strategy, it will repeatedly perform the following operations:&lt;br /&gt;&lt;br /&gt;1. Firstly, the strategy will check the depth information of the market to understand the current situation of sell orders and buy orders.&lt;br /&gt;&lt;br /&gt;2. Next, the strategy will attempt to find sell orders that meet the criteria, specifically sell orders with a quantity greater than or equal to Lot. If a qualifying sell order is found, the price of the sell order will be recorded as askPrice.&lt;br /&gt;&lt;br /&gt;3. Then, the strategy will continue to search for &amp;quot;elephants&amp;quot; (large amount of buy orders). It will traverse through the market&amp;#39;s buy orders, skipping the first one (usually the highest-priced buy order). If it finds an &amp;quot;elephant&amp;quot; that meets the criteria, it will record information about the &amp;quot;elephant&amp;quot;, and increase locks.&lt;br /&gt;&lt;br /&gt;4. If a sufficient number of &amp;quot;elephants&amp;quot; are found consecutively (controlled by the LockCount parameter), the strategy will further perform the following operations:&lt;br /&gt;&lt;br /&gt;- Call the updateStatus function to record the gear and related information of the &amp;quot;elephant&amp;quot;.&lt;br /&gt;- Use the exchange.Buy function to purchase an &amp;quot;elephant&amp;quot;, with a purchase price of elephant.Price + PennyTick, and a quantity of Lot.&lt;br /&gt;- Start a new infinite loop for waiting for execution of the buy order.&lt;br /&gt;- Check order status. If it is completed, break out from loop.&lt;br /&gt;- If waiting time exceeds set interval (WaitInterval), cancel all uncompleted orders.&lt;br /&gt;- Calculate changes in account assets after successful purchase. If change is less than 0.001, it indicates that purchase failed; increase failure count and continue next loop.&lt;br /&gt;- Record information about successful purchases of &amp;quot;elephants&amp;quot;, including quantity purchased.&lt;br /&gt;&lt;br /&gt;5. Next, the strategy will continue to enter a new infinite loop, waiting for the execution of sell operations. In this loop, it will perform the following actions:&lt;br /&gt;- Obtain market depth information, check if the market price has already reached the stop-loss level.&lt;br /&gt;- If the market price has reached or fallen below the stop-loss level, a stop-loss operation will be executed, that is, the remaining assets will be sold.&lt;br /&gt;- Call the CancelAll function to cancel all uncompleted orders, reducing position risk.&lt;br /&gt;- Recheck the change in account assets after a successful purchase. If the change is less than 0.001, it indicates that the purchase has failed and exit the loop.&lt;br /&gt;- Finally, record whether the transaction is successful or not, and update the number of successes and failures based on the transaction results.&lt;br /&gt;&lt;br /&gt;The entire strategy continuously carries out the above operations to capture as many &amp;quot;elephants&amp;quot; as possible and obtain small profits. This is a high-frequency trading strategy that requires quick responses to market changes, while also considering risk management and stop-loss mechanisms to protect capital. Investors should carefully consider using this strategy, especially in highly volatile markets.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;The Penny Jump strategy is a typical example in high-frequency trading, demonstrating the subtle game and competition among market participants. This strategy is particularly prominent in the cryptocurrency market due to its large fluctuations, where institutional investors and high-frequency traders are all pursuing quick profits. However, this also makes the market full of challenges, requiring constant adaptation and adjustment of strategies to maintain competitive advantages. In this fiercely competitive world, only those traders who are good at discerning the microstructure of the market and responding quickly can achieve success.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y64h90yMK02X503c2p65mDbJaN1YYx33tHD7Y1DUrF5Sztk0nqGShZohdsUYDimMo4p8sor5k8q55W_kIBMwXilM" title="https://blog.mathquant.com/2023/11/07/high-frequency-trading-strategy-analysis-penny-jump.html"&gt;https://blog.mathquant.c...analysis-penny-jump.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25598/</id>
    <title type="text">The Evolution of PSY Factor: Upgrading and Transforming for Enhanced Trading Strategies</title>
    <published>2024-03-21T09:11:50Z</published>
    <updated>2024-03-21T09:11:50Z</updated>
    <author>
      <name>FMZ Quant</name>
      <uri>https://stocksharp.com/users/185552/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#strategy" />
    <category term="#market" />
    <category term="#fmz" />
    <category term="#Kline" />
    <category term="#factor" />
    <category term="#PSY" />
    <category term="#quant" />
    <category term="#bullish" />
    <category term="#bearish" />
    <content type="html">Welcome all traders to my channel, I am a Quant Developer, specializing in full-stack development of CTA, HFT &amp;amp; Arbitrage trading strategies.&lt;br /&gt;Thanks to the FMZ Platform, I will share more content related to quantitative development and work together with all traders to maintain the prosperity of the quant community.&lt;br /&gt;&lt;br /&gt;Today, I will bring you an upgrade and transformation of the PSY (Psychological Line) factor. We will show how to add more market information from a simple factor perspective, step by step transform it, and ultimately turn it into a powerful factor with explanatory and logical strength!!! Of course, after reading this article, you can incorporate the transformed PSY factor into your own library of factors as a powerful weapon~&lt;br /&gt;&lt;br /&gt;&amp;gt; PART1 Initial PSY Factor&lt;br /&gt;&lt;br /&gt;The PSY Factor (Psychological Line) is a technical analysis indicator used to measure the impact of market participants&amp;#39; emotions on price trends. It is an emotional index for studying investors&amp;#39; psychological fluctuations in response to market ups and downs, and it&amp;#39;s a type of energy and rise-fall indicator. It has certain reference significance for judging short-term market trends.&lt;br /&gt;&lt;br /&gt;The PSY factor was first proposed by Dr. Wang Yawei in 1991. He believed that the psychological changes in the market are closely related to price trends, and quantified these psychological changes into the PSY factor. As an indicator for analyzing market fluctuations, the PSY factor calculates the total bullish and bearish forces within N K-lines over time to describe whether the current market is strong or weak, or if it&amp;#39;s in an overbought or oversold state. It mainly measures investors&amp;#39; psychological endurance by calculating how many rising K-lines there are within N K-lines, providing a reference for investors&amp;#39; buying and selling operations.&lt;br /&gt;&lt;br /&gt;The PSY factor is based on the number of days the closing price rises or falls over a period of time. Its calculation method is very simple, and the calculation formula is as follows: PSY=(Number of rising days within N K-lines/N)*100. Here, N period represents the selected calculation period, which can be several days, weeks or months etc. The number of rising days refers to the number of trading days with rising prices within the N period. The initial PSY factor function source code based on FMZ platform:&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;function calculatePSY(data, n) {&lt;br /&gt;  let count = 0;&lt;br /&gt;  for (let i = data.length - n; i &amp;lt; data.length; i++) {&lt;br /&gt;    if (data[i] &amp;gt; data[i - 1]) {&lt;br /&gt;      count++;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  return (count / n) * 100;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Usage example&lt;br /&gt;let closePrices = [10, 12, 13, 11, 14, 15, 16, 17, 18, 20];&lt;br /&gt;let nPeriod = 5;&lt;br /&gt;let psyFactor = calculatePSY(closePrices, nPeriod);&lt;br /&gt;Log(psyFactor);&lt;br /&gt;```&lt;br /&gt;&amp;gt; PART2 Enhance PSY Factor (PSY+PRICE)&lt;br /&gt;&lt;br /&gt;The essence of the PSY factor is a momentum factor, which measures the comparison of the root numbers of rising and falling forces over a period of time, with the aim to find out which side has greater strength in the past. However, upon careful observation, it can be found that the PSY factor only considers whether the BAR line is rising or falling, lacking a description of BAR itself and unable to judge the intensity of market conditions, resulting in situations -- Of the last 6 K-lines, 3 were down and 3 were up, and the value of 50, as constructed by the initial PSY factor, it does not discern the strength of the long and short forces in the last 6 K-lines.&lt;br /&gt;&lt;br /&gt;As mentioned above, the uniqueness of a large bullish K-line is not reflected in the PSY indicator, it&amp;#39;s merely treated as an upward line with no difference from the previous small bearish K-line. This is where the problem lies, as the number of rises and falls cannot fully describe the magnitude and direction of price changes. Therefore, our first improvement idea was to weight each BAR&amp;#39;s price change Abs(C-C[1]) to reflect the magnitude of rise and fall forces. The source code for initial PSY+PRICE factor function based on FMZ platform:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149482
" title="https://stocksharp.com/file/149482
"&gt;https://stocksharp.com/file/149482
&lt;/a&gt;&lt;br /&gt;&amp;gt; PART3 Final PSY Factor (PSY+PRICE+VOL)&lt;br /&gt;&lt;br /&gt;After the modification in the previous step, the transformed PSY factor can better reflect the strength and weakness over a period of time. However, it cannot distinguish well if the rise and fall range is basically consistent during that period. At this point, we continue to add trading volume factors. In momentum effect, increased volume represents a more active market, and increased volume situation can better confirm momentum direction. As shown in the figure below:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149483
" title="https://stocksharp.com/file/149483
"&gt;https://stocksharp.com/file/149483
&lt;/a&gt;&lt;br /&gt;Over the past period of time, the magnitude of the rise and the fall were basically the same, but the volume in the rise far exceeded the volume in the fall, reflecting the superior upward force. Therefore, in the final PSY factor, we continue to add the volume factor weighting, VOLUME*Abs(C-C[1]), based on the initial PSY+PRICE factor function source code of FMZ platform:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149487
" title="https://stocksharp.com/file/149487
"&gt;https://stocksharp.com/file/149487
&lt;/a&gt;&lt;br /&gt;&amp;gt; PART4 Construction of PSY Factor Trading Signals&lt;br /&gt;&lt;br /&gt;Based on the final PSY+PRICE+VOL factor constructed in the previous article, we attempt to propose several constructions of momentum signals as follows:&lt;br /&gt;&lt;br /&gt;- psy[0] &amp;gt; X (Over a period of time in the past, the ratio of multiple forces was greater than X value.)&lt;br /&gt;- psy[0] &amp;lt; Y (Over a period of time in the past, the ratio of multiple forces was less than Y value.)&lt;br /&gt;- psy[0] &amp;gt; psy[1] or psy[0] &amp;gt; psyma (Over the past period of time, the ratio of various forces has increased.)&lt;br /&gt;- psy[0] &amp;lt; psy[1] or psy[0] &amp;lt; psyma (Over a period of time, the ratio of multiple forces has decreased.)&lt;br /&gt;&lt;br /&gt;We design a simple momentum strategy with signals to detect factors.&lt;br /&gt;&lt;br /&gt;- Go long: PSY[0] &amp;gt; 70; Close long position: PSY[0] &amp;lt; 30;&lt;br /&gt;- Go short: PSY[0] &amp;lt; 30; Close short position: PSY[0] &amp;gt; 70;&lt;br /&gt;&lt;br /&gt;Using Binance U-denominated contracts, the PSY factor parameter is designed to be 12. Backtesting of BTC-USDT and ETH-USDT contracts was conducted from February 1, 2020 to December 31, 2021 with a slippage of 10, a transaction fee of 0.05%, a leverage of 10 times, and each position remaining principal at 5%:&lt;br /&gt;&lt;br /&gt;BTC-USDT：&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149484
" title="https://stocksharp.com/file/149484
"&gt;https://stocksharp.com/file/149484
&lt;/a&gt;&lt;br /&gt;ETH-USDT：&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149485
" title="https://stocksharp.com/file/149485
"&gt;https://stocksharp.com/file/149485
&lt;/a&gt;&lt;br /&gt;&amp;gt; PART5 Summary&lt;br /&gt;&lt;br /&gt;In this article, we upgraded and transformed the traditional psy factor, resulting in a psy+price+vol factor that can measure the strength of bulls and bears over a past period at the level of volume and price. Using fixed numerical comparisons or self-strength comparisons, corresponding momentum/reversal signals can be constructed. This article finally established a fixed numerical signal, conducted simple strategy backtesting, and found that the psy+price+vol factor can capture momentum movements in volatile markets to some extent, achieving positive expected returns. More forms of signals can be constructed later for more types of factor tests before ultimately being added to an existing strategy library.&lt;br /&gt;&lt;br /&gt;Thanks to the FMZ Platform, for not closing its doors and reinventing the wheel, but providing such a great place for traders to communicate. The road of trading is full of ups and downs, but with warmth from fellow traders and continuous learning from the shared experiences of seniors on the FMZ platform, we can keep growing. Wishing FMZ all the best and may all traders enjoy long-lasting profits.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y6-6TQ0Cd1C_2iQoVjWl6Jxrj4uYlFX0nDGolteAg_cMgDXo8r-1VDRxGVg0z3C3SFlBuat0BX4wLNd4TnRvRmXc" title="https://blog.mathquant.com/2023/11/07/psy-factor-upgrade-and-transformation.html"&gt;https://blog.mathquant.c...-and-transformation.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25597/</id>
    <title type="text">Unveiling Market Noise: Building and Applying Strategies for a Clearer Trading Path</title>
    <published>2024-03-21T07:34:26Z</published>
    <updated>2024-03-21T07:34:26Z</updated>
    <author>
      <name>FMZ Quant</name>
      <uri>https://stocksharp.com/users/185552/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#strategy" />
    <category term="#market" />
    <category term="#fmz" />
    <category term="#platform" />
    <category term="#bitcoin" />
    <category term="#crypto" />
    <category term="#profit" />
    <category term="#loss" />
    <category term="#factor" />
    <content type="html">Welcome all traders to my channel, I am a Quant Developer, specializing in full-stack development of CTA, HFT &amp;amp; Arbitrage trading strategies.&lt;br /&gt;Thanks to the FMZ Platform, I will share more content related to quantitative development and work together with all traders to maintain the prosperity of the quant community.&lt;br /&gt;&lt;br /&gt;- Do you often struggle to distinguish between trends and fluctuations?&lt;br /&gt;- Have you been stopped out by the back-and-forth disorderly market?&lt;br /&gt;- Are you having difficulty understanding the current market situation?&lt;br /&gt;- Do you do trend trading and hope to filter out fluctuations?&lt;br /&gt;&lt;br /&gt;Haha, you&amp;#39;ve come to the right place. Today, I will bring you the construction and application of market noise! As we all know, financial markets are full of noise. How to quantitatively model and depict market noise is very important. The depiction of noise can better help us distinguish the current state of the market and predict future possibilities!&lt;br /&gt;&lt;br /&gt;&amp;gt; PART1 Noise discrimination is very important for financial market trading.&lt;br /&gt;&lt;br /&gt;The time series in the financial market is characterized by a high signal-to-noise ratio, most of the time, the market fluctuations are unclear, and even during trending markets, situations like taking four steps forward and three steps back often occur. Therefore, defining, identifying and classifying market noise in the financial market is very important and has practical significance. Kaufman&amp;#39;s book provides a comprehensive explanation and modeling of this characteristic of noise.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149465
" title="https://stocksharp.com/file/149465
"&gt;https://stocksharp.com/file/149465
&lt;/a&gt;&lt;br /&gt;&amp;gt; PART2 Construction of Noise - ER Efficiency Coefficient&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149463
" title="https://stocksharp.com/file/149463
"&gt;https://stocksharp.com/file/149463
&lt;/a&gt;&lt;br /&gt;The net value of the starting and ending points of price changes divided by the sum of all pairwise price changes during the period.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149456
" title="https://stocksharp.com/file/149456
"&gt;https://stocksharp.com/file/149456
&lt;/a&gt;&lt;br /&gt;The difference between point A and point B divided by the sum of the 7 intermediate movements.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149457
" title="https://stocksharp.com/file/149457
"&gt;https://stocksharp.com/file/149457
&lt;/a&gt;&lt;br /&gt;It demonstrates the different noise levels exhibited by various price operation modes under the same price movement range. A straight line indicates no noise, minor fluctuations around the straight line represent medium noise, and large swings symbolize high noise.&lt;br /&gt;&lt;br /&gt;&amp;gt; PART3 Construction of Noise - Price Density&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149464
" title="https://stocksharp.com/file/149464
"&gt;https://stocksharp.com/file/149464
&lt;/a&gt;&lt;br /&gt;The definition here is: Drawing the high and low points of price movements over a period of time, pulling the highest and lowest prices during this period into a box. The so-called price density refers to the number of price points that can be accommodated within the box.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149458
" title="https://stocksharp.com/file/149458
"&gt;https://stocksharp.com/file/149458
&lt;/a&gt;&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149459
" title="https://stocksharp.com/file/149459
"&gt;https://stocksharp.com/file/149459
&lt;/a&gt;&lt;br /&gt;Compared to the ER efficiency coefficient, the measurement method of price density takes more into account the highest and lowest prices of each K-line.&lt;br /&gt;&lt;br /&gt;&amp;gt; PART4 Construction of Noise - Fractal Dimension&lt;br /&gt;&lt;br /&gt;The fractal dimension cannot be measured accurately, but it can be estimated using the following steps within the past n terms:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149460
" title="https://stocksharp.com/file/149460
"&gt;https://stocksharp.com/file/149460
&lt;/a&gt;&lt;br /&gt;&amp;gt; PART5 Construction of Noise - Other Methods&lt;br /&gt;&lt;br /&gt;CMI = (close[0] - open[n-1]) / (Max high(n) - Min low(n));&lt;br /&gt;When the noise is lower, during this period, the net value at the beginning and end infinitely approaches the difference between the highest and lowest prices, with CMI infinitely approaching 1.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149461
" title="https://stocksharp.com/file/149461
"&gt;https://stocksharp.com/file/149461
&lt;/a&gt;&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149476
" title="https://stocksharp.com/file/149476
"&gt;https://stocksharp.com/file/149476
&lt;/a&gt;&lt;br /&gt;The results obtained from the construction methods of various noise measurements are highly similar. The core is to compare the net changes and change processes or extreme values of a period of movement, and choose the construction method that you prefer or think is more reasonable.&lt;br /&gt;&lt;br /&gt;&amp;gt; PART6 Dividing market styles from the perspectives of noise and volatility.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149462
" title="https://stocksharp.com/file/149462
"&gt;https://stocksharp.com/file/149462
&lt;/a&gt;&lt;br /&gt;Volatility and noise are different dimensions to characterize the market. The sum of price changes in the two types of price models mentioned above is the same, so their volatility is the same, but net value changes more significantly and noise is lower.&lt;br /&gt;&lt;br /&gt;Therefore, noise and volatility are two different perspectives that can be used to classify market styles. If we take persistence and volatility of trends as the x-axis and y-axis respectively to construct a Cartesian coordinate system, we can divide the fluctuation status of market prices into four categories:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149471
" title="https://stocksharp.com/file/149471
"&gt;https://stocksharp.com/file/149471
&lt;/a&gt;&lt;br /&gt;- Good sustainability, high volatility - smooth trend.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149467
" title="https://stocksharp.com/file/149467
"&gt;https://stocksharp.com/file/149467
&lt;/a&gt;&lt;br /&gt;- Good sustainability, low volatility - bumpy trend.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149472
" title="https://stocksharp.com/file/149472
"&gt;https://stocksharp.com/file/149472
&lt;/a&gt;&lt;br /&gt;- Persistent poor performance, low volatility - narrow range consolidation.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149466
" title="https://stocksharp.com/file/149466
"&gt;https://stocksharp.com/file/149466
&lt;/a&gt;&lt;br /&gt;- Persistent poor performance, high volatility - wide range fluctuations.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149473
" title="https://stocksharp.com/file/149473
"&gt;https://stocksharp.com/file/149473
&lt;/a&gt;&lt;br /&gt;It should be pointed out that there are no absolute standards for what is called wide range and narrow range, it has to be relative to the level and system of one&amp;#39;s own trading, just like the setting of the trading period, which is extremely personalized. Moreover, we can only determine the current state of the market by examining a period in the past. However, we cannot predict what state the market will enter next.&lt;br /&gt;&lt;br /&gt;Of course, the four types of fluctuations are not completely random during conversion. In the most ideal state, a smooth trend is often followed by wide-range oscillations, slowly unloading momentum; then it enters narrow-range consolidation, the market is very inactive, and bulls and bears are stuck in a stalemate; when the market is compressed to a critical point, it explodes again and the trend begins; this is an oversimplified ideal model - reality is much more complex. For example, after narrow-range consolidation there may not necessarily be a trend - it could also be wide-ranging oscillation. After a smooth trend there might not necessarily be wide-ranging oscillation - it could continue to reach new highs or lows. Moreover, it&amp;#39;s difficult to develop four strategies that excel at handling four different market conditions and can adapt as needed. So for now, I still think we can only develop strategies that make money in certain markets while minimizing losses in unfavorable ones.&lt;br /&gt;&lt;br /&gt;&amp;gt; PART7 Impact of Noise on Related Transactions&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149477
" title="https://stocksharp.com/file/149477
"&gt;https://stocksharp.com/file/149477
&lt;/a&gt;&lt;br /&gt;The profit factor of the 40-day moving average strategy (going long above the 40-day line and short below, total profit/total loss) is regressed with the 40-day noise (ER efficiency coefficient). It can be seen that the higher the noise, the lower the profit factor of trend strategies. And we can conclude: low noise is beneficial for trend trading, high noise is beneficial for mean reversion trading.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149478
" title="https://stocksharp.com/file/149478
"&gt;https://stocksharp.com/file/149478
&lt;/a&gt;&lt;br /&gt;The concept of market noise is very important in determining trading styles. Before developing corresponding trading strategies, we need to outline the contours of the market.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149469
" title="https://stocksharp.com/file/149469
"&gt;https://stocksharp.com/file/149469
&lt;/a&gt;&lt;br /&gt;&amp;gt; PART8 Market Maturity and Noise&lt;br /&gt;&lt;br /&gt;Over the past 20 years, the noise attribute of the North American stock index market has experienced a steady rise.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149468
" title="https://stocksharp.com/file/149468
"&gt;https://stocksharp.com/file/149468
&lt;/a&gt;&lt;br /&gt;Financial markets in various regions are gradually maturing, with noise levels increasing progressively, and the maturity is coming quickly.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149470
" title="https://stocksharp.com/file/149470
"&gt;https://stocksharp.com/file/149470
&lt;/a&gt;&lt;br /&gt;A study was conducted on the stock index markets of various countries. The market on the far right is the most mature and also has higher noise, while the one on the far left is immature with lower noise. It can be observed that Japan has the most mature market, followed by economies like Hong Kong, China, Singapore, and South Korea. On the far left are relatively immature markets, such as Vietnam and Sri Lanka.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149474
" title="https://stocksharp.com/file/149474
"&gt;https://stocksharp.com/file/149474
&lt;/a&gt;&lt;br /&gt;The noise in the Bitcoin market for each quarter is approximately 0.2-0.3, and it&amp;#39;s in a cyclical state.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149475
" title="https://stocksharp.com/file/149475
"&gt;https://stocksharp.com/file/149475
&lt;/a&gt;&lt;br /&gt;Thanks to the FMZ Platform, for not closing its doors and reinventing the wheel, but providing such a great place for traders to communicate. The road of trading is full of ups and downs, but with warmth from fellow traders and continuous learning from the shared experiences of seniors on the FMZ platform, we can keep growing. Wishing FMZ all the best and may all traders enjoy long-lasting profits.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y60uH-yNR_TZXhu8m7YjsB9muKS9be3QjiHiyGRo8nuNWM3T_Rui0rBV6wRXDS-FOAKRvJffBpDu53KZF7YjuUvA" title="https://blog.mathquant.com/2023/11/07/construction-and-application-of-market-noise.html"&gt;https://blog.mathquant.c...ion-of-market-noise.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25596/</id>
    <title type="text">Mastering Programmatic Trading: The Game-Changing Incremental Update Algorithm for Mean and Variance Calculation</title>
    <published>2024-03-21T05:44:08Z</published>
    <updated>2024-03-21T05:44:08Z</updated>
    <author>
      <name>FMZ Quant</name>
      <uri>https://stocksharp.com/users/185552/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#strategy" />
    <category term="#data" />
    <category term="#fmz" />
    <category term="#python" />
    <category term="#formula" />
    <category term="#crypto" />
    <category term="#average" />
    <category term="#algorithm" />
    <content type="html">### Introduction&lt;br /&gt;In programmatic trading, it is often necessary to calculate averages and variances, such as calculating moving averages and volatility indicators. When we need high-frequency and long-term calculations, it&amp;#39;s necessary to retain historical data for a long time, which is both unnecessary and resource-consuming. This article introduces an online updating algorithm for calculating weighted averages and variances, which is particularly important for processing real-time data streams and dynamically adjusting trading strategies, especially high-frequency strategies. The article also provides corresponding Python code implementation to help traders quickly deploy and apply the algorithm in actual trading.&lt;br /&gt;&lt;br /&gt;### Simple Average and Variance&lt;br /&gt;If we use &lt;a href="https://stocksharp.com/file/149441 " title="https://stocksharp.com/file/149441 "&gt;https://stocksharp.com/file/149441 &lt;/a&gt;to represent the average value of the nth data point, assuming that we have already calculated the average of n-1 data points &lt;a href="https://stocksharp.com/file/149454, " title="https://stocksharp.com/file/149454, "&gt;https://stocksharp.com/file/149454, &lt;/a&gt;now we receive a new data point &lt;a href="https://stocksharp.com/file/149442. " title="https://stocksharp.com/file/149442. "&gt;https://stocksharp.com/file/149442. &lt;/a&gt;We want to calculate the new average number &lt;a href="https://stocksharp.com/file/149441 " title="https://stocksharp.com/file/149441 "&gt;https://stocksharp.com/file/149441 &lt;/a&gt;including the new data point. The following is a detailed derivation.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149450
" title="https://stocksharp.com/file/149450
"&gt;https://stocksharp.com/file/149450
&lt;/a&gt;&lt;br /&gt;The variance update process can be broken down into the following steps:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149455
" title="https://stocksharp.com/file/149455
"&gt;https://stocksharp.com/file/149455
&lt;/a&gt;&lt;br /&gt;As can be seen from the above two formulas, this process allows us to update new averages and variances upon receiving each new data point &lt;a href="https://stocksharp.com/file/149442 " title="https://stocksharp.com/file/149442 "&gt;https://stocksharp.com/file/149442 &lt;/a&gt;by only retaining the average and variance of the previous data, without saving historical data, making calculations more efficient. However, the problem is that what we calculate in this way are the mean and variance of all samples, while in actual strategies, we need to consider a certain fixed period. Observing the above average update shows that the amount of new average updates is a deviation between new data and past averages multiplied by a ratio. If this ratio is fixed, it will lead to an exponentially weighted average, which we will discuss next.&lt;br /&gt;&lt;br /&gt;### Exponentially-weighted mean&lt;br /&gt;The exponential weighted average can be defined by the following recursive relationship:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149445
" title="https://stocksharp.com/file/149445
"&gt;https://stocksharp.com/file/149445
&lt;/a&gt;&lt;br /&gt;Among them, &lt;a href="https://stocksharp.com/file/149451 " title="https://stocksharp.com/file/149451 "&gt;https://stocksharp.com/file/149451 &lt;/a&gt;is the exponential weighted average at time point t, &lt;a href="https://stocksharp.com/file/149444 " title="https://stocksharp.com/file/149444 "&gt;https://stocksharp.com/file/149444 &lt;/a&gt;is the observed value at time point t, α is the weight factor, and &lt;a href="https://stocksharp.com/file/149447 " title="https://stocksharp.com/file/149447 "&gt;https://stocksharp.com/file/149447 &lt;/a&gt;is the exponential weighted average of the previous time point.&lt;br /&gt;&lt;br /&gt;### Exponentially-weighted variance&lt;br /&gt;Regarding variance, we need to calculate the exponential weighted average of squared deviations at each time point. This can be achieved through the following recursive relationship:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149452
" title="https://stocksharp.com/file/149452
"&gt;https://stocksharp.com/file/149452
&lt;/a&gt;&lt;br /&gt;Among them, &lt;a href="https://stocksharp.com/file/149453 " title="https://stocksharp.com/file/149453 "&gt;https://stocksharp.com/file/149453 &lt;/a&gt;is the exponential weighted variance at time point t, and &lt;a href="https://stocksharp.com/file/149449 " title="https://stocksharp.com/file/149449 "&gt;https://stocksharp.com/file/149449 &lt;/a&gt;is the exponential weighted variance of the previous time point.&lt;br /&gt;&lt;br /&gt;Observe the exponentially weighted average and variance, their incremental updates are intuitive, retaining a portion of past values and adding new changes. The specific derivation process can be referred to in this paper: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAACVpro8NJ5Hf6n-q2zdOJRxB7Hj42VELvfONf7mK4kcA-Gp2b2yzpE3bNdUo41izgLaXAzt3ZUBwLu3JpbLvJAs" title="https://fanf2.user.srcf.net/hermes/doc/antiforgery/stats.pdf
"&gt;https://fanf2.user.srcf....c/antiforgery/stats.pdf
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;### SMA and EMA&lt;br /&gt;The SMA (also known as the arithmetic mean) and EMA are two common statistical measures, each with different characteristics and uses. The former one assigns equal weight to each observation, reflecting the central position of the data set. The latter one is a recursive calculation method that gives higher weight to more recent observations. The weights decrease exponentially as the distance from current time increases for each observation.&lt;br /&gt;&lt;br /&gt;- **Weight distribution**: The SMA assigns the same weight to each data point, while the EMA gives higher weight to the most recent data points.&lt;br /&gt;- **Sensitivity to new information**: The SMA is not sensitive enough to newly added data, as it involves recalculating all data points. The EMA, on the other hand, can reflect changes in the latest data more quickly.&lt;br /&gt;- **Computational complexity**: The calculation of the SMA is relatively straightforward, but as the number of data points increases, so does the computational cost. The computation of the EMA is more complex, but due to its recursive nature, it can handle continuous data streams more efficiently.&lt;br /&gt;&lt;br /&gt;### Approximate Conversion Method Between EMA and SMA&lt;br /&gt;Although SMA and EMA are conceptually different, we can make the EMA approximate to a SMA containing a specific number of observations by choosing an appropriate α value. This approximate relationship can be described by the effective sample size, which is a function of the weight factor α in the EMA.&lt;br /&gt;&lt;br /&gt;SMA is the arithmetic average of all prices within a given time window. For a time window N, the centroid of the SMA (i.e., the position where the average number is located) can be considered as:&lt;br /&gt;&lt;br /&gt;the centroid of SMA &lt;a href="https://stocksharp.com/file/149443
" title="https://stocksharp.com/file/149443
"&gt;https://stocksharp.com/file/149443
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;EMA is a type of weighted average where the most recent data points have greater weight. The weight of EMA decreases exponentially over time. The centroid of EMA can be obtained by summing up the following series:&lt;br /&gt;&lt;br /&gt;the centroid of EMA &lt;a href="https://stocksharp.com/file/149438
" title="https://stocksharp.com/file/149438
"&gt;https://stocksharp.com/file/149438
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;When we assume that SMA and EMA have the same centroid, we can obtain:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149448
" title="https://stocksharp.com/file/149448
"&gt;https://stocksharp.com/file/149448
&lt;/a&gt;&lt;br /&gt;To solve this equation, we can obtain the relationship between α and N.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149446
" title="https://stocksharp.com/file/149446
"&gt;https://stocksharp.com/file/149446
&lt;/a&gt;&lt;br /&gt;This means that for a given SMA of N days, the corresponding α value can be used to calculate an &amp;quot;equivalent&amp;quot; EMA, so that they have the same centroid and the results are very similar.&lt;br /&gt;&lt;br /&gt;### Conversion of EMA with Different Update Frequencies&lt;br /&gt;Assume we have an EMA that updates every second, with a weight factor of &lt;a href="https://stocksharp.com/file/149437. " title="https://stocksharp.com/file/149437. "&gt;https://stocksharp.com/file/149437. &lt;/a&gt;This means that every second, the new data point will be added to the EMA with a weight of &lt;a href="https://stocksharp.com/file/149434, " title="https://stocksharp.com/file/149434, "&gt;https://stocksharp.com/file/149434, &lt;/a&gt;while the influence of old data points will be multiplied by &lt;a href="https://stocksharp.com/file/149437.
" title="https://stocksharp.com/file/149437.
"&gt;https://stocksharp.com/file/149437.
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If we change the update frequency, such as updating once every f seconds, we want to find a new weight factor &lt;a href="https://stocksharp.com/file/149440, " title="https://stocksharp.com/file/149440, "&gt;https://stocksharp.com/file/149440, &lt;/a&gt;so that the overall impact of data points within f seconds is the same as when updated every second.&lt;br /&gt;&lt;br /&gt;Within f seconds, if no updates are made, the impact of old data points will continuously decay f times, each time multiplied by /upload/asset/28e50eb9c37d5626d6691.png. Therefore, the total decay factor after f seconds is &lt;a href="https://stocksharp.com/file/149436.
" title="https://stocksharp.com/file/149436.
"&gt;https://stocksharp.com/file/149436.
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In order to make the EMA updated every f seconds have the same decay effect as the EMA updated every second within one update period, we set the total decay factor after f seconds equal to the decay factor within one update period:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149439
" title="https://stocksharp.com/file/149439
"&gt;https://stocksharp.com/file/149439
&lt;/a&gt;&lt;br /&gt;Solving this equation, we obtain new weight factors &lt;a href="https://stocksharp.com/file/149440
" title="https://stocksharp.com/file/149440
"&gt;https://stocksharp.com/file/149440
&lt;/a&gt;&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149435
" title="https://stocksharp.com/file/149435
"&gt;https://stocksharp.com/file/149435
&lt;/a&gt;&lt;br /&gt;This formula provides the approximate value of the new weight factor &lt;a href="https://stocksharp.com/file/149440, " title="https://stocksharp.com/file/149440, "&gt;https://stocksharp.com/file/149440, &lt;/a&gt;which maintains the EMA smoothing effect unchanged when the update frequency changes. For example: When we calculate the average price &lt;a href="https://stocksharp.com/file/149437 " title="https://stocksharp.com/file/149437 "&gt;https://stocksharp.com/file/149437 &lt;/a&gt;with a value of 0.001 and update it every 10 seconds, if it is changed to an update every second, the equivalent value &lt;a href="https://stocksharp.com/file/149440 " title="https://stocksharp.com/file/149440 "&gt;https://stocksharp.com/file/149440 &lt;/a&gt;would be approximately 0.01.&lt;br /&gt;&lt;br /&gt;### Implementation of Python Code&lt;br /&gt;```&lt;br /&gt;class ExponentialWeightedStats:&lt;br /&gt;    def __init__(self, alpha):&lt;br /&gt;        self.alpha = alpha&lt;br /&gt;        self.mu = 0&lt;br /&gt;        self.S = 0&lt;br /&gt;        self.initialized = False&lt;br /&gt;&lt;br /&gt;    def update(self, x):&lt;br /&gt;        if not self.initialized:&lt;br /&gt;            self.mu = x&lt;br /&gt;            self.S = 0&lt;br /&gt;            self.initialized = True&lt;br /&gt;        else:&lt;br /&gt;            temp = x - self.mu&lt;br /&gt;            new_mu = self.mu + self.alpha * temp&lt;br /&gt;            self.S = self.alpha * self.S + (1 - self.alpha) * temp * (x - self.mu)&lt;br /&gt;            self.mu = new_mu&lt;br /&gt;&lt;br /&gt;    @property&lt;br /&gt;    def mean(self):&lt;br /&gt;        return self.mu&lt;br /&gt;&lt;br /&gt;    @property&lt;br /&gt;    def variance(self):&lt;br /&gt;        return self.S&lt;br /&gt;&lt;br /&gt;# Usage example&lt;br /&gt;alpha = 0.05  # Weight factor&lt;br /&gt;stats = ExponentialWeightedStats(alpha)&lt;br /&gt;data_stream = [] # Data stream&lt;br /&gt;for data_point in data_stream:&lt;br /&gt;    stats.update(data_point)&lt;br /&gt;```&lt;br /&gt;### Summary&lt;br /&gt;In high-frequency programmatic trading, the rapid processing of real-time data is crucial. To improve computational efficiency and reduce resource consumption, this article introduces an online update algorithm for continuously calculating the weighted average and variance of a data stream. Real-time incremental updates can also be used for various statistical data and indicator calculations, such as the correlation between two asset prices, linear fitting, etc., with great potential. Incremental updating treats data as a signal system, which is an evolution in thinking compared to fixed-period calculations. If your strategy still includes parts that calculate using historical data, consider transforming it according to this approach: only record estimates of system status and update the system status when new data arrives; repeat this cycle going forward.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y68HB1V7wjCfXJ8_qU0BIwh-eFjkKb5_TwXURaWxoT7LhijhtqKAOuQ2dWssGvRrwgXQK7Zic61at9K_ZmWtCsM0PKpXjiv97R79XfYrdNjvwr4jsYBKLEsUibT7uocxvLRdGnPsbTr1424GfBdABtA-0VLkDUqfYzM_pYPQvS-zk" title="https://blog.mathquant.com/2023/11/09/a-powerful-tool-for-programmatic-traders-incremental-update-algorithm-for-calculating-mean-and-variance.html"&gt;https://blog.mathquant.c...g-mean-and-variance.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25595/</id>
    <title type="text">Measuring Risk and Return - An Introduction to Markowitz Theory</title>
    <published>2024-03-21T03:04:52Z</published>
    <updated>2024-03-21T03:04:52Z</updated>
    <author>
      <name>FMZ Quant</name>
      <uri>https://stocksharp.com/users/185552/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#data" />
    <category term="#fmz" />
    <category term="#python" />
    <category term="#risk" />
    <category term="#crypto" />
    <category term="#Markowitz" />
    <category term="#MPT" />
    <category term="#return" />
    <category term="#asset" />
    <content type="html">Last week, when introducing [How to Measure Position Risk - An Introduction to the VaR Method](https://www.fmz.com/bbs-topic/10255), it was mentioned that the risk of a portfolio is not equal to the risks of individual assets and is related to their price correlation. Taking two assets as an example, if their positive correlation is very strong, meaning they rise and fall together, then diversifying investments will not reduce risk. If there&amp;#39;s a strong negative correlation, diversified investments can reduce risk significantly. The natural question then arises: how do we maximize returns at a certain level of risk when investing in a portfolio? This leads us to Markowitz Theory, which we are going to introduce today.&lt;br /&gt;&lt;br /&gt;The Modern Portfolio Theory (MPT), proposed by Harry Markowitz in 1952, is a mathematical framework for portfolio selection. It aims to maximize expected returns by choosing different combinations of risk assets while controlling risk. The core idea is that the prices of assets do not move completely in sync with each other (i.e., there is incomplete correlation between assets), and overall investment risk can be reduced through diversified asset allocation.&lt;br /&gt;&lt;br /&gt;### The Key Concept of Markowitz Theory&lt;br /&gt;1. **Expected Return Rate**: This is the return that investors expect to receive from holding assets or an investment portfolio, usually predicted based on historical return data.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149420
" title="https://stocksharp.com/file/149420
"&gt;https://stocksharp.com/file/149420
&lt;/a&gt;&lt;br /&gt;Where, &lt;a href="https://stocksharp.com/file/149421 " title="https://stocksharp.com/file/149421 "&gt;https://stocksharp.com/file/149421 &lt;/a&gt;is the expected return of the portfolio, &lt;a href="https://stocksharp.com/file/149422 " title="https://stocksharp.com/file/149422 "&gt;https://stocksharp.com/file/149422 &lt;/a&gt;is the weight of the i-th asset in the portfolio, &lt;a href="https://stocksharp.com/file/149423 " title="https://stocksharp.com/file/149423 "&gt;https://stocksharp.com/file/149423 &lt;/a&gt;is the expected return of the i-th asset.&lt;br /&gt;&lt;br /&gt;2. **Risk (Volatility or Standard Deviation)**: Used to measure the uncertainty of investment returns or the volatility of investments.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149424
" title="https://stocksharp.com/file/149424
"&gt;https://stocksharp.com/file/149424
&lt;/a&gt;&lt;br /&gt;Where, &lt;a href="https://stocksharp.com/file/149425 " title="https://stocksharp.com/file/149425 "&gt;https://stocksharp.com/file/149425 &lt;/a&gt;represents the total risk of the portfolio, &lt;a href="https://stocksharp.com/file/149426 " title="https://stocksharp.com/file/149426 "&gt;https://stocksharp.com/file/149426 &lt;/a&gt;is the covariance of asset i and asset j, which measures the price change relationship between these two assets.&lt;br /&gt;&lt;br /&gt;3. **Covariance**: Measures the mutual relationship between price changes of two assets.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149427
" title="https://stocksharp.com/file/149427
"&gt;https://stocksharp.com/file/149427
&lt;/a&gt;&lt;br /&gt;Where, &lt;a href="https://stocksharp.com/file/149428 " title="https://stocksharp.com/file/149428 "&gt;https://stocksharp.com/file/149428 &lt;/a&gt;is the correlation coefficient of asset i and asset j, &lt;a href="https://stocksharp.com/file/149432 " title="https://stocksharp.com/file/149432 "&gt;https://stocksharp.com/file/149432 &lt;/a&gt;and &lt;a href="https://stocksharp.com/file/149429 " title="https://stocksharp.com/file/149429 "&gt;https://stocksharp.com/file/149429 &lt;/a&gt;are respectively the standard deviations of asset i and asset j.&lt;br /&gt;&lt;br /&gt;4. **Efficient Frontier**: In the risk-return coordinate system, the efficient frontier is the set of investment portfolios that can provide the maximum expected return at a given level of risk.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149430
" title="https://stocksharp.com/file/149430
"&gt;https://stocksharp.com/file/149430
&lt;/a&gt;&lt;br /&gt;The diagram above is an illustration of an efficient frontier, where each point represents a different weighted investment portfolio. The x-axis denotes volatility, which equates to the level of risk, while the y-axis signifies return rate. Clearly, our focus lies on the upper edge of the graph as it achieves the highest returns at equivalent levels of risk.&lt;br /&gt;&lt;br /&gt;In quantitative trading and portfolio management, applying these principles requires statistical analysis of historical data and using mathematical models to estimate expected returns, standard deviations and covariances for various assets. Then optimization techniques are used to find the best asset weight allocation. This process often involves complex mathematical operations and extensive computer processing - this is why quantitative analysis has become so important in modern finance. Next, we will illustrate how to optimize with specific Python examples.&lt;br /&gt;&lt;br /&gt;### Python Code Example for Finding the Optimal Combination Using Simulation Method&lt;br /&gt;Calculating the Markowitz optimal portfolio is a multi-step process, involving several key steps, such as data preparation, portfolio simulation, and indicator calculation. Please refer to: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAUHMBT0RDOYV3HRm60Xu-4dDADxIxONR_JbWY-WOcZ2MZj5NHr6q4_LIRwrxE3Y0SQJ4Z-hJb0e4bQg0r070V4iNaicoSYA5e4-tGvB6cFgQK2RwhacsOWe_3S5-LMtaA" title="https://plotly.com/python/v3/ipython-notebooks/markowitz-portfolio-optimization/
"&gt;https://plotly.com/pytho...portfolio-optimization/
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;1. **Obtain market data**:&lt;br /&gt;&lt;br /&gt;  Through the ```get_data``` function, obtain the historical price data of the selected digital currency. This is the necessary data for calculating returns and risks, which are used to build investment portfolios and calculate Sharpe ratios.&lt;br /&gt;&lt;br /&gt;2. **Calculate Return Rate and Risk**:&lt;br /&gt;&lt;br /&gt;  The ```calculate_returns_risk``` function was used to compute the annualized returns and annualized risk (standard deviation) for each digital currency. This is done to quantify the historical performance of each asset for use in an optimal portfolio.&lt;br /&gt;&lt;br /&gt;3. **Calculate Markowitz Optimal Portfolio**:&lt;br /&gt;&lt;br /&gt;  The ```calculate_optimal_portfolio``` function was used to simulate multiple investment portfolios. In each simulation, asset weights were randomly generated and then the expected return and risk of the portfolio were calculated based on these weights.&lt;br /&gt;  By randomly generating combinations with different weights, it is possible to explore multiple potential investment portfolios in order to find the optimal one. This is one of the core ideas of Markowitz&amp;#39;s portfolio theory.&lt;br /&gt;&lt;br /&gt;The purpose of the entire process is to find the investment portfolio that yields the best expected returns at a given level of risk. By simulating multiple possible combinations, investors can better understand the performance of different configurations and choose the combination that best suits their investment goals and risk tolerance. This method helps optimize investment decisions, making investments more effective.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;import numpy as np&lt;br /&gt;import pandas as pd&lt;br /&gt;import requests&lt;br /&gt;import matplotlib.pyplot as plt&lt;br /&gt;&lt;br /&gt;# Obtain market data&lt;br /&gt;def get_data(symbols):&lt;br /&gt;    data = []&lt;br /&gt;    for symbol in symbols:&lt;br /&gt;        url = &amp;#39;https://api.binance.com/api/v3/klines?symbol=%s&amp;amp;interval=%s&amp;amp;limit=1000&amp;#39;%(symbol,&amp;#39;1d&amp;#39;)&lt;br /&gt;        res = requests.get(url)&lt;br /&gt;        data.append([float(line[4]) for line in res.json()])&lt;br /&gt;    return data&lt;br /&gt;&lt;br /&gt;def calculate_returns_risk(data):&lt;br /&gt;    returns = []&lt;br /&gt;    risks = []&lt;br /&gt;&lt;br /&gt;    for d in data:&lt;br /&gt;        daily_returns = np.diff(d) / d[:-1]&lt;br /&gt;        annualized_return = np.mean(daily_returns) * 365&lt;br /&gt;        annualized_volatility = np.std(daily_returns) * np.sqrt(365)&lt;br /&gt;&lt;br /&gt;        returns.append(annualized_return)&lt;br /&gt;        risks.append(annualized_volatility)&lt;br /&gt;&lt;br /&gt;    return np.array(returns), np.array(risks)&lt;br /&gt;&lt;br /&gt;# Calculate Markowitz Optimal Portfolio&lt;br /&gt;def calculate_optimal_portfolio(returns, risks):&lt;br /&gt;    n_assets = len(returns)&lt;br /&gt;    num_portfolios = 3000&lt;br /&gt;&lt;br /&gt;    results = np.zeros((4, num_portfolios), dtype=object) &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    for i in range(num_portfolios):&lt;br /&gt;        weights = np.random.random(n_assets)&lt;br /&gt;        weights /= np.sum(weights)&lt;br /&gt;&lt;br /&gt;        portfolio_return = np.sum(returns * weights)&lt;br /&gt;        portfolio_risk = np.sqrt(np.dot(weights.T, np.dot(np.cov(returns, rowvar=False), weights)))&lt;br /&gt;&lt;br /&gt;        results[0, i] = portfolio_return&lt;br /&gt;        results[1, i] = portfolio_risk&lt;br /&gt;        results[2, i] = portfolio_return / portfolio_risk&lt;br /&gt;        results[3, i] = list(weights) # Convert weights to a list&lt;br /&gt;&lt;br /&gt;    return results&lt;br /&gt;&lt;br /&gt;symbols = [&amp;#39;BTCUSDT&amp;#39;,&amp;#39;ETHUSDT&amp;#39;, &amp;#39;BNBUSDT&amp;#39;,&amp;#39;LINKUSDT&amp;#39;,&amp;#39;BCHUSDT&amp;#39;,&amp;#39;LTCUSDT&amp;#39;]&lt;br /&gt;data = get_data(symbols)&lt;br /&gt;&lt;br /&gt;returns, risks = calculate_returns_risk(data)&lt;br /&gt;optimal_portfolios = calculate_optimal_portfolio(returns, risks)&lt;br /&gt;&lt;br /&gt;max_sharpe_idx = np.argmax(optimal_portfolios[2])&lt;br /&gt;optimal_return = optimal_portfolios[0, max_sharpe_idx]&lt;br /&gt;optimal_risk = optimal_portfolios[1, max_sharpe_idx]&lt;br /&gt;optimal_weights = optimal_portfolios[3, max_sharpe_idx]&lt;br /&gt;&lt;br /&gt;# Output results&lt;br /&gt;print(&amp;quot;Optimal combination:&amp;quot;)&lt;br /&gt;for i in range(len(symbols)):&lt;br /&gt;    print(f&amp;quot;{symbols[i]} Weight: {optimal_weights[i]:.4f}&amp;quot;)&lt;br /&gt;&lt;br /&gt;print(f&amp;quot;Expected return rate: {optimal_return:.4f}&amp;quot;)&lt;br /&gt;print(f&amp;quot;Expected risk (standard deviation): {optimal_risk:.4f}&amp;quot;)&lt;br /&gt;print(f&amp;quot;Sharpe ratio: {optimal_return / optimal_risk:.4f}&amp;quot;)&lt;br /&gt;&lt;br /&gt;# Visualized investment portfolio&lt;br /&gt;plt.figure(figsize=(10, 5))&lt;br /&gt;plt.scatter(optimal_portfolios[1], optimal_portfolios[0], c=optimal_portfolios[2], marker=&amp;#39;o&amp;#39;, s=3)&lt;br /&gt;plt.title(&amp;#39;portfolio&amp;#39;)&lt;br /&gt;plt.xlabel(&amp;#39;std&amp;#39;)&lt;br /&gt;plt.ylabel(&amp;#39;return&amp;#39;)&lt;br /&gt;plt.colorbar(label=&amp;#39;sharp&amp;#39;)&lt;br /&gt;plt.show()&lt;br /&gt;```&lt;br /&gt;Final output result:&lt;br /&gt;Optimal combination:&lt;br /&gt;Weight of BTCUSDT: 0.0721&lt;br /&gt;Weight of ETHUSDT: 0.2704&lt;br /&gt;Weight of BNBUSDT: 0.3646&lt;br /&gt;Weight of LINKUSDT: 0.1892&lt;br /&gt;Weight of BCHUSDT: 0.0829&lt;br /&gt;Weight of LTCUSDT: 0.0209&lt;br /&gt;Expected return rate: 0.4195&lt;br /&gt;Expected risk (standard deviation): 0.1219&lt;br /&gt;Sharpe ratio: 3.4403&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149431
" title="https://stocksharp.com/file/149431
"&gt;https://stocksharp.com/file/149431
&lt;/a&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y60yuzHEw3YKQQfs6AuOb9k5xBqwFgVWHPNNNoTBpmSjIwVoBPMr_yJmBachsA7MjzwT4lF6wNksWlmoAmDPfjwVQHKmxZAlf7udVmWNxpLvI" title="https://blog.mathquant.com/2023/11/13/measuring-risk-and-return-an-introduction-to-markowitz-theory.html"&gt;https://blog.mathquant.c...to-markowitz-theory.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25594/</id>
    <title type="text">Cracking the Code: Exploring Order Book Balance in Centralized Exchanges</title>
    <published>2024-03-21T01:10:21Z</published>
    <updated>2024-03-21T01:10:21Z</updated>
    <author>
      <name>FMZ Quant</name>
      <uri>https://stocksharp.com/users/185552/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#strategy" />
    <category term="#code" />
    <category term="#data" />
    <category term="#market" />
    <category term="#fmz" />
    <category term="#exchange" />
    <category term="#binance" />
    <category term="#crypto" />
    <category term="#order" />
    <content type="html">Recently, I have summarized some key insights from papers studying limit order books. You will learn how to measure the imbalance of transaction volume in the order book and its predictive ability for price trends. This article explores methods of using order book data to model price changes.&lt;br /&gt;&lt;br /&gt;### First, let&amp;#39;s talk about the order book.&lt;br /&gt;Exchange order book balance refers to the relative balance state between buy and sell orders in an exchange. The order book is a real-time record of all pending buy and sell orders on the market. This includes orders from buyers and sellers who are willing to trade at different prices.&lt;br /&gt;&lt;br /&gt;Below are some key concepts related to exchange order book balance:&lt;br /&gt;&lt;br /&gt;- Buyer and Seller Orders: Buyer orders in the order book represent investors willing to purchase assets at a specific price, while seller orders represent investors willing to sell assets at a specific price.&lt;br /&gt;&lt;br /&gt;- Order Book Depth: Order book depth refers to the number of orders on both the buyer and seller sides. A greater depth indicates there are more buy and sell orders in the market, which may be more liquid.&lt;br /&gt;&lt;br /&gt;- Transaction Price and Transaction Volume: The transaction price is the price of the most recent trade, while the transaction volume is the quantity of assets traded at that price. The transaction price and volume are determined by the competition between buyers and sellers in the order book.&lt;br /&gt;&lt;br /&gt;- Order Book Imbalance: Order book imbalance refers to the discrepancy between the number of buy and sell orders or total transaction volume. This can be determined by examining the depth of the order book, if one side has significantly more orders than the other, there may be an order book imbalance.&lt;br /&gt;&lt;br /&gt;- Market Depth Chart: The market depth chart graphically presents the depth and balance of the order book. Typically, the number of orders from buyers and sellers is displayed on the price level in a bar chart or other visual ways.&lt;br /&gt;&lt;br /&gt;- Factors Affecting the Price: The balance of the order book directly affects market prices. If there are more buy orders, it may push up the price; on the contrary, if there are more sell orders, it may cause a drop in price.&lt;br /&gt;&lt;br /&gt;- High-frequency Trading and Algorithmic Trading: Order book balance is crucial for high-frequency trading and algorithmic trading, as they rely on real-time order book data to make decisions, aiming to seize market opportunities quickly.&lt;br /&gt;&lt;br /&gt;Understanding the balance of order books is important for investors, traders, and market analysts, because it provides useful information about market liquidity, potential price direction, and market trends.&lt;br /&gt;&lt;br /&gt;### Imbalance in Trading Volume&lt;br /&gt;A key idea when analyzing limit order books is to determine whether the overall market tends to buy or sell. This concept is known as imbalance in trading volume.&lt;br /&gt;&lt;br /&gt;The imbalance in trading volume at time t is defined as:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149405
" title="https://stocksharp.com/file/149405
"&gt;https://stocksharp.com/file/149405
&lt;/a&gt;&lt;br /&gt;Where, &lt;a href="https://stocksharp.com/file/149406 " title="https://stocksharp.com/file/149406 "&gt;https://stocksharp.com/file/149406 &lt;/a&gt;represents the transaction volume of the best buy order at time t, &lt;a href="https://stocksharp.com/file/149407 " title="https://stocksharp.com/file/149407 "&gt;https://stocksharp.com/file/149407 &lt;/a&gt;represents the transaction volume of the best sell order at time t. We can interpret ρt close to 1 as strong buying pressure, and ρt close to -1 as strong selling pressure. This only considers the transaction volumes of orders placed at the best buy price and best sell price, that is, L1 order book.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149408
" title="https://stocksharp.com/file/149408
"&gt;https://stocksharp.com/file/149408
&lt;/a&gt;&lt;br /&gt;Imbalance in trading volume and price changes. The graph shows the imbalance of tiered trading volumes (x-axis) and the average value of future price movements, standardized by price difference (y-axis). The dataset is a quarter&amp;#39;s order flow from a certain market. There seems to be a linear relationship between first-level order imbalance and future price changes. However, on average, future price changes are within the bid-ask spread.&lt;br /&gt;&lt;br /&gt;The imbalance in trading volume ρt will be divided into the following three paragraphs:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149409
" title="https://stocksharp.com/file/149409
"&gt;https://stocksharp.com/file/149409
&lt;/a&gt;&lt;br /&gt;It was discovered that these segments can predict future price changes:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149410
" title="https://stocksharp.com/file/149410
"&gt;https://stocksharp.com/file/149410
&lt;/a&gt;&lt;br /&gt;Regarding the predictive ability of volume imbalance, an analysis was conducted on the tick-by-tick order book of a certain commodity from January 2014 to December 2014. For each arriving market order (MO), the volume imbalance was recorded and segmented according to the number of ticks in which the mid-price changed within the next 10 milliseconds. The chart shows the distribution and mid-price changes for each segment. We can see that positive price changes are more likely to occur before order books with greater buying pressure. Similarly, negative changes are more likely to occur before order books with greater selling pressure.&lt;br /&gt;&lt;br /&gt;### Order Flow Imbalance&lt;br /&gt;&lt;br /&gt;The imbalance of trading volume focuses on the total trading volume in the limit order book. One drawback is that some of this volume may come from old orders, which contain less relevant information. We can instead focus on the trading volume of recent orders. This concept is known as order flow imbalance. You can achieve this by tracking individual markets and limit orders (requires Level 3 data) or observing changes in the limit order book.&lt;br /&gt;&lt;br /&gt;Since Level 3 data is expensive and usually only available to institutional traders, we will focus on changes in the limit order book.&lt;br /&gt;&lt;br /&gt;We can calculate the order flow imbalance by looking at how much the trading volumes have moved at best bid price and best ask price. The change in trading volume at best bid price is:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149411
" title="https://stocksharp.com/file/149411
"&gt;https://stocksharp.com/file/149411
&lt;/a&gt;&lt;br /&gt;This is a function involving three scenarios. The first scenario is, if the best buying price is higher than the previous best buying price, then all transaction volumes are new transaction volumes.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149412
" title="https://stocksharp.com/file/149412
"&gt;https://stocksharp.com/file/149412
&lt;/a&gt;&lt;br /&gt;The second scenario is, if the best buying price is the same as the previous best buying price, then the new transaction volume is the difference between the current total transaction volume and the previous total transaction volume.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149413
" title="https://stocksharp.com/file/149413
"&gt;https://stocksharp.com/file/149413
&lt;/a&gt;&lt;br /&gt;The third scenario is, if the best buying price is lower than the previous best buying price, then all previous orders have been traded and are no longer in the order book.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149414
" title="https://stocksharp.com/file/149414
"&gt;https://stocksharp.com/file/149414
&lt;/a&gt;&lt;br /&gt;The calculation method for the change in transaction volume at the best selling price is similar:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149415
" title="https://stocksharp.com/file/149415
"&gt;https://stocksharp.com/file/149415
&lt;/a&gt;&lt;br /&gt;The net order flow imbalance (OFI) at time t is given by the following formula:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149416
" title="https://stocksharp.com/file/149416
"&gt;https://stocksharp.com/file/149416
&lt;/a&gt;&lt;br /&gt;This will be a positive value when there are more buy orders, and a negative value when there are more sell orders. It measures both the quantity and direction of the transaction volume. In the previous part, order imbalance only measured direction without measuring the quantity of transactions.&lt;br /&gt;&lt;br /&gt;You can add these values to get the net order flow imbalance (OFI) over a period of time:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149418
" title="https://stocksharp.com/file/149418
"&gt;https://stocksharp.com/file/149418
&lt;/a&gt;&lt;br /&gt;Use regression models to test whether order flow imbalance contains information about future price changes:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149417
" title="https://stocksharp.com/file/149417
"&gt;https://stocksharp.com/file/149417
&lt;/a&gt;&lt;br /&gt;The calculated OFI value above focuses on the best buying price and selling price. In part 4, the values of the top 5 best prices were also calculated, providing 5 inputs instead of just one. They found that a deep study of the order book can provide new information for future price changes.&lt;br /&gt;&lt;br /&gt;### Summary&lt;br /&gt;Here, I have summarized some key insights from papers studying the order volume in limit order books. These papers indicate that the order book contains information highly predictive of future price changes. However, these changes cannot overcome the bid-ask spread.&lt;br /&gt;&lt;br /&gt;I have added links to the papers in the references section. Please refer to them for more detailed information.&lt;br /&gt;&lt;br /&gt;References &amp;amp; Notes&lt;br /&gt;&lt;br /&gt;- &amp;#193;lvaro Cartea, Ryan Francis Donnelly, and Sebastian Jaimungal: &amp;quot;Enhancing Trading Strategies with Order Book Signals&amp;quot; Applied Mathematical Finance 25(1) pp. 1–35 (2018)&lt;br /&gt;- Alexander Lipton, Umberto Pesavento, and Michael G Sotiropoulos: &amp;quot;Trade arrival dynamics and quote imbalance in a limit order book&amp;quot; arXiv (2013)&lt;br /&gt;- &amp;#193;lvaro Cartea, Sebastian Jaimungal, and J. Penalva: &amp;quot;Algorithmic and high-frequency trading.&amp;quot; Cambridge University Press&lt;br /&gt;- Ke Xu, Martin D. Gould, and Sam D. Howison: &amp;quot;Multi-Level Order-Flow Imbalance in a Limit Order Book&amp;quot; arXiv (2019)&lt;br /&gt;&lt;br /&gt;Reprinted from: Author ~ {Leigh Ford, Adrian}.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y62i5LOkGofAD0pQKW1rZ8lJmxoRx8amKP1FBwVsQEbvwqSTlu_iSjVWCUm_iGnu4iLYeeOXrZskzBXrbRPWHTN6Uoty6nuW8jRnph-_OwyEWuOoYklCxUxNY-B9PXUuZSw" title="https://blog.mathquant.com/2023/11/13/a-brief-discussion-on-the-balance-of-order-books-in-centralized-exchanges.html"&gt;https://blog.mathquant.c...ntralized-exchanges.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25590/</id>
    <title type="text">Decoding Trends: Exploring the Correlation Between Currency Fluctuations and Bitcoin Price Movements</title>
    <published>2024-03-20T09:12:58Z</published>
    <updated>2024-03-20T09:12:58Z</updated>
    <author>
      <name>FMZ Quant</name>
      <uri>https://stocksharp.com/users/185552/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#strategy" />
    <category term="#data" />
    <category term="#market" />
    <category term="#analysis" />
    <category term="#fmz" />
    <category term="#bitcoin" />
    <category term="#formula" />
    <category term="#crypto" />
    <category term="#Ethereum" />
    <content type="html">In previous articles, we discussed a common phenomenon in the digital currency market: most digital currencies, especially those that follow the price fluctuations of Bitcoin and Ethereum, often show a trend of rising and falling together. This phenomenon reveals their high correlation with mainstream currencies. However, the degree of correlation between different digital currencies also varies. So how does this difference in correlation affect the market performance of each currency? In this article, we will use the bull market in the second half of 2023 as an example to explore this issue.&lt;br /&gt;&lt;br /&gt;### The Synchronous Origin of the Digital Currency Market&lt;br /&gt;The digital currency market is known for its volatility and uncertainty. Bitcoin and Ethereum, as the two giants in the market, often play a leading role in price trends. Most small or emerging digital currencies, in order to maintain market competitiveness and trading activity, often keep a certain degree of price synchronization with these mainstream currencies, especially those coins made by project parties. This synchronicity reflects the psychological expectations and trading strategies of market participants, which are important considerations in designing quantitative trading strategies.&lt;br /&gt;&lt;br /&gt;### Formula and Calculation Method of Correlation&lt;br /&gt;In the field of quantitative trading, the measurement of correlation is achieved through statistical methods. The most commonly used measure is the Pearson correlation coefficient, which measures the degree of linear correlation between two variables. Here are some core concepts and calculation methods:&lt;br /&gt;&lt;br /&gt;The range of the Pearson Correlation Coefficient (denoted as r) is from -1 to +1, where +1 indicates a perfect positive correlation, -1 indicates a perfect negative correlation, and 0 indicates no linear relationship. The formula for calculating this coefficient is as follows:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149366
" title="https://stocksharp.com/file/149366
"&gt;https://stocksharp.com/file/149366
&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Among them, &lt;a href="https://stocksharp.com/file/149367 " title="https://stocksharp.com/file/149367 "&gt;https://stocksharp.com/file/149367 &lt;/a&gt;and &lt;a href="https://stocksharp.com/file/149368 " title="https://stocksharp.com/file/149368 "&gt;https://stocksharp.com/file/149368 &lt;/a&gt;are the observed values of two random variables, &lt;a href="https://stocksharp.com/file/149369 " title="https://stocksharp.com/file/149369 "&gt;https://stocksharp.com/file/149369 &lt;/a&gt;and &lt;a href="https://stocksharp.com/file/149370 " title="https://stocksharp.com/file/149370 "&gt;https://stocksharp.com/file/149370 &lt;/a&gt;are the average values of these two random variables respectively. Using Python scientific computing related packages, it&amp;#39;s easy to calculate correlation.&lt;br /&gt;&lt;br /&gt;### Data Collection&lt;br /&gt;This article has collected the 4h K-line data for the entire year of 2023 from Binance, selecting 144 currencies that were listed on January 1st. The specific code to download the data is as follows:&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;import requests&lt;br /&gt;from datetime import date,datetime&lt;br /&gt;import time&lt;br /&gt;import pandas as pd&lt;br /&gt;import numpy as np&lt;br /&gt;import matplotlib.pyplot as plt&lt;br /&gt;&lt;br /&gt;ticker = requests.get(&amp;#39;https://fapi.binance.com/fapi/v1/ticker/24hr&amp;#39;)&lt;br /&gt;ticker = ticker.json()&lt;br /&gt;sort_symbols = [k[&amp;#39;symbol&amp;#39;][:-4] for k in sorted(ticker, key=lambda x :-float(x[&amp;#39;quoteVolume&amp;#39;])) if k[&amp;#39;symbol&amp;#39;][-4:] == &amp;#39;USDT&amp;#39;]&lt;br /&gt;&lt;br /&gt;def GetKlines(symbol=&amp;#39;BTCUSDT&amp;#39;,start=&amp;#39;2020-8-10&amp;#39;,end=&amp;#39;2023-8-10&amp;#39;,period=&amp;#39;1h&amp;#39;,base=&amp;#39;fapi&amp;#39;,v = &amp;#39;v1&amp;#39;):&lt;br /&gt;    Klines = []&lt;br /&gt;    start_time = int(time.mktime(datetime.strptime(start, &amp;quot;%Y-%m-%d&amp;quot;).timetuple()))*1000 + 8*60*60*1000&lt;br /&gt;    end_time =  min(int(time.mktime(datetime.strptime(end, &amp;quot;%Y-%m-%d&amp;quot;).timetuple()))*1000 + 8*60*60*1000,time.time()*1000)&lt;br /&gt;    intervel_map = {&amp;#39;m&amp;#39;:60*1000,&amp;#39;h&amp;#39;:60*60*1000,&amp;#39;d&amp;#39;:24*60*60*1000}&lt;br /&gt;    while start_time &amp;lt; end_time:&lt;br /&gt;        time.sleep(0.5)&lt;br /&gt;        mid_time = start_time+1000*int(period[:-1])*intervel_map[period[-1]]&lt;br /&gt;        url = &amp;#39;https://&amp;#39;+base+&amp;#39;.binance.com/&amp;#39;+base+&amp;#39;/&amp;#39;+v+&amp;#39;/klines?symbol=%s&amp;amp;interval=%s&amp;amp;startTime=%s&amp;amp;endTime=%s&amp;amp;limit=1000&amp;#39;%(symbol,period,start_time,mid_time)&lt;br /&gt;        res = requests.get(url)&lt;br /&gt;        res_list = res.json()&lt;br /&gt;        if type(res_list) == list and len(res_list) &amp;gt; 0:&lt;br /&gt;            start_time = res_list[-1][0]+int(period[:-1])*intervel_map[period[-1]]&lt;br /&gt;            Klines += res_list&lt;br /&gt;        if type(res_list) == list and len(res_list) == 0:&lt;br /&gt;            start_time = start_time+1000*int(period[:-1])*intervel_map[period[-1]]&lt;br /&gt;        if mid_time &amp;gt;= end_time:&lt;br /&gt;            break&lt;br /&gt;    df = pd.DataFrame(Klines,columns=[&amp;#39;time&amp;#39;,&amp;#39;open&amp;#39;,&amp;#39;high&amp;#39;,&amp;#39;low&amp;#39;,&amp;#39;close&amp;#39;,&amp;#39;amount&amp;#39;,&amp;#39;end_time&amp;#39;,&amp;#39;volume&amp;#39;,&amp;#39;count&amp;#39;,&amp;#39;buy_amount&amp;#39;,&amp;#39;buy_volume&amp;#39;,&amp;#39;null&amp;#39;]).astype(&amp;#39;float&amp;#39;)&lt;br /&gt;    df.index = pd.to_datetime(df.time,unit=&amp;#39;ms&amp;#39;)&lt;br /&gt;    return df&lt;br /&gt;&lt;br /&gt;start_date = &amp;#39;2023-01-01&amp;#39;&lt;br /&gt;end_date   = &amp;#39;2023-11-16&amp;#39;&lt;br /&gt;period = &amp;#39;4h&amp;#39;&lt;br /&gt;df_dict = {}&lt;br /&gt;&lt;br /&gt;for symbol in sort_symbols:   &lt;br /&gt;    print(symbol)&lt;br /&gt;    df_s = GetKlines(symbol=symbol+&amp;#39;USDT&amp;#39;,start=start_date,end=end_date,period=period)&lt;br /&gt;    if not df_s.empty:&lt;br /&gt;        df_dict[symbol] = df_s&lt;br /&gt;&lt;br /&gt;df_close = pd.DataFrame(index=pd.date_range(start=start_date, end=end_date, freq=period),columns=df_dict.keys())&lt;br /&gt;for symbol in symbols:&lt;br /&gt;    df_s = df_dict[symbol]&lt;br /&gt;    df_close[symbol] = df_s.close&lt;br /&gt;df_close = df_close.dropna(how=&amp;#39;any&amp;#39;,axis=1)&lt;br /&gt;```&lt;br /&gt;### Market Review&lt;br /&gt;After normalizing the data first, we calculate the index of average price fluctuations. It can be seen that there are two market trends in 2023. One is a significant increase at the beginning of the year, and the other is a major rise starting from October. Currently, it&amp;#39;s basically at a high point in terms of index.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;df_norm = df_close/df_close.fillna(method=&amp;#39;bfill&amp;#39;).iloc[0] #Normalization&lt;br /&gt;total_index = df_norm.mean(axis=1)&lt;br /&gt;total_index.plot(figsize=(15,6),grid=True);&lt;br /&gt;```&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149362
" title="https://stocksharp.com/file/149362
"&gt;https://stocksharp.com/file/149362
&lt;/a&gt;&lt;br /&gt;### Correlation Analysis&lt;br /&gt;Pandas comes with a built-in correlation calculation. The weakest correlation with BTC price is shown in the following figure. Most currencies have a positive correlation, meaning they follow the price of BTC. However, some currencies have a negative correlation, which is considered an anomaly in digital currency market trends.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149363
" title="https://stocksharp.com/file/149363
"&gt;https://stocksharp.com/file/149363
&lt;/a&gt;&lt;br /&gt;```&lt;br /&gt;corr_symbols = df_norm.corrwith(df_norm.BTC).sort_values().index&lt;br /&gt;```&lt;br /&gt;### Correlation and Price Increase&lt;br /&gt;Here, the currencies are loosely divided into two groups. The first group consists of 40 currencies most correlated with BTC price, and the second group includes those least related to BTC price. By subtracting the index of the second group from that of the first, it represents going long on the first group while shorting the second one. In this way, we can calculate a relationship between price fluctuations and BTC correlation. Here is how you do it along with results:&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;(df_norm[corr_symbols[-40:]].mean(axis=1)-df_norm[corr_symbols[:40]].mean(axis=1)).plot(figsize=(15,6),grid=True);&lt;br /&gt;```&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149364
" title="https://stocksharp.com/file/149364
"&gt;https://stocksharp.com/file/149364
&lt;/a&gt;&lt;br /&gt;The results show that the currencies with stronger correlation to BTC price have better increases, and shorting currencies with low correlation also played a good hedging role. The imprecision here is that future data was used when calculating the correlation. Below, we divide the data into two groups: one group calculates the correlation, and another calculates the return after hedging. The result is shown in the following figure, and the conclusion remains unchanged.&lt;br /&gt;&lt;br /&gt;Bitcoin and Ethereum as market leaders often have a huge impact on overall market trends. When these cryptocurrencies rise in price, market sentiment usually becomes optimistic and many investors tend to follow this trend. Investors may see this as a signal of an overall market increase and start buying other currencies. Due to collective behavior of market participants, currencies highly correlated with mainstream ones might experience similar price increases. At such times, expectations about price trends can sometimes become self-fulfilling prophecies. On the contrary, currencies negatively correlated with Bitcoin are unique; their fundamentals may be deteriorating or they may no longer be within sight of mainstream investors - there could even exist Bitcoin&amp;#39;s blood-sucking situation where markets abandon them chasing for those able to keep up with rising prices.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;corr_symbols = (df_norm.iloc[:1500].corrwith(df_norm.BTC.iloc[:1500])-df_norm.iloc[:1500].corrwith(total_index[:1500])).sort_values().index &lt;br /&gt;```&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149365
" title="https://stocksharp.com/file/149365
"&gt;https://stocksharp.com/file/149365
&lt;/a&gt;&lt;br /&gt;### Summary&lt;br /&gt;This article discusses the Pearson correlation coefficient, revealing the degree of correlation between different currencies. The article demonstrates how to obtain data to calculate the correlation between currencies and use this data to assess market trends. It reveals that synchronicity in price fluctuations in the digital currency market not only reflects market psychology and strategy, but can also be quantified and predicted through scientific methods. This is particularly important for designing quantitative trading strategies.&lt;br /&gt;&lt;br /&gt;There are many areas where the ideas in this article can be expanded, such as calculating rolling correlations, separately calculating correlations during rises and falls, etc., which can yield a lot of useful information.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y6_fDA9lkxHIZMIaASo91h6OY2ufQT34QJk0z8S1ICA0Z4cwUYPZfzvD39JSCgFcFURtLawpNJWdgy3F56xFr2xsNSU4GMr6yp3viK1RVNguA" title="https://blog.mathquant.com/2023/11/17/the-correlation-between-the-rise-and-fall-of-currencies-and-bitcoin.html"&gt;https://blog.mathquant.c...rencies-and-bitcoin.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25589/</id>
    <title type="text">Unveiling the Price Dynamics: Analyzing Performance Post Listing on Perpetual Contracts</title>
    <published>2024-03-20T05:37:02Z</published>
    <updated>2024-03-20T05:37:02Z</updated>
    <author>
      <name>FMZ Quant</name>
      <uri>https://stocksharp.com/users/185552/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#code" />
    <category term="#data" />
    <category term="#fmz" />
    <category term="#contract" />
    <category term="#binance" />
    <category term="#spot" />
    <category term="#Kline" />
    <category term="#crypto" />
    <category term="#bull" />
    <content type="html">Most people know that once Binance announces the listing of a new perpetual contract, the spot price of this cryptocurrency often rises immediately. This has led to some robots scraping announcements constantly to buy in at the first moment, not to mention so-called insider information where the currency price has already risen before the announcement is even made. But how do these contract cryptocurrencies perform after they start trading? Do they continue their upward trend or have a pullback? Let&amp;#39;s analyze it today.&lt;br /&gt;&lt;br /&gt;### Data Preparation&lt;br /&gt;Download the 4h K-line data of Binance&amp;#39;s perpetual contract for the year 2023. The specific download code is introduced in the previous article: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAADHZKb-RfbDOdB_w3dJgQKt340BVBnfBL7FKDRx7ipd8M2SDjngavqKT7CrykkTgYA" title="https://www.fmz.com/bbs-topic/10286. "&gt;https://www.fmz.com/bbs-topic/10286. &lt;/a&gt;The listing time does not necessarily coincide with the 4-hour mark, which is a bit imprecise. However, the price at the start of trading is often chaotic. Using fixed intervals can filter out the impact of market opening without delaying analysis. In the data dataframe, NaN represents no data; once the first piece of data appears, it means that this coin has been listed. Here we calculate every 4 hours after listing relative to the first price increase and form a new table. Those already listed from the beginning are filtered out. As of November 16, 2023, Binance has listed a total of 86 currencies, averaging more than one every three days - quite frequent indeed.&lt;br /&gt;&lt;br /&gt;The following is the specific processing code, where only data within 150 days of going live has been extracted.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;df = df_close/df_close.fillna(method=&amp;#39;bfill&amp;#39;).iloc[0]&lt;br /&gt;price_changes = {}&lt;br /&gt;for coin in df.columns[df.iloc[0].isna()]:&lt;br /&gt;    listing_time = df[coin].first_valid_index()&lt;br /&gt;    price_changes[coin] = df[coin][df.index&amp;gt;listing_time].values&lt;br /&gt;changes_df = pd.DataFrame.from_dict(price_changes, orient=&amp;#39;index&amp;#39;).T&lt;br /&gt;changes_df.index = changes_df.index/6&lt;br /&gt;changes_df = changes_df[changes_df.index&amp;lt;150]&lt;br /&gt;changes_df.mean(axis=1).plot(figsize=(15,6),grid=True);&lt;br /&gt;```&lt;br /&gt;### Result Analysis&lt;br /&gt;The results are shown in the following graph, where the horizontal axis represents the number of days on the shelf and the vertical axis represents the average index. This result can be said to be unexpected but reasonable. Surprisingly, after new contracts are listed, they almost all fall, and the longer they are listed, the more they fall. At least within half a year there is no rebound. But it&amp;#39;s also reasonable to think about it; so-called listing benefits have been realized before listing, and subsequent continuous declines are normal. If you open up a K-line chart to look at weekly lines, you can also find that many newly-listed contract currencies follow this pattern - opening at their peak.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149353
" title="https://stocksharp.com/file/149353
"&gt;https://stocksharp.com/file/149353
&lt;/a&gt;&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149354
" title="https://stocksharp.com/file/149354
"&gt;https://stocksharp.com/file/149354
&lt;/a&gt;&lt;br /&gt;### Exclude the Impact of the Index&lt;br /&gt;The previous article has mentioned that digital currencies are greatly affected by simultaneous rises and falls. Does the overall index&amp;#39;s decline affect their performance? Here, let&amp;#39;s change the price changes to be relative to the index changes and look at the results again. From what we see on the graph, it still looks the same - a continuous decline. In fact, it has declined even more compared to the index.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;total_index = df.mean(axis=1)&lt;br /&gt;df = df.divide(total_index,axis=0)&lt;br /&gt;```&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149355
" title="https://stocksharp.com/file/149355
"&gt;https://stocksharp.com/file/149355
&lt;/a&gt;&lt;br /&gt;### Binance&amp;#39;s Currency Listing&lt;br /&gt;By analyzing the relationship between the number of currencies listed each week and the index, we can clearly see Binance&amp;#39;s listing strategy: frequent listings during a bull market, few listings during a bear market. February and October of this year were peak periods for listings, coinciding with bull markets. During times when the market was falling quite badly, Binance hardly listed any new contracts. It is evident that Binance also wants to take advantage of high trading volumes in bull markets and active new contracts to earn more transaction fees. They don&amp;#39;t want new contracts to fall too badly either, but unfortunately, they can&amp;#39;t always control it.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149356
" title="https://stocksharp.com/file/149356
"&gt;https://stocksharp.com/file/149356
&lt;/a&gt;&lt;br /&gt;### Summary&lt;br /&gt;This article analyzes the 4h K-line data of Binance&amp;#39;s perpetual contracts for the year 2023, showing that newly listed contracts tend to decline over a long period. This may reflect the market&amp;#39;s gradual cooling off from initial enthusiasm and return to rationality. If you design a strategy to short a certain amount of funds on the first day of trading, and close out after holding for some time, there is a high probability of making money. Of course, this also carries risks; past trends do not represent the future. But one thing is certain: there is no need to chase hot spot or go long on newly listed contract currencies.&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y62jT7jgUMxT5buH0Adozlwm7yqfufWT_GopKI_KFwlmgfOtowBcFv3wJuVmGPn4eBLGzgeWHm6e5jFwDG2g1hCeTDbyWVt2hkYBR2k9zHA2wvnNuu3-twQM60C7IfNIHew" title="https://blog.mathquant.com/2023/11/20/price-performance-after-the-currency-is-listed-on-perpetual-contracts.html"&gt;https://blog.mathquant.c...perpetual-contracts.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25586/</id>
    <title type="text">Unlocking Efficiency: Leveraging FMZ&amp;apos;s Extended API for Streamlined Group Control in Quantitative Trading</title>
    <published>2024-03-20T00:41:57Z</published>
    <updated>2024-03-20T00:41:57Z</updated>
    <author>
      <name>FMZ Quant</name>
      <uri>https://stocksharp.com/users/185552/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#cryptocurrency" />
    <category term="#strategy" />
    <category term="#code" />
    <category term="#data" />
    <category term="#fmz" />
    <category term="#parameter" />
    <category term="#API" />
    <category term="#robot" />
    <category term="#command" />
    <content type="html">With the popularization and development of quantitative trading, investors often need to manage a large number of live accounts, which brings great challenges to trading decisions, monitoring and execution. In order to improve management efficiency and reduce operational difficulty, traders on FMZ can use FMZ&amp;#39;s extended API for group control management. In this article, we will discuss the advantages of using FMZ&amp;#39;s extended API in quantitative trading and how to achieve efficient group control management.&lt;br /&gt;&lt;br /&gt;Many users have their own customer live accounts that need managing and maintaining. When there are many customer live accounts, a more convenient way is needed for managing them (as few as dozens or as many as hundreds). FMZ provides a powerful extended API; using this for group control management has become an ideal choice.&lt;br /&gt;&lt;br /&gt;### Centralized Monitoring&lt;br /&gt;Through FMZ&amp;#39;s extended API, you can centrally monitor the trading activities and asset conditions of all live accounts. Whether it is checking the positions of each account, historical trading records, or real-time monitoring of the profit and loss status of accounts, all of them can be achieved.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;// Global variable&lt;br /&gt;var isLogMsg = true   // Control whether the log is printed&lt;br /&gt;var isDebug = false   // Debug mode&lt;br /&gt;var arrIndexDesc = [&amp;quot;all&amp;quot;, &amp;quot;running&amp;quot;, &amp;quot;stop&amp;quot;]&lt;br /&gt;var descRobotStatusCode = [&amp;quot;In idle&amp;quot;, &amp;quot;Running&amp;quot;, &amp;quot;Stopping&amp;quot;, &amp;quot;Exited&amp;quot;, &amp;quot;Stopped&amp;quot;, &amp;quot;Strategy error&amp;quot;]&lt;br /&gt;var dicRobotStatusCode = {&lt;br /&gt;    &amp;quot;all&amp;quot; : -1,&lt;br /&gt;    &amp;quot;running&amp;quot; : 1,&lt;br /&gt;    &amp;quot;stop&amp;quot; : 4,&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Extended log function&lt;br /&gt;function LogControl(...args) {&lt;br /&gt;    if (isLogMsg) {&lt;br /&gt;        Log(...args)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// FMZ extended API call function&lt;br /&gt;function callFmzExtAPI(accessKey, secretKey, funcName, ...args) {&lt;br /&gt;    var params = {&lt;br /&gt;        &amp;quot;version&amp;quot; : &amp;quot;1.0&amp;quot;,&lt;br /&gt;        &amp;quot;access_key&amp;quot; : accessKey,&lt;br /&gt;        &amp;quot;method&amp;quot; : funcName,&lt;br /&gt;        &amp;quot;args&amp;quot; : JSON.stringify(args),&lt;br /&gt;        &amp;quot;nonce&amp;quot; : Math.floor(new Date().getTime())&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    var data = `${params[&amp;quot;version&amp;quot;]}|${params[&amp;quot;method&amp;quot;]}|${params[&amp;quot;args&amp;quot;]}|${params[&amp;quot;nonce&amp;quot;]}|${secretKey}`&lt;br /&gt;    params[&amp;quot;sign&amp;quot;] = Encode(&amp;quot;md5&amp;quot;, &amp;quot;string&amp;quot;, &amp;quot;hex&amp;quot;, data)&lt;br /&gt;    &lt;br /&gt;    var arrPairs = []&lt;br /&gt;    for (var k in params) {&lt;br /&gt;        var pair = `${k}=${params[k]}`&lt;br /&gt;        arrPairs.push(pair)&lt;br /&gt;    }&lt;br /&gt;    var query = arrPairs.join(&amp;quot;&amp;amp;&amp;quot;)&lt;br /&gt;    &lt;br /&gt;    var ret = null&lt;br /&gt;    try {&lt;br /&gt;        LogControl(&amp;quot;url:&amp;quot;, baseAPI + &amp;quot;/api/v1?&amp;quot; + query)&lt;br /&gt;        ret = JSON.parse(HttpQuery(baseAPI + &amp;quot;/api/v1?&amp;quot; + query))&lt;br /&gt;        if (isDebug) {&lt;br /&gt;            LogControl(&amp;quot;Debug:&amp;quot;, ret)&lt;br /&gt;        }&lt;br /&gt;    } catch(e) {&lt;br /&gt;        LogControl(&amp;quot;e.name:&amp;quot;, e.name, &amp;quot;e.stack:&amp;quot;, e.stack, &amp;quot;e.message:&amp;quot;, e.message)&lt;br /&gt;    }&lt;br /&gt;    Sleep(100)  // Control frequency&lt;br /&gt;    return ret &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Obtain all live trading information of the specified strategy Id.&lt;br /&gt;function getAllRobotByIdAndStatus(accessKey, secretKey, strategyId, robotStatusCode, maxRetry) {&lt;br /&gt;    var retryCounter = 0&lt;br /&gt;    var length = 100&lt;br /&gt;    var offset = 0&lt;br /&gt;    var arr = []&lt;br /&gt;&lt;br /&gt;    if (typeof(maxRetry) == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;        maxRetry = 10&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    while (true) {&lt;br /&gt;        if (retryCounter &amp;gt; maxRetry) {&lt;br /&gt;            LogControl(&amp;quot;Exceeded the maximum number of retries&amp;quot;, maxRetry)&lt;br /&gt;            return null&lt;br /&gt;        }&lt;br /&gt;        var ret = callFmzExtAPI(accessKey, secretKey, &amp;quot;GetRobotList&amp;quot;, offset, length, robotStatusCode)&lt;br /&gt;        if (!ret || ret[&amp;quot;code&amp;quot;] != 0) {&lt;br /&gt;            Sleep(1000)&lt;br /&gt;            retryCounter++&lt;br /&gt;            continue&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        var robots = ret[&amp;quot;data&amp;quot;][&amp;quot;result&amp;quot;][&amp;quot;robots&amp;quot;]&lt;br /&gt;        for (var i in robots) {&lt;br /&gt;            if (robots[i].strategy_id != strategyId) {&lt;br /&gt;                continue&lt;br /&gt;            }&lt;br /&gt;            arr.push(robots[i])&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (robots.length &amp;lt; length) {&lt;br /&gt;            break&lt;br /&gt;        }&lt;br /&gt;        offset += length&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return arr &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function main() {&lt;br /&gt;    var robotStatusCode = dicRobotStatusCode[arrIndexDesc[robotStatus]]&lt;br /&gt;    var robotList = getAllRobotByIdAndStatus(accessKey, secretKey, strategyId, robotStatusCode)&lt;br /&gt;    if (!robotList) {&lt;br /&gt;        Log(&amp;quot;Failed to obtain live trading data&amp;quot;)&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    var robotTbl = {&amp;quot;type&amp;quot;: &amp;quot;table&amp;quot;, &amp;quot;title&amp;quot;: &amp;quot;live trading list&amp;quot;, &amp;quot;cols&amp;quot;: [], &amp;quot;rows&amp;quot;: []}&lt;br /&gt;    robotTbl.cols = [&amp;quot;live trading Id&amp;quot;, &amp;quot;live trading name&amp;quot;, &amp;quot;live trading status&amp;quot;, &amp;quot;strategy name&amp;quot;, &amp;quot;live trading profit&amp;quot;]&lt;br /&gt;&lt;br /&gt;    _.each(robotList, function(robotInfo) {&lt;br /&gt;        robotTbl.rows.push([robotInfo.id, robotInfo.name, descRobotStatusCode[robotInfo.status], robotInfo.strategy_name, robotInfo.profit])&lt;br /&gt;    })&lt;br /&gt;&lt;br /&gt;    LogStatus(_D(), &amp;quot;`&amp;quot; + JSON.stringify(robotTbl) + &amp;quot;`&amp;quot;)&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;Strategy parameter design:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149332
" title="https://stocksharp.com/file/149332
"&gt;https://stocksharp.com/file/149332
&lt;/a&gt;&lt;br /&gt;Running on live trading:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149333
" title="https://stocksharp.com/file/149333
"&gt;https://stocksharp.com/file/149333
&lt;/a&gt;&lt;br /&gt;### One-click Execution&lt;br /&gt;Group control management makes it very convenient to execute transactions with one-click. You can buy, sell, and close positions on multiple live trading accounts simultaneously without having to open each account individually. This not only improves execution efficiency, but also reduces the possibility of operational errors.&lt;br /&gt;&lt;br /&gt;After obtaining the list of live trading accounts, we can send commands to these accounts and perform a series of predetermined operations. For example: clearing positions in the live account, pausing protection in the live account, switching modes in the live account. All these can be achieved through FMZ&amp;#39;s extended API ```CommandRobot```.&lt;br /&gt;&lt;br /&gt;As we continue writing code, we just need to add some interactions and calls to the extended API interface ```CommandRobot``` in our main function:&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;function main() {&lt;br /&gt;    var robotStatusCode = dicRobotStatusCode[arrIndexDesc[robotStatus]]&lt;br /&gt;    var robotList = getAllRobotByIdAndStatus(accessKey, secretKey, strategyId, robotStatusCode)&lt;br /&gt;    if (!robotList) {&lt;br /&gt;        Log(&amp;quot;Failed to obtain live trading data&amp;quot;)&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    var robotTbl = {&amp;quot;type&amp;quot;: &amp;quot;table&amp;quot;, &amp;quot;title&amp;quot;: &amp;quot;live trading list&amp;quot;, &amp;quot;cols&amp;quot;: [], &amp;quot;rows&amp;quot;: []}&lt;br /&gt;    robotTbl.cols = [&amp;quot;live trading Id&amp;quot;, &amp;quot;live trading name&amp;quot;, &amp;quot;live trading status&amp;quot;, &amp;quot;strategy name&amp;quot;, &amp;quot;live trading profit&amp;quot;]&lt;br /&gt;&lt;br /&gt;    _.each(robotList, function(robotInfo) {&lt;br /&gt;        robotTbl.rows.push([robotInfo.id, robotInfo.name, descRobotStatusCode[robotInfo.status], robotInfo.strategy_name, robotInfo.profit])&lt;br /&gt;    })&lt;br /&gt;&lt;br /&gt;    LogStatus(_D(), &amp;quot;`&amp;quot; + JSON.stringify(robotTbl) + &amp;quot;`&amp;quot;)&lt;br /&gt;&lt;br /&gt;    while(true) {&lt;br /&gt;        LogStatus(_D(), &amp;quot;, Waiting to receive interactive commands&amp;quot;, &amp;quot;\n&amp;quot;, &amp;quot;`&amp;quot; + JSON.stringify(robotTbl) + &amp;quot;`&amp;quot;)&lt;br /&gt;&lt;br /&gt;        var cmd = GetCommand()&lt;br /&gt;        if (cmd) {&lt;br /&gt;            var arrCmd = cmd.split(&amp;quot;:&amp;quot;)&lt;br /&gt;            if (arrCmd.length == 1 &amp;amp;&amp;amp; cmd == &amp;quot;coverAll&amp;quot;) {&lt;br /&gt;                _.each(robotList, function(robotInfo) {&lt;br /&gt;                    var strCmd = &amp;quot;Clearance&amp;quot;               // You can define the required message format&lt;br /&gt;                    if (robotInfo.status != 1) {     // Only the &amp;quot;live&amp;quot; trading platform can receive commands.&lt;br /&gt;                        return &lt;br /&gt;                    }&lt;br /&gt;                    var ret = callFmzExtAPI(accessKey, secretKey, &amp;quot;CommandRobot&amp;quot;, parseInt(robotInfo.id), strCmd)&lt;br /&gt;                    LogControl(&amp;quot;Send command to the live trading board with id: &amp;quot;, robotInfo.id, &amp;quot;:&amp;quot;, strCmd, &amp;quot;, execution result:&amp;quot;, ret)&lt;br /&gt;                })&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        Sleep(1000)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;```&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149334
" title="https://stocksharp.com/file/149334
"&gt;https://stocksharp.com/file/149334
&lt;/a&gt;&lt;br /&gt;The group control strategy sent instructions to &amp;quot;Test 1 A&amp;quot; and &amp;quot;Test 1 B&amp;quot;.&lt;br /&gt;&lt;br /&gt;### Strategy Synchronization&lt;br /&gt;With FMZ&amp;#39;s extended API, you can easily implement batch modifications of strategy parameters, and batch start or stop live trading.&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149335
" title="https://stocksharp.com/file/149335
"&gt;https://stocksharp.com/file/149335
&lt;/a&gt;&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149336
" title="https://stocksharp.com/file/149336
"&gt;https://stocksharp.com/file/149336
&lt;/a&gt;&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149337
" title="https://stocksharp.com/file/149337
"&gt;https://stocksharp.com/file/149337
&lt;/a&gt;&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149338
" title="https://stocksharp.com/file/149338
"&gt;https://stocksharp.com/file/149338
&lt;/a&gt;&lt;br /&gt;### Summary&lt;br /&gt;In quantitative trading, by using FMZ&amp;#39;s extended API for group control management, traders can monitor, execute and adjust multiple live accounts more efficiently. This centralized management method not only improves operational efficiency, but also helps to better implement risk control and strategy synchronization.&lt;br /&gt;&lt;br /&gt;For traders managing a large number of live accounts, FMZ&amp;#39;s extended API provides them with a powerful and flexible tool that makes quantitative trading more convenient and controllable.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y6xi6CcygGojFUBiqPTxAevq5wECkW1uLDRcZq-59qg9OKxUAia2AuB86x2UlrEKgVbhVLcTSWByK5cnm6thO7ha7JspnElZ9CclHO2tbtCWcgEDsFiuh3IYlqWjlIrZ8WADxxcmD3DOqzMbQtv1etWBp-dH16_zcVHvHGQrhEiKO" title="https://blog.mathquant.com/2023/11/20/the-advantages-of-using-fmzs-extended-api-for-efficient-group-control-management-in-quantitative-trading.html"&gt;https://blog.mathquant.c...uantitative-trading.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25583/</id>
    <title type="text">Unraveling the Mystery of Probability: Exploring Bayesian Decision Making and Mathematical Wisdom</title>
    <published>2024-03-19T09:11:08Z</published>
    <updated>2024-03-19T09:11:08Z</updated>
    <author>
      <name>FMZ Quant</name>
      <uri>https://stocksharp.com/users/185552/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#cryptocurrency" />
    <category term="#data" />
    <category term="#fmz" />
    <category term="#parameter" />
    <category term="#Bayes" />
    <category term="#formula" />
    <category term="#math" />
    <category term="#Shannon" />
    <category term="#finance" />
    <content type="html">Bayesian statistics is a powerful discipline in the field of mathematics, with wide applications in many areas including finance, medical research, and information technology. It allows us to combine prior beliefs with evidence to derive new posterior beliefs, enabling us to make wiser decisions.&lt;br /&gt;&lt;br /&gt;In this article, we will briefly introduce some of the main mathematicians who founded this field.&lt;br /&gt;&lt;br /&gt;Before Bayes&lt;br /&gt;To better understand Bayesian statistics, we need to go back to the 18th century and refer to mathematician De Moivre and his paper &amp;quot;The Doctrine of Chances&amp;quot;.&lt;br /&gt;&lt;br /&gt;In his paper, De Moivre solved many problems related to probability and gambling in his era. As you may know, his solution to one of these problems led to the origin of the normal distribution, but that&amp;#39;s another story.&lt;br /&gt;&lt;br /&gt;One of the simplest questions in his paper was:&lt;br /&gt;&lt;br /&gt;&amp;quot;What is the probability of getting three heads when flipping a fair coin three times consecutively?&amp;quot;&lt;br /&gt;&lt;br /&gt;Reading through the problems described in &amp;quot;The Doctrine of Chances&amp;quot;, you might notice that most start with an assumption from which they calculate probabilities for given events. For example, in the above question there is an assumption that considers the coin as fair; therefore, obtaining a head during a toss has a probability of 0.5.&lt;br /&gt;&lt;br /&gt;This would be expressed today in mathematical terms as:&lt;br /&gt;&lt;br /&gt;Formula&lt;br /&gt;```&lt;br /&gt;&amp;#119875;(&amp;#119883;|&amp;#120579;)&lt;br /&gt;```&lt;br /&gt;However, what if we don&amp;#39;t know whether the coin is fair? What if we don&amp;#39;t know ```&amp;#120579;``` ?&lt;br /&gt;&lt;br /&gt;### Thomas Bayes and Richard Price&lt;br /&gt;Nearly fifty years later, in 1763, a paper titled &amp;quot;A Solution to the Problems in the Doctrine of Chances&amp;quot; was published in the Philosophical Transactions of the Royal Society of London.&lt;br /&gt;&lt;br /&gt;In the first few pages of this document, there is a piece written by mathematician Richard Price that summarizes a paper his friend Thomas Bayes wrote several years before his death. In his introduction, Price explained some important discoveries made by Thomas Bayes that were not mentioned in De Moivre&amp;#39;s &amp;quot;Doctrine of Chances&amp;quot;.&lt;br /&gt;&lt;br /&gt;In fact, he referred to one specific problem:&lt;br /&gt;&lt;br /&gt;&amp;quot;Given an unknown event&amp;#39;s number of successes and failures, find its chance between any two named degrees.&amp;quot;&lt;br /&gt;&lt;br /&gt;In other words, after observing an event we determine what is the probability that an unknown parameter ```θ``` falls between two degrees. This is actually one of the first problems related to statistical inference in history and it gave rise to term inverse probability. In mathematical terms:&lt;br /&gt;&lt;br /&gt;Formula&lt;br /&gt;```&lt;br /&gt;&amp;#119875;( &amp;#120579; | &amp;#119883;）&lt;br /&gt;```&lt;br /&gt;This is of course what we call the posterior distribution of Bayes&amp;#39; theorem today.&lt;br /&gt;&lt;br /&gt;### For the Reason of No Cause and Effect&lt;br /&gt;Understanding the motivations behind the research of these two elder ministers, **Thomas Bayes** and **Richard Price**, is actually quite interesting. But to do this, we need to temporarily put aside some knowledge about statistics.&lt;br /&gt;&lt;br /&gt;We are in the 18th century when probability is becoming an increasingly interesting field for mathematicians. Mathematicians like de Moivre or Bernoulli have already shown that some events occur with a certain degree of randomness but are still governed by fixed rules. For example, if you roll a dice multiple times, one-sixth of the time it will land on six. It&amp;#39;s as if there&amp;#39;s a hidden rule determining fate&amp;#39;s chances.&lt;br /&gt;&lt;br /&gt;Now imagine being a mathematician and devout believer living during this period. You might be interested in understanding the relationship between this hidden rule and God.&lt;br /&gt;&lt;br /&gt;This was indeed the question asked by Bayes and Price themselves. They hoped that their solution would directly apply to proving &amp;quot;the world must be the result of wisdom and intelligence; therefore providing evidence for God&amp;#39;s existence as ultimate cause&amp;quot; - that is, cause without causality.&lt;br /&gt;&lt;br /&gt;### Laplace&lt;br /&gt;Surprisingly, around two years later in 1774, without having read Thomas Bayes&amp;#39; paper, the French mathematician Laplace wrote a paper titled &amp;quot;On the Causes of Events by Probability of Events&amp;quot;, which is about inverse probability problems. On the first page, you can read the main principle:&lt;br /&gt;&lt;br /&gt;&amp;quot;If an event can be caused by n different reasons, then the ratios between these causes&amp;#39; probabilities given the event are equal to the probabilities of events given these causes; and each cause&amp;#39;s existence probability equals to the probability of causes given this event divided by total probabilities of events given each one of these causes.&amp;quot;&lt;br /&gt;&lt;br /&gt;This is what we know today as Bayes&amp;#39; theorem:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149324
" title="https://stocksharp.com/file/149324
"&gt;https://stocksharp.com/file/149324
&lt;/a&gt;&lt;br /&gt;Where ```P(θ)``` is a uniform distribution.&lt;br /&gt;&lt;br /&gt;### Coin Experiment&lt;br /&gt;We will bring Bayesian statistics to the present by using Python and PyMC library, and conduct a simple experiment.&lt;br /&gt;&lt;br /&gt;Suppose a friend gives you a coin and asks if you think it&amp;#39;s a fair coin. Because he is in a hurry, he tells you that you can only toss the coin 10 times. As you can see, there is an unknown parameter ```p``` in this problem, which is the probability of getting heads in tossing coins, and we want to estimate the most likely value of the ```p```.&lt;br /&gt;&lt;br /&gt;(Note: We are not saying that parameter ```p``` is a random variable but rather that this parameter is fixed; we want to know where it&amp;#39;s most likely between.)&lt;br /&gt;&lt;br /&gt;To have different views on this problem, we will solve it under two different prior beliefs:&lt;br /&gt;&lt;br /&gt;- 1. You have no prior information about the fairness of the coin, so you assign an equal probability to ```p```. In this case, we will use what is called a non-informative prior because you haven&amp;#39;t added any information to your beliefs.&lt;br /&gt;&lt;br /&gt;- 2. From your experience, you know that even if a coin might be unfair, it&amp;#39;s hard to make it extremely unfair. Therefore, you believe the parameter ```p``` is unlikely to be less than 0.3 or more than 0.7. In this case, we will use an informative prior.&lt;br /&gt;&lt;br /&gt;For these two scenarios, our prior beliefs will be as follows:&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149325
" title="https://stocksharp.com/file/149325
"&gt;https://stocksharp.com/file/149325
&lt;/a&gt;&lt;br /&gt;After flipping a coin 10 times, you got heads twice. With this evidence, where are we likely to find our parameter ```p```?&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149326
" title="https://stocksharp.com/file/149326
"&gt;https://stocksharp.com/file/149326
&lt;/a&gt;&lt;br /&gt;As you can see, in the first case, our prior distribution of parameter ```p``` is concentrated at the maximum likelihood estimate (MLE) ```p=0.2```, which is a method similar to that used by the frequency school. The true unknown parameter will be within the 95% confidence interval, between 0.04 and 0.48.&lt;br /&gt;&lt;br /&gt;On the other hand, in cases where there is high confidence that parameter ```p``` should be between 0.3 and 0.7, we can see that the posterior distribution is around 0.4, much higher than what our MLE gives us. In this case, the true unknown parameter will be within a 95% confidence interval between 0.23 and 0.57.&lt;br /&gt;&lt;br /&gt;Therefore, in the first case scenario you would tell your friend with certainty that this coin isn&amp;#39;t fair but in another situation you&amp;#39;d say it&amp;#39;s uncertain whether or not it&amp;#39;s fair.&lt;br /&gt;&lt;br /&gt;As you can see even when faced with identical evidence (two heads out of ten tosses), under different prior beliefs results may vary greatly; one advantage of Bayesian statistics over traditional methods lies here: like scientific methodology it allows us to update our beliefs by combining them with new observations and evidence.&lt;br /&gt;&lt;br /&gt;### END&lt;br /&gt;In today&amp;#39;s article, we saw the origins of Bayesian statistics and its main contributors. Subsequently, there have been many other important contributors to this field of statistics (Jeffreys, Cox, Shannon and so on), reprinted from quantdare.com.&lt;br /&gt;&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y639wfXoqEZs3GnoRG_u0FEsc7r8-Fu3f7ARYJuPniwI7H7WkOzR-JqYMSLxlaelEjSkzb4YTUt6Y00geQTZ5Y6JsC1ekJ4CS-XzShWmjGIjSobM9kTNsNucSP3v7Mj6-cBa3yYRYw9tyaUDW6Gss4F4" title="https://blog.mathquant.com/2023/11/27/bayes-decoding-the-mystery-of-probability-exploring-the-mathematical-wisdom-behind-decision-making.html"&gt;https://blog.mathquant.c...ind-decision-making.html&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>https://stocksharp.com/topic/25578/</id>
    <title type="text">Which is More Suitable for Bottom Fishing, Low Market Value or Low Price?</title>
    <published>2024-03-19T05:15:22Z</published>
    <updated>2024-03-19T05:15:22Z</updated>
    <author>
      <name>FMZ Quant</name>
      <uri>https://stocksharp.com/users/185552/</uri>
      <email>info@stocksharp.com</email>
    </author>
    <category term="#trading" />
    <category term="#cryptocurrency" />
    <category term="#data" />
    <category term="#market" />
    <category term="#fmz" />
    <category term="#contract" />
    <category term="#binance" />
    <category term="#risk" />
    <category term="#bitcoin" />
    <category term="#indicator" />
    <content type="html">The previous articles &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAADHZKb-RfbDOdB_w3dJgQKtOFYh40OC5dg48A4wezcnse6T8uLbxzpcRWb5tsBTmb0" title="https://www.fmz.com/digest-topic/10286 "&gt;https://www.fmz.com/digest-topic/10286 &lt;/a&gt;and &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAADHZKb-RfbDOdB_w3dJgQKtOFYh40OC5dg48A4wezcnsc77TWG_lj0IXqHQAJmKZ30" title="https://www.fmz.com/digest-topic/10292 "&gt;https://www.fmz.com/digest-topic/10292 &lt;/a&gt;discussed the correlation between cryptocurrency price fluctuations and Bitcoin, as well as the impact of launching perpetual contracts on prices. This article will continue to explore another important factor affecting coin prices - market value. Readers familiar with quantitative trading should know that there is a most effective factor in the A-share market - small market value. The performance of small-cap stock rotation is very counter-intuitive, far exceeding various indicators, those interested can find out for themselves. So how does the price performance of small-cap or low-priced digital currencies look?&lt;br /&gt;&lt;br /&gt;### Data Processing and Collection&lt;br /&gt;This section uses the same data as the previous few articles, so it won&amp;#39;t be repeated here.&lt;br /&gt;&lt;br /&gt;### Performance of Low-Priced Currencies&lt;br /&gt;Low-priced currencies usually refer to digital currencies with lower unit prices. These currencies are more attractive to small investors due to their low prices. Most people only see many zeros in the price but don&amp;#39;t care much about the market value. Each unit reduction (zero) means that the price is multiplied by 10, which is very attractive to some people, but it may also be accompanied by higher price volatility and risk.&lt;br /&gt;&lt;br /&gt;As usual, let&amp;#39;s first look at the performance of the index, with two bull markets at the beginning and end of the year. Every week we select the 20 lowest priced currencies, and the results are very close to those of indicators, indicating that low prices do not provide too much additional return.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;h = 1&lt;br /&gt;lower_index = 1&lt;br /&gt;lower_index_list = [1]&lt;br /&gt;lower_symbols = df_close.iloc[0].dropna().sort_values()[:20].index&lt;br /&gt;lower_prices =  df_close.iloc[0][lower_symbols]&lt;br /&gt;date_list = [df_close.index[0]]&lt;br /&gt;for row in df_close.iterrows():&lt;br /&gt;    if h % 42 == 0:&lt;br /&gt;        date_list.append(row[0])&lt;br /&gt;        lower_index = lower_index * (row[1][lower_symbols] / lower_prices).mean()&lt;br /&gt;        lower_index_list.append(lower_index)&lt;br /&gt;        lower_symbols = row[1].dropna().sort_values()[:20].index&lt;br /&gt;        lower_prices = row[1][lower_symbols]&lt;br /&gt;    h += 1&lt;br /&gt;pd.DataFrame(data=lower_index_list,index=date_list).plot(figsize=(12,5),grid=True);&lt;br /&gt;total_index.plot(figsize=(12,5),grid=True); #overall index&lt;br /&gt;```&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149322
" title="https://stocksharp.com/file/149322
"&gt;https://stocksharp.com/file/149322
&lt;/a&gt;&lt;br /&gt;### Performance of Small Market Cap Currencies&lt;br /&gt;Due to the constantly changing circulation, the market value calculation here uses the total supply volume, with data sourced from Coincapmarket. Those who need it can apply for a key. A total of 1000 currencies with the highest market values were selected. Due to naming methods and unknown total supplies, we obtained 205 currencies that overlap with Binance perpetual contracts.&lt;br /&gt;```&lt;br /&gt;import requests&lt;br /&gt;&lt;br /&gt;def get_latest_crypto_listings(api_key):&lt;br /&gt;    url = &amp;quot;https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?limit=1000&amp;quot;&lt;br /&gt;    headers = {&lt;br /&gt;        &amp;#39;Accepts&amp;#39;: &amp;#39;application/json&amp;#39;,&lt;br /&gt;        &amp;#39;X-CMC_PRO_API_KEY&amp;#39;: api_key,&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    response = requests.get(url, headers=headers)&lt;br /&gt;    if response.status_code == 200:&lt;br /&gt;        return response.json()&lt;br /&gt;    else:&lt;br /&gt;        return f&amp;quot;Error: {response.status_code}&amp;quot;&lt;br /&gt;&lt;br /&gt;# Use your API key&lt;br /&gt;api_key = &amp;quot;xxx&amp;quot;&lt;br /&gt;coin_data = get_latest_crypto_listings(api_key)&lt;br /&gt;supplys = {d[&amp;#39;symbol&amp;#39;]: d[&amp;#39;total_supply&amp;#39;] for d in coin_data[&amp;#39;data&amp;#39;]}&lt;br /&gt;include_symbols = [s for s in list(df_close.columns)  if s in supplys and supplys[s] &amp;gt; 0 ]&lt;br /&gt;```&lt;br /&gt;An index is drawn from the 10 cryptocurrencies with the lowest market value each week, and compared with the overall index. It can be seen that small-cap cryptocurrencies performed slightly better than the overall index in the bull market at the beginning of the year. However, they started to rise ahead of time during September-October&amp;#39;s sideways movement, and their final increase far exceeded that of the total index.&lt;br /&gt;&lt;br /&gt;Small-cap cryptocurrencies are often considered to have higher growth potential. Because their market values are low, even relatively small inflows of funds can cause significant price changes. This potential for high returns attracts investors and speculators&amp;#39; attention. When there is a stir at bottom markets, due to less resistance to rise, small-cap currencies often take off first and may even indicate that a general rising bull market is about to begin.&lt;br /&gt;&lt;br /&gt;```&lt;br /&gt;df_close_include = df_close[include_symbols]&lt;br /&gt;df_norm = df_close_include/df_close_include.fillna(method=&amp;#39;bfill&amp;#39;).iloc[0] #Normalization&lt;br /&gt;total_index = df_norm.mean(axis=1)&lt;br /&gt;h = 1&lt;br /&gt;N = 10&lt;br /&gt;lower_index = 1&lt;br /&gt;lower_index_list = [1]&lt;br /&gt;lower_symbols = df_close_include.iloc[0].dropna().multiply(pd.Series(supplys)[include_symbols], fill_value=np.nan).sort_values()[:N].index&lt;br /&gt;lower_prices =  df_close_include.iloc[0][lower_symbols]&lt;br /&gt;date_list = [df_close_include.index[0]]&lt;br /&gt;for row in df_close_include.iterrows():&lt;br /&gt;    if h % 42 == 0:&lt;br /&gt;        date_list.append(row[0])&lt;br /&gt;        lower_index = lower_index * (row[1][lower_symbols] / lower_prices).mean()&lt;br /&gt;        lower_index_list.append(lower_index)&lt;br /&gt;        lower_symbols = row[1].dropna().multiply(pd.Series(supplys)[include_symbols], fill_value=np.nan).sort_values()[:N].index&lt;br /&gt;        lower_prices = row[1][lower_symbols]&lt;br /&gt;    h += 1&lt;br /&gt;pd.DataFrame(data=lower_index_list,index=date_list).plot(figsize=(12,5),grid=True);&lt;br /&gt;total_index.plot(figsize=(12,5),grid=True);&lt;br /&gt;```&lt;br /&gt;&lt;a href="https://stocksharp.com/file/149323
" title="https://stocksharp.com/file/149323
"&gt;https://stocksharp.com/file/149323
&lt;/a&gt;&lt;br /&gt;### Summary&lt;br /&gt;This article, through data analysis, found that low-priced currencies did not provide additional returns and their performance was close to the market index. The performance of small market cap currencies significantly exceeded the overall index increase. Below is a list of contract currencies with a market value less than 100 million U for reference, even though we are currently in a bull market.&lt;br /&gt;&lt;br /&gt;&amp;#39;HOOK&amp;#39;: 102007225,&lt;br /&gt;&amp;#39;SLP&amp;#39;: 99406669,&lt;br /&gt;&amp;#39;NMR&amp;#39;: 97617143,&lt;br /&gt;&amp;#39;RDNT&amp;#39;: 97501392,&lt;br /&gt;&amp;#39;MBL&amp;#39;: 93681270,&lt;br /&gt;&amp;#39;OMG&amp;#39;: 89129884,&lt;br /&gt;&amp;#39;NKN&amp;#39;: 85700948,&lt;br /&gt;&amp;#39;DENT&amp;#39;: 84558413,&lt;br /&gt;&amp;#39;ALPHA&amp;#39;: 81367392,&lt;br /&gt;&amp;#39;RAD&amp;#39;: 80849568,&lt;br /&gt;&amp;#39;HFT&amp;#39;: 79696303,&lt;br /&gt;&amp;#39;STMX&amp;#39;: 79472000,&lt;br /&gt;&amp;#39;ALICE&amp;#39;: 74615631,&lt;br /&gt;&amp;#39;OGN&amp;#39;: 74226686,&lt;br /&gt;&amp;#39;GTC&amp;#39;: 72933069,&lt;br /&gt;&amp;#39;MAV&amp;#39;: 72174400,&lt;br /&gt;&amp;#39;CTK&amp;#39;: 72066028,&lt;br /&gt;&amp;#39;UNFI&amp;#39;: 71975379,&lt;br /&gt;&amp;#39;OXT&amp;#39;: 71727646,&lt;br /&gt;&amp;#39;COTI&amp;#39;: 71402243,&lt;br /&gt;&amp;#39;HIGH&amp;#39;: 70450329,&lt;br /&gt;&amp;#39;DUSK&amp;#39;: 69178891,&lt;br /&gt;&amp;#39;ARKM&amp;#39;: 68822057,&lt;br /&gt;&amp;#39;HIFI&amp;#39;: 68805227,&lt;br /&gt;&amp;#39;CYBER&amp;#39;: 68264478,&lt;br /&gt;&amp;#39;BADGER&amp;#39;: 67746045,&lt;br /&gt;&amp;#39;AGLD&amp;#39;: 66877113,&lt;br /&gt;&amp;#39;LINA&amp;#39;: 62674752,&lt;br /&gt;&amp;#39;PEOPLE&amp;#39;: 62662701,&lt;br /&gt;&amp;#39;ARPA&amp;#39;: 62446098,&lt;br /&gt;&amp;#39;SPELL&amp;#39;: 61939184,&lt;br /&gt;&amp;#39;TRU&amp;#39;: 60944721,&lt;br /&gt;&amp;#39;REN&amp;#39;: 59955266,&lt;br /&gt;&amp;#39;BIGTIME&amp;#39;: 59209269,&lt;br /&gt;&amp;#39;XVG&amp;#39;: 57470552,&lt;br /&gt;&amp;#39;TLM&amp;#39;: 56963184,&lt;br /&gt;&amp;#39;BAKE&amp;#39;: 52022509,&lt;br /&gt;&amp;#39;COMBO&amp;#39;: 47247951,&lt;br /&gt;&amp;#39;DAR&amp;#39;: 47226484,&lt;br /&gt;&amp;#39;FLM&amp;#39;: 45542629,&lt;br /&gt;&amp;#39;ATA&amp;#39;: 44190701,&lt;br /&gt;&amp;#39;MDT&amp;#39;: 42774267,&lt;br /&gt;&amp;#39;BEL&amp;#39;: 42365397,&lt;br /&gt;&amp;#39;PERP&amp;#39;: 42095057,&lt;br /&gt;&amp;#39;REEF&amp;#39;: 41151983,&lt;br /&gt;&amp;#39;IDEX&amp;#39;: 39463580,&lt;br /&gt;&amp;#39;LEVER&amp;#39;: 38609947,&lt;br /&gt;&amp;#39;PHB&amp;#39;: 36811258,&lt;br /&gt;&amp;#39;LIT&amp;#39;: 35979327,&lt;br /&gt;&amp;#39;KEY&amp;#39;: 31964126,&lt;br /&gt;&amp;#39;BOND&amp;#39;: 29549985,&lt;br /&gt;&amp;#39;FRONT&amp;#39;: 29130102,&lt;br /&gt;&amp;#39;TOKEN&amp;#39;: 28047786,&lt;br /&gt;&amp;#39;AMB&amp;#39;: 24484151&lt;br /&gt;From: &lt;a target="_blank" rel="nofollow" href="https://stocksharp.com/away/?u=AQAAAAAAAAAezbpL9G-wNBo0jpp0vfUOQlbPNxIPafGj0KHUDS3Y6yakhZVRR2EuBPlrJniJl4yzYQNJoE9ijH27m1Norkq9cJx6uDntB1WvRbBs5QeHW70IA9FUvA1MzSOxGOwkN2m0hRm3wSK9DiRPBYiYtMlA1PyuvkBRgHjHc-mZv46XOw" title="https://blog.mathquant.com/2023/12/04/which-is-more-suitable-for-bottom-fishing-low-market-value-or-low-price.html"&gt;https://blog.mathquant.c...-value-or-low-price.html&lt;/a&gt;</content>
  </entry>
</feed>