Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@terwey
Copy link
Collaborator

@terwey terwey commented Oct 31, 2025

feat(orderscaler): introduce order scaling with config, API & audits; integrate engine/emitter

Add an order-scaler subsystem that applies configurable multipliers to mirrored orders, preserves take-profit stack ratios under venue constraints, and records auditable changes. Integrates across engine, storage, API, docs, and tests.

Area Key changes
Config Add OrderScalerMaxMultiplier (flag --order-scaler-max-multiplier, env RECOMMA_ORDER_SCALER_MAX_MULTIPLIER). Validate >0. Wire into API handler and engine.
Engine Insert scaling step before submission; skip orders that fall below venue minimums (with audit); preserve TP stack ratios; feed scaled size/price into fill tracker.
Emitter Return/propagate Hyperliquid order status; log requested_size, executed_size, and IOC retry metadata.
HL constraints Add metadata cache for coin rounding (SizeStep, significant figs, min notional helper).
Storage Persist default + per-bot scaler configs; compute effective scaler; store scaled_orders audit with rounding delta, actor, skip reason; expose list/query helpers.
API (OpenAPI) New endpoints: GET/PUT /api/v1/order-scaler, GET/PUT/DELETE /api/v1/bots/{botId}/order-scaler, GET /api/orders/scalers. Enforce multiplier bounds and vault session.
Streaming Emit order_scaler_config and scaled_order_audit entries on /sse/orders with actor and effective config.
Docs Architecture + operations runbook for the scaler; navigation updates; README pointer.
Tests Unit tests for scaler service, engine integration, emitter logging, fill tracker updates, and API handler.

Notes:

  • Multiplier clamped by configured max; below-minimum-notional legs are skipped and audited with reason.
  • Effective config resolves per-bot overrides against the global default and is included in stream/audit payloads.

Refs: #43, #44, #45, #46, #47

https://chatgpt.com/codex/tasks/task_e_690493b50a808326a027433a459e035a

@terwey
Copy link
Collaborator Author

terwey commented Oct 31, 2025

