- Add PositionTracker.sol: tracks position lifecycle (open/close per recenter), records tick ranges, liquidity, entry/exit blocks/timestamps, token amounts (via LiquidityAmounts math), fees (proportional to liquidity share), IL (LP exit value − HODL value at exit price), and net P&L per position. Aggregates total fees, cumulative IL, net P&L, rebalance count, Anchor time-in-range, and capital efficiency accumulators. Logs with [TRACKER][TYPE] prefix; emits cumulative P&L every 500 blocks. - Modify StrategyExecutor.sol: add IUniswapV3Pool + token0isWeth to constructor (creates PositionTracker internally), call tracker.notifyBlock() on every block for time-in-range, and call tracker.recordRecenter() on each successful recenter. logSummary() now delegates to tracker.logFinalSummary(). - Modify BacktestRunner.s.sol: pass sp.pool and token0isWeth to StrategyExecutor constructor; log tracker address. - forge fmt: reformat all backtesting scripts and affected src/test files to project style (number_underscore=thousands, multiline_func_header=all). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a491ecb7d9
commit
cfcf750084
12 changed files with 666 additions and 244 deletions
|
|
@ -1,15 +1,16 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import { BacktestKraiken } from "./BacktestKraiken.sol";
|
||||
|
||||
import { EventReplayer } from "./EventReplayer.sol";
|
||||
import { KrAIkenDeployer, KrAIkenSystem } from "./KrAIkenDeployer.sol";
|
||||
import { MockToken } from "./MockToken.sol";
|
||||
import { ShadowPool, ShadowPoolDeployer } from "./ShadowPoolDeployer.sol";
|
||||
import { StrategyExecutor } from "./StrategyExecutor.sol";
|
||||
import { IERC20 } from "@openzeppelin/token/ERC20/IERC20.sol";
|
||||
import { Script } from "forge-std/Script.sol";
|
||||
import { console2 } from "forge-std/console2.sol";
|
||||
import { IERC20 } from "@openzeppelin/token/ERC20/IERC20.sol";
|
||||
import { MockToken } from "./MockToken.sol";
|
||||
import { BacktestKraiken } from "./BacktestKraiken.sol";
|
||||
import { ShadowPool, ShadowPoolDeployer } from "./ShadowPoolDeployer.sol";
|
||||
import { EventReplayer } from "./EventReplayer.sol";
|
||||
import { KrAIkenSystem, KrAIkenDeployer } from "./KrAIkenDeployer.sol";
|
||||
import { StrategyExecutor } from "./StrategyExecutor.sol";
|
||||
|
||||
/**
|
||||
* @title BacktestRunner
|
||||
|
|
@ -77,14 +78,14 @@ contract BacktestRunner is Script {
|
|||
// 1. Explicit env override.
|
||||
try vm.envUint("INITIAL_SQRT_PRICE_X96") returns (uint256 val) {
|
||||
if (val != 0) return uint160(val);
|
||||
} catch {}
|
||||
} catch { }
|
||||
|
||||
// 2. First Swap event in the events cache.
|
||||
try vm.envString("BACKTEST_EVENTS_FILE") returns (string memory eventsFile) {
|
||||
try this._parseSqrtPriceFromFile(eventsFile) returns (uint160 val) {
|
||||
if (val != 0) return val;
|
||||
} catch {}
|
||||
} catch {}
|
||||
} catch { }
|
||||
} catch { }
|
||||
|
||||
// 3. Fallback default.
|
||||
return DEFAULT_SQRT_PRICE_X96;
|
||||
|
|
@ -101,12 +102,12 @@ contract BacktestRunner is Script {
|
|||
uint256 recenterInterval = DEFAULT_RECENTER_INTERVAL;
|
||||
try vm.envUint("RECENTER_INTERVAL") returns (uint256 v) {
|
||||
if (v > 0) recenterInterval = v;
|
||||
} catch {}
|
||||
} catch { }
|
||||
|
||||
uint256 initialCapital = KrAIkenDeployer.DEFAULT_INITIAL_CAPITAL;
|
||||
try vm.envUint("INITIAL_CAPITAL_WETH") returns (uint256 v) {
|
||||
if (v > 0) initialCapital = v;
|
||||
} catch {}
|
||||
} catch { }
|
||||
|
||||
vm.startBroadcast();
|
||||
|
||||
|
|
@ -139,15 +140,15 @@ contract BacktestRunner is Script {
|
|||
// 4. Set feeDestination = sender.
|
||||
// 5. Mint initialCapital mock WETH to LM.
|
||||
// ------------------------------------------------------------------
|
||||
KrAIkenSystem memory sys =
|
||||
KrAIkenDeployer.deploy(address(sp.factory), address(mockWeth), address(krk), sender, initialCapital);
|
||||
KrAIkenSystem memory sys = KrAIkenDeployer.deploy(address(sp.factory), address(mockWeth), address(krk), sender, initialCapital);
|
||||
|
||||
// Deploy StrategyExecutor and grant it recenter access on the LM.
|
||||
// recenterAccess bypasses TWAP stability check and cooldown — correct
|
||||
// for simulation where vm.warp drives time, not a real oracle.
|
||||
// sender == feeDestination, so the onlyFeeDestination guard is satisfied.
|
||||
bool token0isWeth = sp.token0 == address(mockWeth);
|
||||
StrategyExecutor executor =
|
||||
new StrategyExecutor(sys.lm, IERC20(address(mockWeth)), IERC20(address(krk)), sender, recenterInterval);
|
||||
new StrategyExecutor(sys.lm, IERC20(address(mockWeth)), IERC20(address(krk)), sender, recenterInterval, sp.pool, token0isWeth);
|
||||
sys.lm.setRecenterAccess(address(executor));
|
||||
|
||||
vm.stopBroadcast();
|
||||
|
|
@ -185,9 +186,10 @@ contract BacktestRunner is Script {
|
|||
console2.log("Optimizer: ", address(sys.optimizer));
|
||||
console2.log("LiquidityMgr: ", address(sys.lm));
|
||||
console2.log("StrategyExec: ", address(executor));
|
||||
console2.log("PositionTracker:", address(executor.tracker()));
|
||||
console2.log("Recenter intv: ", recenterInterval, " blocks");
|
||||
console2.log("Initial capital:", initialCapital, " (mock WETH wei)");
|
||||
console2.log("token0isWeth: ", sp.token0 == address(mockWeth));
|
||||
console2.log("token0isWeth: ", token0isWeth);
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Event replay (runs as local simulation — no broadcast required).
|
||||
|
|
@ -199,7 +201,7 @@ contract BacktestRunner is Script {
|
|||
try vm.envString("BACKTEST_EVENTS_FILE") returns (string memory eventsFile) {
|
||||
if (bytes(eventsFile).length > 0) {
|
||||
// Reset file position — _resolveSqrtPrice() may have consumed line 1.
|
||||
try vm.closeFile(eventsFile) {} catch {}
|
||||
try vm.closeFile(eventsFile) { } catch { }
|
||||
|
||||
// Pre-count events so replay() can show "[N/total]" progress lines.
|
||||
uint256 totalEvents = 0;
|
||||
|
|
@ -221,6 +223,6 @@ contract BacktestRunner is Script {
|
|||
// Print final KrAIken strategy summary.
|
||||
executor.logSummary();
|
||||
}
|
||||
} catch {}
|
||||
} catch { }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue