Skip to content

Releases: apexcharts/apexstock

apexstock@0.5.1

Choose a tag to compare

@github-actions github-actions released this 10 Sep 10:29

Full changelog: CHANGELOG.md · npm: https://www.npmjs.com/package/apexstock/v/0.5.1

Changed

  • The simple moving average is now the shared one from apex-commons, and
    every number it draws is unchanged.
    The same window arithmetic sat here and
    in the analysis layer, so it moved to the package both depend on; the OHLC
    accessor, the memo cache and the 2-decimal display rounding stay here, since
    those belong to this product rather than to the average. Verified exact
    rather than assumed: over 360,000 sampled positions (120 price-like series,
    periods 5 to 200) the shared implementation and the one it replaces agreed on
    every one. apex-commons moves from ^0.4.0 to ^0.7.0 and is inlined into
    the bundle as before, which grows by 223 bytes.

    Only the simple average moved. The exponential average and the Bollinger
    bands stay local on purpose and now say why in their own comments: the EMA
    rounds inside its recursion, which the streaming steppers for EMA, MACD and
    TSI reproduce step for step and an exactness test pins, and the bands measure
    their deviation against the rounded middle band that is actually drawn.
    Delegating either would change values the product displays.

  • A window average no longer depends on how much history precedes it. This
    was already true and is now a test, because the shared implementation could
    have quietly cost it. Computing a rolling mean with a running total (add the
    new value, subtract the old) is the obvious faster shape and makes the result
    carry the rounding error of everything before it, so the same window averaged
    inside a long series and averaged alone occasionally round to a different
    cent. That property is what lets the appendData() path extend an indicator
    by recomputing only the tail window and still match a full recompute exactly.

  • The test harness and the examples now load the ApexCharts a user installs.
    Nothing in the repo declared the engine it renders with: every e2e fixture,
    example, and framework demo pulled apexcharts.js from a sibling checkout on
    the maintainer's disk. A clone plus yarn install could not run the e2e suite
    at all, and when it did run it validated whatever happened to be in that
    directory, which is not what the manifest promises or what a user gets. The
    Angular demo's lockfile shows how far that can drift: it had the engine pinned
    at 5.15.2, two majors behind the peer range declared at the time. ApexCharts
    is now a devDependency pinned to the same range as the peer; fixtures load
    /node_modules/apexcharts/dist/apexcharts.js from a server rooted at the repo
    (it used to be rooted at the parent directory), and examples and demos use the
    relative equivalent. No runtime code changed: the newly installed 7.1.0 is
    byte identical to the checkout the suite had been running against, so the 83
    e2e tests, visual baselines included, pass unchanged.

  • The three framework wrappers ship at 0.2.2 with peer ranges that agree with
    each other.
    react-apexstock, vue-apexstock, and ngx-apexstock had
    gained the apexcharts peer without a release, so npm still served 0.2.1,
    which declared no engine requirement at all. Bumping them surfaced a defect in
    the pairing: apexstock: ">=0.5.0 <1" is the only range that agrees with
    apexcharts: "^7.1.0", because apexstock 0.3.x requires ^5.15.0 and 0.4.x
    requires ^6.7.0. Left as ">=0.3.0 <1" the two peers were mutually
    unsatisfiable, and npm ci (in the publish workflow) and npm install (for a
    user) both failed with ERESOLVE. Their lockfiles were stale for the same
    reason and now resolve apexstock 0.5.0 and apexcharts 7.1.0.

vue-apexstock@0.2.2

Choose a tag to compare

@junedchhipa junedchhipa released this 31 Aug 14:10

Full changelog: CHANGELOG.md · npm: https://www.npmjs.com/package/vue-apexstock/v/0.2.2

The Vue 3 wrapper for ApexStock, published with provenance.

Wrapper releases track the core: see the CHANGELOG for what changed, and packages/vue-apexstock/README.md for the component API.

react-apexstock@0.2.2

Choose a tag to compare

@junedchhipa junedchhipa released this 31 Aug 14:10

Full changelog: CHANGELOG.md · npm: https://www.npmjs.com/package/react-apexstock/v/0.2.2

The React wrapper for ApexStock, published with provenance.

Wrapper releases track the core: see the CHANGELOG for what changed, and packages/react-apexstock/README.md for the component API.

ngx-apexstock@0.2.2

Choose a tag to compare

@junedchhipa junedchhipa released this 31 Aug 14:10

