diff --git a/Hledger/Data/Amount.hs b/Hledger/Data/Amount.hs
--- a/Hledger/Data/Amount.hs
+++ b/Hledger/Data/Amount.hs
@@ -60,7 +60,7 @@
   nullmixedamt,
   missingamt,
   amounts,
-  normaliseMixedAmount,
+  normaliseMixedAmountPreservingFirstPrice,
   canonicaliseMixedAmountCommodity,
   mixedAmountWithCommodity,
   setMixedAmountPrecision,
@@ -262,7 +262,7 @@
 instance Num MixedAmount where
     fromInteger i = Mixed [Amount (comm "") (fromInteger i) Nothing]
     negate (Mixed as) = Mixed $ map negate as
-    (+) (Mixed as) (Mixed bs) = normaliseMixedAmountPreservingPrice $ Mixed $ as ++ bs
+    (+) (Mixed as) (Mixed bs) = normaliseMixedAmountPreservingPrices $ Mixed $ as ++ bs
     (*)    = error' "programming error, mixed amounts do not support multiplication"
     abs    = error' "programming error, mixed amounts do not support abs"
     signum = error' "programming error, mixed amounts do not support signum"
@@ -275,11 +275,11 @@
 missingamt :: MixedAmount
 missingamt = Mixed [Amount unknown{symbol="AUTO"} 0 Nothing]
 
--- | Simplify a mixed amount's component amounts: combine amounts with the
--- same commodity and price, remove any zero amounts, and replace an empty
--- amount list with a single zero amount.
-normaliseMixedAmountPreservingPrice :: MixedAmount -> MixedAmount
-normaliseMixedAmountPreservingPrice (Mixed as) = Mixed as''
+-- | Simplify a mixed amount's component amounts: combine amounts with
+-- the same commodity and price. Also remove any zero amounts and
+-- replace an empty amount list with a single zero amount.
+normaliseMixedAmountPreservingPrices :: MixedAmount -> MixedAmount
+normaliseMixedAmountPreservingPrices (Mixed as) = Mixed as''
     where
       as'' = if null nonzeros then [nullamt] else nonzeros
       (_,nonzeros) = partition (\a -> isReallyZeroAmount a && Mixed [a] /= missingamt) as'
@@ -288,13 +288,13 @@
       group = groupBy (\a1 a2 -> sym a1 == sym a2 && price a1 == price a2)
       sym = symbol . commodity
 
--- | Simplify a mixed amount's component amounts: combine amounts with the
--- same commodity, remove any zero amounts, and replace an empty amount
--- list with a single zero amount. Unlike normaliseMixedAmountPreservingPrice,
--- this one discards all but the first price encountered in each commodity.
--- (This is used more for display than arithmetic, but seems a bit odd. XXX)
-normaliseMixedAmount :: MixedAmount -> MixedAmount
-normaliseMixedAmount (Mixed as) = Mixed as''
+-- | Simplify a mixed amount's component amounts: combine amounts with
+-- the same commodity, using the first amount's price for subsequent
+-- amounts in each commodity (ie, this function alters the amount and
+-- is best used as a rendering helper.). Also remove any zero amounts
+-- and replace an empty amount list with a single zero amount.
+normaliseMixedAmountPreservingFirstPrice :: MixedAmount -> MixedAmount
+normaliseMixedAmountPreservingFirstPrice (Mixed as) = Mixed as''
     where 
       as'' = if null nonzeros then [nullamt] else nonzeros
       (_,nonzeros) = partition (\a -> isReallyZeroAmount a && Mixed [a] /= missingamt) as'
@@ -303,6 +303,12 @@
       group = groupBy (\a1 a2 -> sym a1 == sym a2)
       sym = symbol . commodity
 
+-- discardPrice :: Amount -> Amount
+-- discardPrice a = a{price=Nothing}
+
+-- discardPrices :: MixedAmount -> MixedAmount
+-- discardPrices (Mixed as) = Mixed $ map discardPrice as
+
 sumAmountsUsingFirstPrice [] = nullamt
 sumAmountsUsingFirstPrice as = (sum as){price=price $ head as}
 
@@ -323,15 +329,15 @@
 isNegativeMixedAmount :: MixedAmount -> Maybe Bool
 isNegativeMixedAmount m = case as of [a] -> Just $ isNegativeAmount a
                                      _   -> Nothing
-    where as = amounts $ normaliseMixedAmount m
+    where as = amounts $ normaliseMixedAmountPreservingFirstPrice m
 
 -- | Does this mixed amount appear to be zero when displayed with its given precision ?
 isZeroMixedAmount :: MixedAmount -> Bool
