aboutsummaryrefslogtreecommitdiff
path: root/app.py
blob: 68aacb8b43688631c8e8782b2642f3dbe0ecbd0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from dash import Dash, dcc, html, Input, Output
from analysis import find_intersections, interpolate_intersection 
from api import fetch_chart_data
from ema import calc_emas, calculate_profit
import plotly.graph_objects as go
import json
import datetime
import pandas as pd

app = Dash(__name__)

# pull stock data from json files
# timestamps_file = open('timestamps.json', 'r')
# timestamps_file_data = timestamps_file.read()
# 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())

# intersection_indices = find_intersections(ema_5, ema_13, offset=13) # offset so don't calculate the SMA days
# 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.layout = html.Div([
    html.H4('Backtesting using the EMA method (5 vs 13) [ALPHA VERSION 0.0.2]'),
    html.Div(
        [
            html.Label("Ticker ", htmlFor="ticker"),
            dcc.Input(id="ticker", value="SPY", type="text"),
            html.Br(),
            html.Label("Period ", htmlFor="period_dropdown"),
            dcc.Dropdown(
                id="period_dropdown",
                options=["1d","5d","1mo","3mo","6mo","1y","2y","5y","10y","ytd","max"],
                value = "1y"),
            html.Br(),
            html.Label("Interval ", htmlFor="interval_dropdown"),
            dcc.Dropdown(
                id="interval_dropdown",
                options=["1m", "2m", "5m", "15m", "30m", "60m", "90m", "1h", "4h", "1d", "5d", "1wk", "1mo", "3mo"],
                value = "1d",
            ),
            html.P(id='error_message'),
        ],
        id='input_params'
    ),
    html.Hr(),
    dcc.Graph(id="graph"),
    html.P("If bought and sold on these signals, the percent gain/loss would be:"),
    html.P(id="percent_gain")

])

@app.callback(
    Output("graph", "figure"),
    Output("percent_gain", "children"),
    Output("input_params", "style"),
    Output("error_message", "children"),
    Input("ticker", "value"),
    Input("period_dropdown", "value"),
    Input("interval_dropdown", "value")
    )
def display_color(ticker, period, interval):
        chart_data = fetch_chart_data(ticker, period, interval)
        error_style = {"color" : "inherit"}
        error_message = ''
        if chart_data['error'] == True:
            # implement a feeback mechanism for ERROR codes
            error_style = {"color" : "red"}
            error_message = 'Issue with parameter selection. Please try again.'

        timestamps_raw = chart_data['timestamps']
        timestamps = [datetime.datetime.fromtimestamp(t) for t in timestamps_raw]
        prices = chart_data['prices']

        ema_5 = calc_emas(5, prices)
        ema_13 = calc_emas(13, prices)
        profit = calculate_profit(ema_5, ema_13, prices, timestamps, 13)
        buy_info = profit[-2]
        print(buy_info)
        buy_x = []
        buy_y = []
        for x,y,_ in buy_info:
            buy_x.append(x)
            buy_y.append(y)

        sell_info = profit[-1]
        sell_x = []
        sell_y = []
        for x,y,_ in sell_info:
            sell_x.append(x)
            sell_y.append(y)

        print("Result Analysis:\n", "Percent gain/loss:\t", profit[0], profit[1], profit[2])
        percent_gain = profit[0] * 100

        # Code to execute no matter what (optional)
        fig = go.Figure(
            data = [
                go.Scatter(name='Price', x=timestamps, y=prices, line=dict(color='rgb(0, 0, 0)'), mode='lines'), 
                # go.Scatter(name='5 day EMA', x=timestamps, y=ema_5, line=dict(color='rgb(0, 255, 0)'),  mode='lines'), 
                # go.Scatter(name='13 day EMA', x=timestamps, y=ema_13, line=dict(color='rgb(0, 0, 255)'),  mode='lines'), 
                # go.Scatter(name='EMA Intersections', x=intersected_x, y=intersected_y, line=dict(color='rgb(255, 0, 0)'), mode='markers'),
                go.Scatter(name='Buys', x=buy_x, y=buy_y, line=dict(color='rgb(0, 0, 255)'), mode='markers', marker_size=10),
                go.Scatter(name='Sells', x=sell_x, y=sell_y, line=dict(color='rgb(255, 255, 0)'), mode='markers', marker_size=10),
            ],
            layout = go.Layout(
                title=go.layout.Title(text='Chart for ' + chart_data['name']),
                xaxis=go.layout.XAxis(title='Date (dt=' + interval + ', range=' + period + ')'),
                yaxis=go.layout.YAxis(title='Price ($)')
            )
        )
        return fig, percent_gain, error_style, error_message



app.run(debug=True)