Skip to content

Commit

Permalink
gema rename
Browse files Browse the repository at this point in the history
  • Loading branch information
micahkendall committed Sep 5, 2024
1 parent c2bbcf3 commit ead6d8d
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 117 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:
tag_name: ${{ github.ref_name }}
files: "./*.pdf"

- run: "mkdir output && mv ema.pdf output/ema.pdf"
- run: "mkdir output && mv gema.pdf output/gema.pdf"

- name: Publish
uses: ryand56/r2-upload-action@latest
Expand Down
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
@@ -1 +1 @@
typst c ema.typ
typst c gema.typ
95 changes: 0 additions & 95 deletions ema.typ

This file was deleted.

101 changes: 101 additions & 0 deletions gema.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#let special_version = read("./version.txt")
#align(center, [
#v(2em)
#[#set par(justify: true)
#image("img/logo-black.png", width: 120pt)]
#set text(size:18pt)

Oracle Specifications
#align(center, text(12pt, weight: 400)[
v. #special_version
])

#datetime.today().display("[day] [month repr:long], [year]")
])
#v(2em)
= GEMA Oracle Specification

== Overview
This specification outlines the Greater Exponential Moving Average (GEMA) oracle algorithm, designed to provide a responsive and adaptive measure of asset price trends. It is particularly suited for financial applications requiring quick reactions to market downturns while maintaining stability during upward trends.

== Algorithm Description
The GEMA algorithm uses a single piece of previous state to add a drag for price increases while immediately reflecting decreases. This approach combines quick responsiveness to potential losses with the stability of trend following during growth periods.

== Key Features
1. Immediate reflection of price decreases
2. Smoothed response to price increases using GEMA calculation
3. Single state variable for efficient implementation

== Implementation Details

=== Inputs
- `prices`: A list of asset prices over time
- `period`: The number of days for the GEMA calculation (default: 20)

=== Output
- A list of GEMA values corresponding to the input prices

== Visual Representation

#figure(
image("img/example.png", width: 80%),
caption: [
Comparison of Asset Price and GEMA over time.
The red line represents the GEMA, which quickly adapts to price decreases while smoothing price increases.
]
)

This graph demonstrates how the GEMA (red line) closely follows the asset price (blue line) during downward movements, while providing a smoother trend during upward movements.

=== Algorithm
#figure(
$f(t) = min {
gamma dot f(t-1) + (1-gamma) x_t,
x_t
}$,
caption: "GEMA Algorithm"
)

=== Pseudocode
#figure(
align(left)[
#set text(font: "New Computer Modern Mono")
#set par(leading: 0.65em)
#let prices = [...price values]

#table(
columns: (auto, auto),
inset: 0pt,
stroke: none,
align: left + horizon,
[*Input:*], [prices, period],
[*Output:*], [gema],
)

#v(0.5em)
$"gema" arrow.l [prices[0]]$\
$"multiplier" arrow.l 2 / ("period" + 1)$\
#v(0.5em)
*for* $"price"$ *in* $"prices"[1:]$ *do*\
#h(1em) *if* $"price" < "gema"[-1]$ *then*\
#h(2em) $"gema"."append"("price")$\
#h(1em) *else*\
#h(2em) $"new_gema" arrow.l ("price" - "gema"[-1]) dot "multiplier" + "gema"[-1]$\
#h(2em) $"gema"."append"("new_gema")$\
#h(1em) *end if*\
*end for*
#v(0.5em)
*return* $"gema"$
],
caption: "GEMA Algorithm"
)

== Notes
1. The algorithm initializes the GEMA with the first price in the series.
2. For each subsequent price:
- If the new price is lower than the previous GEMA, it immediately becomes the new GEMA value.
- If the new price is higher, a standard GEMA calculation is applied.
3. This approach ensures quick adaptation to price drops while smoothing out price increases.

== Reference Implementation
For a reference implementation, refer to the `calculate_gema` function in the `oracles.py` file.
Binary file modified img/example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 9 additions & 20 deletions oracles.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,45 +10,34 @@ def generate_price_data(initial_price, num_days, volatility):
prices.append(new_price)
return prices

def calculate_modified_ema(prices, period=20):
"""Calculate Modified Exponential Moving Average."""
ema = [prices[0]]
multiplier = 2 / (period + 1)
for price in prices[1:]:
if price < ema[-1]:
ema.append(price) # Immediately adjust to price decrease
else:
ema.append((price - ema[-1]) * multiplier + ema[-1]) # Use EMA for price increase
return ema

def calculate_simple_ema(prices, period=20):
def calculate_gema(prices, period=20):
"""
Calculate Simple Exponential Moving Average with immediate price decrease reflection.
Calculate Greater Exponential Moving Average with immediate price decrease reflection.
This is the preferred model for our analysis. It has the following characteristics:
1. Immediately adjusts to price decreases, providing quick responsiveness to market downturns.
2. Uses standard EMA calculation for price increases, allowing for a smoother trend during upward movements.
This combination allows for quick reaction to potential losses while maintaining trend stability during growth periods.
"""
ema = [prices[0]]
gema = [prices[0]]
multiplier = 2 / (period + 1)
for price in prices[1:]:
if price < ema[-1]:
ema.append(price) # Immediately adjust to price decrease
if price < gema[-1]:
gema.append(price) # Immediately adjust to price decrease
else:
ema.append((price - ema[-1]) * multiplier + ema[-1]) # Use EMA for price increase
return ema
gema.append((price - gema[-1]) * multiplier + gema[-1]) # Use EMA for price increase
return gema

def plot_asset_price(asset_name, initial_price=100, num_days=365, volatility=1):
"""Plot the price of an asset over time."""
days = range(num_days)
prices = generate_price_data(initial_price, num_days, volatility)
simple_ema = calculate_simple_ema(prices)
gema = calculate_gema(prices)

plt.figure(figsize=(10, 6))
plt.plot(days, prices, label='Price')
plt.plot(days, simple_ema, label='Simple EMA (Preferred Model)', color='red')
plt.plot(days, gema, label='GEMA (Preferred Model)', color='red')
plt.title(f"Price of {asset_name} Over Time")
plt.xlabel("Days")
plt.ylabel("Price")
Expand Down

0 comments on commit ead6d8d

Please sign in to comment.