PINE LIBRARY
Updated

blueprint_ephemeris_lib

2 095
🔭 Library blueprint_ephemeris_lib


Consolidated planetary ephemeris library with improved accuracy. Supersedes previous individual planet libraries (lib_vsop_core, lib_vsop_mercury, lib_vsop_venus, etc.). One import gives you geocentric/heliocentric positions for all 10 solar system bodies.


ACCURACY — VALIDATED AGAINST JPL DE440

Every planetary body was validated against NASA's DE440 ephemeris (via Skyfield). Using only 1.6% of the full VSOP87D theory (511 of 31,577 terms), this library achieves sub-arcminute accuracy for all planets:

Sun 0.004° (14 arcseconds)
Mercury 0.005° (18")
Venus 0.006° (22")
Mars 0.010° (36")
Jupiter 0.007° (25")
Saturn 0.009° (32")
Uranus 0.013° (47")
Neptune 0.017° (61")
Moon 0.062° (3.7')
Pluto 0.059° (3.5')

All bodies under 0.1° RMS — more than sufficient for aspect calculations, ingress timing, and planetary line work. The Sun is accurate to 14 arcseconds using a truncated series that fits entirely inside Pine Script's token limits.


WHAT'S NEW (V2)

The original ephemeris required 11 chained library imports. A full validation audit uncovered critical coefficient errors and motivated this rewrite:

L1[0] Precession Fix — All 8 VSOP87 planets had incorrect longitude rate coefficients (VSOP87B values instead of VSOP87D). Each was missing +0.24382 rad/millennium of general precession. This single correction reduced error from ~0.75° to < 0.1° across the board.

28% Smaller — 4,300 lines across 11 files → ~3,100 lines in 1 file.

Single Import — No dependency chain. Faster execution.

Moon Improvements — Functions accept raw `time` directly. Node functions renamed with explicit north/south designation.


THEORIES

VSOP87D (Bretagnon & Francou, 1988) — Mercury through Neptune
511 truncated terms out of 31,577 total (1.6%). Heliocentric spherical
coordinates in the ecliptic of date.

ELP2000-82 (Chapront-Touzé & Chapront, 1983) — Moon
91 terms (48 longitude + 43 latitude) from Meeus Chapter 47.

Meeus Series (Meeus, 1998) — Pluto
Analytical series from "Astronomical Algorithms" Ch. 37.
Valid ±1 century from J2000.


HOW TO USE

Import the library:
Pine Script®
import BlueprintResearch/blueprint_ephemeris_lib/1 as eph


Basic — plot a planet's geocentric longitude and declination:
Pine Script®
float jupiter_lon = eph.get_longitude(eph.Planet.Jupiter, time, true) float jupiter_decl = eph.get_declination(eph.Planet.Jupiter, time) plot(jupiter_lon, "Jupiter Geo Lon", color.yellow) plot(jupiter_decl, "Jupiter Decl", color.red)


Retrograde detection:
Pine Script®
bool mercury_retro = eph.is_retrograde(eph.Planet.Mercury, time) bgcolor(mercury_retro ? color.new(color.red, 90) : na)


Moon nodes and declination:
Pine Script®
float north_node = eph.get_mean_north_node_lon(time) float south_node = eph.get_mean_south_node_lon(time) float moon_decl = eph.get_declination(time) plot(north_node, "North Node", color.green) plot(south_node, "South Node", color.purple) plot(moon_decl, "Moon Declination", color.orange)


Dynamic planet selection from input:
Pine Script®
string planet_str = input.string("Sun", "Planet", options=["Sun", "Moon", "Mercury", "Venus", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"]) eph.Planet p = eph.string_to_planet(planet_str) float geo = eph.get_longitude(p, time, true) float helio = eph.get_longitude(p, time, false) float speed = eph.get_speed(p, time) plot(geo, "Geocentric", color.yellow) plot(helio, "Heliocentric", color.blue) plot(speed * 100, "Speed x100", color.white)


All functions accept TradingView's `time` variable directly.


FUNCTIONS

Unified API (all planets):
`get_longitude(Planet, time, preferGeo)` — geo or heliocentric longitude
`get_declination(Planet, time)` — equatorial declination
`get_speed(Planet, time)` — longitude speed (°/day)
`is_retrograde(Planet, time)` — true when retrograde
`string_to_planet(string)` — name to enum

Averages:
`get_avg6_geo_lon` / `get_avg6_helio_lon` — Mercury–Saturn
`get_avg8_geo_lon` / `get_avg8_helio_lon` — Mercury–Neptune

Moon (direct access):
`get_geo_ecl_lon(time)` · `get_geo_ecl_lat(time)` · `get_declination(time)`
`get_mean_north_node_lon(time)` · `get_mean_south_node_lon(time)`
`get_true_north_node_lon(time)` · `get_true_south_node_lon(time)`
`get_north_node_declination(time)` · `get_south_node_declination(time)`


LIMITATIONS

• Truncated series — sub-degree accuracy, not sub-arcsecond. More than sufficient for ingress timing and aspect work.
• Validated against DE440 across 250 years (1850–2100). Over this full span, the worst-case VSOP87 planet (Uranus) is 0.017° RMS / 0.043° max error. Ingress dates manually verified back to the late 1800s with consistent accuracy.
• Pluto uses Meeus series, limited to ±1 century from J2000.
• Moon has no speed function.



ACKNOWLEDGMENTS

Coefficient validation was made possible by Greg Miller's VSOP87 multi-language project, which provides the complete VSOP87D coefficient tables in accessible formats. His work converting the original Fortran data files into CSV/JSON for multiple languages was essential for identifying the L1[0] precession errors in the original libraries. Miller released this work into the public domain.
github.com/gmiller123456/vsop87-multilang

References:
• Meeus, Jean. Astronomical Algorithms (2nd Ed., 1998)
• Bretagnon & Francou. VSOP87 Solutions (Astronomy & Astrophysics, 1988)
• Chapront-Touzé & Chapront. ELP2000-82 (1983)


OPEN SOURCE

MIT License — part of the Blueprint Research open-source toolkit.
Source code on GitHub





get_geo_ecl_lon(time_)
  Returns geocentric ecliptic longitude of the Moon.
  Parameters:
    time_ (float)
  Returns: (float) Longitude in degrees, range [0, 360).

get_geo_ecl_lat(time_)
  Returns geocentric ecliptic latitude of the Moon.
  Parameters:
    time_ (float)
  Returns: (float) Latitude in degrees.

get_obliquity_j(time_)
  Returns mean obliquity of the ecliptic.
  Parameters:
    time_ (float)
  Returns: (float) Obliquity in degrees.

get_declination(time_)
  Returns geocentric equatorial declination of the Moon.
  Parameters:
    time_ (float)
  Returns: (float) Declination in degrees, range [-90, +90] where positive is north.

get_declination(p, t)
  Returns planetary geocentric equatorial declination.
  Parameters:
    p (series Planet): (Planet) Planet to query.
    t (float): (float) Unix timestamp in milliseconds (use built-in 'time' variable).
  Returns: (float) Geocentric declination in degrees, range [-90, +90] where positive is north.
note Declination is always geocentric (no heliocentric equivalent in library).

get_mean_north_node_lon(time_)
  Returns mean longitude of the Moon's North Node (ascending node).
  Parameters:
    time_ (float)
  Returns: (float) Longitude in degrees, range [0, 360).
note Mean node is a simple averaged calculation, reducing computational error. Used for declination calculations.

get_mean_south_node_lon(time_)
  Returns mean longitude of the Moon's South Node (descending node).
  Parameters:
    time_ (float)
  Returns: (float) Longitude in degrees, range [0, 360). Equals North Node + 180°.

get_true_north_node_lon(time_)
  Returns true longitude of the Moon's North Node with perturbation corrections.
  Parameters:
    time_ (float)
  Returns: (float) Longitude in degrees, range [0, 360).
note True node includes periodic perturbations but formula is low precision. Consider using mean node for consistency.

get_true_south_node_lon(time_)
  Returns true longitude of the Moon's South Node with perturbation corrections.
  Parameters:
    time_ (float)
  Returns: (float) Longitude in degrees, range [0, 360). Equals True North Node + 180°.

get_north_node_declination(time_)
  Returns declination of the Moon's North Node.
  Parameters:
    time_ (float)
  Returns: (float) Declination in degrees, range [-23.4, +23.4] (bounded by obliquity).
note Uses mean node for calculation (more consistent than true node).

get_south_node_declination(time_)
  Returns declination of the Moon's South Node.
  Parameters:
    time_ (float)
  Returns: (float) Declination in degrees. Inverse of North Node declination.

normalizeLongitude(lon)
  Normalizes any longitude value to the range [0, 360) degrees.
  Parameters:
    lon (float): (float) Longitude in degrees (can be any value, including negative or >360).
  Returns: (float) Normalized longitude in range [0, 360).

string_to_planet(planetStr)
  Converts a planet string identifier to Planet enum value.
  Parameters:
    planetStr (string): (string) Planet name (case-insensitive). Supports formats: "Sun", "☉︎ Sun", "sun", "SUN"
  Returns: (Planet) Corresponding Planet enum. Returns Planet.Sun if string not recognized.
note Supported planet strings: Sun, Moon, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto

get_longitude(p, t, preferGeo)
  Returns planetary longitude with automatic coordinate system selection.
  Parameters:
    p (series Planet): (Planet) Planet to query.
    t (float): (float) Unix timestamp in milliseconds (use built-in 'time' variable).
    preferGeo (bool): (bool) If true, return geocentric; if false, return heliocentric.
  Returns: (float) Longitude in degrees, normalized to range [0, 360).
note Sun and Moon always return geocentric regardless of preference (heliocentric not applicable).

get_speed(p, t)
  Returns planetary geocentric longitude speed (rate of change).
  Parameters:
    p (series Planet): (Planet) Planet to query.
    t (float): (float) Unix timestamp in milliseconds (use built-in 'time' variable).
  Returns: (float) Geocentric longitude speed in degrees per day. Negative values indicate retrograde motion. Returns na for Moon.
note Speed is always geocentric (no heliocentric equivalent in library). Moon speed calculation not implemented.

get_avg6_geo_lon(t)
  get_avg6_geo_lon
description Returns the arithmetic average of the geocentric longitudes for the six outer planets: Mars, Jupiter, Saturn, Uranus, Neptune, and Pluto.
  Parameters:
    t (float): (float) Time in Unix timestamp (milliseconds).
  Returns: (float) Average geocentric longitude of the six outer planets in degrees, range [0, 360).

get_avg6_helio_lon(t)
  get_avg6_helio_lon
description Returns the arithmetic average of the heliocentric longitudes for the six outer planets: Mars, Jupiter, Saturn, Uranus, Neptune, and Pluto.
  Parameters:
    t (float): (float) Time in Unix timestamp (milliseconds).
  Returns: (float) Average heliocentric longitude of the six outer planets in degrees, range [0, 360).

get_avg8_geo_lon(t)
  get_avg8_geo_lon
description Returns the arithmetic average of the geocentric longitudes for all eight classical planets: Mercury, Venus, Mars, Jupiter, Saturn, Uranus, Neptune, and Pluto.
  Parameters:
    t (float): (float) Time in Unix timestamp (milliseconds).
  Returns: (float) Average geocentric longitude of all eight classical planets in degrees, range [0, 360).

get_avg8_helio_lon(t)
  get_avg8_helio_lon
description Returns the arithmetic average of the heliocentric longitudes for all eight classical planets: Mercury, Venus, Mars, Jupiter, Saturn, Uranus, Neptune, and Pluto.
  Parameters:
    t (float): (float) Time in Unix timestamp (milliseconds).
  Returns: (float) Average heliocentric longitude of all eight classical planets in degrees, range [0, 360).

is_retrograde(p, t)
  Returns true if the planet is currently in retrograde motion (geocentric speed < 0) == 0 = stationary.
  Parameters:
    p (series Planet): The planet to check.
    t (float): Time in Unix timestamp (milliseconds).
  Returns: true if the planet is in retrograde, false otherwise.
Release Notes
V2 — 25 NEW FUNCTIONS + FULL DE440 VALIDATION

This update adds 25 new exported functions across 6 categories, bringing the total to 45. Every calculation has been validated against NASA's JPL DE440 ephemeris over 250 years (1850–2100).

New capabilities:

Ecliptic Latitude — geocentric and heliocentric latitude for all planets
Right Ascension & Heliocentric Declination — equatorial coordinates from both Earth and Sun perspectives
Distance — heliocentric radius (AU) and geocentric distance (AU)
Elongation — unsigned (0–180°) and signed (morning/evening star)
Aspects & Relationships — aspect angle, midpoint, synodic phase, speed differential, parallel, contraparallel
Visibility & Phase — phase angle, illuminated fraction
Zodiac — sign index, sign degree, sign name
Sidereal Time & Angles — GMST, LST, Ascendant/Descendant/Midheaven/IC, Whole Sign and Equal House cusps
Obliquity — mean obliquity of the ecliptic

For heliocentric synodic cycles, use Planet.Earth (e.g., Earth–Jupiter instead of Sun–Jupiter).

Accuracy (validated over 250 years vs DE440):

Longitude: 0.004°–0.062° RMS (all bodies < 0.1°)
Latitude: 0.0001°–0.093° RMS
Right Ascension: 0.006°–0.062° RMS
Helio Declination: 0.005°–0.028° RMS
Distance: 0.00001–0.006 AU RMS
Ascendant/MC: 0.021° RMS

Bug fixes:
• Fixed Jupiter speed L1[0] coefficient (was still using old VSOP87B value).
• Corrected Moon function parameter documentation.

Validation plots:

snapshot

Release Notes
v3
Disabled test plots.
Release Notes
v4- Ascendant Formula Fix

Summary

The get_angles() ASC formula had two bugs that combined, producing the descendant instead of the ascendant.
Release Notes
V5 — MOON DISTANCE + ANGULAR SIZE

2 new functions (47 total). Moon distance via ELP2000-82 sigma_r (46 cosine terms). Angular size for all bodies using IAU 2015 radii.

New:

get_moon_distance(t) — Moon's geocentric distance in km (~356,500–406,700 km). Uses ELP2000-82 distance series. Validated: 27.5 km RMS over 250 years (0.007%).

get_angular_size(p, t) — Apparent angular diameter in arcseconds. Works for all planets, the Sun, Moon, and Pluto. Returns na for Earth.
Sun: ~1,891–1,952" | Moon: ~1,764–2,010" | Venus: ~10–66"
Jupiter: ~30–50" | Saturn: ~15–21" | Mars: ~3.5–25"

Updated:

get_distance(Planet.Moon, t) — Now returns AU instead of na.

Accuracy vs DE440 (250 years):
Moon Distance: 27.5 km RMS (max 50.1 km)
Angular Size: Sun 0.28" | Moon 0.13" | Jupiter 0.008" | all others < 0.01"

Bug fix: eval_sigma_b had 44 terms instead of the correct 43 (extra trailing zero).

snapshot
Release Notes
v6 License updated to CC BY-NC-SA 4.0 (Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International)
Release Notes
v7 Update

Balanced VSOP87D longitude term expansion for improved outer planet accuracy.

  • Jupiter: 0.010° → 0.005° (50% improvement)
  • Saturn: 0.013° → 0.005° (58% improvement)
  • Uranus: 0.017° → 0.004° (78% improvement)


807 VSOP87D terms across all planets (up from ~270). Earth terms synced internally. All other API functions are unchanged from v6 with no regressions.

Pure theory; no empirical correction factors are applied here.

Disclaimer

The information and publications are not meant to be, and do not constitute, financial, investment, trading, or other types of advice or recommendations supplied or endorsed by TradingView. Read more in the Terms of Use.