def save_symbols(symbols: SyncedList, start: dt.datetime, end: dt.datetime, listener: Listener, dir: str): """ Saves data from the range given by <start>-<end> for each symbol in <symbols>, placing output in the folder given by <dir>. For each symbol in <symbols>, fetches as much price data as possible within the given range, and saves it in a file named <symbol>.csv, in the folder given by <dir>. Args: symbols: a SyncedList of stock symbols that should be saved start: a datetime object representing the beginning of the range to try and get data from end: listener: dir: Returns: """ msg = Message() symbol = symbols.pop() while symbol is not None: msg.reset() msg.add_line("Saving " + symbol + "...") listener.send(msg) save(symbol, start, end, listener, dir) symbol = symbols.pop()
def check_overbought_oversold(symbols: SyncedList, start: datetime.datetime, end: datetime.datetime, period: int, listener: Listener): symbol = symbols.pop() while symbol is not None: msg = Message() msg.add_line("Checking " + symbol + "...") listener.send(msg) df = rsi(symbol, start, end, period) if df is not None: for date in df.index: if df["RSI"][date] >= 80: msg = Message() msg.add_line("=========================") msg.add_line(symbol + " was overbought on " + str(date)) msg.add_line("=========================") listener.send(msg) elif df["RSI"][date] <= 20: msg = Message() msg.add_line("=========================") msg.add_line(symbol + " was oversold on " + str(date)) msg.add_line("=========================") listener.send(msg) symbol = symbols.pop()
def _analyze_thread(symbols: SyncedList, tracker: IndicatorResultTracker, days: int, listener: Listener): symbol = symbols.pop() while symbol is not None: msg = Message() msg.add_line(f"Thread {threading.currentThread()} analyzing {symbol}") listener.send(msg) analyze(symbol, tracker, days, listener) symbol = symbols.pop()
def check_for_crosses(lst: SyncedList, listener: Listener, start: datetime.datetime, end: datetime.datetime): """ Check for crosses of the <short>-day moving average above the <long>-day moving average in the last five days of trading. <lst> should be a SyncedList of stock symbols, and <listener> is what the threads spawned to accomplish the task will use to communicate with the console. """ msg = Message() symbol = lst.pop() while symbol is not None: msg.add_line("Analyzing symbol...") listener.send(msg) msg.reset() crosses = golden_cross(symbol, listener, SHORT_MOVING_AVERAGE, LONG_MOVING_AVERAGE, start, end) for cross in crosses: msg.add_line("=========================================") msg.add_line(f"Cross above for {symbol} on {cross}") listener.send(msg) msg.reset() symbol = lst.pop()
def check_for_MACD_signal_crosses(lst: SyncedList, listener: Listener, start: datetime.datetime, end: datetime.datetime): """ Check each stock symbol in the given SyncedList for crosses of the MACD above its signal line while price is above its 200-day EMA during the period from <start> to <end>. Print a message to the console for each such cross found. """ symbol = lst.pop() msg = Message() while symbol is not None: msg.add_line(f"Analyzing {symbol}...") listener.send(msg) msg.reset() signals = MACD_signal(symbol, listener, start, end, local=True, dir="../data") for signal in signals: msg.add_line("======================================") msg.add_line(f"Signal on {signal} for {symbol}") msg.add_line("======================================") listener.send(msg) signal_output.save(msg) msg.reset() symbol = lst.pop()
def analyze_symbols(symbols: SyncedList, days: int): threads = [] tracker = IndicatorResultTracker(days) listener = Listener() for i in range(6): x = threading.Thread(target=_analyze_thread, args=(symbols, tracker, days, listener)) x.start() threads.append(x) for thread in threads: thread.join() tracker.summarize() if __name__ == '__main__': f = open("../s&p500_symbols.txt") symbols = [] for line in f: line = line.strip() symbols.append(line) synced = SyncedList(symbols) analyze_symbols(synced, DAYS_TO_ANALYZE)
threads.append(x) return threads """ This script is run by passing in one command-line argument: the name of the source file from which it loads all the stock tickers for analysis. This file should simply contain a list of stock tickers, with one ticker per line. """ if __name__ == '__main__': securities = [] f = open(sys.argv[1], "r") for line in f: line = line.strip() securities.append(line) lst = SyncedList(securities) start = time.time() threads = analyze_symbols(lst, datetime.datetime.today() - datetime.timedelta(7), datetime.datetime.today(), check_for_MACD_signal_crosses) main_thread = threading.current_thread() for thread in threads: if thread is not main_thread: thread.join() end = time.time() print("Time taken: " + str(end - start))
msg.add_line("Checking " + symbol + "...") listener.send(msg) df = rsi(symbol, start, end, period) if df is not None: for date in df.index: if df["RSI"][date] >= 80: msg = Message() msg.add_line("=========================") msg.add_line(symbol + " was overbought on " + str(date)) msg.add_line("=========================") listener.send(msg) elif df["RSI"][date] <= 20: msg = Message() msg.add_line("=========================") msg.add_line(symbol + " was oversold on " + str(date)) msg.add_line("=========================") listener.send(msg) symbol = symbols.pop() if __name__ == '__main__': symbols = [] f = open("../s&p500_symbols.txt") for line in f: line = line.strip() symbols.append(line) lst = SyncedList(symbols) check_overbought_oversold(lst, datetime.datetime(2010, 1, 1), datetime.datetime(2019, 12, 31), 14, Listener())