feat: add orderbook shadow training pipeline
This commit is contained in:
@@ -22,6 +22,10 @@ param(
|
||||
[int]$HoldoutWindow = 0,
|
||||
[string]$Interval = "",
|
||||
[string]$EnvFile = "",
|
||||
[string]$OrderbookDb = "",
|
||||
[int]$OrderbookMinSamplesPerBucket = 0,
|
||||
[int]$OrderbookMinCoveredBuckets = 0,
|
||||
[int]$OrderbookMinSymbols = 0,
|
||||
[switch]$Pooled,
|
||||
[switch]$SkipGuard,
|
||||
[switch]$ResumeCandidate
|
||||
@@ -124,6 +128,10 @@ if ($HoldoutWindow -le 0) { $HoldoutWindow = if ($env:TORCH_RETRAIN_HOLDOUT_WIND
|
||||
if (-not $Interval -and $env:TORCH_RETRAIN_INTERVAL) { $Interval = $env:TORCH_RETRAIN_INTERVAL }
|
||||
if (-not $EnvFile -and $env:TORCH_RETRAIN_ENV) { $EnvFile = $env:TORCH_RETRAIN_ENV }
|
||||
if (-not $EnvFile -and (Test-Path (Join-Path $RepoRoot ".env"))) { $EnvFile = Join-Path $RepoRoot ".env" }
|
||||
if (-not $OrderbookDb -and $env:TORCH_ORDERBOOK_DB) { $OrderbookDb = $env:TORCH_ORDERBOOK_DB }
|
||||
if ($OrderbookMinSamplesPerBucket -le 0) { $OrderbookMinSamplesPerBucket = if ($env:TORCH_ORDERBOOK_MIN_SAMPLES_PER_BUCKET) { [int]$env:TORCH_ORDERBOOK_MIN_SAMPLES_PER_BUCKET } else { 20 } }
|
||||
if ($OrderbookMinCoveredBuckets -le 0) { $OrderbookMinCoveredBuckets = if ($env:TORCH_ORDERBOOK_MIN_COVERED_BUCKETS) { [int]$env:TORCH_ORDERBOOK_MIN_COVERED_BUCKETS } else { 240 } }
|
||||
if ($OrderbookMinSymbols -le 0) { $OrderbookMinSymbols = if ($env:TORCH_ORDERBOOK_MIN_SYMBOLS) { [int]$env:TORCH_ORDERBOOK_MIN_SYMBOLS } else { 2 } }
|
||||
|
||||
$ModelFile = if ($env:TIME_SERIES_LSTM_MODEL_PATH) { $env:TIME_SERIES_LSTM_MODEL_PATH } else { Join-Path $RuntimeDir "lstm_forecaster.json" }
|
||||
if (-not [System.IO.Path]::IsPathRooted($ModelFile)) { $ModelFile = Join-Path $RepoRoot $ModelFile }
|
||||
@@ -131,6 +139,10 @@ $CandidateFile = Join-Path $RuntimeDir "lstm_forecaster.candidate.json"
|
||||
$CurrentCalibration = Join-Path $RuntimeDir "torch_guard_current.json"
|
||||
$CandidateCalibration = Join-Path $RuntimeDir "torch_guard_candidate.json"
|
||||
$GuardReport = Join-Path $RuntimeDir "torch_retrain_guard.json"
|
||||
$ShadowModelFile = Join-Path $RuntimeDir "lstm_forecaster.shadow.json"
|
||||
$ShadowCalibration = Join-Path $RuntimeDir "torch_shadow_calibration.json"
|
||||
$ShadowGuard = Join-Path $RuntimeDir "torch_shadow_guard.json"
|
||||
$ShadowMode = -not [string]::IsNullOrWhiteSpace($OrderbookDb)
|
||||
|
||||
$mutex = New-Object System.Threading.Mutex($false, "TradeBotTorchRecurrentRetrainer")
|
||||
$hasLock = $false
|
||||
@@ -177,6 +189,14 @@ try {
|
||||
if ($Features) { $trainerArgs += @("--features", $Features) }
|
||||
if ($ContextSymbols) { $trainerArgs += @("--context-symbols", $ContextSymbols) }
|
||||
if ($Seed -gt 0) { $trainerArgs += @("--seed", $Seed.ToString()) }
|
||||
if ($OrderbookDb) {
|
||||
$trainerArgs += @(
|
||||
"--orderbook-db", $OrderbookDb,
|
||||
"--orderbook-min-samples-per-bucket", $OrderbookMinSamplesPerBucket.ToString(),
|
||||
"--orderbook-min-covered-buckets", $OrderbookMinCoveredBuckets.ToString(),
|
||||
"--orderbook-min-symbols", $OrderbookMinSymbols.ToString()
|
||||
)
|
||||
}
|
||||
|
||||
Push-Location $RepoRoot
|
||||
$pushedLocation = $true
|
||||
@@ -216,6 +236,12 @@ try {
|
||||
)
|
||||
if ($Symbols) { $calibrationBaseArgs += @("--symbols", $Symbols) }
|
||||
if ($EnvFile) { $calibrationBaseArgs += @("--env", $EnvFile) }
|
||||
if ($OrderbookDb) {
|
||||
$calibrationBaseArgs += @(
|
||||
"--orderbook-db", $OrderbookDb,
|
||||
"--orderbook-min-samples-per-bucket", $OrderbookMinSamplesPerBucket.ToString()
|
||||
)
|
||||
}
|
||||
|
||||
if (Test-Path $ModelFile) {
|
||||
Write-RetrainLog "Calibrating current artifact for guard."
|
||||
@@ -243,13 +269,14 @@ try {
|
||||
}
|
||||
|
||||
Write-RetrainLog "Running retrain guard."
|
||||
$GuardTarget = if ($ShadowMode) { $ShadowModelFile } else { $ModelFile }
|
||||
$guardArgs = @(
|
||||
"-u",
|
||||
"tools\accept_torch_candidate.py",
|
||||
"--current-report", $CurrentCalibration,
|
||||
"--candidate-report", $CandidateCalibration,
|
||||
"--candidate-artifact", $CandidateFile,
|
||||
"--target-artifact", $ModelFile,
|
||||
"--target-artifact", $GuardTarget,
|
||||
"--report", $GuardReport
|
||||
)
|
||||
$guardExitCode = Invoke-LoggedNativeCommand -FilePath $python -ArgumentList $guardArgs -LogPath $LogFile
|
||||
@@ -261,10 +288,22 @@ try {
|
||||
throw "Retrain guard failed with exit code $guardExitCode."
|
||||
}
|
||||
if (Test-Path $CandidateCalibration) {
|
||||
Copy-Item -Force -LiteralPath $CandidateCalibration -Destination (Join-Path $RuntimeDir "torch_threshold_calibration.json")
|
||||
Write-RetrainLog "Updated active threshold calibration: $(Join-Path $RuntimeDir "torch_threshold_calibration.json")"
|
||||
if ($ShadowMode) {
|
||||
Copy-Item -Force -LiteralPath $CandidateCalibration -Destination $ShadowCalibration
|
||||
Copy-Item -Force -LiteralPath $GuardReport -Destination $ShadowGuard
|
||||
Write-RetrainLog "Candidate passed offline gate and was staged for shadow only: $ShadowModelFile"
|
||||
}
|
||||
else {
|
||||
Copy-Item -Force -LiteralPath $CandidateCalibration -Destination (Join-Path $RuntimeDir "torch_threshold_calibration.json")
|
||||
Write-RetrainLog "Updated active threshold calibration: $(Join-Path $RuntimeDir "torch_threshold_calibration.json")"
|
||||
}
|
||||
}
|
||||
if ($ShadowMode) {
|
||||
Write-RetrainLog "Candidate accepted by offline guard. Active artifact was not changed: $ModelFile"
|
||||
}
|
||||
else {
|
||||
Write-RetrainLog "Candidate accepted by guard. Active artifact: $ModelFile"
|
||||
}
|
||||
Write-RetrainLog "Candidate accepted by guard. Active artifact: $ModelFile"
|
||||
}
|
||||
catch {
|
||||
Write-RetrainLog "ERROR: $($_.Exception.Message)"
|
||||
|
||||
Reference in New Issue
Block a user