From 01f3886447b12ee504575609550a7d09a1d6bec9 Mon Sep 17 00:00:00 2001 From: dcatki <42241987+dcatki@users.noreply.github.com> Date: Tue, 9 Jul 2024 00:15:45 +0100 Subject: [PATCH 1/2] Create wlth-grid-recharging-exponential-amount.rain # Strat: Recharging grid exponential amount growth # Recharging grid trading with exponential amount growth is a strategy that involves placing buy and sell # orders at predetermined intervals above and below a set price # level to profit from market volatility. Unlike traditional grid trading, # where each trade clears only once, recharging grid trading continuously recharges # and executes trades as long as liquidity is provided. In this method, the amount levels # within the grid grow exponentially rather than linearly. This creates a dynamic and perpetual # grid of orders, capturing profits from regular price fluctuations without predicting market direction. # The exponential growth of amount levels allows the grid to adapt to larger market movements # more effectively. This method is particularly effective in volatile markets, where prices experience # frequent and significant movements, allowing liquidity providers to provide liquidity at the # best prices and avoid being drained by sudden movements. --- ...th-grid-recharging-exponential-amount.rain | 499 ++++++++++++++++++ 1 file changed, 499 insertions(+) create mode 100644 strategies/wlth/wlth-grid-recharging-exponential-amount.rain diff --git a/strategies/wlth/wlth-grid-recharging-exponential-amount.rain b/strategies/wlth/wlth-grid-recharging-exponential-amount.rain new file mode 100644 index 0000000..4833e11 --- /dev/null +++ b/strategies/wlth/wlth-grid-recharging-exponential-amount.rain @@ -0,0 +1,499 @@ +# Strat: Recharging grid exponential amount growth +# Recharging grid trading with exponential amount growth is a strategy that involves placing buy and sell +# orders at predetermined intervals above and below a set price +# level to profit from market volatility. Unlike traditional grid trading, +# where each trade clears only once, recharging grid trading continuously recharges +# and executes trades as long as liquidity is provided. In this method, the amount levels +# within the grid grow exponentially rather than linearly. This creates a dynamic and perpetual +# grid of orders, capturing profits from regular price fluctuations without predicting market direction. +# The exponential growth of amount levels allows the grid to adapt to larger market movements +# more effectively. This method is particularly effective in volatile markets, where prices experience +# frequent and significant movements, allowing liquidity providers to provide liquidity at the +# best prices and avoid being drained by sudden movements. +# +# Target Network: Base +# Quote (Input / Incoming): USDC or WLTH +# Base (Output / Outgoing): WLTH or USDC +# Token contract: https://basescan.org/address/0x99b2B1A2aDB02B38222ADcD057783D7e5D1FCC7D +# Token github: NA +# Liquidity protocol: Uniswap V3 +# Liquidity pool address: https://www.dextools.io/app/en/base/pair-explorer/0x1536ee1506e24e5a36be99c73136cd82907a902e?t=1717921711270 +# Liquidity pool fee: 0.3% + +networks: + base-community: + rpc: https://mainnet.base.org + chain-id: 8453 + network-id: 8453 + currency: ETH + +subgraphs: + base-community: https://api.thegraph.com/subgraphs/name/h20liquidity/base-0x2aee87 + +orderbooks: + base-community: + address: 0x2AeE87D75CD000583DAEC7A28db103B1c0c18b76 + network: base-community + subgraph: base-community + +deployers: + base-community: + address: 0x56394785a22b3BE25470a0e03eD9E0a939C47b9b + network: base-community + +tokens: + base-wlth: + network: base-community + address: 0x99b2B1A2aDB02B38222ADcD057783D7e5D1FCC7D + base-usdc: + network: base-community + address: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 + +orders: + # vault-id generated with `openssl rand -hex 32` + base-wlth-sell: + orderbook: base-community + inputs: + - token: base-usdc + vault-id: 0x28e042e95154e0eaa486f57c65f44e3fd2ea345bb61aca594e074fd4028b2f9d + outputs: + - token: base-wlth + vault-id: 0x28e042e95154e0eaa486f57c65f44e3fd2ea345bb61aca594e074fd4028b2f9d + base-wlth-buy: + orderbook: base-community + inputs: + - token: base-wlth + vault-id: 0x85bdfb90f2cabd6661c1bce26962cb35b8c1f43687641f4a4aa58066be447b52 + outputs: + - token: base-usdc + vault-id: 0x85bdfb90f2cabd6661c1bce26962cb35b8c1f43687641f4a4aa58066be447b52 + +scenarios: + grid-recharging: + network: base-community + deployer: base-community + orderbook: base-community + bindings: + # The uniswap words are only requiWLTH if there is a conversion between + # the input/output token and some external price. Typically this is + # not the case as the io-ratio is defined in terms of the input/output + # token and the io-ratio-multiplier is set to the identity function. + uniswap-words: 0xD6B34F97d4A8Cb38D0544dB241CB3f335866f490 + + # Uniswap v3 factory contract address and corresponding init code hash. + # If the factory address and the init code aren't available as a literals + # then non-literal address and hash value can be given as bindings. + uniswap-v3-factory: 0x33128a8fC17869897dcE68Ed026d694621f6FDfD + uniswap-v3-init-code: '[uniswap-v3-init-code]' + + # Orderbook subparser for orderbook words. + orderbook-subparser: 0x8D96ea3EF24D7123882c51CE4325b89bc0d63f9e + scenarios: + buy: + bindings: + # WLTH/USDC base ratio and increment. + io-ratio-base: 40 + io-ratio-growth: 2.5 + + # Base amount of USDC tokens to offer and increment. + tranche-size-base: 5 + tranche-size-growth: 1 + + scenarios: + grid: + bindings: + + # How far we move through tranche space in a second. + # 1 is a whole tranche, so we divide 1 by the number of seconds + # per recharge to calculate the per-second rate. + # Examples: + # 172800 seconds in 2 days, 48 hours = 1 / 172800 = 0.000005787037037037 + # 86400 seconds in 1 day, 24 hours = 1 / 86400 = 0.000011574074074074 + # 43200 seconds in 12 hours, 12 hours = 1 / 43200 = 0.000023148148148148 + # 3600 seconds in 1 hour, 1 hour = 1 / 3600 = 0.000277777777777777 + tranche-space-per-second: 0.000011574074074074 + + tranche-space-recharge-delay: 300 + min-tranche-space-diff: 0.1 + tranche-space-snap-threshold: 0.01 + io-ratio-multiplier: '''io-ratio-multiplier-identity' + amount-is-output: 1 + tranche-space-shyness: 0 + initial-tranche-space: 0 + io-ratio-expr: '''linear-growth' + tranche-size-expr: '''exponential-growth' + scenarios: + prod: + bindings: + get-last-tranche: '''get-last-tranche-prod' + set-last-tranche: '''set-last-tranche-prod' + plottables: '''plottables-prod' + tranche-space-shyness: 0 + initial-tranche-space: 0 + init: + runs: 100 + bindings: + get-last-tranche: '''get-last-tranche-test-init' + set-last-tranche: '''set-last-tranche-test' + plottables: '''plottables-test' + test-last-update-time: 0 + test-now: 0 + test: + runs: 10000 + bindings: + get-last-tranche: '''get-last-tranche-test' + set-last-tranche: '''set-last-tranche-test' + plottables: '''plottables-test' + max-test-tranche-space: 20 + test-last-update-time: 0 + test-now: 0 + sell: + bindings: + # USDC/WLTH base ratio and increment. + io-ratio-base: 0.020 + io-ratio-growth: 0.002 + + # Base amount of USDC tokens to received and increment. + tranche-size-base: 5 + tranche-size-growth: 1 + + scenarios: + grid: + bindings: + tranche-space-per-second: 0 + tranche-space-recharge-delay: 300 + min-tranche-space-diff: 0.1 + tranche-space-snap-threshold: 0.01 + io-ratio-multiplier: '''io-ratio-multiplier-identity' + amount-is-output: 0 + tranche-space-shyness: 0 + initial-tranche-space: 0 + io-ratio-expr: '''linear-growth' + tranche-size-expr: '''exponential-growth' + scenarios: + prod: + bindings: + get-last-tranche: '''get-last-tranche-prod' + set-last-tranche: '''set-last-tranche-prod' + plottables: '''plottables-prod' + tranche-space-shyness: 0 + initial-tranche-space: 0 + init: + runs: 100 + bindings: + get-last-tranche: '''get-last-tranche-test-init' + set-last-tranche: '''set-last-tranche-test' + plottables: '''plottables-test' + test-last-update-time: 0 + test-now: 0 + test: + runs: 10000 + bindings: + get-last-tranche: '''get-last-tranche-test' + set-last-tranche: '''set-last-tranche-test' + plottables: '''plottables-test' + max-test-tranche-space: 20 + test-last-update-time: 0 + test-now: 0 + +charts: + base-wlth-buy-deployment: + scenario: grid-recharging.buy.grid.init + metrics: + - label: Initial USDC sold + value: 0.6 + description: 'Amount of USDC sold to buy WLTH in the first tranche (stack item 0.6)' + - label: Initial WLTH bought + value: 0.5.2 + description: 'Amount of WLTH purchased in the first tranche (stack item 0.5.2)' + - label: Initial io-ratio + value: 0.7 + description: '# WLTH purchased per USDC spent (stack item 0.7)' + - label: Starting tranche + value: 0.2.0 + description: 'This strategy starts executing buys at the initial tranche (stack item 0.2.0)' + - label: Initial buy price + value: 0.5.3 + precision: 4 + unit-suffix: " USDC" + description: 'Price you pay for 1 WLTH in USDC, visible on dextools (stack item 0.5.3)' + plots: + + buy-simulation: + scenario: grid-recharging.buy.grid.test + plots: + USDT sold per tranche: + x: + label: 'Tranche space' + y: + label: 'USDT spent' + marks: + - type: line + options: + x: 0.0 + y: 0.6 + WLTH bought per tranche: + x: + label: 'Tranche space' + y: + label: 'WLTH bought' + marks: + - type: line + options: + x: 0.0 + y: 0.5.2 + 'io-ratio per tranche': + subtitle: 'Ratio of WLTH bought per 1 USDT sold per tranche' + x: + label: 'Tranche space' + y: + label: 'WLTH bought per 1 USDT' + marks: + - type: line + options: + x: 0.0 + y: 0.7 + buy price by tranche: + subtitle: 'Price paid for 1 WLTH in USDT, visible on dextools as WLTH/USDT pair' + x: + label: 'Tranche space' + y: + label: '1 WLTH priced in USDT' + marks: + - type: line + options: + x: 0.0 + y: 0.5.3 + + base-wlth-sell-deployment: + scenario: grid-recharging.sell.grid.init + metrics: + - label: Initial WLTH sold + value: 0.6 + description: 'Amount of WLTH sold for USDC in the first tranche (stack item 0.6)' + - label: Initial USDC bought + value: 0.5.2 + description: 'Amount of USDC purchased by selling WLTH in the first tranche (stack item 0.5.2)' + - label: Initial io-ratio + value: 0.7 + description: '# USDC purchased per WLTH spent (stack item 0.7)' + - label: Starting tranche + value: 0.2.0 + description: 'This strategy starts executing sells at the initial tranche (stack item 0.2.0)' + - label: Initial sell price + value: 0.7 + precision: 4 + unit-suffix: "USDC" + description: 'Price you pay for 1 WLTH in USDC, visible on dextools (stack item 0.7)' + plots: + + sell-simulation: + scenario: grid-recharging.sell.grid.test + plots: + WLTH sold per tranche: + x: + label: 'Tranche space' + y: + label: 'WLTH spent' + marks: + - type: line + options: + x: 0.0 + y: 0.6 + USDC bought per tranche: + x: + label: 'Tranche space' + y: + label: 'USDC bought' + marks: + - type: line + options: + x: 0.0 + y: 0.5.2 + 'io-ratio per tranche': + subtitle: 'Ratio of USDC bought per 1 WLTH sold per tranche' + x: + label: 'Tranche space' + y: + label: 'WLTH bought per 1 USDC' + marks: + - type: line + options: + x: 0.0 + y: 0.7 + sell price by tranche: + subtitle: 'Price paid for 1 WLTH in USDC, visible on dextools as WLTH/USDC pair' + x: + label: 'Tranche space' + y: + label: '1 WLTH priced in USDC' + marks: + - type: line + options: + x: 0.0 + y: 0.7 + +deployments: + base-wlth-buy: + scenario: grid-recharging.buy.grid.prod + order: base-wlth-buy + base-wlth-sell: + scenario: grid-recharging.sell.grid.prod + order: base-wlth-sell +--- +#tranche-space-per-second !The amount of tranche space that is recharged per second. +#tranche-space-recharge-delay !The duration in seconds that no recharging occurs after a trade occurs. + +#tranche-size-expr !The binding to get the tranche size for the current tranche space. +#tranche-size-base !Base tranche size is the size of the smallest tranche, denominated in output token. +#tranche-size-growth !The exponential growth factor of the size of each tranche. E.g. 0.01 is 1% output amount growth per tranche. + +#io-ratio-expr !The binding to get the IO ratio for the current tranche space. +#io-ratio-base !The base IO ratio, as a decimal 18 fixed point number. This is the IO ratio at tranche space 0 and grows according to the growth factor per tranche. +#io-ratio-growth !The exponential growth factor of the IO ratio. E.g. 0.01 is 1% io-ratio growth per tranche. + +#reference-stable !The stable token that is used as a reference for the TWAP to offer dollar equivalent conversions. +#reference-stable-decimals !The number of decimals of the reference stable token. +#reference-reserve !The token that will be used to compare against the reference stable token to calculate the TWAP for dollar equivalent conversions. +#reference-reserve-decimals !The number of decimals of the reserve token. +#twap-duration !The duration in seconds of the TWAP window for dollar equivalence conversions. +#twap-fee !The uniswap fee tier to use for the TWAP. + +#min-tranche-space-diff !The minimum tranche space difference that is allowed per trade. Prevents dusting the strat to stop it recharging. +#tranche-space-snap-threshold !The threshold in tranche space to snap to the nearest tranche to avoid dust issues at the edges. + +#initial-tranche-space !The initial tranche space when the order is first deployed. +#get-last-tranche !The binding to get the last tranche space and update time. +#set-last-tranche !The binding to set the last tranche space and update time. + +#test-tranche-space-before !Returned by get-test-last-tranche to allow the tranche space before to be bound for testing. +#test-last-update-time !Returned by get-test-last-tranche to allow the last update time to be bound for testing. +#test-now !Returned by get-test-last-tranche to allow the current time to be bound for testing. + +#io-ratio-multiplier !The binding to get the IO ratio multiplier. + +#amount-is-output !Whether the amount is an output or input amount. Non-zero means output (i.e. normal orderbook behaviour), zero means input. + +#init-key "init" +#tranche-space-key "tranche-space" +#update-time-key "update-time" + +#plottables !The binding for additional things we want to plot during testing. + +#uniswap-words !The subparser for the Uniswap words +#uniswap-v3-factory !Uniswap v3 factory address. +#uniswap-v3-init-code !Uniswap v3 init code hash. +#orderbook-subparser !The subparser for the Orderbook + +#plottables-test + amount + io-ratio:, + input-amount: mul(amount io-ratio), + effective-price: inv(io-ratio); + +#plottables-prod + amount + io-ratio:; + +#get-last-tranche-prod + is-initialized: get(hash(order-hash() init-key)), + tranche-space-before: if( + is-initialized + get(hash(order-hash() tranche-space-key)) + initial-tranche-space + ), + last-update-time: if( + is-initialized + get(hash(order-hash() update-time-key)) + now() + ), + current-time: now(); + +#tranche-space-shyness !The shyness of the liquidity in tranches. E.g. 0.9 is 90% shy. +#set-last-tranche-prod + tranche-space current-time:, + shy-tranche-space: if( + is-zero(frac(tranche-space)) + add(tranche-space tranche-space-shyness) + tranche-space), + :set(hash(order-hash() init-key) 1), + :set(hash(order-hash() tranche-space-key) shy-tranche-space), + :set(hash(order-hash() update-time-key) current-time); + +/* Forward the bindings through as is to the caller. */ +#max-test-tranche-space !The maximum tranche space that will appear on the test chart. +#get-last-tranche-test + tranche-space-before: mod(test-tranche-space-before max-test-tranche-space), + last-update-time: test-last-update-time, + current-time: test-now; +#get-last-tranche-test-init + tranche-space-before: initial-tranche-space, + last-update-time: test-last-update-time, + current-time: test-now; +/* There's nothing to set if we're just rebinding in tests. */ +#set-last-tranche-test + tranche-space current-time:; + +#exponential-growth + base rate t:, + _: exponential-growth(base rate t); + +#linear-growth + base rate t:, + _: linear-growth(base rate t); + +#constant-growth + base _ _:, + _: base; + +#calculate-tranche + tranche-space-before + last-update-time + current-time: call<'get-last-tranche>(), + recharge-duration: saturating-sub(current-time add(last-update-time tranche-space-recharge-delay)), + recharged-tranche-space: mul(recharge-duration tranche-space-per-second), + /* repeat current-time for easy access by callers */ + _: current-time, + tranche-space-now: saturating-sub(tranche-space-before recharged-tranche-space), + tranche-space-available: headroom(tranche-space-now), + tranche-total-size: call<'tranche-size-expr>(tranche-size-base tranche-size-growth floor(tranche-space-now)); + +#io-ratio-multiplier-sell + multiplier: uniswap-v3-twap-output-ratio(reference-stable reference-reserve twap-duration 0 uniswap-v3-factory uniswap-v3-init-code twap-fee); + +#io-ratio-multiplier-buy + multiplier: uniswap-v3-twap-output-ratio(reference-reserve reference-stable twap-duration 0 uniswap-v3-factory uniswap-v3-init-code twap-fee); + +#io-ratio-multiplier-identity + multiplier: 1; + +#calculate-io + using-words-from uniswap-words orderbook-subparser + tranche-space-now + tranche-space-available + tranche-total-size: call<'calculate-tranche>(), + tranche-io-ratio: call<'io-ratio-expr>(io-ratio-base io-ratio-growth floor(tranche-space-now)), + final-io-ratio: mul(tranche-io-ratio call<'io-ratio-multiplier>()), + amount-available: mul(tranche-total-size tranche-space-available), + amount: if(amount-is-output amount-available div(amount-available final-io-ratio)), + io-ratio: final-io-ratio, + :call<'plottables>(amount io-ratio); + +#handle-io + current-time + tranche-space-before + _ + tranche-total-size: call<'calculate-tranche>(), + tranche-amount-diff: if( + amount-is-output + scale-18-dynamic(output-token-decimals() uint256-output-vault-decrease()) + scale-18-dynamic(input-token-decimals() uint256-input-vault-increase())), + tranche-space-diff: div(tranche-amount-diff tranche-total-size), + tranche-space-after: add(tranche-space-before tranche-space-diff), + /* Snap tranche space to the nearest tranche to avoid dust issues at the edges */ + tranche-space-after-snapped: snap-to-unit(tranche-space-snap-threshold tranche-space-after), + :ensure( + greater-than-or-equal-to(tranche-space-after-snapped add(tranche-space-before min-tranche-space-diff)) + "Minimum trade size not met." + ), + :call<'set-last-tranche>(tranche-space-after-snapped current-time); From 07559c020ccbea04a5b4ac55f472cad3f85ca49c Mon Sep 17 00:00:00 2001 From: Siddharth2207 Date: Tue, 9 Jul 2024 21:15:03 +0530 Subject: [PATCH 2/2] exp amt --- ...th-grid-recharging-exponential-amount.rain | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/strategies/wlth/wlth-grid-recharging-exponential-amount.rain b/strategies/wlth/wlth-grid-recharging-exponential-amount.rain index 4833e11..2a7c75a 100644 --- a/strategies/wlth/wlth-grid-recharging-exponential-amount.rain +++ b/strategies/wlth/wlth-grid-recharging-exponential-amount.rain @@ -69,7 +69,7 @@ orders: vault-id: 0x85bdfb90f2cabd6661c1bce26962cb35b8c1f43687641f4a4aa58066be447b52 scenarios: - grid-recharging: + grid-recharging-exp-amt: network: base-community deployer: base-community orderbook: base-community @@ -97,22 +97,21 @@ scenarios: # Base amount of USDC tokens to offer and increment. tranche-size-base: 5 - tranche-size-growth: 1 + tranche-size-growth: 0.05 + + # How far we move through tranche space in a second. + # 1 is a whole tranche, so we divide 1 by the number of seconds + # per recharge to calculate the per-second rate. + # Examples: + # 172800 seconds in 2 days, 48 hours = 1 / 172800 = 0.000005787037037037 + # 86400 seconds in 1 day, 24 hours = 1 / 86400 = 0.000011574074074074 + # 43200 seconds in 12 hours, 12 hours = 1 / 43200 = 0.000023148148148148 + # 3600 seconds in 1 hour, 1 hour = 1 / 3600 = 0.000277777777777777 + tranche-space-per-second: 0.000011574074074074 scenarios: grid: bindings: - - # How far we move through tranche space in a second. - # 1 is a whole tranche, so we divide 1 by the number of seconds - # per recharge to calculate the per-second rate. - # Examples: - # 172800 seconds in 2 days, 48 hours = 1 / 172800 = 0.000005787037037037 - # 86400 seconds in 1 day, 24 hours = 1 / 86400 = 0.000011574074074074 - # 43200 seconds in 12 hours, 12 hours = 1 / 43200 = 0.000023148148148148 - # 3600 seconds in 1 hour, 1 hour = 1 / 3600 = 0.000277777777777777 - tranche-space-per-second: 0.000011574074074074 - tranche-space-recharge-delay: 300 min-tranche-space-diff: 0.1 tranche-space-snap-threshold: 0.01 @@ -155,12 +154,21 @@ scenarios: # Base amount of USDC tokens to received and increment. tranche-size-base: 5 - tranche-size-growth: 1 + tranche-size-growth: 0.05 + + # How far we move through tranche space in a second. + # 1 is a whole tranche, so we divide 1 by the number of seconds + # per recharge to calculate the per-second rate. + # Examples: + # 172800 seconds in 2 days, 48 hours = 1 / 172800 = 0.000005787037037037 + # 86400 seconds in 1 day, 24 hours = 1 / 86400 = 0.000011574074074074 + # 43200 seconds in 12 hours, 12 hours = 1 / 43200 = 0.000023148148148148 + # 3600 seconds in 1 hour, 1 hour = 1 / 3600 = 0.000277777777777777 + tranche-space-per-second: 0.000011574074074074 scenarios: grid: bindings: - tranche-space-per-second: 0 tranche-space-recharge-delay: 300 min-tranche-space-diff: 0.1 tranche-space-snap-threshold: 0.01 @@ -198,7 +206,7 @@ scenarios: charts: base-wlth-buy-deployment: - scenario: grid-recharging.buy.grid.init + scenario: grid-recharging-exp-amt.buy.grid.init metrics: - label: Initial USDC sold value: 0.6 @@ -220,7 +228,7 @@ charts: plots: buy-simulation: - scenario: grid-recharging.buy.grid.test + scenario: grid-recharging-exp-amt.buy.grid.test plots: USDT sold per tranche: x: @@ -266,7 +274,7 @@ charts: y: 0.5.3 base-wlth-sell-deployment: - scenario: grid-recharging.sell.grid.init + scenario: grid-recharging-exp-amt.sell.grid.init metrics: - label: Initial WLTH sold value: 0.6 @@ -288,7 +296,7 @@ charts: plots: sell-simulation: - scenario: grid-recharging.sell.grid.test + scenario: grid-recharging-exp-amt.sell.grid.test plots: WLTH sold per tranche: x: @@ -335,10 +343,10 @@ charts: deployments: base-wlth-buy: - scenario: grid-recharging.buy.grid.prod + scenario: grid-recharging-exp-amt.buy.grid.prod order: base-wlth-buy base-wlth-sell: - scenario: grid-recharging.sell.grid.prod + scenario: grid-recharging-exp-amt.sell.grid.prod order: base-wlth-sell --- #tranche-space-per-second !The amount of tranche space that is recharged per second.