#!/bin/sh
#
# Portfolio tracking by Vince Darley
#
# This file may be freely modified, sold, changed, etc.
# If you do make useful changes, I would like a copy,
# although you aren't obligated to send me anything.
#
# Ideas for future improvements: auto-update every N minutes,
# graphs of total portfolio value over time,
# ability to record changes in portfolio over time...
#
#\
exec wish "$0"
package require http
namespace eval portfolio {}
set shares(AAPL) 550
set shares(ORCL) 100
set shares(INKT) 100
set cash 3285.74
##
# -------------------------------------------------------------------------
#
# "portfolio::getInformation" --
#
# Takes a list of symbols, from Nasdaq, NYSE or even mutual funds etc.,
# and returns a list of results, one for each symbol given.
# Each returned result is a string containing comma separated values,
# in the order:
#
# symbol, price, date, ...
#
# We use a quote server from yahoo.
# -------------------------------------------------------------------------
##
proc portfolio::getInformation {symbols} {
set query "http://quote.yahoo.com"
append query "/d/quotes.csv?s=[join $symbols +]&f=sl1d1t1c1ohgv&e=.csv"
set token [http::geturl $query]
set actual {}
foreach res [split [string trim [http::data $token]] "\r\n"] {
if {$res != ""} {
set res [split $res ,]
lappend actual [lreplace $res 0 0 [string trim [lindex $res 0] {{}""}]]
}
}
return $actual
}
proc portfolio::dumpData {data} {
foreach result $data {
set items [split $result ","]
puts stdout $items
}
}
proc portfolio::createWindow {portfolio} {
foreach {s q} $portfolio {
set w [symbolToWin $s]
label ${w}symb -text $s
label ${w}price -text ""
label ${w}change -text ""
label ${w}quantity -text $q
label ${w}value -text ""
grid ${w}symb ${w}price ${w}change ${w}quantity ${w}value
}
button .update -text "Update" -command portfolio::updateAll
label .total -text ""
grid .update .total
wm title . "Portfolio"
wm withdraw .
portfolio::updateAll
wm deiconify .
}
proc portfolio::symbolToWin {symbol} {
return ".[join [string tolower $symbol]]"
}
proc portfolio::updateWindow {data} {
global cash
if {[info exists cash]} {
set total $cash
} else {
set total 0.0
}
foreach items $data {
set w [symbolToWin [lindex $items 0]]
set price [lindex $items 1]
set change [lindex $items 4]
${w}price configure -text $price
${w}change configure -text $change
set val [expr {[${w}quantity cget -text] * $price}]
${w}value configure -text $val
set total [expr {$total + $val}]
}
.total configure -text $total
}
proc portfolio::updateAll {} {
global shares
updateWindow [getInformation [array names shares]]
}
portfolio::createWindow [array get shares]Also see http://sourceforge.net/projects/tkstkw


