# `ZenQuant.PowerLaw`
[🔗](https://github.com/ZenHive/zen_quant/blob/v0.8.1/lib/zen_quant/power_law.ex#L1)

Bitcoin Power Law model calculations.

The Power Law model describes Bitcoin's long-term price trend as a function
of time since the genesis block. It provides a framework for understanding
where current price sits relative to the historical trend.

## Model

The power law relationship: `log(price) = a + b * log(days_since_genesis)`

Where:
  * `a` - Intercept (approximately -17.01)
  * `b` - Slope (approximately 5.82)

## Example

    # Get fair value for today
    ZenQuant.PowerLaw.fair_value()
    # => 85000.0

    # Calculate z-score for current price
    ZenQuant.PowerLaw.z_score(95000.0)
    # => 0.35  (35% of a standard deviation above trend)

## References

- Harold Christopher Burger's original research
- Giovanni Santostasi's power law corridor model

## API Functions
| Function | Arity | Description | Param Kinds |
| --- | --- | --- | --- |
| `genesis_date` | 0 | Get the Bitcoin genesis block date. | - |
| `forecast` | 2 | Project fair value range to a future date offset. | `days_ahead: value`, `base: value` |
| `fair_value_range` | 1 | Returns 1-sigma and 2-sigma confidence bands around fair value. | `date_or_days: value` |
| `classify` | 2 | Classify price position in the power law corridor. | `price: value`, `date_or_days: value` |
| `days_since_genesis` | 1 | Get number of days since Bitcoin genesis block. | `date: value` |
| `resistance` | 2 | Calculate power law resistance price (upper band). | `date_or_days: value`, `deviations: value` |
| `support` | 2 | Calculate power law support price (lower band). | `date_or_days: value`, `deviations: value` |
| `z_score` | 2 | Calculate how many standard deviations price is from fair value. | `price: value`, `date_or_days: value` |
| `fair_value` | 1 | Calculate BTC fair value based on the power law model. | `date_or_days: value` |

# `classify`

```elixir
@spec classify(number(), Date.t() | DateTime.t() | pos_integer() | nil) ::
  :extreme_low | :undervalued | :fair | :overvalued | :extreme_high
```

Classify price position in the power law corridor.

## Parameters

  * `price` - Current BTC price in USD (value)
  * `date_or_days` - Date, DateTime, days since genesis, or nil (default: today) (value)

## Returns

:extreme_low | :undervalued | :fair | :overvalued | :extreme_high (`atom`)

### Example

```elixir
:fair
```

```elixir
# descripex:contract
%{
  params: %{
    price: %{description: "Current BTC price in USD", kind: :value},
    date_or_days: %{
      description: "Date, DateTime, days since genesis, or nil (default: today)",
      kind: :value
    }
  },
  returns: %{
    type: :atom,
    description: ":extreme_low | :undervalued | :fair | :overvalued | :extreme_high"
  },
  returns_example: :fair
}
```

# `days_since_genesis`

```elixir
@spec days_since_genesis(Date.t() | DateTime.t() | nil) :: integer()
```

Get number of days since Bitcoin genesis block.

## Parameters

  * `date` - Date, DateTime, or nil (default: today) (value)

## Returns

Days since 2009-01-03 (`integer`)

### Example

```elixir
6200
```

```elixir
# descripex:contract
%{
  params: %{
    date: %{
      description: "Date, DateTime, or nil (default: today)",
      kind: :value
    }
  },
  returns: %{type: :integer, description: "Days since 2009-01-03"},
  returns_example: 6200
}
```

# `fair_value`

```elixir
@spec fair_value(Date.t() | DateTime.t() | pos_integer() | nil) :: float()
```

Calculate BTC fair value based on the power law model.

## Parameters

  * `date_or_days` - Date, DateTime, integer days since genesis, or nil (default: today) (value)

## Returns

Model-predicted BTC price in USD (`float`)

### Example

```elixir
0.1095
```

```elixir
# descripex:contract
%{
  params: %{
    date_or_days: %{
      description: "Date, DateTime, integer days since genesis, or nil (default: today)",
      kind: :value
    }
  },
  returns: %{type: :float, description: "Model-predicted BTC price in USD"},
  returns_example: 0.1095
}
```

# `fair_value_range`

```elixir
@spec fair_value_range(Date.t() | DateTime.t() | pos_integer() | nil) :: %{
  fair: float(),
  lower_1s: float(),
  upper_1s: float(),
  lower_2s: float(),
  upper_2s: float()
}
```

Returns 1-sigma and 2-sigma confidence bands around fair value.

## Parameters

  * `date_or_days` - Date, DateTime, integer days since genesis, or nil (default: today) (value)

## Returns

Map with :fair, :lower_1s, :upper_1s, :lower_2s, :upper_2s (`map`)

### Example

```elixir
%{
  fair: 85000.0,
  lower_1s: 62000.0,
  upper_1s: 116000.0,
  lower_2s: 45000.0,
  upper_2s: 160000.0
}
```

```elixir
# descripex:contract
%{
  params: %{
    date_or_days: %{
      description: "Date, DateTime, integer days since genesis, or nil (default: today)",
      kind: :value
    }
  },
  returns: %{
    type: :map,
    description: "Map with :fair, :lower_1s, :upper_1s, :lower_2s, :upper_2s"
  },
  returns_example: %{
    fair: 85000.0,
    lower_1s: 62000.0,
    upper_1s: 116000.0,
    lower_2s: 45000.0,
    upper_2s: 160000.0
  }
}
```

# `forecast`

```elixir
@spec forecast(non_neg_integer(), Date.t() | DateTime.t() | pos_integer() | nil) :: %{
  date: Date.t(),
  days_since_genesis: pos_integer(),
  fair: float(),
  lower_1s: float(),
  upper_1s: float(),
  lower_2s: float(),
  upper_2s: float()
}
```

Project fair value range to a future date offset.

## Parameters

  * `days_ahead` - Number of days into the future (0 = today) (value)
  * `base` - Starting date as Date, DateTime, integer days, or nil (default: today) (value)

## Returns

Map with :date, :days_since_genesis, :fair, :lower_1s, :upper_1s, :lower_2s, :upper_2s (`map`)

### Example

```elixir
%{
  date: ~D[2026-03-27],
  fair: 86000.0,
  days_since_genesis: 6295,
  lower_1s: 62800.0,
  upper_1s: 117500.0,
  lower_2s: 45600.0,
  upper_2s: 161200.0
}
```

```elixir
# descripex:contract
%{
  params: %{
    base: %{
      description: "Starting date as Date, DateTime, integer days, or nil (default: today)",
      kind: :value
    },
    days_ahead: %{
      description: "Number of days into the future (0 = today)",
      kind: :value
    }
  },
  returns: %{
    type: :map,
    description: "Map with :date, :days_since_genesis, :fair, :lower_1s, :upper_1s, :lower_2s, :upper_2s"
  },
  returns_example: %{
    date: ~D[2026-03-27],
    fair: 86000.0,
    days_since_genesis: 6295,
    lower_1s: 62800.0,
    upper_1s: 117500.0,
    lower_2s: 45600.0,
    upper_2s: 161200.0
  }
}
```

# `genesis_date`

```elixir
@spec genesis_date() :: Date.t()
```

Get the Bitcoin genesis block date.

## Returns

~D[2009-01-03] (`date`)

### Example

```elixir
~D[2009-01-03]
```

```elixir
# descripex:contract
%{
  returns: %{type: :date, description: "~D[2009-01-03]"},
  returns_example: ~D[2009-01-03]
}
```

# `resistance`

```elixir
@spec resistance(Date.t() | DateTime.t() | pos_integer() | nil, number()) :: float()
```

Calculate power law resistance price (upper band).

## Parameters

  * `date_or_days` - Date, DateTime, days since genesis, or nil (default: today) (value)
  * `deviations` - Number of standard deviations above fair value (default: `1.5`, value)

## Returns

Resistance price in USD (`float`)

### Example

```elixir
0.1095
```

```elixir
# descripex:contract
%{
  params: %{
    date_or_days: %{
      description: "Date, DateTime, days since genesis, or nil (default: today)",
      kind: :value
    },
    deviations: %{
      default: 1.5,
      description: "Number of standard deviations above fair value",
      kind: :value
    }
  },
  returns: %{type: :float, description: "Resistance price in USD"},
  returns_example: 0.1095
}
```

# `support`

```elixir
@spec support(Date.t() | DateTime.t() | pos_integer() | nil, number()) :: float()
```

Calculate power law support price (lower band).

## Parameters

  * `date_or_days` - Date, DateTime, days since genesis, or nil (default: today) (value)
  * `deviations` - Number of standard deviations below fair value (default: `1.5`, value)

## Returns

Support price in USD (`float`)

### Example

```elixir
0.1095
```

```elixir
# descripex:contract
%{
  params: %{
    date_or_days: %{
      description: "Date, DateTime, days since genesis, or nil (default: today)",
      kind: :value
    },
    deviations: %{
      default: 1.5,
      description: "Number of standard deviations below fair value",
      kind: :value
    }
  },
  returns: %{type: :float, description: "Support price in USD"},
  returns_example: 0.1095
}
```

# `z_score`

```elixir
@spec z_score(number(), Date.t() | DateTime.t() | pos_integer() | nil) :: float()
```

Calculate how many standard deviations price is from fair value.

## Parameters

  * `price` - Current BTC price in USD (value)
  * `date_or_days` - Date, DateTime, days since genesis, or nil (default: today) (value)

## Returns

Z-score (>0 = above trend, <0 = below trend, |z|>2 = extreme) (`float`)

### Example

```elixir
0.1095
```

```elixir
# descripex:contract
%{
  params: %{
    price: %{description: "Current BTC price in USD", kind: :value},
    date_or_days: %{
      description: "Date, DateTime, days since genesis, or nil (default: today)",
      kind: :value
    }
  },
  returns: %{
    type: :float,
    description: "Z-score (>0 = above trend, <0 = below trend, |z|>2 = extreme)"
  },
  returns_example: 0.1095
}
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