Full changelog: CHANGELOG.md · npm: https://www.npmjs.com/package/ngx-apexstock/v/0.2.2

The Angular wrapper for ApexStock, published with provenance.

Wrapper releases track the core: see the CHANGELOG for what changed, and packages/ngx-apexstock/README.md for the component API.

apexstock@0.5.0

Choose a tag to compare

@junedchhipa junedchhipa released this 31 Aug 14:10

Full changelog: CHANGELOG.md · npm: https://www.npmjs.com/package/apexstock/v/0.5.0

The largest release since the library went commercial: sixteen additions, seven
behaviour changes, fifteen fixes.

One breaking change. The apexcharts peer requirement moves to ^7.1.0
(was ^6.7.0). Upgrade both together:

npm install apexstock@0.5.0 apexcharts@^7.1.0

Two reasons it had to move. The old range had gone stale, and did not admit the
7.x line that every example and test fixture here actually loads, so the suite
was validating a combination the manifest forbade. And the crosshair fix below
lives in ApexCharts 7.1.0: on a zoomed chart with indicators the crosshair drew
on the wrong bar, off by one bar-width per warm-up bar (259px three wheel
notches in, 2056px at nine), and the main chart and each oscillator pane
disagreed with each other because their warm-ups differ.

The headline additions are a financial-analysis workspace (getRangeStats,
getDrawdown, measureRange, a drawdown pane, weighted pane heights),
comparison v2 with baseline policies and a benchmark role, cross-chart
sync
, event markers, an on-chart data legend, price-scale modes
(linear / log / percent / indexed), a theme preset pack with
registerTheme, toolbar customization, and a unified export() covering
png / svg / pdf / csv / json, the PDF written without adding a dependency.

Also new is rangeChanging, a per-frame companion to rangeChange. If you have
custom chrome that must follow a zoom gesture, subscribe to it: rangeChange
fires once when the gesture settles, by design, so chrome hung off it alone
freezes for the duration of a wheel zoom.

The three framework wrappers are released alongside at 0.2.2 with the matching
peer requirement.

