Sep-27-2016, 07:00 PM
Now with a new addition! The amount changed since startup (ideally since the start of the trading day) is shown, along with an arrow indicating positive or negative (for the colorblind :)
import pygame import random import time WHITE = (255, 255, 255) BLACK = ( 0, 0, 0) RED = (255, 0, 0) GREEN = ( 0, 255, 0) """ TickerItem cares about WHAT it looks like, not WHERE it is. The TickerGroup handles positioning. """ class TickerItem(object): font = None @classmethod def get_font(cls): if not cls.font: pygame.font.init()#lucidafax cls.font = pygame.font.SysFont("monospace", 16, True) return cls.font def __init__(self, ticker): self.symbol = ticker[0] self.value = self.initial_value = round(ticker[1], 2) self.last_update = 0 self.update() self.inital_value = self.value def render_text(self): color = WHITE if self.value > self.initial_value: color = GREEN elif self.value < self.initial_value: color = RED difference = self.value - self.initial_value arrow = '\u25B2' if difference > 0 else '\u25BC' text = "{0}[{1:.2f}{2}{3:.2f}]".format(self.symbol, self.value, arrow, abs(difference)) font = self.get_font() self.surface = font.render(text, True, color, BLACK) self.text_size = font.size(text) def update(self): # only update the value once every 10 seconds if time.time() - self.last_update > 10: self.value += (random.random() * random.choice([1, -1])) self.value = round(self.value, 2) self.render_text() self.last_update = time.time() """ Maintains a list of TickerItems, and their positions in space. TickerGroup handles moving the TickerItems around, but doesn't care about what they look like or what they say. """ class TickerGroup(object): def __init__(self, screen, tickers): self.distance = 10 self.screen = screen self.tickers = [] # uncomment if you want the ticker to be blank when it starts, # and for all stocks to creep in, instead of being started full of tickers xpos = 5 # self.screen.get_width() for ticker in tickers: tcker = TickerItem(ticker) pos = [xpos, 0] self.tickers.append({ "ticker": tcker, "position": pos }) xpos += tcker.text_size[0] + self.distance self.last = xpos def update(self): for ticker in self.tickers: ticker['ticker'].update() ticker['position'][0] -= 1 text_size = ticker['ticker'].text_size[0] if ticker['position'][0] + text_size < 0: ticker['position'][0] = self.last self.last = ticker['position'][0] + text_size + self.distance self.screen.blit(ticker['ticker'].surface, ticker['position']) if __name__ == '__main__': # set the window to be at the top of the screen import os os.environ['SDL_VIDEO_WINDOW_POS'] = "0,0" pygame.init() # find the current resolution, and use that as our width so we stretch across the screen sizes = pygame.display.list_modes() screen_size = (sizes[0][0], 20) screen = pygame.display.set_mode(screen_size, pygame.NOFRAME) clock = pygame.time.Clock() ticker = TickerGroup(screen, [ ["SPY", 200], ["AAPL", 115], ["AXP", 63], ["BA", 130], ["BAC", 15], ["CAT", 82], ["CSCO", 30], ["CVX", 98], ["DD", 66], ["GE", 30], ["IBM", 153], ["MCD", 116], ["MMM", 175], ["MSFT", 57], ["PG", 87], ["UNH", 139], ["UTX", 102], ["V", 82], ["VZ", 52], ["XOM", 83] ]) running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: running = False screen.fill(BLACK) ticker.update() pygame.display.flip() clock.tick(60) pygame.quit()