home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / share / pyshared / invest / chart.py < prev    next >
Encoding:
Python Source  |  2010-07-07  |  6.8 KB  |  258 lines

  1. #!/usr/bin/env python
  2.  
  3. import gtk, gtk.gdk
  4. import gobject
  5. import os
  6. import invest
  7. from gettext import gettext as _
  8. from invest import *
  9. import sys
  10. from os.path import join
  11. import urllib
  12. from threading import Thread
  13. import time
  14.  
  15. AUTOREFRESH_TIMEOUT = 20*60*1000 # 15 minutes
  16.  
  17. # based on http://www.johnstowers.co.nz/blog/index.php/2007/03/12/threading-and-pygtk/
  18. class _IdleObject(gobject.GObject):
  19.     """
  20.     Override gobject.GObject to always emit signals in the main thread
  21.     by emmitting on an idle handler
  22.     """
  23.     def __init__(self):
  24.         gobject.GObject.__init__(self)
  25.  
  26.     def emit(self, *args):
  27.         gobject.idle_add(gobject.GObject.emit,self,*args)
  28.  
  29. class ImageRetriever(Thread, _IdleObject):
  30.     """
  31.     Thread which uses gobject signals to return information
  32.     to the GUI.
  33.     """
  34.     __gsignals__ =  { 
  35.             "completed": (
  36.                 gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, []),
  37.             # FIXME: should we be making use of this?
  38.             #"progress": (
  39.             #    gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [
  40.             #    gobject.TYPE_FLOAT])        #percent complete
  41.             }
  42.  
  43.     def __init__(self, image_url):
  44.         Thread.__init__(self)
  45.         _IdleObject.__init__(self)    
  46.         self.image_url = image_url
  47.         self.retrieved = False
  48.         
  49.     def run(self):
  50.         self.image = gtk.Image()
  51.         try: sock = urllib.urlopen(self.image_url, proxies = invest.PROXY)
  52.         except Exception, msg:
  53.             invest.debug("Error while opening %s: %s" % (self.image_url, msg))
  54.         else:
  55.             loader = gtk.gdk.PixbufLoader()
  56.             loader.connect("closed", lambda loader: self.image.set_from_pixbuf(loader.get_pixbuf()))
  57.             loader.write(sock.read())
  58.             sock.close()
  59.             loader.close()
  60.             self.retrieved = True
  61.         self.emit("completed")
  62.  
  63. # p:
  64. #  eX = Exponential Moving Average
  65. #  mX = Moving Average
  66. #  b = Bollinger Bands Overlay
  67. #  v = Volume Overlay
  68. #  p = Parabolic SAR overlay
  69. #  s = Splits Overlay
  70. # q:
  71. #  l = Line
  72. #  c = Candles
  73. #  b = Bars
  74. # l:
  75. #  on = Logarithmic
  76. #  off = Linear
  77. # z:
  78. #  l = Large
  79. #  m = Medium
  80. # t:
  81. #  Xd = X Days
  82. #  Xm = X Months
  83. #  Xy = X Years
  84. # a:
  85. #  fX = MFI X days
  86. #  ss = Slow Stochastic
  87. #  fs = Fast Stochastic
  88. #  wX = W%R X Days
  89. #  mX-Y-Z = MACD X Days, Y Days, Signal
  90. #  pX = ROC X Days
  91. #  rX = RSI X Days
  92. #  v = Volume
  93. #  vm = Volume +MA
  94. # c:
  95. #  X = compare with X
  96. #
  97.  
  98. class FinancialChart:
  99.     def __init__(self, ui):
  100.         self.ui = ui
  101.         
  102.         #Time ranges of the plot
  103.         self.time_ranges = ["1d", "5d", "3m", "6m", "1y", "5y", "my"]
  104.         
  105.         # Window Properties
  106.         win = ui.get_object("window")
  107.         win.set_title(_("Financial Chart"))
  108.         
  109.         try:
  110.             pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(join(invest.ART_DATA_DIR, "invest_neutral.svg"), 96,96)
  111.             self.ui.get_object("plot").set_from_pixbuf(pixbuf)
  112.         except Exception, msg:
  113.             invest.debug("Could not load 'invest-neutral.svg' file: %s" % msg)
  114.             pass
  115.         
  116.         # Defaut comboboxes values
  117.         for widget in ["t", "q"]:
  118.             ui.get_object(widget).set_active(0)
  119.         
  120.         # Connect every option widget to its corresponding change signal    
  121.         symbolentry = ui.get_object("s")
  122.         refresh_chart_callback = lambda w: self.on_refresh_chart()
  123.         
  124.         for widgets, signal in [
  125.             (("pm5","pm10","pm20","pm50","pm100","pm200",
  126.             "pe5","pe10", "pe20","pe50","pe100","pe200",
  127.             "pb","pp","ps","pv",
  128.             "ar","af","ap","aw","am","ass","afs","av","avm"), "toggled"),
  129.             (("t", "q"), "changed"),
  130.             (("s",), "activate"),
  131.         ]:
  132.             for widget in widgets:
  133.                 ui.get_object(widget).connect(signal, refresh_chart_callback)
  134.         
  135.         ui.get_object("progress").hide()
  136.         
  137.         # Connect auto-refresh widget
  138.         self.autorefresh_id = 0
  139.         ui.get_object("autorefresh").connect("toggled", self.on_autorefresh_toggled)
  140.                                         
  141.     def on_refresh_chart(self, from_timer=False):
  142.         tickers = self.ui.get_object("s").get_text()
  143.             
  144.         if tickers.strip() == "":
  145.             return True
  146.         
  147.         # FIXME: We don't just do US stocks, so we can't be this
  148.         # simplistic about it, but it is a good idea.
  149.         #if from_timer and not ustime.hour_between(9, 16):
  150.         #    return True
  151.             
  152.         tickers = [ticker.strip().upper() for ticker in tickers.split(' ') if ticker != ""]
  153.         
  154.         # Update Window Title ------------------------------------------------------
  155.         win = self.ui.get_object("window")
  156.         title = _("Financial Chart - %s")
  157.         titletail = ""
  158.         for ticker in tickers:
  159.             titletail += "%s / " % ticker
  160.         title = title % titletail
  161.         
  162.         win.set_title(title[:-3])
  163.  
  164.         # Detect Comparison or simple chart ----------------------------------------
  165.         opt = ""
  166.         for ticker in tickers[1:]:
  167.             opt += "&c=%s" % ticker
  168.         
  169.         # Create the overlay string ------------------------------------------------
  170.         p = ""
  171.         for name, param in [
  172.             ("pm5",   5),
  173.             ("pm10",  10),
  174.             ("pm20",  20),
  175.             ("pm50",  50),
  176.             ("pm100", 100),
  177.             ("pm200", 200),
  178.             ("pe5",   5),
  179.             ("pe10",  10),
  180.             ("pe20",  20),
  181.             ("pe50",  50),
  182.             ("pe100", 100),
  183.             ("pe200", 200),
  184.             ("pb", ""),
  185.             ("pp", ""),
  186.             ("ps", ""),
  187.             ("pv", ""),
  188.         ]:
  189.             if self.ui.get_object(name).get_active():
  190.                 p += "%s%s," % (name[1], param)
  191.             
  192.         # Create the indicators string ---------------------------------------------
  193.         a = ""
  194.         for name, param in [
  195.             ("ar",  14),
  196.             ("af",  14),
  197.             ("ap",  12),
  198.             ("aw",  14),
  199.             ("am",  "26-12-9"),
  200.             ("ass", ""),
  201.             ("afs", ""),
  202.             ("av",  ""),
  203.             ("avm", ""),
  204.         ]:
  205.             if self.ui.get_object(name).get_active():
  206.                 a += "%s%s," % (name[1:], param)
  207.         
  208.         # Create the image URL -----------------------------------------------------
  209.         chart_base_url = "http://ichart.europe.yahoo.com/z?s=%(s)s&t=%(t)s&q=%(q)s&l=%(l)s&z=%(z)s&p=%(p)s&a=%(a)s%(opt)s"
  210.         url = chart_base_url % {
  211.             "s": tickers[0],
  212.             "t": self.time_ranges[self.ui.get_object("t").get_active()],
  213.             "q": self.ui.get_object("q").get_active_text(),
  214.             "l": "off",
  215.             "z": "l",
  216.             "p": p,
  217.             "a": a,
  218.             "opt": opt,
  219.         }
  220.  
  221.         # Download and display the image -------------------------------------------    
  222.         progress = self.ui.get_object("progress")
  223.         progress.set_text(_("Opening Chart"))
  224.         progress.show()
  225.         
  226.         image_retriever = ImageRetriever(url)
  227.         image_retriever.connect("completed", self.on_retriever_completed)
  228.         image_retriever.start()
  229.  
  230.         # Update timer if needed
  231.         self.on_autorefresh_toggled(self.ui.get_object("autorefresh"))
  232.         return True
  233.     
  234.     def on_retriever_completed(self, retriever):
  235.         self.ui.get_object("plot").set_from_pixbuf(retriever.image.get_pixbuf())
  236.         progress = self.ui.get_object("progress")
  237.         if retriever.retrieved == True:
  238.             progress.set_text(_("Chart downloaded"))
  239.         else:
  240.             progress.set_text(_("Chart could not be downloaded"))
  241.     
  242.     def on_autorefresh_toggled(self, autorefresh):
  243.         if self.autorefresh_id != 0:
  244.             gobject.source_remove(self.autorefresh_id)
  245.             self.autorefresh_id = 0
  246.             
  247.         if autorefresh.get_active():
  248.             self.autorefresh_id = gobject.timeout_add(AUTOREFRESH_TIMEOUT, self.on_refresh_chart, True)
  249.  
  250. def show_chart(tickers):
  251.     ui = gtk.Builder();
  252.     ui.add_from_file(os.path.join(invest.BUILDER_DATA_DIR, "financialchart.ui"))
  253.     chart = FinancialChart(ui)
  254.     ui.get_object("s").set_text(' '.join(tickers))
  255.     chart.on_refresh_chart()
  256.     return ui.get_object("window")
  257.  
  258.