Added

  • Drawdown as a first-class pane, and per-pane heights. Phase 4 of the
    financial-analysis workspace (see plans/financial-analysis-workspace.md):
    price on top, how far underwater it is below, on one shared x-axis and zoom.

    • updateIndicator("drawdown") toggles an analysis pane plotting percent below
      the running peak, with zero pinned to the top of the axis (a drawdown is
      never positive) and the deepest point labelled on the pane itself. It is an
      ordinary oscillator-registry entry, so it inherits the whole pane machinery:
      stacking with other panes, the shared zoom, the theme rebuild, getDataAt,
      getState/setState, and the settings-free dropdown entry. No new pane
      system, and no separate API.
    • It measures on the chart's analysis.drawdownBasis, so the pane,
      getRangeStats(), and getDrawdown() cannot disagree, and the basis
      round-trips in state with the pane.
    • It streams incrementally on appendData: the state is the running peak, so
      the step is O(1) with no warm-up period. The pane's "max" label is
      re-asserted after each append, so a new deeper trough moves it instead of
      leaving a stale line behind.
    • The indicators dropdown groups it under an Analysis heading (a new
      optional group on a registry entry), keeping analysis views distinct from
      technical indicators without adding a second control.
    • Per-pane heights. Panes now divide the indicator area in proportion to a
      relative heightRatio rather than always evenly: the drawdown pane takes 1.4
      shares (it is cumulative, so it earns the room) and everything else takes 1.
      Configure with panes: { drawdown: { heightRatio: 2 } } at construction, or
      setPaneHeightRatio(key, ratio) / getPaneHeightRatios() at runtime (null
      restores the pane's default). The heights always add up to the container
      exactly, and the ratios you set are captured by getState() as a new panes
      key.
      See the README "The drawdown pane" section.
  • Comparison persists, and the analysis can be exported. Phase 5 of the
    financial-analysis workspace (see plans/financial-analysis-workspace.md).

    • getState() gains a comparison key: the mode, benchmark, alignment policy,
      and each instrument's name and color. Instrument data is deliberately not
      captured
      : your app fetches it, it runs to thousands of bars per instrument,
      and it would be stale the moment it was written to storage. So setState()
      restores the setup, keeps any instrument whose data is still loaded, and
      emits the new comparisonRestoreNeeded event with { names } for the
      rest, which the consumer re-supplies with addComparison (the remembered
      color is reapplied). A benchmark whose instrument has not come back yet is
      remembered by name, with the primary filling the role until it does. Same
      division of labour as the price lines' interactive callbacks.
    • Measurements need no state key of their own: a measurement is a measure
      drawing, so it already round-tripped inside drawings.
    • exportData / export gain include, which carries the analysis into an
      export and means something appropriate to each medium. For csv/json:
      "indicators" adds one column per active indicator series (main-chart
      overlays and oscillator panes, null through each warm-up) and
      "analysis" adds return and drawdown per bar. For pdf: "analysis"
      sets a text summary below the chart image (the window's dates and bar count,
      change, high, low, average, volume, annualized return, volatility, max
      drawdown, and the comparison leaderboard when one is active), overridable
      with summary: string[]. The PDF summary follows range, defaulting to the
      visible window there, so the exported numbers describe what you were looking
      at.
    • The OHLC columns are always present, so a CSV keeps round-tripping through
      ApexStock.fromCSV whatever you add, and an extra column whose name collides
      with a spine column is suffixed rather than overwriting it. Range statistics
      are a summary, not a per-bar value, so they are not columns; read them from
      getRangeStats().
    • The PDF summary is still dependency-free: buildPdfFromJpeg grows the page
      for a text band below the image and sets it in Helvetica, one of the PDF
      base-14 fonts, so there is nothing to embed.
      See the README "State Persistence" and "Exporting the analysis" sections.
  • Comparison v2: instrument alignment, baseline policies, indexed / relative /
    ratio modes, the benchmark role, and getComparisonStats().
    Phase 3 of the
    financial-analysis workspace (see plans/financial-analysis-workspace.md):
    comparison mode now answers "who's up more" fairly even when the instruments
    do not share a calendar.

    • Every instrument, the primary included, is aligned onto one shared x grid
      before anything is normalized, so a newer listing, a different holiday
      calendar, or a missing day no longer skews the comparison.
      setComparisonOptions({ join, fill, baseline, indexBase, source, rebaseRatio, resample }) / getComparisonOptions() expose the policies:
      join ("union" by default, or "primary" to resample onto the primary's
      bars, or "intersection") and fill ("hold" by default, or "gap", or
      "drop").
    • A carried-forward value is used for the math but is not plotted, so a
      line never shows a bar its instrument does not have.
      getComparisonStats() reports how many points were filled.
      resample: true plots the filled grid instead (the default for
      join: "primary", which exists to resample).
    • Baseline policies: "common" (the new default) rebases at the first x
      where every instrument has data; earlier history still plots, as a negative
      percent, rather than being hidden. "own" is the previous behavior, kept for
      compatibility. "visible" rebases to the left edge of the visible window and
      follows the zoom. A number is an explicit x value.
    • Three new modes on top of absolute and percent: indexed (the baseline
      reads indexBase, default 100, the "100 = starting value" view), relative
      (percentChange(asset) - percentChange(benchmark), in percentage points,
      where zero means "kept pace"), and ratio (asset / benchmark, rebased to
      indexBase).
    • The benchmark is a role, not a ticker:
      setComparisonBenchmark(name | "__primary__") /
      getComparisonBenchmark() points it at any added instrument or the chart's
      own symbol (the default). In relative and ratio mode the benchmark's own
      line becomes the flat reference, so what everything is measured against is
      visible on the chart. Removing that instrument hands the role back to the
      primary. No symbol is hard-coded anywhere in the library.
    • getComparisonStats({ from?, to? }) returns the leaderboard ready to render:
      one row per instrument (primary included) with change, excess return vs the
      benchmark, high and low, volatility, worst drawdown, rank, and grid coverage.
      The window runs from the baseline to the last observation, so with
      baseline: "visible" the rows follow the zoom. Volatility and drawdown are
      measured on each instrument's own observations, so a weekly line on a
      daily grid is not annualized as if it had 252 bars a year.
    • New event comparisonChange
      ({ reason, mode, benchmark, baseline, instruments, stats, warnings }),
      carrying the recomputed leaderboard and skipped entirely when nothing is
      subscribed. baseline reports the policy actually applied, which can fall
      back to "own" when no x value has data for every instrument.
    • Declarative defaults via
      analysis: { comparison: { mode, benchmark, join, fill, baseline, indexBase, source } }. A benchmark named there is remembered until its instrument is
      added, with the primary filling the role (and saying so in warnings) until
      then. Unknown option values are warned about and ignored rathe...
Read more