Four Pillars of Destiny (BaZi)¶
A BaZi engine computing the four natal pillars (eight characters), Ten Gods and five-element analysis, luck pillars (大运) and the annual pillar, with a selectable time model.
from fortune_telling_core import Querent, ReadingRequest
from fortune_telling_core.traditions.four_pillars import (
FOUR_PILLARS_DECK,
FOUR_PILLARS_SPREAD,
build_engine,
)
engine = build_engine()
request = ReadingRequest(
deck_id=FOUR_PILLARS_DECK.id,
spread_id=FOUR_PILLARS_SPREAD.id,
querent=Querent(
id="sample",
display_name="Sample",
attributes={
"birth_datetime": "1990-01-01T12:00:00+00:00",
"latitude": "51.5074",
"longitude": "-0.1278",
"gender": "male",
"target_year": "2026",
},
),
)
reading = engine.cast(request)
The annual pillar (流年) year defaults to the request-level
as_of moment (or requested_at when unset); the
target_year attribute overrides it when you need a specific year.
four_pillars ¶
FOUR_PILLARS_DECK
module-attribute
¶
FOUR_PILLARS_DECK = Deck(
id="fp.deck.ganzhi.v1",
symbols=tuple(
(
Symbol(
id=f"fp.stem.{stem.slug}",
name=f"{stem.cjk} {stem.slug.title()}",
attributes={
"kind": "stem",
"cjk": stem.cjk,
"element": stem.element.value,
"polarity": stem.polarity.value,
},
)
)
for stem in STEMS
)
+ tuple(
(
Symbol(
id=f"fp.branch.{branch.slug}",
name=f"{branch.cjk} {branch.animal}",
attributes={
"kind": "branch",
"cjk": branch.cjk,
"element": branch.element.value,
"polarity": branch.polarity.value,
"animal": branch.animal,
"hidden_stems": ",".join(
(str(index))
for index in (branch.hidden_stems)
),
},
)
)
for branch in BRANCHES
),
)
FOUR_PILLARS_SPREAD
module-attribute
¶
FOUR_PILLARS_SPREAD = Spread(
id="fp.spread.natal.v1",
name="Four Pillars",
positions=(
Position(
"year_stem",
"Year Stem",
"Heavenly stem of the year pillar.",
),
Position(
"year_branch",
"Year Branch",
"Earthly branch of the year pillar.",
),
Position(
"month_stem",
"Month Stem",
"Heavenly stem of the month pillar.",
),
Position(
"month_branch",
"Month Branch",
"Earthly branch of the month pillar.",
),
Position(
"day_stem",
"Day Stem",
"Heavenly stem of the day pillar and Day Master.",
),
Position(
"day_branch",
"Day Branch",
"Earthly branch of the day pillar.",
),
Position(
"hour_stem",
"Hour Stem",
"Heavenly stem of the hour pillar.",
),
Position(
"hour_branch",
"Hour Branch",
"Earthly branch of the hour pillar.",
),
),
)
FourPillarsEngine ¶
FourPillarsEngine(
ephemeris: Ephemeris | None = None,
*,
time_model: TimeModel = TimeModel.CLOCK,
day_boundary: DayBoundary = DayBoundary.MIDNIGHT,
luck_count: int = 8,
)
Bases: AbstractEngine
Four Pillars engine using shared solar-term astronomy.
The engine deterministically computes year, month, day, and hour pillars, then enriches the reading summary with element balance, Day Master strength, Luck Pillars, and the annual pillar.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ephemeris
|
Ephemeris | None
|
Optional backend implementing the shared ephemeris protocol.
Defaults to |
None
|
time_model
|
TimeModel
|
Default time adjustment model used when the request does not specify one. |
CLOCK
|
day_boundary
|
DayBoundary
|
Default day-boundary rule used when the request does not specify one. |
MIDNIGHT
|
luck_count
|
int
|
Default number of Luck Pillars to render. |
8
|
Source code in src/fortune_telling_core/traditions/four_pillars/engine.py
deck ¶
Return the Four Pillars stem and branch deck.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
ReadingRequest
|
Reading request whose |
required |
Returns:
| Type | Description |
|---|---|
Deck
|
The bundled stem and branch deck. |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If the requested deck is unsupported. |
Source code in src/fortune_telling_core/traditions/four_pillars/engine.py
spread ¶
Return the eight-position Four Pillars spread.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
ReadingRequest
|
Reading request whose |
required |
Returns:
| Type | Description |
|---|---|
Spread
|
The bundled Four Pillars spread. |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If the requested spread is unsupported. |
Source code in src/fortune_telling_core/traditions/four_pillars/engine.py
draw ¶
Compute Four Pillars as a deterministic draw.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
ReadingRequest
|
Reading request with birth data. |
required |
rng
|
Rng
|
Ignored. The argument is present for |
required |
Returns:
| Type | Description |
|---|---|
Draw
|
A draw with stem and branch selections for the four pillars. |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If required birth data or options are invalid. |
EphemerisError
|
If the configured ephemeris cannot compute solar terms. |
Source code in src/fortune_telling_core/traditions/four_pillars/engine.py
cast ¶
Compute Four Pillars without a caller RNG.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
ReadingRequest
|
Reading request containing birth data and optional BaZi configuration. |
required |
Returns:
| Type | Description |
|---|---|
Reading
|
A reading with pillar placements and BaZi summary text. |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If required birth data or options are invalid. |
EphemerisError
|
If the configured ephemeris cannot compute solar terms. |
Source code in src/fortune_telling_core/traditions/four_pillars/engine.py
build_engine ¶
build_engine(
ephemeris: Ephemeris | None = None,
*,
time_model: TimeModel = TimeModel.CLOCK,
day_boundary: DayBoundary = DayBoundary.MIDNIGHT,
luck_count: int = 8,
) -> FourPillarsEngine
Create a Four Pillars engine.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ephemeris
|
Ephemeris | None
|
Optional ephemeris backend. Defaults to the built-in pure-Python backend. |
None
|
time_model
|
TimeModel
|
Default time adjustment model. |
CLOCK
|
day_boundary
|
DayBoundary
|
Default day-boundary rule. |
MIDNIGHT
|
luck_count
|
int
|
Default number of Luck Pillars to render. |
8
|
Returns:
| Type | Description |
|---|---|
FourPillarsEngine
|
A new |