diff --git a/UMM.cabal b/UMM.cabal
--- a/UMM.cabal
+++ b/UMM.cabal
@@ -1,5 +1,5 @@
 Name:             UMM
-Version:          0.3.0
+Version:          0.3.1
 Homepage:         http://www.korgwal.com/umm/
 Author:           Uwe Hollerbach <uh@alumni.caltech.edu>
 Maintainer:       Uwe Hollerbach <uh@alumni.caltech.edu>
diff --git a/UMM.hs b/UMM.hs
--- a/UMM.hs
+++ b/UMM.hs
@@ -16,7 +16,7 @@
 along with umm; if not, write to the Free Software Foundation, Inc.,
 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-$Id: UMM.hs,v 1.69 2010/07/06 03:12:06 uwe Exp $ -}
+$Id: UMM.hs,v 1.73 2010/08/08 19:17:14 uwe Exp $ -}
 
 module Main where
 import Prelude hiding (putStr,putStrLn,print,readFile,getContents)
@@ -202,7 +202,7 @@
   do final <- getBalances startTime date Nothing False accts trans
      let fsel = selAccts ke names final
          sp = genSum dc ccs prices date (concatMap tr3 fsel)
-     putStrLn ("Account balances as of " ++ (gregorianDateToWDay date)
+     putStrLn ("Account balances as of " ++ gregorianDateToWDay date
               ++ " " ++ show date)
      mapM_ putStrLn (ppAccts (showPos dc ccs date prices fsel) 8)
      putStrLn ("Grand total: ~" ++ show sp)
@@ -272,13 +272,17 @@
        PlotCmd name date1 date2 (Name output) ->
          let crec = find (\r -> getRecName r == name) cd
              gs = genSum1 dc ccs prices
+             auxa = AccountRec name date1 False "" Nothing
+             auxt1 = dropWhile (\t -> getRecDate t <= date1) trans
+             auxt2 = mergeTrans trans (reverse prices)
          in if elem name (map getRecName cb)
                then putStrLn (show name ++ " is a base CCS!")
                else if isNothing crec
-                       then if elem name (map getRecName accts)
-                               then plotBalances date1 date2 name
-                                                 accts trans output gs
-                               else putStrLn (show name ++ " is unknown!")
+                       then if elem name (map getRecName (incs ++ exps))
+                               then plotBalances date1 date2 name [name]
+                                                 (auxa : accts) auxt1 output gs
+                               else plotBalances date1 date2 name (egrp name)
+                                                 accts auxt2 output gs
                        else plotPrices name (getNB (fromJust crec))
                                        date1 date2 prices output
        PriceCmd name date1 date2 ->
diff --git a/UMMEval.hs b/UMMEval.hs
--- a/UMMEval.hs
+++ b/UMMEval.hs
@@ -16,7 +16,7 @@
 along with umm; if not, write to the Free Software Foundation, Inc.,
 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-$Id: UMMEval.hs,v 1.50 2010/07/12 00:03:27 uwe Exp $ -}
