Tokenize a smart contract managed multiple moving average crossover trading strategy with Set Protocol V2 and Uniswap V3 oracles.
npm install @openzeppelin/contracts@3.1.0npm install @setprotocol/set-protocol-v2npm install @setprotocol/index-coop-contractsnpm install @uniswap/v3-coreThe Indicator contract utilizes a Uniswap V3 Pool as an on-chain oracle.
The Manager contract has two key functions for the Keeper
getIndicatorIsChanged(), which can be called for free and checks if theIndicatorsignal has changed since the last rebalancerebalance(), which can only be called by theKeeperand utilizes theTrade Moduleto change the allocation of theSet Token
The Keeper can be set to periodically call getIndicatorIsChanged() for free, and subsequently call rebalance() if the indicator signal has changed.
Consider two groups of moving averages: S, a group of n short term moving averages and L, a group of m long term moving averages.
S = [S1, S2, ..., Sn]
L = [L1, L2, ..., Lm]
An indicator MMA() can be constructed as follows
- bullish if min(S) > max(L)
- bearish if max(S) < min(L)
- uncertain otherwise
The uncertain case, when the short term and long term groups of moving averages overlap, can be considered either bullish (risk-on) or bearish (risk-off) depending on manager preference.
This indicator uses a Uniswap V3 pool as on-chain oracle by deriving the arithmetic mean tick over an interval and using that as a moving average. The arithmetic mean tick over a given interval is derived with values stored in the tick accumulator.
With a risk-on asset (ex: $ETH) and a risk-off asset (ex: $USDC) the trading strategy is as follows
- hold $ETH when MMA() using the Uniswap V3 ETHUSDC pool is bullish
- hold $USDC when MMA() using the Uniswap V3 ETHUSDC pool is bearish or uncertain
- Place calls to tradeModule in a more optimal way (reduce slippage)
- Gas optimization in indicator
- Add Aave/Compound lending (wrapModule) to manager
