142 lines
4.7 KiB
PowerShell
142 lines
4.7 KiB
PowerShell
[CmdletBinding()]
|
|
param(
|
|
[int]$MinReplayTrades = 8,
|
|
[int]$MaxAttempts = 0,
|
|
[string]$Symbols = "BTCUSDT,ETHUSDT,SOLUSDT,LTCUSDT",
|
|
[int]$Limit = 3000,
|
|
[switch]$DeployToPi,
|
|
[string]$PiHost = "192.168.0.185",
|
|
[string]$PiUser = "sevenhill",
|
|
[string]$PiRoot = "/mnt/data/tradebot",
|
|
[string]$PiSshKeyPath = "",
|
|
[int]$SeedStart = 0
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
|
|
$RuntimeDir = Join-Path $RepoRoot "runtime"
|
|
$LoopLog = Join-Path $RuntimeDir "torch_retrain_until_replay8.log"
|
|
$GuardReport = Join-Path $RuntimeDir "torch_retrain_guard.json"
|
|
$ActiveCalibration = Join-Path $RuntimeDir "torch_threshold_calibration.json"
|
|
$Runner = Join-Path $RepoRoot "tools\run_torch_retrain.ps1"
|
|
New-Item -ItemType Directory -Force -Path $RuntimeDir | Out-Null
|
|
|
|
function Write-LoopLog {
|
|
param([string]$Message)
|
|
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ssK"
|
|
"[$timestamp] $Message" | Tee-Object -FilePath $LoopLog -Append
|
|
}
|
|
|
|
function ConvertTo-IntOrZero {
|
|
param($Value)
|
|
try {
|
|
if ($null -eq $Value) {
|
|
return 0
|
|
}
|
|
return [int]$Value
|
|
}
|
|
catch {
|
|
return 0
|
|
}
|
|
}
|
|
|
|
function Read-GuardSummary {
|
|
if (-not (Test-Path $GuardReport)) {
|
|
return [pscustomobject]@{
|
|
Accepted = $false
|
|
Reason = "guard_report_missing"
|
|
CandidateReplayTrades = 0
|
|
CurrentReplayTrades = 0
|
|
WalkForwardTrades = 0
|
|
}
|
|
}
|
|
try {
|
|
$payload = Get-Content -Raw -LiteralPath $GuardReport | ConvertFrom-Json
|
|
return [pscustomobject]@{
|
|
Accepted = [bool]$payload.accepted
|
|
Reason = [string]$payload.reason
|
|
CandidateReplayTrades = ConvertTo-IntOrZero $payload.candidate.full_replay.trades
|
|
CurrentReplayTrades = ConvertTo-IntOrZero $payload.current.full_replay.trades
|
|
WalkForwardTrades = ConvertTo-IntOrZero $payload.candidate.walk_forward_summary.trades
|
|
}
|
|
}
|
|
catch {
|
|
return [pscustomobject]@{
|
|
Accepted = $false
|
|
Reason = "guard_report_unreadable"
|
|
CandidateReplayTrades = 0
|
|
CurrentReplayTrades = 0
|
|
WalkForwardTrades = 0
|
|
}
|
|
}
|
|
}
|
|
|
|
function Read-ActiveReplayTrades {
|
|
if (-not (Test-Path $ActiveCalibration)) {
|
|
return 0
|
|
}
|
|
try {
|
|
$payload = Get-Content -Raw -LiteralPath $ActiveCalibration | ConvertFrom-Json
|
|
return ConvertTo-IntOrZero $payload.full_replay.trades
|
|
}
|
|
catch {
|
|
return 0
|
|
}
|
|
}
|
|
|
|
$attempt = 0
|
|
while ($true) {
|
|
$activeReplayTrades = Read-ActiveReplayTrades
|
|
if ($activeReplayTrades -ge $MinReplayTrades) {
|
|
Write-LoopLog "Stop condition reached: active calibration full_replay.trades=$activeReplayTrades >= $MinReplayTrades."
|
|
exit 0
|
|
}
|
|
|
|
$attempt += 1
|
|
if ($SeedStart -gt 0) {
|
|
$attemptSeed = $SeedStart + $attempt - 1
|
|
}
|
|
else {
|
|
$attemptSeed = Get-Random -Minimum 1 -Maximum 2147483647
|
|
}
|
|
Write-LoopLog "Attempt $attempt started; seed=$attemptSeed; target full_replay.trades >= $MinReplayTrades."
|
|
|
|
$runnerArgs = @(
|
|
"-NoProfile",
|
|
"-ExecutionPolicy", "Bypass",
|
|
"-File", $Runner,
|
|
"-Symbols", $Symbols,
|
|
"-Limit", $Limit.ToString(),
|
|
"-Seed", $attemptSeed.ToString()
|
|
)
|
|
if ($DeployToPi) {
|
|
$runnerArgs += "-DeployToPi"
|
|
if ($PiHost) { $runnerArgs += @("-PiHost", $PiHost) }
|
|
if ($PiUser) { $runnerArgs += @("-PiUser", $PiUser) }
|
|
if ($PiRoot) { $runnerArgs += @("-PiRoot", $PiRoot) }
|
|
if ($PiSshKeyPath) { $runnerArgs += @("-PiSshKeyPath", $PiSshKeyPath) }
|
|
}
|
|
|
|
& powershell.exe @runnerArgs 2>&1 | Tee-Object -FilePath $LoopLog -Append
|
|
$runnerExit = $LASTEXITCODE
|
|
$summary = Read-GuardSummary
|
|
Write-LoopLog "Attempt $attempt finished; runner_exit=$runnerExit accepted=$($summary.Accepted) reason=$($summary.Reason) candidate_full_replay.trades=$($summary.CandidateReplayTrades) current_full_replay.trades=$($summary.CurrentReplayTrades) walk_forward.trades=$($summary.WalkForwardTrades)."
|
|
|
|
if ($summary.Accepted -and $summary.CandidateReplayTrades -ge $MinReplayTrades) {
|
|
Write-LoopLog "Stop condition reached: accepted candidate full_replay.trades=$($summary.CandidateReplayTrades) >= $MinReplayTrades."
|
|
exit 0
|
|
}
|
|
if ($summary.CurrentReplayTrades -ge $MinReplayTrades) {
|
|
Write-LoopLog "Stop condition reached: current artifact full_replay.trades=$($summary.CurrentReplayTrades) >= $MinReplayTrades."
|
|
exit 0
|
|
}
|
|
|
|
if ($MaxAttempts -gt 0 -and $attempt -ge $MaxAttempts) {
|
|
Write-LoopLog "MaxAttempts=$MaxAttempts reached before replay target."
|
|
exit 2
|
|
}
|
|
|
|
Start-Sleep -Seconds 10
|
|
}
|