npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vulcan-js/strategies

v0.2.0

Published

Composable trading strategies with structured signal output for the Vulcan library

Downloads

56

Readme

@vulcan-js/strategies

Composable trading strategies for the Vulcan library. Combines multiple indicators into structured signal output with position management.

Installation

pnpm add @vulcan-js/strategies

Usage

Built-in strategies

Every strategy is a generator function (just like indicators). Pass OHLCV bars and iterate over signals:

import { collect } from '@vulcan-js/core'
import { goldenCross } from '@vulcan-js/strategies'

const bars = [
  { o: 10, h: 12, l: 9, c: 11, v: 1000 },
  { o: 11, h: 13, l: 10, c: 12, v: 1200 },
  // ...
]

// Collect all signals
const signals = collect(goldenCross(bars, { fastPeriod: 10, slowPeriod: 30 }))

// Or iterate lazily
for (const signal of goldenCross(bars)) {
  console.log(signal.action) // 'long' | 'short' | 'close' | 'hold'
  console.log(signal.reason) // human-readable explanation
}

Use .create() for real-time / streaming scenarios:

import { goldenCross } from '@vulcan-js/strategies'

const process = goldenCross.create({ fastPeriod: 10, slowPeriod: 30 })

// Feed bars one by one
const signal = process({ o: 10, h: 12, l: 9, c: 11, v: 1000 })

Custom strategies

Use createStrategy to build your own strategy. It mirrors createSignal from core, but adds a rolling window of historical bars and structured signal output:

import { ema } from '@vulcan-js/indicators'
import { createStrategy } from '@vulcan-js/strategies'

const myStrategy = createStrategy(
  ({ emaPeriod, threshold }) => {
    const emaProc = ema.create({ period: emaPeriod })

    return (ctx) => {
      const price = ctx.bar.c
      const emaValue = emaProc(price)

      // Access historical bars via ctx.bars (oldest first)
      // Access current bar index via ctx.index

      return { action: 'hold' }
    }
  },
  { windowSize: 10, emaPeriod: 20, threshold: 0.05 },
)

API

createStrategy(factory, defaultOptions)

Creates a generator-based strategy from a factory function.

Returns a StrategyGenerator with:

  • Generator iterationstrategy(source, options?) yields StrategySignal for each bar
  • .create(options?) — returns a stateful Processor<CandleData, StrategySignal> for point-by-point feeding
  • .defaultOptions — the default options for the strategy

The factory receives resolved options and returns a function (ctx: StrategyContext) => StrategySignal. The StrategyContext provides:

| Property | Type | Description | | --- | --- | --- | | bar | CandleData | The current OHLCV bar | | bars | readonly CandleData[] | Rolling window of historical bars (oldest first, includes current bar) | | index | number | Zero-based index of the current bar since the strategy started |

StrategySignal

| Property | Type | Description | | --- | --- | --- | | action | 'long' \| 'short' \| 'close' \| 'hold' | The recommended action | | size? | number | Position size as a fraction (0–1) | | stopLoss? | number | Stop-loss price level | | takeProfit? | number | Take-profit price level | | reason? | string | Human-readable reason for the signal |

BaseStrategyOptions

All strategy options must extend BaseStrategyOptions:

| Property | Type | Description | | --- | --- | --- | | windowSize | number | Number of historical bars to keep in the rolling window |

Built-in Strategies

| Strategy | Function | Alias | Description | | --- | --- | --- | --- | | Golden Cross / Death Cross | goldenCross | goldenCrossStrategy | Detects fast SMA crossing above/below slow SMA | | RSI Oversold/Overbought | rsiOversoldOverbought | rsiOversoldOverboughtStrategy | Detects RSI crossing oversold/overbought levels |

Golden Cross

Detects when a fast SMA crosses above (golden cross) or below (death cross) a slow SMA. Includes stop-loss based on a configurable percentage.

| Option | Type | Default | Description | | --- | --- | --- | --- | | fastPeriod | number | 50 | Fast SMA period | | slowPeriod | number | 200 | Slow SMA period | | stopLossPercent | number | 0.02 | Stop-loss percentage (0–1) | | windowSize | number | 2 | Rolling window size |

RSI Oversold/Overbought

Uses the Relative Strength Index to detect oversold and overbought reversal conditions.

| Option | Type | Default | Description | | --- | --- | --- | --- | | period | number | 14 | RSI calculation period | | overboughtLevel | number | 70 | RSI level considered overbought | | oversoldLevel | number | 30 | RSI level considered oversold | | windowSize | number | 2 | Rolling window size |

License

MIT