simmer-automaton 0.6.4 → 0.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/tuning.js CHANGED
@@ -110,9 +110,10 @@ export function computeTuningChanges(skills, tunableSkills, cycleCount, budgetUs
110
110
  const cur = currentValue(t, ts.config);
111
111
  if (typeof cur !== "number")
112
112
  continue;
113
- let newVal = cur * 0.8;
113
+ // Round to 4 decimal places — don't snapToStep (step is a UI hint, not a constraint,
114
+ // and coarse steps like 0.01 would round 0.02*0.8=0.016 back to 0.02, blocking tuning)
115
+ let newVal = Math.round(cur * 0.8 * 10000) / 10000;
114
116
  newVal = clampToRange(newVal, t);
115
- newVal = snapToStep(newVal, t);
116
117
  if (newVal !== cur) {
117
118
  changes.push({ slug: ts.slug, env: t.env, oldValue: cur, newValue: newVal, reason: `zero signals for ${sk.consecutiveZeroSignals} cycles — widening threshold` });
118
119
  lastTunedCycle.set(ts.slug, cycleCount);
@@ -132,9 +133,8 @@ export function computeTuningChanges(skills, tunableSkills, cycleCount, budgetUs
132
133
  const cur = currentValue(t, ts.config);
133
134
  if (typeof cur !== "number")
134
135
  continue;
135
- let newVal = cur * 0.5;
136
+ let newVal = Math.round(cur * 0.5 * 10000) / 10000;
136
137
  newVal = clampToRange(newVal, t);
137
- newVal = snapToStep(newVal, t);
138
138
  if (newVal !== cur) {
139
139
  changes.push({ slug: ts.slug, env: t.env, oldValue: cur, newValue: newVal, reason: `P&L ${sk.totalPnl.toFixed(2)} (${lossPct.toFixed(0)}% of budget) — halving max bet` });
140
140
  lastTunedCycle.set(ts.slug, cycleCount);
@@ -153,10 +153,8 @@ export function computeTuningChanges(skills, tunableSkills, cycleCount, budgetUs
153
153
  const cur = currentValue(t, ts.config);
154
154
  if (typeof cur !== "number")
155
155
  continue;
156
- let newVal = cur - 1;
157
- newVal = Math.max(1, newVal);
156
+ let newVal = Math.max(1, cur - 1);
158
157
  newVal = clampToRange(newVal, t);
159
- newVal = snapToStep(newVal, t);
160
158
  if (newVal !== cur) {
161
159
  changes.push({ slug: ts.slug, env: t.env, oldValue: cur, newValue: newVal, reason: `win rate ${(winRate * 100).toFixed(0)}% — reducing max trades` });
162
160
  lastTunedCycle.set(ts.slug, cycleCount);
@@ -177,9 +175,8 @@ export function computeTuningChanges(skills, tunableSkills, cycleCount, budgetUs
177
175
  const cur = currentValue(t, ts.config);
178
176
  if (typeof cur !== "number")
179
177
  continue;
180
- let newVal = cur * 1.25;
178
+ let newVal = Math.round(cur * 1.25 * 10000) / 10000;
181
179
  newVal = clampToRange(newVal, t);
182
- newVal = snapToStep(newVal, t);
183
180
  if (newVal !== cur) {
184
181
  changes.push({ slug: ts.slug, env: t.env, oldValue: cur, newValue: newVal, reason: `win rate ${(winRate * 100).toFixed(0)}% — increasing max bet` });
185
182
  lastTunedCycle.set(ts.slug, cycleCount);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simmer-automaton",
3
- "version": "0.6.4",
3
+ "version": "0.6.5",
4
4
  "description": "Simmer Automaton plugin for OpenClaw — autonomous trading skill orchestration",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/tuning.ts CHANGED
@@ -156,9 +156,10 @@ export function computeTuningChanges(
156
156
  if (t.type !== "number" || pinnedSet.has(t.env) || !isEntryThresholdTunable(t)) continue;
157
157
  const cur = currentValue(t, ts.config);
158
158
  if (typeof cur !== "number") continue;
159
- let newVal = cur * 0.8;
159
+ // Round to 4 decimal places — don't snapToStep (step is a UI hint, not a constraint,
160
+ // and coarse steps like 0.01 would round 0.02*0.8=0.016 back to 0.02, blocking tuning)
161
+ let newVal = Math.round(cur * 0.8 * 10000) / 10000;
160
162
  newVal = clampToRange(newVal, t);
161
- newVal = snapToStep(newVal, t);
162
163
  if (newVal !== cur) {
163
164
  changes.push({ slug: ts.slug, env: t.env, oldValue: cur, newValue: newVal, reason: `zero signals for ${sk.consecutiveZeroSignals} cycles — widening threshold` });
164
165
  lastTunedCycle.set(ts.slug, cycleCount);
@@ -176,9 +177,8 @@ export function computeTuningChanges(
176
177
  if (changes.some((c) => c.slug === ts.slug && c.env === t.env)) continue;
177
178
  const cur = currentValue(t, ts.config);
178
179
  if (typeof cur !== "number") continue;
179
- let newVal = cur * 0.5;
180
+ let newVal = Math.round(cur * 0.5 * 10000) / 10000;
180
181
  newVal = clampToRange(newVal, t);
181
- newVal = snapToStep(newVal, t);
182
182
  if (newVal !== cur) {
183
183
  changes.push({ slug: ts.slug, env: t.env, oldValue: cur, newValue: newVal, reason: `P&L ${sk.totalPnl.toFixed(2)} (${lossPct.toFixed(0)}% of budget) — halving max bet` });
184
184
  lastTunedCycle.set(ts.slug, cycleCount);
@@ -196,10 +196,8 @@ export function computeTuningChanges(
196
196
  if (t.type !== "number" || pinnedSet.has(t.env) || !isMaxTradesTunable(t)) continue;
197
197
  const cur = currentValue(t, ts.config);
198
198
  if (typeof cur !== "number") continue;
199
- let newVal = cur - 1;
200
- newVal = Math.max(1, newVal);
199
+ let newVal = Math.max(1, cur - 1);
201
200
  newVal = clampToRange(newVal, t);
202
- newVal = snapToStep(newVal, t);
203
201
  if (newVal !== cur) {
204
202
  changes.push({ slug: ts.slug, env: t.env, oldValue: cur, newValue: newVal, reason: `win rate ${(winRate * 100).toFixed(0)}% — reducing max trades` });
205
203
  lastTunedCycle.set(ts.slug, cycleCount);
@@ -218,9 +216,8 @@ export function computeTuningChanges(
218
216
  if (changes.some((c) => c.slug === ts.slug && c.env === t.env)) continue;
219
217
  const cur = currentValue(t, ts.config);
220
218
  if (typeof cur !== "number") continue;
221
- let newVal = cur * 1.25;
219
+ let newVal = Math.round(cur * 1.25 * 10000) / 10000;
222
220
  newVal = clampToRange(newVal, t);
223
- newVal = snapToStep(newVal, t);
224
221
  if (newVal !== cur) {
225
222
  changes.push({ slug: ts.slug, env: t.env, oldValue: cur, newValue: newVal, reason: `win rate ${(winRate * 100).toFixed(0)}% — increasing max bet` });
226
223
  lastTunedCycle.set(ts.slug, cycleCount);