aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--analysis.py94
-rw-r--r--app.py25
-rw-r--r--main.py10
3 files changed, 121 insertions, 8 deletions
diff --git a/analysis.py b/analysis.py
new file mode 100644
index 0000000..2b5ed59
--- /dev/null
+++ b/analysis.py
@@ -0,0 +1,94 @@
+import json
+import datetime
+
+# pull stock data from json files
+# timestamps_file = open('timestamps.json', 'r')
+# timestamps_file_data = timestamps_file.read()
+# timestamps = json.loads(timestamps_file_data)
+# timestamps = [datetime.datetime.fromtimestamp(t) for t in timestamps]
+
+# prices_file = open('close_prices.json', 'r')
+# prices = json.loads(prices_file.read())
+
+# print('timestamps:\t', timestamps, '\nprices:\t', prices)
+
+# make the line data for the 5 day exponential moving average (EMA)
+
+def calc_first_sma(period, prices):
+ prices_sum = 0
+ for i in range(0, period):
+ prices_sum += prices[i] # 0, 1, 2, 3 ("popping" order)
+ # print('prices_sum:\t', prices_sum)
+
+ return prices_sum / period
+
+def calc_emas(period, prices):
+ weighted_multiplier = 2.0 / (period + 1.0)
+
+ # calculate the first ema
+ first_ema = calc_first_sma(period, prices)
+
+ # calculate the rest ema's using that first
+ emas = [first_ema] * period
+ for i in range(period + 1, len(prices)): # 4, 5, 6, ... , last
+ last_ema = emas[-1]
+ next_ema = prices[i] * weighted_multiplier + last_ema * (1 - weighted_multiplier)
+ emas.append(next_ema)
+ return emas
+
+def interpolate_intersection(intersection_indices, timestamps, prices1, prices2):
+ left_index = intersection_indices[0]
+ right_index = intersection_indices[1]
+ if right_index == -1:
+ return timestamps[left_index]
+
+ y_1 = prices1[left_index]
+ y_2 = prices1[right_index] # first line
+
+ v_1 = prices2[left_index]
+ v_2 = prices2[right_index] # second line
+
+ x_1 = 0 # take this as zero the simplify the algebra
+ x_diff = timestamps[right_index] - timestamps[left_index] # same for both lines
+
+ # find intersection between those lines
+ x_diff = x_diff.total_seconds()
+ m_1 = (y_2 - y_1) / x_diff # slope of line 1
+ m_2 = (v_2 - v_1) / x_diff
+
+ x_interpolated = (v_1 - y_1) / (m_1 - m_2)
+ y_interpolated = m_1 * (x_interpolated) + y_1
+
+ # add back the time we subtracted to make x_1=0
+ x_interpolated = datetime.timedelta(seconds = x_interpolated) + timestamps[left_index]
+ return (x_interpolated, y_interpolated)
+
+
+
+"""
+Returns the indices of where two arrays' values intersects
+"""
+def find_intersections(prices1, prices2):
+ if len(prices1) != len(prices2):
+ print("ERROR IN find_intersections: len of arrs not the same")
+ return []
+ prev_p1 = prices1[0]
+ prev_p2 = prices2[0]
+ intersection_indices = set()
+ for i in range(1, len(prices1)):
+ next_p1 = prices1[i]
+ next_p2 = prices2[i]
+ # if the sign (negative to positive) changes, then there was an intersection between these pts
+ sub_prev = prev_p1 - prev_p2
+ sub_next = next_p1 - next_p2
+
+ if (sub_prev > 0 and sub_next < 0) or (sub_prev < 0 and sub_next > 0): # TODO, consider on the 0 case
+ intersection_indices.add((i-1, i))
+
+ if sub_next == 0:
+ intersection_indices.add((i, -1))
+
+ prev_p1 = next_p1
+ prev_p2 = next_p2
+
+ return intersection_indices
diff --git a/app.py b/app.py
index a2e9f07..5cd5521 100644
--- a/app.py
+++ b/app.py
@@ -1,4 +1,5 @@
from dash import Dash, dcc, html, Input, Output
+from analysis import calc_emas, find_intersections, interpolate_intersection
import plotly.graph_objects as go
import json
import datetime
@@ -21,13 +22,23 @@ app.layout = html.Div([
# pull stock data from json files
timestamps_file = open('timestamps.json', 'r')
timestamps_file_data = timestamps_file.read()
-timestamps = json.loads(timestamps_file_data)
-timestamps = [datetime.datetime.fromtimestamp(t) for t in timestamps]
+timestamps_raw = json.loads(timestamps_file_data)
+timestamps = [datetime.datetime.fromtimestamp(t) for t in timestamps_raw]
prices_file = open('close_prices.json', 'r')
prices = json.loads(prices_file.read())
-# print('timestamps:\t', timestamps, '\nprices:\t', prices)
+ema_5 = calc_emas(5, prices)
+ema_13 = calc_emas(13, prices)
+
+intersection_indices = find_intersections(ema_5, ema_13)
+interpolated_intersections = [interpolate_intersection(indices, timestamps, ema_5, ema_13) for indices in intersection_indices]
+intersected_x = []
+intersected_y = []
+for x,y in interpolated_intersections:
+ intersected_x.append(x)
+ intersected_y.append(y)
+
@app.callback(
@@ -35,7 +46,13 @@ prices = json.loads(prices_file.read())
Input("dropdown", "value"))
def display_color(color):
fig = go.Figure(
- data=go.Line(x=timestamps, y=prices, marker_color=color))
+ [
+ go.Scatter(name='Price', x=timestamps, y=prices, line=dict(color='rgb(0, 255, 255)'), mode='lines'), # prices
+ go.Scatter(name='5 day EMA', x=timestamps, y=ema_5, line=dict(color='rgb(0, 255, 0)'), mode='lines'), # 5 ema line
+ go.Scatter(name='13 day EMA', x=timestamps, y=ema_13, line=dict(color='rgb(0, 0, 255)'), mode='lines'), # 13 ema line
+ go.Scatter(name='EMA Intersections', x=intersected_x, y=intersected_y, line=dict(color='rgb(255, 0, 0)'), mode='markers') # EMA intersection points
+ ]
+ )
return fig
diff --git a/main.py b/main.py
index 8e7afdb..2a4ddff 100644
--- a/main.py
+++ b/main.py
@@ -1,14 +1,16 @@
import requests
import json
+import datetime
print("hello")
"""
First pull data from yahoo api
"""
-params = {'period1' : '1753487940',
- 'period2' : '1753725600',
- 'interval' : '1m',
+params = { #'period1' : '1753487940',
+ #'period2' : '1753725600',
+ 'interval' : '1d',
+ 'range' : '1y',
'events' : 'div|split|earn',
'includePrePost' : 'false' }
headers = {'User-agent' : 'fin-backtesting-proj'}
@@ -38,5 +40,5 @@ timestamps_file.close()
close_prices_file = open('close_prices.json', 'w')
close_prices_file.truncate(0)
close_prices_file.write(close_prices_encoded)
-timestamps_file.close()
+close_prices_file.close()