diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -17,6 +17,9 @@
 For user-visible changes, see the hledger package changelog.
 
 
+# 1.52.1 2026-04-28
+ 
+ 
 # 1.52 2026-03-20
 
 Breaking changes
diff --git a/Hledger/Data/AccountName.hs b/Hledger/Data/AccountName.hs
--- a/Hledger/Data/AccountName.hs
+++ b/Hledger/Data/AccountName.hs
@@ -112,7 +112,6 @@
   | regexMatchText liabilityAccountRegex  a = Just Liability
   | regexMatchText conversionAccountRegex a = Just Conversion
   | regexMatchText equityAccountRegex     a = Just Equity
-  | regexMatchText gainAccountRegex       a = Just Gain
   | regexMatchText revenueAccountRegex    a = Just Revenue
   | regexMatchText expenseAccountRegex    a = Just Expense
   | otherwise                               = Nothing
@@ -450,13 +449,14 @@
     accountNameInferType "revenues"          @?= Just Revenue
     accountNameInferType "revenue"           @?= Just Revenue
     accountNameInferType "income"            @?= Just Revenue
-    accountNameInferType "income:gains"          @?= Just Gain
-    accountNameInferType "revenue:gain"          @?= Just Gain
-    accountNameInferType "revenues:capital-gains" @?= Just Gain
-    accountNameInferType "income:capitalgain"    @?= Just Gain
-    accountNameInferType "income:losses"         @?= Just Gain
-    accountNameInferType "revenue:capital-loss"  @?= Just Gain
-    accountNameInferType "income:gains:realized" @?= Just Gain
+    -- Gain type is no longer inferred from names; these are now Revenue
+    accountNameInferType "income:gains"          @?= Just Revenue
+    accountNameInferType "revenue:gain"          @?= Just Revenue
+    accountNameInferType "revenues:capital-gains" @?= Just Revenue
+    accountNameInferType "income:capitalgain"    @?= Just Revenue
+    accountNameInferType "income:losses"         @?= Just Revenue
+    accountNameInferType "revenue:capital-loss"  @?= Just Revenue
+    accountNameInferType "income:gains:realized" @?= Just Revenue
   ,testCase "joinAccountNames" $ do
     joinAccountNames "assets" "cash"     @?= "assets:cash"
     joinAccountNames "assets:cash" "a"   @?= "assets:cash:a"
diff --git a/Hledger/Data/Balancing.hs b/Hledger/Data/Balancing.hs
--- a/Hledger/Data/Balancing.hs
+++ b/Hledger/Data/Balancing.hs
@@ -66,6 +66,7 @@
                                     --   Distinct from InputOpts{infer_costs_}.
   , commodity_styles_      :: Maybe (M.Map CommoditySymbol AmountStyle)  -- ^ commodity display styles
   , txn_balancing_         :: TransactionBalancingPrecision
+  , account_types_         :: M.Map AccountName AccountType  -- ^ account type map, passed through for any balancing helpers that need it
   } deriving (Eq, Ord, Show)
 
 defbalancingopts :: BalancingOpts
@@ -74,6 +75,7 @@
   , infer_balancing_costs_ = True
   , commodity_styles_      = Nothing
   , txn_balancing_         = TBPExact
+  , account_types_         = M.empty
   }
 
 -- | Check that this transaction would appear balanced to a human when displayed.