+$Id: UMMEval.hs,v 1.54 2010/08/08 18:23:11 uwe Exp $ -}
 
 module UMMEval (validateRecs, validateCCS, validateAccts, classifyRecs,
                 validateTransPrices, generateImplicitPrices, getBalances,
@@ -240,7 +240,7 @@
   let isJ = isJust reg
       rn = fromJust reg
       acc = filter (\a -> elem (tr1 a) rn) newaccs
-      nb = if null acc then [CCSAmt noName (Amount 0)] else tr3 (head acc)
+      nb = if null acc then [CCSAmt noName (Amount 0)] else concatMap tr3 acc
   in if isJ && tst rn
         then recordInfo (record, nb)
         else recordNil
@@ -297,6 +297,17 @@
   where doST (a1,a2,a3) = (a1, a2, scaleBy a3 (CCSAmt ccs (Amount (an/ao))))
 splitTrans _ r _ = intErr "splitTrans" r
 
+-- When we are plotting the value of an account over time, we want price
+-- changes to be reflected in the plot, even though there is no change in
+-- the number of shares. So this do-nothing transaction fires on price
+-- records
+
+voidTrans :: Maybe [Name] -> Record -> AccountData ->
+             Ledger e (Record, [CCSAmt]) AccountData
+voidTrans reg record@(PriceRec _ _ _ _) acc =
+  maybeRecord reg record acc (const True) >> return acc
+voidTrans _ r _ = intErr "voidTrans" r
+
 {-
 -- new version with printing of initial values
 mkInit reg as =
@@ -323,6 +334,7 @@
             XferRec _ _ _ _ _ _   -> xferTrans r f t as >>= appTr d r f ts
             ExchRec _ _ _ _ _ _ _ -> exchTrans r f t as >>= appTr d r f ts
             SplitRec _ _ _ _      -> splitTrans r t as  >>= appTr d r f ts
+            PriceRec _ _ _ _      -> voidTrans r t as   >>= appTr d r f ts
             NoteRec _ isrec SN_T _ ->
               (if isrec then recordNil else recordInfo (t,[]))
                 >> appTr d r f ts as
@@ -361,15 +373,15 @@
      unless (null i) (putStrLn "Notes:" >> mapM_ ss i >> putStrLn "")
      return r
 
-plotBalances :: Date -> Date -> Name -> [Record] -> [Record] ->
+plotBalances :: Date -> Date -> Name -> [Name] -> [Record] -> [Record] ->
                 String -> ((Record, [CCSAmt]) -> (Date, [Amount])) -> IO ()
-plotBalances date1 date2 reg accts trans output gs =
+plotBalances date1 date2 name names accts trans output gs =
   do let (_,i1,e) =
-           runLedger (mkInit accts >>= appTr date2 (Just [reg]) False trans)
+           runLedger (mkInit accts >>= appTr date2 (Just names) False trans)
          i = dropWhile (\t -> getRecDate (fst t) < date1) i1
      unless (null e) (showErrs "processing errors" e)
-     if null i then putStrLn ("No balances known for " ++ show reg)
-               else genPlot output reg date1 date2 (map gs i)
+     if null i then putStrLn ("No balances known for " ++ show name)
+               else genPlot output name date1 date2 (map gs i)
 
 -- For now, we don't generate "swap prices" internally, so unless the user
 -- enters some, we won't see any; see also generateImplicitPrices above.
@@ -441,4 +453,6 @@
           XferRec dc (dc <= dr) f t m i
         mRD (ExchRec t _ _ a c1 c2 m) dr dc =
           ExchRec t dc (dc <= dr) a c1 c2 m
+        mRD (NoteRec _ _ SN_T m) dr dc =
+          NoteRec dc (dc <= dr) SN_T m
         mRD r _ _ = intErr "expandRecurringTrans" r
diff --git a/UMMHelp.hs b/UMMHelp.hs
--- a/UMMHelp.hs
+++ b/UMMHelp.hs
@@ -16,13 +16,13 @@
 along with umm; if not, write to the Free Software Foundation, Inc.,
 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-$Id: help-head.txt,v 1.6 2010/07/12 00:26:27 uwe Exp $ -}
+$Id: help-head.txt,v 1.7 2010/07/25 19:18:22 uwe Exp $ -}
 
 module UMMHelp (writeHdr, usageMsg) where
 import Prelude
 
 version :: String
-version = "0.3.0"
+version = "0.3.1"
 
 writeHdr :: String
 writeHdr =
@@ -39,10 +39,10 @@
   "    'balance' [account-or-group] [date]\n" ++
   "    'change' acc-or-inc-or-exp [date-range]\n" ++
   "    'list' ['all' | 'accounts' | 'ccs' | 'expenses' | 'incomes' | 'groups']\n" ++
-  "    'plot' account-or-ccs [date-range] [output-template]\n" ++
+  "    'plot' account-or-group-or-ccs [date-range] [output-template]\n" ++
   "    'price' ccs [date-range]\n" ++
-  "    'register' account [date-range]\n" ++
-  "    'reconcile' [account] [date]\n" ++
+  "    'register' account-or-group [date-range]\n" ++
+  "    'reconcile' [account-or-group] [date]\n" ++
   "    'todo' [date]\n" ++
   "    'basis' ccs [date]\n" ++
   "    'export'\n" ++
@@ -76,30 +76,30 @@
   "\n" ++
   "* 'plot' generates a plot of the price history of the specified\n" ++
   "  currency, commodity, or security, or of the value of the specified\n" ++
-  "  account, in the given date range.\n" ++
+  "  account or account group, in the given date range.\n" ++
   "\n" ++
   "* 'price' shows the price history of the specified currency,\n" ++
