Clarify retrain gate status in Android app

This commit is contained in:
Codex
2026-06-27 12:42:38 +03:00
parent 83bffadc0a
commit baf307041a
2 changed files with 33 additions and 3 deletions
+2 -2
View File
@@ -10,7 +10,7 @@ android {
applicationId = "xyz.kusoft.tradebotmonitor"
minSdk = 26
targetSdk = 36
versionCode = 8
versionName = "0.2.5"
versionCode = 9
versionName = "0.2.6"
}
}
@@ -640,7 +640,7 @@ class MainActivity : Activity() {
addView(thinDivider().top(dp(12)))
addView(trainingProcessPanel(coordination))
if (retrain.optBoolean("available", false)) {
addView(keyValueLine("Последний guard", if (retrain.optBoolean("accepted", false)) "модель принята" else "модель отклонена", if (retrain.optBoolean("accepted", false)) palette.green else palette.amber).top(dp(10)))
addView(guardSummaryPanel(retrain).top(dp(10)))
}
val replay = backtest.optJSONObject("full_replay") ?: JSONObject()
addView(keyValueLine("Replay сделок", replay.optInt("trades", 0).toString()).top(dp(4)))
@@ -678,6 +678,36 @@ class MainActivity : Activity() {
}
}
private fun guardSummaryPanel(retrain: JSONObject): View =
LinearLayout(this).apply {
val accepted = retrain.optBoolean("accepted", false)
val reason = retrain.optStringClean("reason")
val candidate = retrain.optJSONObject("candidate") ?: JSONObject()
val current = retrain.optJSONObject("current") ?: JSONObject()
val candidateScore = candidate.optDouble("score", Double.NaN)
val currentScore = current.optDouble("score", Double.NaN)
val status = if (accepted) {
"новая модель принята"
} else {
"candidate обучен, но gate не дал ему ходу"
}
val explanation = if (accepted) {
"Новая модель прошла проверку и стала действующей."
} else {
when (reason) {
"candidate_score_regressed_vs_current" -> "Обучение завершилось, но текущая модель сильнее по проверке. Бот оставил действующую модель."
else -> "Обучение завершилось, но защитный gate не разрешил заменить действующую модель."
}
}
orientation = LinearLayout.VERTICAL
addView(keyValueLine("Последний gate", status, if (accepted) palette.green else palette.amber))
addView(text(explanation, 12f, Typeface.NORMAL, palette.text).top(dp(7)))
if (!candidateScore.isNaN() && !currentScore.isNaN()) {
addView(keyValueLine("Score candidate / текущая", "${number(candidateScore, 2)} / ${number(currentScore, 2)}", if (accepted) palette.green else palette.amber).top(dp(7)))
}
}
private fun liveSettingsBlock(data: BotSnapshot?): View {
val config = data?.config ?: JSONObject()
return LinearLayout(this).apply {