@@ -193,7 +195,7 @@
   (t', inferredamtsandaccts) <- t
     & (if infer_balancing_costs_ bopts then transactionInferBalancingCosts else id)
     & dbg9With (lbl "amounts after balancing-cost-inferring".show.map showMixedAmountOneLine.transactionAmounts)
-    & transactionInferBalancingAmount (fromMaybe M.empty $ commodity_styles_ bopts)
+    & transactionInferBalancingAmount (fromMaybe M.empty $ commodity_styles_ bopts) (account_types_ bopts)
     <&> dbg9With (lbl "balancing amounts inferred".show.map (second showMixedAmountOneLine).snd)
   case transactionCheckBalanced bopts t' of
     []   -> Right (txnTieKnot t', inferredamtsandaccts)
@@ -242,9 +244,10 @@
 -- have the same price(s), and will be converted to the price commodity.
 transactionInferBalancingAmount ::
      M.Map CommoditySymbol AmountStyle -- ^ commodity display styles
+  -> M.Map AccountName AccountType     -- ^ account type map (passed through; reserved for future use)
   -> Transaction
   -> Either String (Transaction, [(AccountName, MixedAmount)])
-transactionInferBalancingAmount styles t@Transaction{tpostings=ps}
+transactionInferBalancingAmount styles _atypes t@Transaction{tpostings=ps}
   | length amountlessrealps > 1
       = Left $ transactionBalanceError t
         ["There can't be more than one real posting with no amount."
@@ -793,10 +796,10 @@
   testGroup "Balancing" [
 
       testCase "transactionInferBalancingAmount" $ do
-         (fst <$> transactionInferBalancingAmount M.empty nulltransaction) @?= Right nulltransaction
-         (fst <$> transactionInferBalancingAmount M.empty nulltransaction{tpostings = ["a" `post` usd (-5), "b" `post` missingamt]}) @?=
+         (fst <$> transactionInferBalancingAmount M.empty M.empty nulltransaction) @?= Right nulltransaction
+         (fst <$> transactionInferBalancingAmount M.empty M.empty nulltransaction{tpostings = ["a" `post` usd (-5), "b" `post` missingamt]}) @?=
            Right nulltransaction{tpostings = ["a" `post` usd (-5), "b" `post` usd 5]}
-         (fst <$> transactionInferBalancingAmount M.empty nulltransaction{tpostings = ["a" `post` usd (-5), "b" `post` (eur 3 @@ usd 4), "c" `post` missingamt]}) @?=
+         (fst <$> transactionInferBalancingAmount M.empty M.empty nulltransaction{tpostings = ["a" `post` usd (-5), "b" `post` (eur 3 @@ usd 4), "c" `post` missingamt]}) @?=
            Right nulltransaction{tpostings = ["a" `post` usd (-5), "b" `post` (eur 3 @@ usd 4), "c" `post` usd 1]}
 
     , testGroup "balanceSingleTransaction" [
diff --git a/Hledger/Data/Types.hs b/Hledger/Data/Types.hs
--- a/Hledger/Data/Types.hs
+++ b/Hledger/Data/Types.hs
@@ -187,20 +187,22 @@
   | Equity
   | Revenue
   | Expense
-  | Cash  -- ^ a subtype of Asset - liquid assets to show in cashflow report
-  | Conversion -- ^ a subtype of Equity - account with which to balance commodity conversions
-  | Gain      -- ^ a subtype of Revenue - capital gains/losses
+  | Cash            -- ^ a subtype of Asset - liquid assets to show in cashflow report
+  | Conversion      -- ^ a subtype of Equity - account with which to balance commodity conversions
+  | Gain            -- ^ a subtype of Revenue - realised capital gains/losses
+  | UnrealisedGain  -- ^ a subtype of Equity - accumulated unrealised capital gains/losses (used by hledger 2)
   deriving (Eq,Ord,Generic)
 
 instance Show AccountType where
-  show Asset      = "A"
-  show Liability  = "L"
-  show Equity     = "E"
-  show Revenue    = "R"
-  show Expense    = "X"
-  show Cash       = "C"
-  show Conversion = "V"
-  show Gain       = "G"
+  show Asset          = "A"
+  show Liability      = "L"
+  show Equity         = "E"
+  show Revenue        = "R"
+  show Expense        = "X"
+  show Cash           = "C"
+  show Conversion     = "V"
+  show Gain           = "G"
+  show UnrealisedGain = "U"
 
 isBalanceSheetAccountType :: AccountType -> Bool
 isBalanceSheetAccountType t = t `elem` [
@@ -208,7 +210,8 @@
   Liability,
   Equity,
   Cash,
-  Conversion
+  Conversion,
+  UnrealisedGain
   ]
 
 isIncomeStatementAccountType :: AccountType -> Bool
@@ -221,18 +224,20 @@
 -- | Check whether the first argument is a subtype of the second: either equal
 -- or one of the defined subtypes.
 isAccountSubtypeOf :: AccountType -> AccountType -> Bool
-isAccountSubtypeOf Asset      Asset      = True
-isAccountSubtypeOf Liability  Liability  = True
-isAccountSubtypeOf Equity     Equity     = True
-isAccountSubtypeOf Revenue    Revenue    = True
-isAccountSubtypeOf Expense    Expense    = True
-isAccountSubtypeOf Cash       Cash       = True
-isAccountSubtypeOf Cash       Asset      = True
-isAccountSubtypeOf Conversion Conversion = True
-isAccountSubtypeOf Conversion Equity     = True
-isAccountSubtypeOf Gain       Gain       = True
-isAccountSubtypeOf Gain       Revenue    = True
-isAccountSubtypeOf _          _          = False
+isAccountSubtypeOf Asset          Asset          = True
+isAccountSubtypeOf Liability      Liability      = True
+isAccountSubtypeOf Equity         Equity         = True
+isAccountSubtypeOf Revenue        Revenue        = True
+isAccountSubtypeOf Expense        Expense        = True
+isAccountSubtypeOf Cash           Cash           = True
+isAccountSubtypeOf Cash           Asset          = True
+isAccountSubtypeOf Conversion     Conversion     = True
+isAccountSubtypeOf Conversion     Equity         = True
+isAccountSubtypeOf Gain           Gain           = True
+isAccountSubtypeOf Gain           Revenue        = True
+isAccountSubtypeOf UnrealisedGain UnrealisedGain = True
+isAccountSubtypeOf UnrealisedGain Equity         = True
+isAccountSubtypeOf _              _              = False
 
 -- not worth the trouble, letters defined in accountdirectivep for now
 --instance Read AccountType
diff --git a/Hledger/Query.hs b/Hledger/Query.hs
--- a/Hledger/Query.hs
+++ b/Hledger/Query.hs
@@ -519,8 +519,8 @@
 accountTypeChoices allowlongform =
   intercalate ", "
     -- keep synced with parseAccountType
-    $ ["A","L","E","R","X","C","V","G"]
-    ++ if allowlongform then ["Asset","Liability","Equity","Revenue","Expense","Cash","Conversion","Gain"] else []
+    $ ["A","L","E","R","X","C","V","G","U"]
+    ++ if allowlongform then ["Asset","Liability","Equity","Revenue","Expense","Cash","Conversion","Gain","UnrealisedGain"] else []
 
 -- | Case-insensitively parse one single-letter code, or one long-form word if permitted, to an account type.
 -- On failure, returns the unparseable text.
@@ -528,23 +528,26 @@
 parseAccountType allowlongform s =
   case T.toLower s of
     -- keep synced with accountTypeChoices
-    "a"                          -> Right Asset
-    "l"                          -> Right Liability
-    "e"                          -> Right Equity
-    "r"                          -> Right Revenue
-    "x"                          -> Right Expense
-    "c"                          -> Right Cash
-    "v"                          -> Right Conversion
-    "g"                          -> Right Gain
-    "asset"      | allowlongform -> Right Asset
-    "liability"  | allowlongform -> Right Liability
-    "equity"     | allowlongform -> Right Equity
-    "revenue"    | allowlongform -> Right Revenue
-    "expense"    | allowlongform -> Right Expense
-    "cash"       | allowlongform -> Right Cash
-    "conversion" | allowlongform -> Right Conversion
-    "gains"      | allowlongform -> Right Gain
-    _                            -> Left $ T.unpack s
+    "a"                               -> Right Asset
+    "l"                               -> Right Liability
+    "e"                               -> Right Equity
+    "r"                               -> Right Revenue
+    "x"                               -> Right Expense
+    "c"                               -> Right Cash
+    "v"                               -> Right Conversion
+    "g"                               -> Right Gain
+    "u"                               -> Right UnrealisedGain
+    "asset"          | allowlongform  -> Right Asset
+    "liability"      | allowlongform  -> Right Liability
+    "equity"         | allowlongform  -> Right Equity
+    "revenue"        | allowlongform  -> Right Revenue
+    "expense"        | allowlongform  -> Right Expense
+    "cash"           | allowlongform  -> Right Cash
+    "conversion"     | allowlongform  -> Right Conversion
+    "gain"           | allowlongform  -> Right Gain
+    "unrealisedgain" | allowlongform  -> Right UnrealisedGain
+    "unrealizedgain" | allowlongform  -> Right UnrealisedGain
+    _                                 -> Left $ T.unpack s
 
 -- | Parse the value part of a "status:" query, or return an error.
 parseStatus :: T.Text -> Either String Status
diff --git a/Hledger/Read/Common.hs b/Hledger/Read/Common.hs
--- a/Hledger/Read/Common.hs
+++ b/Hledger/Read/Common.hs
@@ -404,7 +404,7 @@
        -- >>= \j -> deepseq (concatMap (T.unpack.showTransaction).jtxns $ j) (return j)
       <&> dbg9With (lbl "amounts after styling, forecasting, auto-posting".showJournalPostingAmountsDebug)
       >>= (\j -> if checkordereddates then journalCheckOrdereddates j $> j else Right j)  -- check ordereddates before assertions. The outer parentheses are needed.
-      >>= journalBalanceTransactions balancingopts_{ignore_assertions_=not checkassertions}  -- infer balance assignments and missing amounts, and maybe check balance assertions.
+      >>= (\j -> journalBalanceTransactions balancingopts_{ignore_assertions_=not checkassertions, account_types_ = jaccounttypes j} j)  -- infer balance assignments and missing amounts, and maybe check balance assertions.
       <&> dbg9With (lbl "amounts after transaction-balancing".showJournalPostingAmountsDebug)
       -- <&> dbg9With (("journalFinalise amounts after styling, forecasting, auto postings, transaction balancing"<>).showJournalPostingAmountsDebug)
       >>= journalInferCommodityStyles                    -- infer commodity styles once more now that all posting amounts are present
diff --git a/Hledger/Read/JournalReader.hs b/Hledger/Read/JournalReader.hs
--- a/Hledger/Read/JournalReader.hs
+++ b/Hledger/Read/JournalReader.hs
@@ -549,26 +549,28 @@
 parseAccountTypeCode :: Text -> Either String AccountType
 parseAccountTypeCode s =
   case T.toLower s of
-    "asset"      -> Right Asset
-    "a"          -> Right Asset
-    "liability"  -> Right Liability
-    "l"          -> Right Liability
-    "equity"     -> Right Equity
-    "e"          -> Right Equity
-    "revenue"    -> Right Revenue
-    "r"          -> Right Revenue
-    "expense"    -> Right Expense
-    "x"          -> Right Expense
-    "cash"       -> Right Cash
-    "c"          -> Right Cash
-    "conversion" -> Right Conversion
-    "v"          -> Right Conversion
-    "gains"      -> Right Gain
-    "g"          -> Right Gain
-    _            -> Left err
+    "asset"            -> Right Asset
+    "a"                -> Right Asset
+    "liability"        -> Right Liability
+    "l"                -> Right Liability
+    "equity"           -> Right Equity
+    "e"                -> Right Equity
+    "revenue"          -> Right Revenue
+    "r"                -> Right Revenue
+    "expense"          -> Right Expense
+    "x"                -> Right Expense
+    "cash"             -> Right Cash
+    "c"                -> Right Cash
+    "conversion"       -> Right Conversion
+    "v"                -> Right Conversion
+    "gain"             -> Right Gain
+    "g"                -> Right Gain
+    "unrealisedgain"   -> Right UnrealisedGain
+    "u"                -> Right UnrealisedGain
+    _                  -> Left err
   where
     err = T.unpack $ "invalid account type code "<>s<>", should be one of " <>
-            T.intercalate ", " ["A","L","E","R","X","C","V","G","Asset","Liability","Equity","Revenue","Expense","Cash","Conversion","Gain"]
+            T.intercalate ", " ["A","L","E","R","X","C","V","G","U","Asset","Liability","Equity","Revenue","Expense","Cash","Conversion","Gain","UnrealisedGain"]
 
 -- Add an account declaration to the journal, auto-numbering it.
 addAccountDeclaration :: (AccountName,Text,[Tag],SourcePos) -> JournalParser m ()
diff --git a/Hledger/Reports/AccountTransactionsReport.hs b/Hledger/Reports/AccountTransactionsReport.hs
--- a/Hledger/Reports/AccountTransactionsReport.hs
+++ b/Hledger/Reports/AccountTransactionsReport.hs
@@ -146,7 +146,7 @@
       | balanceaccum_ ropts == Historical = sumPostings priorps
       | otherwise                         = nullmixedamt
       where
-        priorps = dbg5 "priorps" . journalPostings $ filterJournalPostings priorq acctJournal
+        priorps = dbg5 "priorps" . filter hasAmount . journalPostings $ filterJournalPostings priorq acctJournal
         priorq = dbg5 "priorq" $ And [thisacctq, tostartdateq, datelessreportq]
         tostartdateq =
           case mstartdate of
diff --git a/Hledger/Reports/MultiBalanceReport.hs b/Hledger/Reports/MultiBalanceReport.hs
--- a/Hledger/Reports/MultiBalanceReport.hs
+++ b/Hledger/Reports/MultiBalanceReport.hs
@@ -183,6 +183,7 @@
 getPostings :: ReportSpec -> Journal -> PriceOracle -> DateSpan -> [Posting]
 getPostings rspec@ReportSpec{_rsQuery=query, _rsReportOpts=ropts} j priceoracle reportspan =
     setPostingsCount
+    . filter hasAmount  -- omit postings with no definite amount
     . journalPostings
     $ journalValueAndFilterPostingsWith rspec' j priceoracle
   where
diff --git a/Hledger/Reports/PostingsReport.hs b/Hledger/Reports/PostingsReport.hs
--- a/Hledger/Reports/PostingsReport.hs
+++ b/Hledger/Reports/PostingsReport.hs
@@ -156,9 +156,10 @@
     dbg5 "beforeps, duringps" $ span (beforestartq `matchesPosting`) beforeandduringps
   where
     beforestartq = dbg3 "beforestartq" $ dateqtype $ DateSpan Nothing (Exact <$> spanStart reportspan)
-    beforeandduringps = 
+    beforeandduringps =
         sortOn (postingDateOrDate2 (whichDate ropts))            -- sort postings by date or date2
       . (if invert_ ropts then map postingNegateMainAmount else id)  -- with --invert, invert amounts
+      . filter hasAmount                                         -- omit postings with no definite amount
       . journalPostings
       -- With most calls we will not require transaction prices past this point, and can get a big
       -- speed improvement by stripping them early. In some cases, such as in hledger-ui, we still
diff --git a/hledger-lib.cabal b/hledger-lib.cabal
--- a/hledger-lib.cabal
+++ b/hledger-lib.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           hledger-lib
-version:        1.52
+version:        1.52.1
 synopsis:       A library providing the core functionality of hledger
 description:    This library contains hledger's core functionality.
                 It is used by most hledger* packages so that they support the same
@@ -124,7 +124,7 @@
   hs-source-dirs:
       ./
   ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind
-  cpp-options: -DVERSION="1.52"
+  cpp-options: -DVERSION="1.52.1"
   build-depends:
       Decimal >=0.5.1
     , Glob >=0.9
@@ -184,7 +184,7 @@
   hs-source-dirs:
       test
   ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind
-  cpp-options: -DVERSION="1.52"
+  cpp-options: -DVERSION="1.52.1"
   build-depends:
       Decimal >=0.5.1
     , Glob >=0.7
@@ -245,7 +245,7 @@
   hs-source-dirs:
       test
   ghc-options: -Wall -Wno-incomplete-uni-patterns -Wno-missing-signatures -Wno-orphans -Wno-type-defaults -Wno-unused-do-bind
-  cpp-options: -DVERSION="1.52"
+  cpp-options: -DVERSION="1.52.1"
   build-depends:
       Decimal >=0.5.1
     , Glob >=0.9
