Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
marketcalls avatar

Custom Indicator

  • 390 installs
  • 13 repo stars
  • Updated June 12, 2026
  • marketcalls/openalgo-indicator-skills

custom-indicator is an agent skill that scaffolds production-grade OpenAlgo technical indicators from Rust-core ta primitives and vectorized NumPy for developers who need backtest-safe signal logic.

About

custom-indicator is a Claude Code skill in marketcalls/openalgo-indicator-skills that authors custom technical indicators by composing OpenAlgo Rust-core ta primitives with vectorized NumPy. The skill reads indicator-expert rules, accepts an indicator name argument such as zscore, squeeze, vwap-bands, or custom-rsi, and generates O(n) indicator functions with charting and benchmarking hooks. Developers reach for custom-indicator when building algorithmic trading strategies that need correct inputs, outputs, signal logic, and backtest-safe calculations beyond built-in indicators. Allowed tools include Read, Write, Edit, Bash, Glob, and Grep for inspecting rules and writing indicator modules.

  • Indicator parameter design
  • Signal and plot definitions
  • OpenAlgo API conventions
  • Backtest-safe calculations
  • Reusable strategy primitives

Custom Indicator by the numbers

  • 390 all-time installs (skills.sh)
  • +21 installs in the week ending Aug 2, 2026 (Skillselion tracking)
  • Ranked #275 of 1,106 Finance & Trading skills by installs in the Skillselion catalog
  • Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/marketcalls/openalgo-indicator-skills --skill custom-indicator

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs390
repo stars13
Last updatedJune 12, 2026
Repositorymarketcalls/openalgo-indicator-skills

How do you build custom OpenAlgo indicators with NumPy?

Author custom OpenAlgo trading indicators with correct inputs, outputs, signal logic, and backtest-safe calculations for algorithmic strategies.

Who is it for?

Quant developers and algo engineers implementing custom signals on OpenAlgo with NumPy and Rust-core ta primitives.

Skip if: Developers who only need prebuilt indicators without custom signal logic or who are not using the OpenAlgo trading stack.

When should I use this skill?

A developer asks to create, extend, or benchmark a custom technical indicator for OpenAlgo algorithmic strategies.

What you get

O(n) indicator Python functions, signal logic modules, charting hooks, and benchmark-ready calculations

  • Custom indicator function
  • Signal logic module
  • Benchmark-ready calculation code

By the numbers

  • Generates O(n) indicator functions from Rust-core ta primitives
  • Allowed-tools list includes Read, Write, Edit, Bash, Glob, and Grep

Files

SKILL.mdMarkdownGitHub ↗

Create a custom technical indicator by composing openalgo's Rust-core ta primitives with vectorized NumPy.

Arguments

  • $0 = indicator name (e.g., zscore, squeeze, vwap-bands, custom-rsi, mean-reversion). Required.

If no arguments, ask the user what indicator they want to build.

Instructions

1. Read the indicator-expert rules, especially:

  • rules/custom-indicators.md — NumPy + ta-primitive patterns and templates
  • rules/performance.md — Rust core performance, O(n) guarantees, benchmarking
  • rules/indicator-catalog.md — Check if indicator already exists in openalgo.ta

2. Check first: If the indicator already exists in openalgo.ta (100+ indicators), tell the user and show the existing API 3. Create custom_indicators/{indicator_name}/ directory (on-demand) 4. Create {indicator_name}.py with:

File Structure

"""
{Indicator Name} — Custom Indicator
Description: {what it measures}
Category: {trend/momentum/volatility/volume/oscillator}
"""
import numpy as np
import pandas as pd
from openalgo import ta

# --- Core Computation (vectorized NumPy on ta primitives) ---
def _compute_{name}(arr: np.ndarray, period: int) -> np.ndarray:
    """Vectorized core computation built on Rust-core primitives."""
    n = len(arr)
    result = np.full(n, np.nan)
    # Compose from ta primitives (they run in Rust):
    # mean = ta.sma(arr, period); std = ta.stdev(arr, period); ...
    # then combine with NumPy array math (np.where, masks)
    return result

# --- Public API ---
def {name}(data, period=20):
    """
    {Indicator Name}

    Args:
        data: Close prices (numpy array, pandas Series, or list)
        period: Lookback period (default: 20)

    Returns:
        Same type as input with indicator values
    """
    if isinstance(data, pd.Series):
        idx = data.index
        result = _compute_{name}(data.values.astype(np.float64), period)
        return pd.Series(result, index=idx, name="{Name}({period})")
    arr = np.asarray(data, dtype=np.float64)
    return _compute_{name}(arr, period)

5. Create chart.py for visualization:

"""Chart the custom indicator with Plotly."""
import os
from pathlib import Path
from datetime import datetime, timedelta
from dotenv import find_dotenv, load_dotenv
from openalgo import api, ta
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from {indicator_name} import {name}

# ... fetch data, compute indicator, create chart ...

6. Create benchmark.py for performance testing (no warmup needed — the Rust core runs at full speed from the first call):

"""Benchmark the custom indicator."""
import numpy as np
import time
from {indicator_name} import {name}

for size in [10_000, 100_000, 500_000]:
    data = np.random.randn(size).cumsum() + 1000
    t0 = time.perf_counter()
    _ = {name}(data, 20)
    elapsed = (time.perf_counter() - t0) * 1000
    print(f"{size:>10,} bars: {elapsed:>8.2f}ms")

NumPy Rules (CRITICAL)

MUST DO

  • Compose from ta primitives wherever possible — they run in the Rust core
  • np.full(n, np.nan) to initialize output arrays
  • Vectorize with array expressions, np.where, and boolean masks
  • Guard divisions: np.errstate(invalid="ignore", divide="ignore") plus a safe denominator mask
  • Respect NaN warm-up periods from the primitives (mask on ~np.isnan(...))
  • Float64 for all numeric arrays
  • O(n) algorithms only

MUST NOT

  • Never reimplement an indicator that already exists in openalgo.ta
  • Never write per-bar Python loops over large arrays — vectorize instead
  • Never divide without masking zero/NaN denominators
  • If the indicator is genuinely path-dependent (sequential state no primitive covers), check whether ta.ema / Wilder-style primitives already provide the recursion first; a plain Python loop is a last resort — keep it O(n) and document the trade-off

Available Building Blocks

Public ta methods that run in the Rust core:

from openalgo import ta

# Rolling math:    ta.sma, ta.ema, ta.wma, ta.stdev, ta.highest, ta.lowest
# Price action:    ta.true_range, ta.atr, ta.change, ta.roc
# Bands/channels:  ta.bbands, ta.keltner, ta.donchian
# Signals:         ta.crossover, ta.crossunder, ta.exrem, ta.rising, ta.falling

Common Custom Indicator Patterns

PatternImplementation
Z-Score(value - rolling_mean) / rolling_stdev
SqueezeBollinger inside Keltner channel
VWAP BandsVWAP + N * rolling stdev of (close - vwap)
Momentum ScoreWeighted sum of RSI + MACD + ADX conditions
Mean ReversionDistance from SMA as % + threshold
Range FilterATR-based dynamic filter on close
Trend StrengthADX + directional movement composite

Example Usage

/custom-indicator zscore /custom-indicator squeeze-momentum /custom-indicator vwap-bands /custom-indicator range-filter

Related skills

How it compares

Choose custom-indicator when you need new OpenAlgo signal logic composed from ta primitives rather than configuring existing chart indicators.

FAQ

What stack does custom-indicator use?

custom-indicator builds OpenAlgo indicators by composing Rust-core ta primitives with vectorized NumPy. The skill follows indicator-expert rules to produce O(n) functions with charting and benchmarking support for algorithmic strategies.

What indicator names can custom-indicator accept?

custom-indicator takes a required indicator-name argument such as zscore, squeeze, vwap-bands, custom-rsi, or mean-reversion. If no name is provided, the skill asks which indicator the developer wants before generating code.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.