aboutsummaryrefslogtreecommitdiff
path: root/analysis.py
blob: 644fe9379ac94357b6b25baea363b9f42ac72ada (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
123
124
125
126
127
128
129
130
131
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, offset=0):
    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 + offset, 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):
            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

def calculate_profit(buy_line, sell_line, prices, timestamps, offset=0, starting_money=10000):
    if len(buy_line) != len(sell_line):
        print("ERROR IN find_intersections: len of arrs not the same")
        return []
    is_bought = False
    curr_money = 10000
    shares_owned = 0
    buy_info = []
    sell_info = []
    for i in range(offset, len(buy_line)):
        current_b1 = buy_line[i]
        current_sl = sell_line[i]
        # if the sign is positive, we want to hold, if it's negative, we want to sell
        sign_signal = current_b1 - current_sl

        if sign_signal > 0:
            if not is_bought:
                # buy the stock
                shares_owned = curr_money / prices[i]
                curr_money = 0
                buy_info.append((timestamps[i], prices[i], i))
            is_bought = True
        if sign_signal < 0:
            if is_bought:
                # selling the stock
                curr_money = prices[i] * shares_owned
                shares_owned = 0
                sell_info.append((timestamps[i], prices[i], i))
            is_bought = False

    # TODO: consider end interval
    total_assets = prices[-1] * shares_owned + curr_money
    percent_gain = (total_assets - starting_money) / starting_money
    return (percent_gain, total_assets, buy_info, sell_info)