Class Sweep
QTSurfer.sweep(SweepRequest) once the platform has accepted the
sweep; the leaderboard keeps being polled in the background.
await()resolves with the finalExecuteSweepResult.results(SweepOrder)re-reads that leaderboard in another view — the untruncated one, for instance — without re-running anything.progress()streamsSweepProgressEvents.cancel()asks the platform to stop between parameter vectors.sensitivity()reads how the objective responds to each axis.state()returns a local snapshot of the lifecycle.accepted()carries what acceptance already answered — the effective seed, the grid size, whether this submission enqueued anything, and whether this is a walk-forward sweep.
-
Nested Class Summary
Nested Classes -
Constructor Summary
ConstructorsConstructorDescriptionSweep(com.qtsurfer.api.client.model.ExecuteSweepAccepted accepted, String requestId, String strategyId, CompletableFuture<com.qtsurfer.api.client.model.ExecuteSweepResult> result, Flow.Publisher<SweepProgressEvent> progress, AtomicReference<Sweep.State> state, Runnable cancelHook, BiFunction<SweepOrder, SweepRanking, com.qtsurfer.api.client.model.ExecuteSweepResult> resultsReader, Function<SweepObjective, com.qtsurfer.api.client.model.SweepSensitivity> sensitivityReader) Internal constructor used by the SDK workflow; not part of the public contract. -
Method Summary
Modifier and TypeMethodDescriptioncom.qtsurfer.api.client.model.ExecuteSweepAcceptedaccepted()Deprecated.CompletableFuture<com.qtsurfer.api.client.model.ExecuteSweepResult>await()Resolves with the final leaderboard once the sweep stops advancing.booleancancel()Ask the platform to stop the sweep between parameter vectors.com.qtsurfer.api.client.model.ExecuteSweepAcceptedWhat acceptance already answered, before a single trial has run, exactly as the platform sent it.Reactive-streams feed of progress events; terminates when the sweep reaches a terminal state.com.qtsurfer.api.client.model.ExecuteSweepResultgetResults(SweepOrder order) Re-read this sweep's leaderboard in a different view.com.qtsurfer.api.client.model.ExecuteSweepResultgetResults(SweepOrder order, SweepRanking ranking) Re-read this sweep's leaderboard in a different view, without re-running anything.com.qtsurfer.api.client.model.SweepSensitivitySensitivity surfaces for the objective this sweep was submitted with.com.qtsurfer.api.client.model.SweepSensitivitygetSensitivity(SweepObjective objective) How the objective moves as each parameter moves — the question a leaderboard cannot answer.getState()Local snapshot of the sweep lifecycle; does not itself contact the server.id()Server-side sweepId.progress()Deprecated.UsegetProgress().The prepared dataset every trial ran against — the prepare jobId the workflow resolved before submitting, which is also what addresses this sweep on the wire.com.qtsurfer.api.client.model.ExecuteSweepResultresults(SweepOrder order) Deprecated.com.qtsurfer.api.client.model.ExecuteSweepResultresults(SweepOrder order, SweepRanking ranking) Deprecated.com.qtsurfer.api.client.model.SweepSensitivityDeprecated.UsegetSensitivity().com.qtsurfer.api.client.model.SweepSensitivitysensitivity(SweepObjective objective) Deprecated.state()Deprecated.UsegetState().The compiled strategy every trial shares.toString()Compact debug representation including the sweep id and current state.
-
Constructor Details
-
Sweep
public Sweep(com.qtsurfer.api.client.model.ExecuteSweepAccepted accepted, String requestId, String strategyId, CompletableFuture<com.qtsurfer.api.client.model.ExecuteSweepResult> result, Flow.Publisher<SweepProgressEvent> progress, AtomicReference<Sweep.State> state, Runnable cancelHook, BiFunction<SweepOrder, SweepRanking, com.qtsurfer.api.client.model.ExecuteSweepResult> resultsReader, Function<SweepObjective, com.qtsurfer.api.client.model.SweepSensitivity> sensitivityReader) Internal constructor used by the SDK workflow; not part of the public contract.- Parameters:
accepted- the platform's acceptance of the sweep, exactly as it answeredrequestId- the prepared dataset this sweep runs onstrategyId- the compilation every trial runsresult- resolves with the final leaderboardprogress- feed of progress eventsstate- lifecycle holder, shared with the polling taskcancelHook- requests server-side cancellationresultsReader- re-reads the leaderboard for an optional order and rankingsensitivityReader- reads sensitivity surfaces for an optional objective
-
-
Method Details
-
id
Server-side sweepId.- Returns:
- the sweep identifier
-
requestId
The prepared dataset every trial ran against — the prepare jobId the workflow resolved before submitting, which is also what addresses this sweep on the wire.This is the value the workflow prepared with, not the acceptance echo of it.
accepted()carries the echo, unmodified, for anyone who wants to compare the two.- Returns:
- the prepared-dataset identifier
-
strategyId
The compiled strategy every trial shares.- Returns:
- the strategyId
-
getAccepted
public com.qtsurfer.api.client.model.ExecuteSweepAccepted getAccepted()What acceptance already answered, before a single trial has run, exactly as the platform sent it.Three of its fields are the reason this is exposed rather than folded away:
ExecuteSweepAccepted.getSeed()— the effective seed, generated platform-side when the request omitted one. Submitting it again is what makes a randomly sampled sweep replayable.ExecuteSweepAccepted.getQueued()—falsemeans an identical sweep already existed and nothing new was enqueued. The handle is still valid and still resolves; it is just reading a sweep this call did not start.ExecuteSweepAccepted.getWalkForward()— present exactly when this is a walk-forward sweep. It is the discriminator, and it is available here immediately, so code watchingprogress()can branch on the answer's shape without waiting forawait().
- Returns:
- the acceptance record
-
accepted
Deprecated.UsegetAccepted(). -
getState
Local snapshot of the sweep lifecycle; does not itself contact the server.- Returns:
- the current state
-
state
Deprecated.UsegetState(). -
getProgress
Reactive-streams feed of progress events; terminates when the sweep reaches a terminal state.- Returns:
- the progress publisher
-
progress
Deprecated.UsegetProgress(). -
await
Resolves with the final leaderboard once the sweep stops advancing.This resolves on every terminal status, cancellation included —
COMPLETED,PARTIALandCANCELLEDall hand back the result rather than raising. That is a deliberate divergence fromBacktest.await(), which completes exceptionally when its run is aborted: a cancelled sweep keeps every row it already finished, and throwing them away would lose the only reason to cancel a sweep late rather than early. ReadExecuteSweepResult.getStatus()to find out which of the three you got. The future completes exceptionally only for transport failures, HTTP errors, and stage timeouts.PARTIALmeans at least one unit of work died and its runs are simply missing. There is no failed status for a sweep as a whole, so a sweep whose every shard died isPARTIALwith an empty leaderboard — checkExecuteSweepResult.getLeaderboardSize()before reading anything into a top row.Reading the leaderboard
The default order is not the raw objective order. It is plateau order, and
ExecuteSweepResult.getRanking()says which was actually applied — not always the one requested, because a sweep with no stored parameter grid cannot be plateau-ranked and falls back to raw. SeeSweepRanking.The default view is capped. When
ExecuteSweepResult.getTruncated()istrue, rows exist that the leaderboard does not carry —ExecuteSweepResult.getLeaderboardSize()counts what is available.results(SweepOrder.NATURAL)returns all of them, inrunIxorder and with no ranking applied, by re-reading this same sweep — nothing is re-run.SweepRunRow.getPlateauScore()andSweepRunRow.getNeighbourCount()are read together. A neighbour count of0means the point had no neighbours in the grid to compare against, so its plateau score is unevidenced rather than confirmed — on its own it is indistinguishable from a genuinely robust one.SweepRunRow.getDeflatedSharpe()is the probability that a row's Sharpe reflects real edge rather than the best draw from however many vectors were tried. Around 0.95 and up it survives the multiple-testing correction; near 0.5 or below it is not distinguishable from the best of a pile of coin flips. It is absent on aborted runs, and on sweeps with too few trials to establish any dispersion to deflate against.ExecuteSweepResult.getPbo()is the probability of backtest overfitting for the sweep as a whole: how often the configuration that won in-sample lands below median out-of-sample. Above roughly 0.5 the sweep is selecting noise, and that verdict is about the search, not about any one row — a high value discredits the top row however good it looks. It is computed once the last unit of work finishes, so it is absent while the sweep is still running and on sweeps too small for the statistic to mean anything.A walk-forward sweep answers in a different shape
ExecuteSweepResult.getWalkForward()is the discriminator, and it appears as soon as the sweep is accepted — before any fold has finished — so it is safe to branch on while polling (it is also onaccepted()). When it is present, the leaderboard is one row per completed fold: that fold's winner as it scored out-of-sample, withSweepRunRow.getRunIx()carrying the fold index rather than a position in the grid. No plateau score, deflated Sharpe or PBO figure is reported for one — the out-of-sample numbers are already the honest measurement.WalkForwardResult.getParamDrift()absent is not zero. The field is omitted whenever the figure could not be computed — fewer than two folds finished, or no stored grid to place the winners on — and zero is itself a meaningful reading there (winners that never moved), so a placeholder would be indistinguishable from perfect stability.An empty leaderboard is not always an empty answer. A sweep can finish having scored nothing — every shard failed before producing a row — and in that case
ExecuteSweepResult.getFailReason()carries the cause reported by the first shard to fail, typically something the whole grid would have hit, such as a strategy that could not be loaded. Read it before concluding that a sweep with no rows simply found nothing: those are different outcomes and the leaderboard alone cannot tell them apart. Only the first failure is recorded, so where several shards failed differently this names one of them rather than summarising all — pair it withgetProgress().getFailedShards()for the count.- Returns:
- the final leaderboard
-
getResults
Re-read this sweep's leaderboard in a different view.Equivalent to
results(SweepOrder, SweepRanking)with no ranking preference.- Parameters:
order- which view to read;nulltakes the platform default- Returns:
- the leaderboard as it stands now, in the requested view
- Throws:
QTSError- on HTTP 4xx/5xx or transport failure
-
getResults
public com.qtsurfer.api.client.model.ExecuteSweepResult getResults(SweepOrder order, SweepRanking ranking) Re-read this sweep's leaderboard in a different view, without re-running anything.This is a read of the same sweep, addressed by the ids this handle already holds. It does not compile, does not prepare, does not submit, and does not create a second sweep — the view is a query parameter on the read, not a property of the run.
await()resolves once, in whatever viewSweepOptionsfixed at submit time; this is how to look at the same rows another way afterwards.It is the route to rows the ranked view dropped. When
ExecuteSweepResult.getTruncated()istruethe leaderboard was capped for display;SweepOrder.NATURALreturns every available row instead, in deterministicrunIxorder.rankingis ignored whenorderisSweepOrder.NATURAL— that view is always ordered byrunIx, and the response comes backrawwhatever was asked for. Rank, plateau score and neighbour count belong to the ranked view and are not part of it.Works on a sweep still in flight, where it returns the rows finished so far — the same as
sensitivity(). It is not only for completed sweeps, and it does not wait for one.Synchronous — blocks the calling thread for one HTTP round trip. Like every handle-scoped call, it does not take part in an
AuthenticatedClient's refresh-on-401 policy.- Parameters:
order- which view to read;nulltakes the platform default (SweepOrder.RANKED)ranking- how to order the ranked view;nulltakes the platform default (SweepRanking.PLATEAU)- Returns:
- the leaderboard as it stands now, in the requested view
- Throws:
QTSError- on HTTP 4xx/5xx or transport failure
-
results
@Deprecated(forRemoval=false) public com.qtsurfer.api.client.model.ExecuteSweepResult results(SweepOrder order) Deprecated. -
results
@Deprecated(forRemoval=false) public com.qtsurfer.api.client.model.ExecuteSweepResult results(SweepOrder order, SweepRanking ranking) Deprecated. -
cancel
public boolean cancel()Ask the platform to stop the sweep between parameter vectors.The rows already finished stay readable, so this does not abandon the work done so far: the poll keeps running until the platform reports the sweep as
CANCELLED, andawait()then resolves normally with the partial leaderboard. Cancelling therefore depends on the platform answering; on aSweepOptionswith notimeout, a sweep that never reports cancelled leavesawait()waiting.A cancel that arrives after the last unit of work has finished changes nothing — the sweep completes and
state()settles onSweep.State.COMPLETED.- Returns:
trueif the call caused a transition fromSweep.State.EXECUTING
-
getSensitivity
public com.qtsurfer.api.client.model.SweepSensitivity getSensitivity()Sensitivity surfaces for the objective this sweep was submitted with.- Returns:
- how the objective responds to each axis
- Throws:
QTSError- on HTTP 4xx/5xx or transport failure
-
getSensitivity
How the objective moves as each parameter moves — the question a leaderboard cannot answer. A leaderboard says which point won; a sweep can spend its whole budget on an axis that never moved the objective at all, and the top rows hide that completely.A marginal takes one axis and collapses every other one: for each value of that axis it aggregates every run that used it, whatever the rest of the parameters were. A flat marginal means the axis did not matter over the range swept.
best,meanandworstare all reported because them disagreeing is the signal — a value with a high best and a poor mean only works in specific company, which is an interaction, and a single number would hide it. A heatmap does the same over a pair of axes, where that interaction is visible directly.Check
SweepSensitivity.getHeatmapsTruncated(). Marginals are always complete; the pair surfaces are quadratic in the axis count and may be capped to stay inside the response budget. When the flag istrue, at least one pair was left out, so the list you have is not the full set of interactions. This method hands back the wholeSweepSensitivityrather than just its surfaces precisely so that flag cannot be lost on the way out.Readable while the sweep is still running, in which case the aggregates describe the runs finished so far and
SweepSensitivity.getRowsAnalysed()says how many that was. Aborted runs are excluded throughout: a run that threw measured nothing, and counting it as a bad outcome would invent evidence against a parameter value that was never really tested.Synchronous — blocks the calling thread for one HTTP round trip. Like every handle-scoped call, it does not take part in an
AuthenticatedClient's refresh-on-401 policy.- Parameters:
objective- which metric to aggregate;nulluses the objective the sweep was submitted with- Returns:
- the marginals, the heatmaps, and whether the heatmaps are all of them
- Throws:
QTSError- on HTTP 4xx/5xx or transport failure- See Also:
-
SweepMarginal
-
sensitivity
Deprecated.UsegetSensitivity(). -
sensitivity
@Deprecated(forRemoval=false) public com.qtsurfer.api.client.model.SweepSensitivity sensitivity(SweepObjective objective) Deprecated. -
toString
Compact debug representation including the sweep id and current state.
-
getAccepted().