-  "  commodity, or security, in the given date range\n" ++
+  "  commodity, or security, in the given date range.\n" ++
   "\n" ++
   "* 'register' shows all transactions involving the specified\n" ++
-  "  account in the given date range, and shows the balance as of\n" ++
-  "  the end of that date range.\n" ++
+  "  account or account group in the given date range, and shows\n" ++
+  "  the balance as of the end of that date range.\n" ++
   "\n" ++
   "* 'reconcile' applies all reconciled transactions up to the\n" ++
   "  given date, shows relevant unreconciled transactions up to\n" ++
   "  that date, and shows the reconciled balance(s) as of that\n" ++
   "  date.\n" ++
   "\n" ++
-  "  If 'reconcile' is given an account, then only unreconciled\n" ++
-  "  transactions involving that account are shown, otherwise all\n" ++
-  "  unreconciled transactions are shown\n" ++
+  "  If 'reconcile' is given an account or account group, then only\n" ++
+  "  unreconciled transactions involving that account or account group\n" ++
+  "  are shown, otherwise all unreconciled transactions are shown.\n" ++
   "\n" ++
   "* 'todo' shows all the unreconciled 'todo' items in the ledger\n" ++
-  "  up to the date specified, defaulting to the current date\n" ++
+  "  up to the date specified, defaulting to the current date.\n" ++
   "\n" ++
   "* 'list' shows summaries of the various kinds of non-transaction\n" ++
   "  entries in the ledger file: currencies/commodities/securities,\n" ++
-  "  income and expense categories, accounts, and groups\n" ++
+  "  income and expense categories, accounts, and groups.\n" ++
   "\n" ++
   "* 'basis' shows the cost basis for a given currency or commodity\n" ++
   "  or security.\n" ++
@@ -118,7 +118,7 @@
   "    'group' name [name...]\n" ++
   "    'price' date [amount1] name1 amount2 [name2]\n" ++
   "    'split' date name amount1 amount2\n" ++
-  "    'todo' [rec] date text\n" ++
+  "    [period] 'todo' [rec] date text\n" ++
   "    [period] 'xfer' [rec] date name1 name2 amount [name] [desc] [id]\n" ++
   "    [period] 'xfer' [rec] date name1 {name2 amount [name],\\\n" ++
   "        \\ name3 amount [name], ...} [desc] [id]\n" ++
@@ -137,7 +137,7 @@
   "records, and an empty ledger file is syntactically legal. However, a\n" ++
   "minimally-useful ledger file will probably contain at least some\n" ++
   "'xfer' records, which in turn require that there be at least a couple\n" ++
-  "of 'account' or 'income' or 'expense' records, or possibly some 'todo'\n" ++
+  "of 'account' or 'income' or 'expense' records; or possibly some 'todo'\n" ++
   "records.\n" ++
   "\n" ++
   "The order of records in the ledger file is not significant; the\n" ++
@@ -154,7 +154,7 @@
   "* 'ccs name [desc] [amount] [name]' describes a currency or commodity\n" ++
   "  or security: the things you want to keep track of. The first ccs\n" ++
   "  record in the ledger file is the default unit; my ledger file has\n" ++
-  "  'ccs US$' very near the top. However, you don't need one, in which\n" ++
+  "  'ccs $' very near the top. However, you don't need one, in which\n" ++
   "  case the program computes in Zorkmid ('zm'). If you don't enter any\n" ++
   "  'ccs' record, you can't specify any units in 'xfer' records, and you\n" ++
   "  can't use any 'price' or 'split' records. You can use 'exch' (and\n" ++
@@ -198,15 +198,15 @@
   "  specify the price of one ccs in terms of another; usually a\n" ++
   "  currency. If the first amount is not specified, it defaults to 1,\n" ++
   "  and if the second name is not specified, it defaults to the default\n" ++
-  "  ccs. For example, if you are tracking ounces of gold using the ccs\n" ++
-  "  name 'Au', you might have a price record\n" ++
+  "  ccs. For example, if you are tracking troy ounces of gold using the\n" ++
+  "  ccs name 'Au', you might have a price record\n" ++
   "\n" ++
   "        price 2009-10-21 Au 1063.70\n" ++
   "\n" ++
   "  and if you track ounces but for some reason have a price quote in\n" ++
   "  grams, you might write\n" ++
   "\n" ++
-  "        price 2009-10-21 0.03215075 Au 34.19875 US$\n" ++
+  "        price 2009-10-21 0.03215075 Au 34.19875 $\n" ++
   "\n" ++
   "  'name1' (and 'name2', if specified) must be specified in the ledger\n" ++
   "  by 'ccs' records.\n" ++
@@ -232,7 +232,7 @@
   "  to account 'name2'; 'name1' may be either an account specified by an\n" ++
   "  'account' record, or a source specified by an 'income' record. If\n" ++
   "  you don't specify the name of what's being transferred, the program\n" ++
-  "  assumes it's the default ccs, US$ or Zorkmids or whatever. For\n" ++
+  "  assumes it's the default ccs, $ or Zorkmids or whatever. For\n" ++
   "  example, this record from my ledger file\n" ++
   "\n" ++
   "        xfer* 2009/2/27 interest abc:savings 0.01\n" ++
@@ -242,7 +242,7 @@
   "\n" ++
   "        xfer* 2009/9/26 checking utility:water 43.99 1216\n" ++
   "\n" ++
-  "  is the payment of my water bill, in the amount of US$ 43.99, with\n" ++
+  "  is the payment of my water bill, in the amount of $ 43.99, with\n" ++
   "  check #1216.\n" ++
   "\n" ++
   "  Both of these are marked as reconciled; this affects only the\n" ++
@@ -284,20 +284,20 @@
   "\n" ++
   "  would undo the previous 'buy' transaction. These could both be\n" ++
   "  written as 'exch' instead, as follows; I've added the explicit\n" ++
-  "  specifier of US$.\n" ++
+  "  specifier of $.\n" ++
   "\n" ++
-  "        exch 2009/10/2 brokerage 3.959 VTSMX 100 US$\n" ++
-  "        exch 2009/10/2 brokerage 100 US$ 3.959 VTSMX\n" ++
+  "        exch 2009/10/2 brokerage 3.959 VTSMX 100 $\n" ++
+  "        exch 2009/10/2 brokerage 100 $ 3.959 VTSMX\n" ++
   "\n" ++
   "  Again, for details on the optional [period] prefix, see below.\n" ++
   "\n" ++
-  "* 'todo [rec] date text' is basically a sticky note in the ledger. If\n" ++
-  "  the record is not marked as reconciled, and the date falls within\n" ++
-  "  the range of the command being executed, the text is printed out. If\n" ++
-  "  the record is marked as reconciled, the text is not printed out; the\n" ++
-  "  record merely serves as a comment in the ledger. This is for leaving\n" ++
-  "  yourself reminders of stuff that needs to be done at some time: for\n" ++
-  "  example, my ledger file has entries\n" ++
+  "* '[period] todo [rec] date text' is basically a sticky note in the\n" ++
+  "  ledger. If the record is not marked as reconciled, and the date falls\n" ++
+  "  within the range of the command being executed, the text is printed\n" ++
+  "  out. If the record is marked as reconciled, the text is not printed\n" ++
+  "  out; the record merely serves as a comment in the ledger. This is for\n" ++
+  "  leaving yourself reminders of stuff that needs to be done at some time:\n" ++
+  "  for example, my ledger file has entries\n" ++
   "\n" ++
   "        todo 2009/12/1 Start actively gathering tax info\n" ++
   "        todo 2010/4/10 Taxes better be done!!!\n" ++
@@ -305,6 +305,8 @@
   "  yet I won't be bothered by seeing these until those dates have\n" ++
   "  passed (or if I do a query for some time in the future).\n" ++
   "\n" ++
+  "  Again, for details on the optional [period] prefix, see below.\n" ++
+  "\n" ++
   "  In addition, there are two not-quite-financial bits of syntactic\n" ++
   "  sugar: there are two record types 'birthday' and 'anniversary', with\n" ++
   "  syntax otherwise just like 'todo', that act somewhat similarly. Both\n" ++
@@ -325,6 +327,9 @@
   "  them. As in 'todo' records, the reconciliation mark serves to\n" ++
   "  suppress these.\n" ++
   "\n" ++
