Class AbstractSubscriptionStrategy<T>
- All Implemented Interfaces:
Nameable, Named, Unsubscribable, Strategy, SubscriptionStrategy<T>
- Direct Known Subclasses:
AbstractFundingRateStrategy, AbstractKlineStrategy, AbstractTickerStrategy
-
Field Summary
Fields inherited from class AbstractStrategy
CONFIG_INPUT_CURRENCY, CONFIG_OUTPUT_CURRENCY, inputCurrency, outputCurrency, stats -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprotected voidprotected BuySignalcreateBuySignal(Instrument instrument, Number price) createInfoStrategySignal(Instrument instrument) protected abstract InstrumentGroupRTIndicatorcreateInstrumentGroupRTIndicator(Instrument instrument) protected SellSignalcreateSellSignal(Instrument instrument, Number price) protected voidemitBuy(Instrument instrument, Number price) protected voidemitInfo(Instrument instrument) protected voidemitSell(Instrument instrument, Number price) voidemitSignal(@NonNull StrategySignal signal) Emits a signal, replacing the system timestamp with the backtest virtual clock when backtesting is enabled.voidemitYield(@NonNull StrategyYield yield) Emits a yield, replacing the system timestamp with the backtest virtual clock when backtesting is enabled.voidfillSignal(InstrumentMapRTIndicator indicators, InfoStrategySignal signal) protected InstrumentGroupRTIndicatorgetInstrumentIndicatorGroup(Instrument instrument) longprotected final StringAdds this strategy's per-instrument indicator groups to the strategy-wide notices, which come first.protected Optional<RTIndicator> getRTIndicator(Instrument instrument, String key) getStateStore(@NonNull Instrument instrument) protected StateStoreprotected InfoStrategySignalgetUpdatedSignal(InstrumentMapRTIndicator indicators) Creates a new info signal populated with the current values of all public indicators.longCount of events whoseSubscriptionStrategy.update(T)threw and were isolated (subscription survived).booleanbooleanWhether the market-data source terminated with an error (the strategy receives no data).protected voidoverrideTimestamp(@NonNull AbstractStrategyEvent event) Replaces the event's wall-clock timestamp with the last market data timestamp during backtesting, ensuring time-consistent replay.voidreset(@NonNull Instrument instrument) voidsetEnableIndicatorsSignals(boolean enableIndicatorsSignals) voidsetIndicatorBankSession(com.wualabs.qtsurfer.engine.indicators.cache.IndicatorBank.Session indicatorBankSession) This strategy instance's view of a sweep's indicator memoization bank, ornull— which is every case except a batch of backtest runs over one dataset.voidsetLastEventTimestamp(long lastEventTimestamp) voidsetStateStoreProvider(@NonNull StateStoreProvider stateStoreProvider) Injects the backend behind this strategy's per-instrument state.protected voidsetupIndicators(InstrumentGroupRTIndicator indicators) protected InstrumentGroupRTIndicatorsetupInstrumentGroupRTIndicator(Instrument instrument) Creates and configures the RT indicator group for an instrument, including backtest mode propagation and subclass-specific indicator setup.protected io.reactivex.rxjava3.core.BackpressureStrategyBackpressure policy applied when consuming the market-data source.voidsubscribeSource(@NonNull io.reactivex.rxjava3.core.Observable<T> source) Subscribes to a market data source under supervision.protected voidtoString(com.google.common.base.MoreObjects.ToStringHelper ts) voidprotected InstrumentMapRTIndicatorupdateIndicators(Instrument instrument, T source) Updates the RT indicator group for an instrument from the market data source, triggering recalculation of all indicators in the group.protected voidupdateInstrument(@NonNull Instrument instrument, long timestamp) Tracks an instrument update: registers the instrument, records the timestamp for backtesting, and increments the stats counter.Methods inherited from class AbstractStrategy
acceptCurrency, applyProperty, clearNotice, configure, equals, getCurrencyFilter, getEngineVersion, getEngineVersionMajor, getEngineVersionMinor, getExchangeName, getExecutionCallback, getExecutionConfig, getExecutionMode, getId, getInputCurrency, getInstruments, getMinGain, getMinPercentGainMultiplier, getOutputCurrency, getPercentGain, getProperty, getPropertyInfo, getPropertyInfos, getSignals, getStats, getYields, hashCode, hasProperty, init, isEnabled, raiseNotice, registerPropertyInfo, registerPropertyInfo, registerPropertyInfo, registerPropertyInfo, setBlacklistedCurrencies, setCurrencyFilter, setEnabled, setExecutionCallback, setExecutionMode, setMinGain, setMultiEntryEnabled, setPercentGain, setProperty, setWhitelistedCurrencies, toStringMethods inherited from class AbstractNameable
getName, setNameMethods inherited from interface Strategy
applyProperty, configure, getExecutionCallback, getExecutionConfig, getExecutionMode, getId, getInputCurrency, getInstruments, getOutputCurrency, getProperty, getProperty, getPropertyInfo, getPropertyInfos, getSignals, getStats, getYields, hasProperty, hasProperty, init, isCurrencyLess, isEnabled, setEnabled, setProperty, setPropertyMethods inherited from interface SubscriptionStrategy
accept, acceptInstrument, getMarketDataSource, update, updateFrom
-
Constructor Details
-
AbstractSubscriptionStrategy
protected AbstractSubscriptionStrategy()
-
-
Method Details
-
subscribeSource
Subscribes to a market data source under supervision. Unsubscribes any previous subscription first, filters events viaSubscriptionStrategy.accept(T), and processes them on the IO scheduler to avoid blocking the source thread. Source-agnostic: the same path runs whether the stream comes from an internal exchange link or an external SPI provider (e.g. NATS).Supervision (this used to be a bare
subscribe(this::update)):- Per-event error isolation — an exception thrown by strategy/indicator code for
one event no longer terminates the subscription (which silently blinded the strategy,
possibly with open positions). The event is logged and counted
(
getUpdateErrorCount()); the feed keeps flowing. - Source failure visibility — an upstream
onErroris logged loudly and flipsisSourceFailed()so health checks can see a blind strategy. Auto-resubscription is deliberately out of scope (it needs the provider lifecycle). - Bounded buffering — the source is consumed as a
Flowablewith thesourceBackpressure()policy instead of an unboundedobserveOnbuffer; a slow strategy no longer grows the heap and (for conflatable feeds) no longer acts on stale events.
- Specified by:
subscribeSourcein interfaceSubscriptionStrategy<T>- Parameters:
source- the observable market data stream
- Per-event error isolation — an exception thrown by strategy/indicator code for
one event no longer terminates the subscription (which silently blinded the strategy,
possibly with open positions). The event is logged and counted
(
-
sourceBackpressure
protected io.reactivex.rxjava3.core.BackpressureStrategy sourceBackpressure()Backpressure policy applied when consuming the market-data source. Default isBackpressureStrategy.LATEST: for conflatable feeds (tickers) a stale event is worthless once a fresher one exists, so a slow strategy skips ahead instead of buffering without bound. Subclasses whose events are discrete facts that must not be dropped (closed klines, funding settlements) override toBackpressureStrategy.BUFFER— safe there because those feeds emit at low frequency. -
getUpdateErrorCount
public long getUpdateErrorCount()Count of events whoseSubscriptionStrategy.update(T)threw and were isolated (subscription survived). -
isSourceFailed
public boolean isSourceFailed()Whether the market-data source terminated with an error (the strategy receives no data). -
unsubscribe
public void unsubscribe()- Specified by:
unsubscribein interfaceUnsubscribable
-
reset
- Specified by:
resetin interfaceStrategy- Overrides:
resetin classAbstractStrategy
-
createInfoStrategySignal
-
fillSignal
-
updateInstrument
Tracks an instrument update: registers the instrument, records the timestamp for backtesting, and increments the stats counter.Every
update(T)override calls this first, before touching indicators or its own fields — which is what makes it the right place to apply@StrategyPropertydefaults (idempotent; a no-op after the first event). The compile-time dry run drives a strategy through this same path without ever callingAbstractStrategy.init(ExchangeSupport), so relying oninitalone would leave it seeing undefaulted fields.- Parameters:
instrument- the instrument that was updatedtimestamp- the event timestamp (used as virtual clock in backtest mode)
-
updateIndicators
Updates the RT indicator group for an instrument from the market data source, triggering recalculation of all indicators in the group.- Parameters:
instrument- the instrument to update indicators forsource- the raw market data to feed into the indicators- Returns:
- the updated indicator map
-
getUpdatedSignal
Creates a new info signal populated with the current values of all public indicators.- Parameters:
indicators- the indicator map to read values from- Returns:
- a signal carrying all public indicator values
-
emitSignal
Emits a signal, replacing the system timestamp with the backtest virtual clock when backtesting is enabled.- Overrides:
emitSignalin classAbstractStrategy
-
emitYield
Emits a yield, replacing the system timestamp with the backtest virtual clock when backtesting is enabled.- Overrides:
emitYieldin classAbstractStrategy
-
createBuySignal
-
createSellSignal
-
emitBuy
-
emitSell
-
emitInfo
-
overrideTimestamp
Replaces the event's wall-clock timestamp with the last market data timestamp during backtesting, ensuring time-consistent replay. -
setStateStoreProvider
Injects the backend behind this strategy's per-instrument state. Everything the strategy persists for an instrument —update()state, every window listener's state, and the execution callbacks' state — comes from the store this provider returns, so swapping it is enough to move state onto a persistent backend. The provider is consulted once per instrument and the result memoized; set it before the strategy sees its first tick.- Parameters:
stateStoreProvider- supplies the store for an instrument
-
getStateStore
- Specified by:
getStateStorein interfaceStrategy
-
getStateStoreForResult
-
getRTIndicator
-
clearIndicators
protected void clearIndicators() -
getNotices
Adds this strategy's per-instrument indicator groups to the strategy-wide notices, which come first. No deduplication is applied here and none is needed: each scope already reports a given condition once — the groups by (code, indicator) and the strategy by code — and the groups partition by instrument, which every indicator notice carries.The result is reproducible, not chronological. Each half is in first-raised order, but concatenating them puts every strategy-wide notice before every indicator one whenever it was actually raised — a source failure at the last event still precedes an indicator notice from the first. True cross-scope chronology would need a sequence shared with
qtsurfer-engine-indicators, which holds no reference back to the strategy. What callers need is that two calls agree, and that the API's notice cap keeps the same 50 twice.Groups are therefore visited in
Instrument.symbol()order rather than ininstrumentIndicatorGroups' iteration order: that map is aConcurrentHashMapcarryingcomputeIfAbsenton the dispatch path, which it should stay, so the ordering is imposed here where it costs one sort per read instead of on every event.- Specified by:
getNoticesin interfaceStrategy- Overrides:
getNoticesin classAbstractStrategy- Returns:
- the notices raised so far, empty if none (the default for strategies without indicators)
-
getInstrumentIndicatorGroup
-
setupInstrumentGroupRTIndicator
Creates and configures the RT indicator group for an instrument, including backtest mode propagation and subclass-specific indicator setup.- Parameters:
instrument- the instrument to build indicators for- Returns:
- the fully configured indicator group
-
setupIndicators
-
createInstrumentGroupRTIndicator
protected abstract InstrumentGroupRTIndicator createInstrumentGroupRTIndicator(Instrument instrument) -
getMarketDataSourceName
-
toString
protected void toString(com.google.common.base.MoreObjects.ToStringHelper ts) - Overrides:
toStringin classAbstractStrategy
-
getLastEventTimestamp
public long getLastEventTimestamp() -
setLastEventTimestamp
public void setLastEventTimestamp(long lastEventTimestamp) -
isEnableIndicatorsSignals
public boolean isEnableIndicatorsSignals() -
setEnableIndicatorsSignals
public void setEnableIndicatorsSignals(boolean enableIndicatorsSignals) -
setIndicatorBankSession
public void setIndicatorBankSession(com.wualabs.qtsurfer.engine.indicators.cache.IndicatorBank.Session indicatorBankSession) This strategy instance's view of a sweep's indicator memoization bank, ornull— which is every case except a batch of backtest runs over one dataset.Set it before the indicator groups are built, i.e. before the strategy sees its first data point; the groups pick it up as they register their indicators.
-