-isZeroMixedAmount = all isZeroAmount . amounts . normaliseMixedAmount
+isZeroMixedAmount = all isZeroAmount . amounts . normaliseMixedAmountPreservingFirstPrice
 
 -- | Is this mixed amount "really" zero ? See isReallyZeroAmount.
 isReallyZeroMixedAmount :: MixedAmount -> Bool
-isReallyZeroMixedAmount = all isReallyZeroAmount . amounts . normaliseMixedAmount
+isReallyZeroMixedAmount = all isReallyZeroAmount . amounts . normaliseMixedAmountPreservingFirstPrice
 
 -- | Is this mixed amount "really" zero, after converting to cost
 -- commodities where possible ?
@@ -349,14 +355,14 @@
 -- -- For now, use this when cross-commodity zero equality is important.
 -- mixedAmountEquals :: MixedAmount -> MixedAmount -> Bool
 -- mixedAmountEquals a b = amounts a' == amounts b' || (isZeroMixedAmount a' && isZeroMixedAmount b')
---     where a' = normaliseMixedAmount a
---           b' = normaliseMixedAmount b
+--     where a' = normaliseMixedAmountPreservingFirstPrice a
+--           b' = normaliseMixedAmountPreservingFirstPrice b
 
 -- | Get the string representation of a mixed amount, showing each of
 -- its component amounts. NB a mixed amount can have an empty amounts
 -- list in which case it shows as \"\".
 showMixedAmount :: MixedAmount -> String
-showMixedAmount m = vConcatRightAligned $ map show $ amounts $ normaliseMixedAmount m
+showMixedAmount m = vConcatRightAligned $ map show $ amounts $ normaliseMixedAmountPreservingFirstPrice m
 
 -- | Set the display precision in the amount's commodities.
 setMixedAmountPrecision :: Int -> MixedAmount -> MixedAmount
@@ -367,19 +373,19 @@
 -- commoditys' display precision settings.
 showMixedAmountWithPrecision :: Int -> MixedAmount -> String
 showMixedAmountWithPrecision p m =
-    vConcatRightAligned $ map (showAmountWithPrecision p) $ amounts $ normaliseMixedAmount m
+    vConcatRightAligned $ map (showAmountWithPrecision p) $ amounts $ normaliseMixedAmountPreservingFirstPrice m
 
 -- | Get an unambiguous string representation of a mixed amount for debugging.
 showMixedAmountDebug :: MixedAmount -> String
 showMixedAmountDebug m = printf "Mixed [%s]" as
-    where as = intercalate "\n       " $ map showAmountDebug $ amounts $ normaliseMixedAmount m
+    where as = intercalate "\n       " $ map showAmountDebug $ amounts $ normaliseMixedAmountPreservingFirstPrice m
 
 -- | Get the string representation of a mixed amount, but without
 -- any \@ prices.
 showMixedAmountWithoutPrice :: MixedAmount -> String
 showMixedAmountWithoutPrice m = concat $ intersperse "\n" $ map showfixedwidth as
     where
-      (Mixed as) = normaliseMixedAmount $ stripPrices m
+      (Mixed as) = normaliseMixedAmountPreservingFirstPrice $ stripPrices m
       stripPrices (Mixed as) = Mixed $ map stripprice as where stripprice a = a{price=Nothing}
       width = maximum $ map (length . show) as
       showfixedwidth = printf (printf "%%%ds" width) . showAmountWithoutPrice
@@ -434,9 +440,9 @@
 
   -- MixedAmount
 