+  "  It's illegal to have a [period] prefix with 'birthday' or 'anniversary'\n" ++
+  "  records.\n" ++
+  "\n" ++
   "In the above:\n" ++
   "\n" ++
   "* 'name' is a sequence of non-blank characters whose first character\n" ++
@@ -388,6 +393,9 @@
   "  has been properly reconciled with a statement, and for 'account'\n" ++
   "  records, it indicates that the account is inactive and should not\n" ++
   "  be printed in balance inquiries (unless there is something in it).\n" ++
+  "\n" ++
+  "  There is no difference, as far as the program is concerned, between\n" ++
+  "  '*' and '!'.\n" ++
   "\n" ++
   "* 'id' (in an 'xfer' record) is a sequence of digits: a check number\n" ++
   "  or other identifying number.\n" ++
diff --git a/UMMParser.hs b/UMMParser.hs
--- a/UMMParser.hs
+++ b/UMMParser.hs
@@ -16,7 +16,7 @@
 along with umm; if not, write to the Free Software Foundation, Inc.,
 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-$Id: UMMParser.hs,v 1.49 2010/05/17 05:24:10 uwe Exp $ -}
+$Id: UMMParser.hs,v 1.52 2010/07/27 04:09:05 uwe Exp $ -}
 
 -- TODO: template := <to be determined>
 
@@ -420,7 +420,7 @@
      dr <- option startTime
                   (TPCP.try (parsePrefixOf 3 "reconciled" >> parseDate))
      many space
-     record <- parseEBS <|> parseXfer
+     record <- TPCP.try parseEBS <|> parseXfer <|> parseTBA
      return (RecurRec period dl dr record)
 
 parseBlank = many space >> return (CommentRec "")
diff --git a/UMMPlot.hs b/UMMPlot.hs
--- a/UMMPlot.hs
+++ b/UMMPlot.hs
@@ -16,7 +16,7 @@
 along with umm; if not, write to the Free Software Foundation, Inc.,
 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-$Id: UMMPlot.hs,v 1.7 2010/07/12 00:26:26 uwe Exp $ -}
+$Id: UMMPlot.hs,v 1.10 2010/08/08 18:23:11 uwe Exp $ -}
 
 module UMMPlot (genPlot) where
 import Prelude hiding (putStr, putStrLn, print)
@@ -112,7 +112,7 @@
 plot_cmds output name lo hi =
   "set terminal postscript 'Times-Roman' 16\n" ++
   "set output '" ++ output ++ ".ps'\n" ++
-  "set title 'Value of " ++ name ++ " over time'\n" ++
+  "set title 'Value of account \"" ++ name ++ "\" over time'\n" ++
   "unset key\n" ++
   "set xdata time\n" ++
   "set timefmt \"%Y-%m-%d\"\n" ++
@@ -120,14 +120,23 @@
   "set xrange [\"" ++ show lo ++ "\":\"" ++ show hi ++ "\"]\n" ++
   "plot '" ++ output ++ ".dat' using 1:2 with lines\n"
 
+-- If we don't specify a range in plotting data, we get the default,
+-- which is "beginning of time to now"; that produces a not-very-useful
+-- graph. Since I don't want to necessarily always auto-snap to the
+-- dates given by the data (sometimes I want to show a 5-year graph of
+-- partial data, in order to combine it later with other, more-complete,
+-- data), there's a bit of hackery required: that's the "d1 = ..." stuff.
+
 genPlot :: String -> Name -> Date -> Date -> [(Date, [Amount])] -> IO ()
 genPlot output name date1 date2 pts =
   let pts1 = filter (not . null . snd) pts
+      d1 = if date1 == startTime then foldl1 min (map fst pts1) else date1
+      shn = show name
   in if null pts1
-        then putStrLn ("Nothing to show while trying to plot " ++ show name)
-        else do let (nlo, nhi, _) = niceDateBounds date1 date2
+        then putStrLn ("Nothing to show while trying to plot " ++ shn)
+        else do let (nlo, nhi, _) = niceDateBounds d1 date2
                 withFile (output ++ ".plot") WriteMode
-                  (\h -> hPutStr h (plot_cmds output (show name) nlo nhi))
+                  (\h -> hPutStr h (plot_cmds output shn nlo nhi))
                 withFile (output ++ ".dat") WriteMode
                   (\h -> mapM_ (dP h) pts1)
                 doit ("gnuplot " ++ output ++ ".plot")