@codex review and check if it matches specs/order_scaler.adoc

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +72 to +76
func (s *Storage) UpsertOrderScaler(ctx context.Context, multiplier float64, updatedBy string, notes *string) (OrderScalerState, error) {
s.mu.Lock()
defer s.mu.Unlock()

params := sqlcgen.UpsertOrderScalerParams{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Publish SSE events when order scaler settings change

The spec requires multiplier configuration to be “hot‑reloadable” and broadcast via the storage stream, but UpsertOrderScaler (and similarly UpsertBotOrderScaler/DeleteBotOrderScaler) only persist to SQLite and immediately return without calling publishStreamEventLocked. Components that cache the effective multiplier will never see updates unless they poll or restart, so UI/API consumers cannot react to configuration changes as described in specs/order_scaler.adoc.

Useful? React with 👍 / 👎.

@terwey
Copy link
Collaborator Author

terwey commented Oct 31, 2025

@codex review and confirm if specs/order_scaler.adoc is fully implemented

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 493 to 515
func (e *Engine) applyScaling(
ctx context.Context,
md metadata.Metadata,
latest *recomma.BotEvent,
action recomma.Action,
logger *slog.Logger,
) (recomma.Action, *orderscaler.Result, bool, error) {
if e.scaler == nil || latest == nil {
return action, nil, true, nil
}

switch action.Type {
case recomma.ActionCreate:
if action.Create == nil {
return action, nil, true, nil
}
req := orderscaler.BuildRequest(md, latest.BotEvent, *action.Create)
result, err := e.scaler.Scale(ctx, req, action.Create)
if err != nil {
if errors.Is(err, orderscaler.ErrBelowMinimum) {
logger.Warn("skipping scaled order below venue minimum", slog.Float64("price", req.Price), slog.Float64("size", req.OriginalSize))
return recomma.Action{Type: recomma.ActionNone, Reason: "scaled order below minimum"}, nil, false, nil
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Emit an audit when a scaled order is skipped

The spec requires deals that fall below Hyperliquid minimums to be “flag[ged] for operator review and skip submission rather than silently discarding legs”. In applyScaling a below‑minimum leg is handled by logging and returning ActionNone, but no storage audit or SSE event is emitted. As a result operators who rely on the order scaler records or the streamed logs have no visibility that an order was skipped, so the requirement to flag the deal is not met.

Useful? React with 👍 / 👎.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codex plan a task how we resolve this properly

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current implementation in Engine.applyScaling turns a below-minimum leg into ActionNone without recording anything in storage or the SSE stream, so operators never see that the scaled order was skipped. This violates the spec’s requirement to flag sub-minimum deals for review instead of silently discarding them. engine/engine.goL500-L536 specs/order_scaler.adocL14-L18

:::task-stub{title="Record and broadcast skipped scaled orders"}
Step 1. Extend the scaler audit model to represent skipped submissions (e.g., add a skipped flag or reason) by updating storage/sqlc/schema.sql, corresponding queries, and regenerating storage/sqlcgen. Update storage/order_scalers.go conversions and publishStreamEventLocked to include the new metadata, and reflect the shape change in openapi.yaml/generated API types so SSE consumers can detect skipped legs.

Step 2. Teach engine/orderscaler.Service to invoke the new storage hook when constraints.NotionalBelowMinimum triggers, ensuring the audit row and SSE event are created before returning ErrBelowMinimum. Add focused coverage in engine/orderscaler/service_test.go for the skip path.

Step 3. Update Engine.applyScaling so that when Scale reports a skipped order it forwards the scaler’s audit metadata (if any) and logs, ensuring the engine records the skip without re-entering storage. Extend existing engine tests (or add new ones) to verify the audit emission when an order is skipped.
:::

View task →

@terwey
Copy link
Collaborator Author

terwey commented Oct 31, 2025

@codex review and confirm if specs/order_scaler.adoc is fully implemented. I do not care about database migrations, nobody is running this software yet in prod.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 103 to 117
scaledSize := req.OriginalSize * multiplier

constraints, err := s.constraints.Resolve(ctx, req.Coin)
if err != nil {
return Result{}, fmt.Errorf("resolve constraints: %w", err)
}

roundedPrice := order.Price
if req.Price > 0 {
roundedPrice = req.Price
}
roundedPrice = constraints.RoundPrice(roundedPrice)

roundedSize := constraints.RoundSize(scaledSize)
roundedSize = clampToNonNegative(roundedSize)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep take‑profit ratios intact when rounding scaled legs

The order scaler currently multiplies and rounds each order independently (scaledSize := req.OriginalSize * multiplier followed by constraints.RoundSize), which can change the proportional sizes of stacked take‑profit orders when lot rounding kicks in. The spec in specs/order_scaler.adoc requires that “scaled legs preserve ratio orderings” after applying venue tick/lot rules. With the existing implementation two legs sized 1.0 and 1.05 with a 0.5× multiplier and 0.1 size step become 0.5 and 0.5 after rounding, altering the leg ratios and changing exposure. Consider adjusting the algorithm to scale the entire stack and redistribute rounding deltas so the relative sizes remain consistent while still respecting the venue’s increments.

Useful? React with 👍 / 👎.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codex propose a better implementation

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Testing

  • ⚠️ go test ./... (hung waiting on external module downloads; aborted)

View task →

@terwey
Copy link
Collaborator Author

terwey commented Oct 31, 2025

@codex review

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. Breezy!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@terwey terwey changed the title feat(storage): add order scaler persistence feat(orderscaler): introduce order scaling with config, API & audits; integrate engine/emitter Oct 31, 2025
@terwey terwey merged commit ebcf246 into main Oct 31, 2025
1 check passed
@terwey terwey deleted the codex/update-schema-and-queries-for-orders branch October 31, 2025 15:46
terwey added a commit that referenced this pull request Oct 31, 2025
…or-orders

feat(orderscaler): introduce order scaling with config, API & audits; integrate engine/emitter

Add an order-scaler subsystem that applies configurable multipliers to mirrored orders, preserves take-profit stack ratios under venue constraints, and records auditable changes. Integrates across engine, storage, API, docs, and tests.

| Area           | Key changes                                                                                                                                                                |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Config         | Add `OrderScalerMaxMultiplier` (flag `--order-scaler-max-multiplier`, env `RECOMMA_ORDER_SCALER_MAX_MULTIPLIER`). Validate >0. Wire into API handler and engine.           |
| Engine         | Insert scaling step before submission; skip orders that fall below venue minimums (with audit); preserve TP stack ratios; feed scaled size/price into fill tracker.        |
| Emitter        | Return/propagate Hyperliquid order status; log `requested_size`, `executed_size`, and IOC retry metadata.                                                                  |
| HL constraints | Add metadata cache for coin rounding (`SizeStep`, significant figs, min notional helper).                                                                                  |
| Storage        | Persist default + per-bot scaler configs; compute effective scaler; store `scaled_orders` audit with rounding delta, actor, skip reason; expose list/query helpers.        |
| API (OpenAPI)  | New endpoints: `GET/PUT /api/v1/order-scaler`, `GET/PUT/DELETE /api/v1/bots/{botId}/order-scaler`, `GET /api/orders/scalers`. Enforce multiplier bounds and vault session. |
| Streaming      | Emit `order_scaler_config` and `scaled_order_audit` entries on `/sse/orders` with actor and effective config.                                                              |
| Docs           | Architecture + operations runbook for the scaler; navigation updates; README pointer.                                                                                      |
| Tests          | Unit tests for scaler service, engine integration, emitter logging, fill tracker updates, and API handler.                                                                 |

Notes:

* Multiplier clamped by configured max; below-minimum-notional legs are **skipped** and audited with reason.
* Effective config resolves per-bot overrides against the global default and is included in stream/audit payloads.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants