Systemicalpha

Cosine

systemic:core-cosMathfunction1 cr

Inputs

NameTypeDescription
DatafloatarrayThe Data input receives a series of numeric values to be transformed using the cosine function.

Outputs

NameTypeDescription
CosfloatarrayThe Cos output provides the cosine value for each input angle.

The Cosine module computes the cosine of each input value, interpreting them as angles measured in radians.


The Formula

For each input value θi\theta_i, the output is:

Ci=cos⁡(θi)C_i = \cos(\theta_i)

The cosine function maps an angle to the x-coordinate of the corresponding point on the unit circle. This seemingly simple operation unlocks a world of applications in finance, from encoding cyclical patterns to analyzing market phases.


The Unit Circle: Cosine's Geometric Heart

The unit circle—a circle with radius 1 centered at the origin—provides the most intuitive way to understand cosine. As an angle θ\theta sweeps counterclockwise from the positive x-axis, the cosine value equals the x-coordinate of the point where the angle's terminal side intersects the circle.

Angle (radians)Angle (degrees)Cosine ValuePosition on Circle
000°+1.0Rightmost point (3 o'clock)
π2\frac{\pi}{2}90°0.0Top (12 o'clock)
π\pi180°-1.0Leftmost point (9 o'clock)
3π2\frac{3\pi}{2}270°0.0Bottom (6 o'clock)
2π2\pi360°+1.0Back to start

Key Mathematical Properties

PropertyDescription
Period2π2\pi radians (360°) — the function repeats every full rotation
Range[−1,+1][-1, +1] — output is always bounded
Even Functioncos⁡(−θ)=cos⁡(θ)\cos(-\theta) = \cos(\theta) — symmetric about the y-axis
ContinuousInfinitely differentiable, producing smooth transitions
Phase Relationshipcos⁡(θ)=sin⁡(θ+π2)\cos(\theta) = \sin(\theta + \frac{\pi}{2}) — leads sine by 90°

Critical Note: Radians, Not Degrees

⚠️ The Cosine module interprets all input values as radians.

If your data is in degrees, convert it first using the formula:

θradians=θdegrees×π180\theta_{radians} = \theta_{degrees} \times \frac{\pi}{180}
DegreesRadiansCosine
0°01.0
45°π4≈0.785\frac{\pi}{4} \approx 0.7850.707
60°π3≈1.047\frac{\pi}{3} \approx 1.0470.5
90°π2≈1.571\frac{\pi}{2} \approx 1.5710.0
180°π≈3.14\pi \approx 3.14-1.0

Creative Applications in Finance

1. Cyclical Time Encoding for Machine Learning

Financial markets exhibit powerful cyclical patterns: daily trading sessions, weekly flows (Fridays often see different behavior than Mondays), monthly portfolio rebalancing, and annual tax-driven effects like the January Effect.

Traditional approaches encode time features as categorical variables (e.g., "January", "February"...), but this creates an artificial discontinuity: December 31 appears completely unrelated to January 1, when in reality they're adjacent points in a continuous cycle.

Cosine encoding solves this elegantly. By transforming time into an angle and taking its cosine (paired with sine), we create a smooth, continuous representation where December 31 naturally connects to January 1.

The Encoding Formula

For any cyclical feature with period PP:

θ=2π×valueP\theta = \frac{2\pi \times \text{value}}{P}

Then apply cosine (and sine for the complementary component):

Time FeaturePeriod (PP)Conversion
Hour of day24θ=2π×hour24\theta = \frac{2\pi \times hour}{24}
Day of week7θ=2π×day7\theta = \frac{2\pi \times day}{7}
Month of year12θ=2π×(month−1)12\theta = \frac{2\pi \times (month - 1)}{12}
Day of year365θ=2π×(day−1)365\theta = \frac{2\pi \times (day - 1)}{365}

Why This Matters

Research from NVIDIA demonstrates that cyclical sine/cosine encoding captures temporal patterns that traditional dummy variables miss. When building predictive models for asset prices or trading signals, this encoding:

  • Preserves the continuity between cycle endpoints
  • Reduces feature dimensionality (2 features vs. 12 for months)
  • Works naturally with linear models and neural networks
  • Captures where you are within any repeating cycle

2. Bitcoin's Four-Year Halving Cycle

One of the most documented cycles in cryptocurrency markets is Bitcoin's approximately four-year halving cycle. Every 210,000 blocks (roughly 4 years), the block reward is cut in half, creating a supply shock that has historically preceded major bull runs.

Using cosine encoding, we can represent where we are within this cycle and potentially identify whether we're in an "accumulation" phase (cycle trough) or "distribution" phase (cycle peak).

The halving dates are:

  • November 28, 2012 — Block reward: 50 → 25 BTC
  • July 9, 2016 — Block reward: 25 → 12.5 BTC
  • May 11, 2020 — Block reward: 12.5 → 6.25 BTC
  • April 19, 2024 — Block reward: 6.25 → 3.125 BTC
xychart-beta
    title "Bitcoin Monthly Prices (2020-2025)"
    x-axis ["Jan20", "Apr20", "Jul20", "Oct20", "Jan21", "Apr21", "Jul21", "Oct21", "Jan22", "Apr22", "Jul22", "Oct22", "Jan23", "Apr23", "Jul23", "Oct23", "Jan24", "Apr24", "Jul24", "Oct24", "Jan25"]
    y-axis "Price (USD)" 0 --> 130000
    bar [9336, 8607, 11335, 13795, 33136, 57758, 41701, 61340, 38472, 37660, 23314, 20504, 23153, 29311, 29226, 34650, 42611, 60762, 64666, 70340, 102411]

The May 2020 halving (at approximately 9,000)wasfollowedbyan11−monthclimbtoall−timehighsabove9,000) was followed by an 11-month climb to all-time highs above 60,000. By encoding time since the last halving as a cosine value, models can learn this cyclical relationship without memorizing specific dates.

💡 Experiment Idea: Create a system that combines Bitcoin price with a halving cycle phase indicator (using cosine of the days-since-halving angle). Observe whether extremes in the phase indicator correlate with major market tops or bottoms.


3. Fourier Decomposition: The Building Blocks of Price Movement

One of the most profound insights from mathematics is Fourier's theorem: any periodic signal can be decomposed into a sum of sines and cosines of different frequencies.

In principle, a price series could be viewed as a combination of:

  • Long-term cycles (secular bull/bear markets)
  • Medium-term cycles (business cycles, months)
  • Short-term cycles (weekly patterns, daily volatility)
  • Noise (random fluctuations)
flowchart LR
    subgraph "Price Signal Decomposition"
        A[Raw Price Data] --> B[Trend Component]
        A --> C["Long Cycle<br/>cos(annual phase)"]
        A --> D["Medium Cycle<br/>cos(monthly phase)"]
        A --> E["Short Cycle<br/>cos(weekly phase)"]
        A --> F[Residual Noise]
    end
    
    B --> G[Reconstructed<br/>Smooth Signal]
    C --> G
    D --> G
    E --> G

While Fourier analysis has mixed results for price prediction (markets are too noisy and non-stationary), understanding this framework helps explain why cyclical encoding works: you're essentially providing the model with the phase information for known, real-world cycles (time of day, day of week, etc.) rather than trying to discover unknown cycles in noisy data.

📚 Further Study: John Ehlers' work on Digital Signal Processing in trading provides deeper exploration of these concepts, including the Hilbert Transform for phase detection.


Pairing Cosine with Sine: Complete Circular Representation

A critical insight: cosine alone cannot uniquely identify a position within a cycle. Consider that cos⁡(π3)=cos⁡(5π3)=0.5\cos(\frac{\pi}{3}) = \cos(\frac{5\pi}{3}) = 0.5, yet these represent completely different positions on the unit circle.

The solution is to use both cosine and sine together, creating a 2D representation where every point in the cycle maps to a unique (x,y)(x, y) coordinate:

x=cos⁡(θ),y=sin⁡(θ)x = \cos(\theta), \quad y = \sin(\theta)
flowchart TD
    subgraph "Why You Need Both"
        A["θ = π/3<br/>(60°)"] --> B["cos = 0.5<br/>sin = 0.87"]
        C["θ = 5π/3<br/>(300°)"] --> D["cos = 0.5<br/>sin = -0.87"]
    end
    
    B --> E["Upper right<br/>of circle"]
    D --> F["Lower right<br/>of circle"]
    
    G["Same cosine value<br/>but different positions!"] -.-> A
    G -.-> C

When encoding cyclical features for machine learning:

  • Use the Cosine module for the x-component
  • Use the Sine module for the y-component
  • Connect both to the same angle input

This creates what researchers call a "circular embedding" that machine learning models can interpret correctly.


Input Behavior and Data Alignment in Systemic

When the Cosine module receives inputs from other modules in Systemic, the platform automatically aligns data of different frequencies through upsampling and padding.

How This Works

If you connect two data sources with different frequencies:

  1. Upsampling: Lower-frequency data is expanded to match higher-frequency data by repeating the last known value
  2. Padding: Shorter series are extended to match longer ones by repeating the final value

Example: If you're computing the cosine of a daily time-phase indicator but connecting it to hourly price data, the daily values will be repeated for each hour until the next day's value appears.

For the Cosine module specifically, this behavior means:

  • Constant angle inputs work naturally
  • Phase values from lower-frequency time encodings will "step" through the day rather than interpolate smoothly
  • Consider computing time phases at the same frequency as your primary data for smoother results

Missing Data

When an input position is missing (null) — for example, a stock series has no bar on a weekend or holiday — the output at that same position is null. Values are never invented to fill a gap: every non-null output is the true cosine of a real datapoint, and the output keeps the same length as the input so every value stays aligned with its timestamp. A fabricated 0.0 would be indistinguishable from a genuine 90° phase reading and silently corrupt downstream signals.

In live mode, the module returns exactly one datapoint — the most recent position — and it may be null when no bar exists at that moment (e.g., a weekend tick on a market-hours series). That gap is correct, not an error.


Handling Invalid Inputs

An infinite input (±∞) is a real datapoint whose cosine simply does not exist — the function keeps oscillating and never settles as the angle grows without bound. This is distinct from missing data, where no datapoint exists at all. Both surface as null in the output, but they mean different things:

  • Missing input → null: there was no bar to compute from
  • ±Infinity input → null: there was a bar, but the math is undefined for it

Every finite angle, however large, produces a valid cosine (effectively reduced modulo 2π2\pi).


Edge Cases and Special Values

InputCosine OutputNotes
01.0Starting position
Missing (null)nullGap preserved at the same position — never filled
NaNnullTreated as missing data
±InfinitynullCosine is mathematically undefined for an infinite angle
Very large numbersValid resultEffectively reduced modulo 2π2\pi
Negative anglesSame as positiveEven function symmetry

Further Reading

Rendering diagrams...
© 2026 WanoLabs. All rights reservedAlpha build v0.1.5