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)