-  ,"normaliseMixedAmount" ~: do
-    normaliseMixedAmount (Mixed []) `is` Mixed [nullamt]
-    assertBool "" $ isZeroMixedAmount $ normaliseMixedAmount (Mixed [Amount {commodity=dollar, quantity=10,    price=Nothing}
+  ,"normaliseMixedAmountPreservingFirstPrice" ~: do
+    normaliseMixedAmountPreservingFirstPrice (Mixed []) `is` Mixed [nullamt]
+    assertBool "" $ isZeroMixedAmount $ normaliseMixedAmountPreservingFirstPrice (Mixed [Amount {commodity=dollar, quantity=10,    price=Nothing}
                                                                     ,Amount {commodity=dollar, quantity=10,    price=Just (TotalPrice (Mixed [Amount {commodity=euro, quantity=7, price=Nothing}]))}
                                                                     ,Amount {commodity=dollar, quantity=(-10), price=Nothing}
                                                                     ,Amount {commodity=dollar, quantity=(-10), price=Just (TotalPrice (Mixed [Amount {commodity=euro, quantity=7, price=Nothing}]))}
diff --git a/Hledger/Data/Journal.hs b/Hledger/Data/Journal.hs
--- a/Hledger/Data/Journal.hs
+++ b/Hledger/Data/Journal.hs
@@ -266,7 +266,6 @@
 journalFinalise tclock tlocal path txt ctx j@Journal{files=fs} =
     journalBalanceTransactions $
     journalCanonicaliseAmounts $
-    journalApplyHistoricalPrices $
     journalCloseTimeLogEntries tlocal
     j{files=(path,txt):fs, filereadtime=tclock, jContext=ctx}
 
@@ -280,11 +279,10 @@
                                     Left e    -> Left e
       where balance = balanceTransaction (Just $ journalCanonicalCommodities j)
 
--- | Convert all the journal's amounts to their canonical display
--- settings.  Ie, all amounts in a given commodity will use (a) the
--- display settings of the first, and (b) the greatest precision, of the
--- amounts in that commodity. Prices are canonicalised as well, so consider
--- calling journalApplyHistoricalPrices before this.
+-- | Convert all the journal's posting amounts (not price amounts) to
+-- their canonical display settings. Ie, all amounts in a given
+-- commodity will use (a) the display settings of the first, and (b)
+-- the greatest precision, of the posting amounts in that commodity.
 journalCanonicaliseAmounts :: Journal -> Journal
 journalCanonicaliseAmounts j@Journal{jtxns=ts} = j{jtxns=map fixtransaction ts}
     where
diff --git a/Hledger/Data/Transaction.hs b/Hledger/Data/Transaction.hs
--- a/Hledger/Data/Transaction.hs
+++ b/Hledger/Data/Transaction.hs
@@ -141,17 +141,20 @@
       bvsum' = canonicaliseMixedAmountCommodity canonicalcommoditymap $ costOfMixedAmount bvsum
 
 -- | Ensure this transaction is balanced, possibly inferring a missing
--- amount or a conversion price first, or return an error message.
+-- amount or conversion price, or return an error message.
 --
--- Balancing is affected by the provided commodities' display precisions.
+-- Balancing is affected by commodity display precisions, so those may
+-- be provided.
 --
--- We can infer an amount when there are multiple real postings and
--- exactly one of them is amountless; likewise for balanced virtual
--- postings. Inferred amounts are converted to cost basis when possible.
+-- We can infer a missing real amount when there are multiple real
+-- postings and exactly one of them is amountless (likewise for
+-- balanced virtual postings). Inferred amounts are converted to cost
+-- basis when possible.
 --
--- We can infer a price when all amounts were specified and the sum of
--- real postings' amounts is exactly two non-explicitly-priced amounts in
--- different commodities; likewise for balanced virtual postings.
+-- We can infer a conversion price when all real amounts are specified
+-- and the sum of real postings' amounts is exactly two
+-- non-explicitly-priced amounts in different commodities (likewise
+-- for balanced virtual postings).
 balanceTransaction :: Maybe (Map.Map String Commodity) -> Transaction -> Either String Transaction
 balanceTransaction canonicalcommoditymap t@Transaction{tpostings=ps}
     | length rwithoutamounts > 1 || length bvwithoutamounts > 1
@@ -166,8 +169,8 @@
       bvamounts = map pamount bvwithamounts
       t' = t{tpostings=map inferamount ps}
           where 
-            inferamount p | not (hasAmount p) && isReal p            = p{pamount = (- sum ramounts)}
-                          | not (hasAmount p) && isBalancedVirtual p = p{pamount = (- sum bvamounts)}
+            inferamount p | not (hasAmount p) && isReal p            = p{pamount = costOfMixedAmount (- sum ramounts)}
+                          | not (hasAmount p) && isBalancedVirtual p = p{pamount = costOfMixedAmount (- sum bvamounts)}
                           | otherwise                             = p
 
       -- maybe infer conversion prices, for real postings
diff --git a/hledger-lib.cabal b/hledger-lib.cabal
--- a/hledger-lib.cabal
+++ b/hledger-lib.cabal
@@ -1,5 +1,5 @@
 name:           hledger-lib
-version: 0.16.1
+version: 0.17
 category:       Finance
 synopsis:       Core data types, parsers and utilities for the hledger accounting tool.
 description:
@@ -17,7 +17,7 @@
 homepage:       http://hledger.org
 bug-reports:    http://code.google.com/p/hledger/issues
 stability:      beta
-tested-with:    GHC==6.12, GHC==7.0
+tested-with:    GHC==7.0, GHC==7.2
 cabal-version:  >= 1.6
 build-type:     Simple
 -- data-dir:       data
@@ -56,7 +56,7 @@
   Build-Depends:
                   base >= 3 && < 5
                  ,bytestring
-                 ,cmdargs >= 0.8   && < 0.9
+                 ,cmdargs >= 0.9.1   && < 0.10
                  ,containers
                  ,directory
                  ,filepath
