lists.arthurdejong.org
RSS feed

python-stdnum branch master updated. 1.17-5-ga9039c1

[Date Prev][Date Next] [Thread Prev][Thread Next]

python-stdnum branch master updated. 1.17-5-ga9039c1



This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "python-stdnum".

The branch, master has been updated
       via  a9039c1a51463a040aad5cce3d8b66cb3d44a542 (commit)
       via  219ff54156e7a86c6d6d44548a5bdce3bfafdebb (commit)
       via  fd32e61850022cc3c54945c2e513da5d577c407b (commit)
      from  02dec52602ae0709b940b781fc1fcebfde7340b7 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://arthurdejong.org/git/python-stdnum/commit/?id=a9039c1a51463a040aad5cce3d8b66cb3d44a542

commit a9039c1a51463a040aad5cce3d8b66cb3d44a542
Author: Arthur de Jong <arthur@arthurdejong.org>
Date:   Sun Feb 13 20:53:04 2022 +0100

    Add Classification of Financial Instruments
    
    This implements parsing of ISO 10962 CFI codes based on the published
    description of the structure of these numbers.
    
    Closes https://github.com/arthurdejong/python-stdnum/issues/283

diff --git a/stdnum/cfi.dat b/stdnum/cfi.dat
new file mode 100644
index 0000000..d84a2e9
--- /dev/null
+++ b/stdnum/cfi.dat
@@ -0,0 +1,1532 @@
+# generated from cfitest_20210507_current.xlsx, downloaded from
+# 
https://www.six-group.com/en/products-services/financial-information/data-standards.html
+C category="CIVs"
+ B group="Real estate investment trust"
+  C v="Closed-end"
+  M v="Others"
+  O v="Open-end"
+  A-Z a="Closed/open-end"
+   G v="Accumulation funds"
+   I v="Income funds"
+   J v="Mixed funds"
+   A-Z a="Distribution policy"
+    A-Z
+     Q v="Shares for QI"
+     S v="Shares"
+     U v="Units"
+     Y v="Units for QI"
+     A-Z a="Security type and investor restrictions"
+ E group="Exchange traded funds"
+  C v="Closed-end"
+  M v="Others"
+  O v="Open-end"
+  A-Z a="Closed/open-end"
+   G v="Accumulation funds"
+   I v="Income funds"
+   J v="Mixed funds"
+   A-Z a="Distribution policy"
+    B v="Debt instruments"
+    C v="Commodities"
+    D v="Derivatives"
+    E v="Equities"
+    F v="Referential instruments excluding commodities"
+    K v="Credits"
+    L v="Mixed"
+    M v="Others"
+    R v="Real estate"
+    V v="Convertible securities"
+    A-Z a="Assets"
+     S v="Shares"
+     U v="Units"
+     A-Z a="Security type and investor restrictions"
+ F group="Funds of funds"
+  C v="Closed-end"
+  M v="Others"
+  O v="Open-end"
+  A-Z a="Closed/open-end"
+   G v="Accumulation funds"
+   I v="Income funds"
+   J v="Mixed funds"
+   A-Z a="Distribution policy"
+    B v="REITs"
+    E v="ETFs"
+    H v="Hedge funds"
+    I v="Standard"
+    M v="Others"
+    M v="Others"
+    P v="Private equity funds"
+    A-Z a="Type of funds"
+     Q v="Shares for QI"
+     S v="Shares"
+     U v="Units"
+     Y v="Units for QI"
+     A-Z a="Security type and investor restrictions"
+ H group="Hedge funds"
+  A v="Arbitrage"
+  D v="Directional"
+  E v="Event-driven"
+  L v="Asset-based lending"
+  M v="Others"
+  N v="Multi-strategy"
+  R v="Relative value"
+  S v="Security selection"
+  A-Z a="Investment strategy"
+   A-Z
+    A-Z
+     A-Z
+ I group="Standard"
+  C v="Closed-end"
+  M v="Others"
+  O v="Open-end"
+  A-Z a="Closed/open-end"
+   G v="Accumulation funds"
+   I v="Income funds"
+   J v="Mixed funds"
+   A-Z a="Distribution policy"
+    B v="Debt instruments"
+    C v="Commodities"
+    D v="Derivatives"
+    E v="Equities"
+    F v="Referential instruments excluding commodities"
+    K v="Credits"
+    L v="Mixed"
+    M v="Others"
+    R v="Real estate"
+    V v="Convertible securities"
+    A-Z a="Assets"
+     Q v="Shares for QI"
+     S v="Shares"
+     U v="Units"
+     Y v="Units for QI"
+     A-Z a="Security type and investor restrictions"
+ M group="Others"
+  A-Z
+   A-Z
+    A-Z
+     Q v="Shares for QI"
+     S v="Shares"
+     U v="Units"
+     Y v="Units for QI"
+     A-Z a="Security type and investor restrictions"
+ P group="Private equity funds"
+  C v="Closed-end"
+  M v="Others"
+  O v="Open-end"
+  A-Z a="Closed/open-end"
+   G v="Accumulation funds"
+   I v="Income funds"
+   J v="Mixed funds"
+   A-Z a="Distribution policy"
+    B v="Debt instruments"
+    C v="Commodities"
+    D v="Derivatives"
+    E v="Equities"
+    F v="Referential instruments excluding commodities"
+    K v="Credits"
+    L v="Mixed"
+    M v="Others"
+    R v="Real estate"
+    V v="Convertible securities"
+    A-Z a="Assets"
+     Q v="Shares for QI"
+     S v="Shares"
+     U v="Units"
+     Y v="Units for QI"
+     A-Z a="Security type and investor restrictions"
+ S group="Pension funds"
+  C v="Closed"
+  M v="Others"
+  O v="Open"
+  A-Z a="Closed/open"
+   B v="Balanced/conservative"
+   G v="Growth"
+   L v="Life style"
+   M v="Others"
+   A-Z a="Strategy/style"
+    B v="Defined contribution"
+    M v="Others"
+    R v="Defined benefit"
+    A-Z a="Type"
+     S v="Shares"
+     U v="Units"
+     A-Z a="Security type and investor restrictions"
+D category="Debt instruments"
+ A group="Asset-backed securities"
+  F v="Fixed rate"
+  V v="Variable"
+  Z v="Zero rate/discounted"
+  A-Z a="Type of interest"
+   C v="Supranational"
+   G v="Joint guarantee"
+   J v="Junior subordinated"
+   N v="Senior"
+   O v="Senior subordinated"
+   P v="Negative pledge"
+   Q v="Junior"
+   S v="Secured"
+   T v="Government guarantee"
+   U v="Unsecured/unguaranteed"
+   A-Z a="Guarantee or ranking"
+    A v="Amortization plan"
+    B v="Amortization plan with call feature"
+    C v="Fixed maturity with put feature"
+    D v="Fixed maturity with put and call"
+    E v="Extendible"
+    F v="Fixed maturity"
+    G v="Fixed maturity with call feature"
+    L v="Amortization plan with put and call"
+    P v="Perpetual"
+    Q v="Perpetual with call feature"
+    R v="Perpetual with put feature"
+    T v="Amortization plan with put feature"
+    A-Z a="Redemption/reimbursement"
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ B group="Bonds"
+  C v="Cash payment"
+  F v="Fixed rate"
+  K v="Payment in kind"
+  V v="Variable"
+  Z v="Zero rate/discounted"
+  A-Z a="Type of interest or cash payment"
+   C v="Supranational"
+   G v="Joint guarantee"
+   J v="Junior subordinated"
+   N v="Senior"
+   O v="Senior subordinated"
+   P v="Negative pledge"
+   Q v="Junior"
+   S v="Secured"
+   T v="Government guarantee"
+   U v="Unsecured/unguaranteed"
+   A-Z a="Guarantee or ranking"
+    A v="Amortization plan"
+    B v="Amortization plan with call feature"
+    C v="Fixed maturity with put feature"
+    D v="Fixed maturity with put and call"
+    E v="Extendible"
+    F v="Fixed maturity"
+    G v="Fixed maturity with call feature"
+    L v="Amortization plan with put and call"
+    P v="Perpetual"
+    Q v="Perpetual with call feature"
+    R v="Perpetual with put feature"
+    T v="Amortization plan with put feature"
+    A-Z a="Redemption/reimbursement"
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ C group="Convertible bonds"
+  F v="Fixed rate"
+  K v="Payment in kind"
+  V v="Variable"
+  Z v="Zero rate/discounted"
+  A-Z a="Type of interest"
+   C v="Supranational"
+   G v="Joint guarantee"
+   J v="Junior subordinated"
+   N v="Senior"
+   O v="Senior subordinated"
+   P v="Negative pledge"
+   Q v="Junior"
+   S v="Secured"
+   T v="Government guarantee"
+   U v="Unsecured/unguaranteed"
+   A-Z a="Guarantee or ranking"
+    A v="Amortization plan"
+    B v="Amortization plan with call feature"
+    C v="Fixed maturity with put feature"
+    D v="Fixed maturity with put and call"
+    E v="Extendible"
+    F v="Fixed maturity"
+    G v="Fixed maturity with call feature"
+    L v="Amortization plan with put and call"
+    P v="Perpetual"
+    Q v="Perpetual with call feature"
+    R v="Perpetual with put feature"
+    T v="Amortization plan with put feature"
+    A-Z a="Redemption/reimbursement"
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ D group="Depositary receipts on debt instruments"
+  A v="Asset-backed securities"
+  B v="Bonds"
+  C v="Convertible bonds"
+  G v="Mortgage-backed securities"
+  M v="Others"
+  N v="Municipal bonds"
+  T v="Medium-term notes"
+  W v="Bonds with warrants attached"
+  Y v="Money market instruments"
+  A-Z a="Instrument dependency"
+   C v="Cash payment"
+   F v="Fixed rate"
+   V v="Variable"
+   Z v="Zero rate/discounted"
+   A-Z a="Type of interest/cash payment"
+    C v="Supranational"
+    G v="Joint guarantee"
+    J v="Junior subordinated"
+    N v="Senior"
+    O v="Senior subordinated"
+    P v="Negative pledge"
+    Q v="Junior"
+    S v="Secured"
+    T v="Government guarantee"
+    U v="Unsecured/unguaranteed"
+    A-Z a="Guarantee or ranking"
+     A v="Amortization plan"
+     B v="Amortization plan with call feature"
+     C v="Fixed maturity with put feature"
+     D v="Fixed maturity with put and call"
+     E v="Extendible"
+     F v="Fixed maturity"
+     G v="Fixed maturity with call feature"
+     L v="Amortization plan with put and call"
+     P v="Perpetual"
+     Q v="Perpetual with call feature"
+     R v="Perpetual with put feature"
+     T v="Amortization plan with put feature"
+     A-Z a="Redemption/reimbursement"
+ E group="Structured instruments"
+  A v="Discount certificate"
+  B v="Barrier discount certificate"
+  C v="Reverse convertible"
+  D v="Barrier reverse convertible"
+  E v="Express certificate"
+  M v="Others"
+  A-Z a="Type"
+   D v="Dividend payments"
+   F v="Fixed interest payments"
+   M v="Others"
+   V v="Variable interest payments"
+   Y v="No payments"
+   A-Z a="Distribution"
+    C v="Repayment in assets and cash"
+    M v="Others"
+    R v="Repayment in cash"
+    S v="Repayment in assets"
+    T v="Repayment in assets or cash"
+    A-Z a="Repayment"
+     B v="Baskets"
+     C v="Currencies"
+     D v="Debt instruments"
+     I v="Indices"
+     M v="Others"
+     N v="Interest rates"
+     S v="Equities"
+     T v="Commodities"
+     A-Z a="Underlying assets"
+ G group="Mortgage-backed securities"
+  F v="Fixed rate"
+  V v="Variable"
+  Z v="Zero rate/discounted"
+  A-Z a="Type of interest"
+   C v="Supranational"
+   G v="Joint guarantee"
+   J v="Junior subordinated"
+   N v="Senior"
+   O v="Senior subordinated"
+   P v="Negative pledge"
+   Q v="Junior"
+   S v="Secured"
+   T v="Government guarantee"
+   U v="Unsecured/unguaranteed"
+   A-Z a="Guarantee or ranking"
+    A v="Amortization plan"
+    B v="Amortization plan with call feature"
+    C v="Fixed maturity with put feature"
+    D v="Fixed maturity with put and call"
+    E v="Extendible"
+    F v="Fixed maturity"
+    G v="Fixed maturity with call feature"
+    L v="Amortization plan with put and call"
+    P v="Perpetual"
+    Q v="Perpetual with call feature"
+    R v="Perpetual with put feature"
+    T v="Amortization plan with put feature"
+    A-Z a="Redemption/reimbursement"
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ M group="Others"
+  B v="Bank loan"
+  M v="Others"
+  P v="Promissory note"
+  A-Z a="Type"
+   A-Z
+    A-Z
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ N group="Municipal bonds"
+  F v="Fixed rate"
+  V v="Variable"
+  Z v="Zero rate/discounted"
+  A-Z a="Type of interest"
+   C v="Supranational"
+   G v="Joint guarantee"
+   J v="Junior subordinated"
+   N v="Senior"
+   O v="Senior subordinated"
+   P v="Negative pledge"
+   Q v="Junior"
+   S v="Secured"
+   T v="State guarantee"
+   U v="Unsecured/unguaranteed"
+   A-Z a="Guarantee or ranking"
+    A v="Amortization plan"
+    B v="Amortization plan with call feature"
+    C v="Fixed maturity with put feature"
+    D v="Fixed maturity with put and call"
+    E v="Extendible"
+    F v="Fixed maturity"
+    G v="Fixed maturity with call feature"
+    L v="Amortization plan with put and call"
+    P v="Perpetual"
+    Q v="Perpetual with call feature"
+    R v="Perpetual with put feature"
+    T v="Amortization plan with put feature"
+    A-Z a="Redemption/reimbursement"
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ S group="Structured instruments"
+  A v="Capital protection certificate with participation"
+  B v="Capital protection convertible certificate"
+  C v="Barrier capital protection certificate"
+  D v="Capital protection certificate with coupons"
+  M v="Others"
+  A-Z a="Type"
+   D v="Dividend payments"
+   F v="Fixed interest payments"
+   M v="Others"
+   V v="Variable interest payments"
+   Y v="No payments"
+   A-Z a="Distribution"
+    F v="Fixed cash repayment"
+    M v="Others"
+    V v="Variable cash repayment"
+    A-Z a="Repayment"
+     B v="Baskets"
+     C v="Currencies"
+     D v="Debt instruments"
+     I v="Indices"
+     M v="Others"
+     N v="Interest rates"
+     S v="Equities"
+     T v="Commodities"
+     A-Z a="Underlying assets"
+ T group="Medium-term notes"
+  F v="Fixed rate"
+  K v="Payment in kind"
+  V v="Variable"
+  Z v="Zero rate/discounted"
+  A-Z a="Type of interest"
+   C v="Supranational"
+   G v="Joint guarantee"
+   J v="Junior subordinated"
+   N v="Senior"
+   O v="Senior subordinated"
+   P v="Negative pledge"
+   Q v="Junior"
+   S v="Secured"
+   T v="Government guarantee"
+   U v="Unsecured/unguaranteed"
+   A-Z a="Guarantee or ranking"
+    A v="Amortization plan"
+    B v="Amortization plan with call feature"
+    C v="Fixed maturity with put feature"
+    D v="Fixed maturity with put and call"
+    E v="Extendible"
+    F v="Fixed maturity"
+    G v="Fixed maturity with call feature"
+    L v="Amortization plan with put and call"
+    P v="Perpetual"
+    Q v="Perpetual with call feature"
+    R v="Perpetual with put feature"
+    T v="Amortization plan with put feature"
+    A-Z a="Redemption/reimbursement"
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ W group="Bonds with warrants attached"
+  F v="Fixed rate"
+  K v="Payment in kind"
+  V v="Variable"
+  Z v="Zero rate/discounted"
+  A-Z a="Type of interest"
+   C v="Supranational"
+   G v="Joint guarantee"
+   J v="Junior subordinated"
+   N v="Senior"
+   O v="Senior subordinated"
+   P v="Negative pledge"
+   Q v="Junior"
+   S v="Secured"
+   T v="Government guarantee"
+   U v="Unsecured/unguaranteed"
+   A-Z a="Guarantee or ranking"
+    A v="Amortization plan"
+    B v="Amortization plan with call feature"
+    C v="Fixed maturity with put feature"
+    D v="Fixed maturity with put and call"
+    E v="Extendible"
+    F v="Fixed maturity"
+    G v="Fixed maturity with call feature"
+    L v="Amortization plan with put and call"
+    P v="Perpetual"
+    Q v="Perpetual with call feature"
+    R v="Perpetual with put feature"
+    T v="Amortization plan with put feature"
+    A-Z a="Redemption/reimbursement"
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ Y group="Money market instruments"
+  F v="Fixed rate"
+  K v="Payment in kind"
+  V v="Variable"
+  Z v="Zero rate/discounted"
+  A-Z a="Type of interest"
+   C v="Supranational"
+   G v="Joint guarantee"
+   J v="Junior subordinated"
+   N v="Senior"
+   O v="Senior subordinated"
+   P v="Negative pledge"
+   Q v="Junior"
+   S v="Secured"
+   T v="Government guarantee"
+   U v="Unsecured/unguaranteed"
+   A-Z a="Guarantee or ranking"
+    A-Z
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+E category="Equities"
+ C group="Common/ordinary convertible shares"
+  E v="Enhanced voting"
+  N v="Non-voting"
+  R v="Restricted voting"
+  V v="Voting"
+  A-Z a="Voting right"
+   T v="Restrictions"
+   U v="Free"
+   A-Z a="Ownership/transfer/sales restrictions"
+    F v="Fully paid"
+    O v="Nil paid"
+    P v="Partly paid"
+    A-Z a="Payment status"
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ D group="Depositary receipts on equities"
+  C v="Common/ordinary convertible shares"
+  F v="Preferred/preference convertible shares"
+  L v="Limited partnership units"
+  M v="Others"
+  P v="Preferred/preference shares"
+  S v="Common/ordinary shares"
+  A-Z a="Instrument dependency"
+   B v="Convertible"
+   D v="Convertible/redeemable"
+   N v="Perpetual"
+   R v="Redeemable"
+   A-Z a="Redemption/conversion of the underlying assets"
+    A v="Adjustable/variable rate income"
+    C v="Cumulative, fixed rate income"
+    F v="Fixed rate income"
+    N v="Dividends"
+    N v="Normal rate income"
+    P v="Participating income"
+    Q v="Cumulative, participating income"
+    U v="Auction rate income"
+    A-Z a="Income"
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ F group="Preferred/preference convertible shares"
+  E v="Enhanced voting"
+  N v="Non-voting"
+  R v="Restricted voting"
+  V v="Voting"
+  A-Z a="Voting right"
+   A v="Redeemable/exchangeable/extendible"
+   C v="Redeemable/exchangeable"
+   E v="Extendible"
+   G v="Exchangeable"
+   N v="Perpetual"
+   R v="Redeemable"
+   T v="Redeemable/extendible"
+   A-Z a="Redemption"
+    A v="Adjustable/variable rate income"
+    C v="Cumulative, fixed rate income"
+    F v="Fixed rate income"
+    N v="Normal rate income"
+    P v="Participating income"
+    Q v="Cumulative, participating income"
+    U v="Auction rate income"
+    A-Z a="Income"
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ L group="Limited partnership units"
+  E v="Enhanced voting"
+  N v="Non-voting"
+  R v="Restricted voting"
+  V v="Voting"
+  A-Z a="Voting right"
+   T v="Restrictions"
+   U v="Free"
+   A-Z a="Ownership/transfer/sales restrictions"
+    F v="Fully paid"
+    O v="Nil paid"
+    P v="Partly paid"
+    A-Z a="Payment status"
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ M group="Others"
+  A-Z
+   A-Z
+    A-Z
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ P group="Preferred/preference shares"
+  E v="Enhanced voting"
+  N v="Non-voting"
+  R v="Restricted voting"
+  V v="Voting"
+  A-Z a="Voting right"
+   A v="Redeemable/exchangeable/extendible"
+   C v="Redeemable/exchangeable"
+   E v="Extendible"
+   G v="Exchangeable"
+   N v="Perpetual"
+   R v="Redeemable"
+   T v="Redeemable/extendible"
+   A-Z a="Redemption"
+    A v="Adjustable/variable rate income"
+    C v="Cumulative, fixed rate income"
+    F v="Fixed rate income"
+    N v="Normal rate income"
+    P v="Participating income"
+    Q v="Cumulative, participating income"
+    U v="Auction rate income"
+    A-Z a="Income"
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ S group="Common/ordinary shares"
+  E v="Enhanced voting"
+  N v="Non-voting"
+  R v="Restricted voting"
+  V v="Voting"
+  A-Z a="Voting right"
+   T v="Restrictions"
+   U v="Free"
+   A-Z a="Ownership/transfer/sales restrictions"
+    F v="Fully paid"
+    O v="Nil paid"
+    P v="Partly paid"
+    A-Z a="Payment status"
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ Y group="Structured instruments"
+  A v="Tracker certificate"
+  B v="Outperformance certificate"
+  C v="Bonus certificate"
+  D v="Outperformance bonus certificate"
+  E v="Twin-win-certificate"
+  M v="Others"
+  A-Z a="Type"
+   D v="Dividend payments"
+   M v="Others"
+   Y v="No payments"
+   A-Z a="Distribution"
+    E v="Elect at settlement"
+    F v="Cash repayment"
+    M v="Others"
+    V v="Physical repayment"
+    A-Z a="Repayment"
+     B v="Baskets"
+     C v="Currencies"
+     D v="Debt instruments"
+     G v="Derivatives"
+     I v="Indices"
+     M v="Others"
+     N v="Interest rates"
+     S v="Equities"
+     T v="Commodities"
+     A-Z a="Underlying assets"
+F category="Futures"
+ C group="Commodities futures"
+  A v="Agriculture"
+  E v="Extraction resources"
+  H v="Generated resources"
+  I v="Industrial products"
+  M v="Others"
+  N v="Environmental"
+  P v="Polypropylene products"
+  S v="Services"
+  A-Z a="Underlying assets"
+   C v="Cash"
+   N v="Non-deliverable"
+   P v="Physical"
+   A-Z a="Delivery"
+    N v="Non-standardized"
+    S v="Standardized"
+    A-Z a="Standardized/non-standardized"
+     A-Z
+ F group="Financial futures"
+  B v="Baskets"
+  C v="Currencies"
+  D v="Debt instruments"
+  F v="Futures"
+  I v="Indices"
+  M v="Others"
+  N v="Interest rates"
+  O v="Options"
+  S v="Stock-equities"
+  V v="Stock dividends"
+  W v="Swaps"
+  A-Z a="Underlying assets"
+   C v="Cash"
+   N v="Non-deliverable"
+   P v="Physical"
+   A-Z a="Delivery"
+    N v="Non-standardized"
+    S v="Standardized"
+    A-Z a="Standardized/non-standardized"
+     A-Z
+H category="Non-listed and complex listed options"
+ C group="Credit"
+  I v="CDS on an index"
+  M v="Others"
+  U v="CDS on a single name"
+  V v="CDS on an index tranche"
+  W v="Swaps"
+  A-Z a="Underlying assets"
+   A v="European-Call"
+   B v="American-Call"
+   C v="Bermudan-Call"
+   D v="European-Put"
+   E v="American-Put"
+   F v="Bermudan-Put"
+   G v="European-Chooser"
+   H v="American-Chooser"
+   I v="Bermudan-Chooser"
+   A-Z a="Option style and type"
+    A v="Asian"
+    B v="Barrier"
+    D v="Digital"
+    G v="Digital barrier"
+    L v="Lookback"
+    M v="Others"
+    P v="Other path dependent"
+    V v="Vanilla"
+    A-Z a="Valuation method or trigger"
+     C v="Cash"
+     E v="Elect at settlement"
+     P v="Physical"
+     A-Z a="Delivery"
+ E group="Equity"
+  B v="Basket"
+  F v="Futures"
+  I v="Index"
+  M v="Others"
+  O v="Options"
+  R v="Forwards"
+  S v="Single stock"
+  A-Z a="Underlying assets"
+   A v="European-Call"
+   B v="American-Call"
+   C v="Bermudan-Call"
+   D v="European-Put"
+   E v="American-Put"
+   F v="Bermudan-Put"
+   G v="European-Chooser"
+   H v="American-Chooser"
+   I v="Bermudan-Chooser"
+   A-Z a="Option style and type"
+    A v="Asian"
+    B v="Barrier"
+    D v="Digital"
+    G v="Digital barrier"
+    L v="Lookback"
+    M v="Others"
+    P v="Other path dependent"
+    V v="Vanilla"
+    A-Z a="Valuation method or trigger"
+     C v="Cash"
+     E v="Elect at settlement"
+     P v="Physical"
+     A-Z a="Delivery"
+ F group="Foreign exchange"
+  B v="Forwards – Currency Index"
+  C v="Futures – Currency Index"
+  D v="Spot – Currency Index"
+  E v="Volatility – Currency Index"
+  F v="Futures – Single Currency Pair"
+  M v="Others"
+  Q v="Forwards – Custom Basket of Currencies"
+  R v="Forwards – Single Currency Pair"
+  T v="Spot – Single Currency Pair"
+  U v="Futures – Custom Basket of Currencies"
+  V v="Volatility – Single Currency Pair"
+  W v="Spot – Custom Basket of Currencies"
+  Y v="Volatility – Custom Basket of Currencies"
+  A-Z a="Underlying assets"
+   J v="European"
+   K v="American"
+   L v="Bermudan"
+   A-Z a="Option style and type"
+    A v="Asian"
+    B v="Barrier"
+    D v="Digital"
+    G v="Digital barrier"
+    L v="Lookback"
+    M v="Others"
+    P v="Other path dependent"
+    V v="Vanilla"
+    A-Z a="Valuation method or trigger"
+     C v="Cash"
+     E v="Elect at settlement"
+     P v="Physical"
+     A-Z a="Delivery"
+ M group="Others"
+  M v="Others"
+  P v="Commercial property"
+  A-Z a="Underlying assets"
+   A v="European-Call"
+   B v="American-Call"
+   C v="Bermudan-Call"
+   D v="European-Put"
+   E v="American-Put"
+   F v="Bermudan-Put"
+   G v="European-Chooser"
+   H v="American-Chooser"
+   I v="Bermudan-Chooser"
+   J v="European"
+   K v="American"
+   L v="Bermudan"
+   A-Z a="Option style and type"
+    A v="Asian"
+    B v="Barrier"
+    D v="Digital"
+    G v="Digital barrier"
+    L v="Lookback"
+    M v="Others"
+    P v="Other path dependent"
+    V v="Vanilla"
+    A-Z a="Valuation method or trigger"
+     A v="Auction"
+     C v="Cash"
+     E v="Elect at exercise"
+     N v="Non-deliverable"
+     P v="Physical"
+     A-Z a="Delivery"
+ R group="Rates"
+  A v="Basis swap"
+  C v="Fixed-floating swap"
+  D v="Fixed-fixed swap"
+  E v="Interest rate index"
+  F v="Futures"
+  G v="Inflation rate index"
+  H v="OIS"
+  M v="Others"
+  O v="Options"
+  R v="Forwards"
+  A-Z a="Underlying assets"
+   A v="European-Call"
+   B v="American-Call"
+   C v="Bermudan-Call"
+   D v="European-Put"
+   E v="American-Put"
+   F v="Bermudan-Put"
+   G v="European-Chooser"
+   H v="American-Chooser"
+   I v="Bermudan-Chooser"
+   A-Z a="Option style and type"
+    A v="Asian"
+    B v="Barrier"
+    C v="Cap"
+    D v="Digital"
+    F v="Floor"
+    G v="Digital barrier"
+    L v="Lookback"
+    M v="Others"
+    P v="Other path dependent"
+    V v="Vanilla"
+    A-Z a="Valuation method or trigger"
+     C v="Cash"
+     E v="Elect at settlement"
+     P v="Physical"
+     A-Z a="Delivery"
+ T group="Commodities"
+  A v="Agriculture"
+  B v="Basket – single-commodity"
+  C v="Basket – multi-commodity"
+  F v="Futures"
+  G v="Freight"
+  H v="Index – multi-commodity"
+  I v="Index – single-commodity"
+  J v="Energy"
+  K v="Metals"
+  M v="Others"
+  N v="Environmental"
+  O v="Options"
+  P v="Polypropylene products"
+  R v="Forwards"
+  S v="Fertilizer"
+  T v="Paper"
+  W v="Swaps"
+  A-Z a="Underlying assets"
+   A v="European-Call"
+   B v="American-Call"
+   C v="Bermudan-Call"
+   D v="European-Put"
+   E v="American-Put"
+   F v="Bermudan-Put"
+   G v="European-Chooser"
+   H v="American-Chooser"
+   I v="Bermudan-Chooser"
+   A-Z a="Option style and type"
+    A v="Asian"
+    B v="Barrier"
+    D v="Digital"
+    G v="Digital barrier"
+    L v="Lookback"
+    M v="Others"
+    P v="Other path dependent"
+    V v="Vanilla"
+    A-Z a="Valuation method or trigger"
+     C v="Cash"
+     E v="Elect at settlement"
+     P v="Physical"
+     A-Z a="Delivery"
+I category="Spot"
+ F group="Foreign exchange"
+  A-Z
+   A-Z
+    A-Z
+     P v="Physical"
+     A-Z a="Delivery"
+ T group="Commodities"
+  A v="Agriculture"
+  J v="Energy"
+  K v="Metals"
+  M v="Others"
+  N v="Environmental"
+  P v="Polypropylene products"
+  S v="Fertilizer"
+  T v="Paper"
+  A-Z a="Underlying assets"
+   A-Z
+    A-Z
+     A-Z
+J category="Forwards"
+ C group="Credit"
+  A v="Single name"
+  B v="Basket"
+  C v="CDS on a single name"
+  D v="CDS on an index"
+  G v="CDS on a basket"
+  I v="Index"
+  O v="Options"
+  A-Z a="Underlying assets"
+   A-Z
+    C v="CFD"
+    F v="Forward price of underlying instrument"
+    S v="Spread-bet"
+    A-Z a="Return or payout trigger"
+     C v="Cash"
+     P v="Physical"
+     A-Z a="Delivery"
+ E group="Equity"
+  B v="Basket"
+  F v="Futures"
+  I v="Index"
+  O v="Options"
+  S v="Single stock"
+  A-Z a="Underlying assets"
+   A-Z
+    C v="CFD"
+    F v="Forward price of underlying instrument"
+    S v="Spread-bet"
+    A-Z a="Return or payout trigger"
+     C v="Cash"
+     P v="Physical"
+     A-Z a="Delivery"
+ F group="Foreign exchange"
+  F v="Futures – Single Currency Pair"
+  J v="Options – Currency Index"
+  K v="Options – Custom Basket of Currencies"
+  L v="Futures – Currency Index"
+  N v="Futures – Custom Basket of Currencies"
+  O v="Options – Single Currency Pair"
+  R v="Forward – Single Currency Pair"
+  S v="Forward – Currency Index"
+  T v="Spot – Single Currency Pair"
+  U v="Spot – Currency Index"
+  V v="Spot – Custom Basket of Currencies"
+  W v="Forward – Custom Basket of Currencies"
+  A-Z a="Underlying assets"
+   A-Z
+    C v="CFD"
+    F v="Forward price of underlying instrument"
+    R v="Rolling spot"
+    S v="Spread-bet"
+    A-Z a="Return or payout trigger"
+     C v="Cash"
+     P v="Physical"
+     A-Z a="Delivery"
+ R group="Rates"
+  I v="Interest rate index"
+  M v="Others"
+  O v="Options"
+  A-Z a="Underlying assets"
+   A-Z
+    C v="CFD"
+    F v="Forward price of underlying instrument"
+    S v="Spread-bet"
+    A-Z a="Return or payout trigger"
+     C v="Cash"
+     P v="Physical"
+     A-Z a="Delivery"
+ T group="Commodities"
+  A v="Agriculture"
+  B v="Basket – single-commodity"
+  C v="Basket – multi-commodity"
+  G v="Freight"
+  H v="Index – multi-commodity"
+  I v="Index – single-commodity"
+  J v="Energy"
+  K v="Metals"
+  M v="Others"
+  N v="Environmental"
+  P v="Polypropylene products"
+  S v="Fertilizer"
+  T v="Paper"
+  A-Z a="Underlying assets"
+   A-Z
+    C v="CFD"
+    F v="Forward price of underlying instrument"
+    S v="Spread-bet"
+    A-Z a="Return or payout trigger"
+     C v="Cash"
+     P v="Physical"
+     A-Z a="Delivery"
+K category="Strategies"
+ C group="Credit"
+  A-Z
+   A-Z
+    A-Z
+     A-Z
+ E group="Equity"
+  A-Z
+   A-Z
+    A-Z
+     A-Z
+ F group="Foreign exchange"
+  A-Z
+   A-Z
+    A-Z
+     A-Z
+ M group="Others"
+  A-Z
+   A-Z
+    A-Z
+     A-Z
+ R group="Rates"
+  A-Z
+   A-Z
+    A-Z
+     A-Z
+ T group="Commodities"
+  A-Z
+   A-Z
+    A-Z
+     A-Z
+ Y group="Mixed assets"
+  A-Z
+   A-Z
+    A-Z
+     A-Z
+L category="Financing"
+ L group="Loan-lease"
+  A v="Agriculture"
+  B v="Baskets"
+  J v="Energy"
+  K v="Metals"
+  M v="Others"
+  N v="Environmental"
+  P v="Polypropylene products"
+  S v="Fertilizer"
+  T v="Paper"
+  A-Z a="Underlying assets"
+   A-Z
+    A-Z
+     C v="Cash"
+     P v="Physical"
+     A-Z a="Delivery"
+ R group="Repurchase agreements"
+  C v="Cash collateral"
+  G v="General collateral"
+  S v="Specific security collateral"
+  A-Z a="Underlying assets"
+   F v="Flexible"
+   N v="Overnight"
+   O v="Open"
+   T v="Term"
+   A-Z a="Termination"
+    A-Z
+     D v="Delivery versus payment"
+     H v="Hold-in-custody"
+     T v="Tri-party"
+     A-Z a="Delivery"
+ S group="Securities lending"
+  C v="Cash collateral"
+  D v="Certificate of deposit"
+  E v="Equity"
+  G v="Government bonds"
+  K v="Money market instruments"
+  L v="Letter of credit"
+  M v="Others"
+  P v="Corporate bonds"
+  T v="Convertible bonds"
+  W v="Warrants"
+  A-Z a="Underlying assets"
+   N v="Overnight"
+   O v="Open"
+   T v="Term"
+   A-Z a="Termination"
+    A-Z
+     D v="Delivery versus payment"
+     F v="Free of payment"
+     H v="Hold-in-custody"
+     T v="Tri-party"
+     A-Z a="Delivery"
+M category="Others (miscellaneous)"
+ C group="Combined instruments"
+  A v="Share and warrant"
+  B v="Combination of bonds"
+  H v="Share and bond"
+  M v="Others"
+  S v="Combination of shares"
+  U v="Fund unit and other components"
+  W v="Warrant and warrant"
+  A-Z a="Components"
+   T v="Restrictions"
+   U v="Free"
+   A-Z a="Ownership/transfer/sales restrictions"
+    A-Z
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ M group="Other assets"
+  E v="Escrow receipts"
+  I v="Insurance policies"
+  M v="Others"
+  N v="Carbon credit"
+  P v="Precious metal receipts"
+  R v="Real estate deeds"
+  S v="Other OTC derivative products"
+  T v="Trade finance instruments"
+  A-Z a="Further grouping"
+   A-Z
+    A-Z
+     A-Z
+O category="Listed options"
+ C group="Call options"
+  A v="American"
+  B v="Bermudan"
+  E v="European"
+  A-Z a="Exercise option style"
+   B v="Baskets"
+   C v="Currencies"
+   D v="Debt instruments"
+   F v="Futures"
+   I v="Indices"
+   M v="Others"
+   N v="Interest rates"
+   O v="Options"
+   S v="Stock-equities"
+   T v="Commodities"
+   W v="Swaps"
+   A-Z a="Underlying assets"
+    C v="Cash"
+    E v="Elect at exercise"
+    N v="Non-deliverable"
+    P v="Physical"
+    A-Z a="Delivery"
+     N v="Non-standardized"
+     S v="Standardized"
+     A-Z a="Standardized/non-standardized"
+ M group="Others"
+  A-Z
+   A-Z
+    A-Z
+     A-Z
+ P group="Put options"
+  A v="American"
+  B v="Bermudan"
+  E v="European"
+  A-Z a="Exercise option style"
+   B v="Baskets"
+   C v="Currencies"
+   D v="Debt instruments"
+   F v="Futures"
+   I v="Indices"
+   M v="Others"
+   N v="Interest rates"
+   O v="Options"
+   S v="Stock-equities"
+   T v="Commodities"
+   W v="Swaps"
+   A-Z a="Underlying assets"
+    C v="Cash"
+    E v="Elect at exercise"
+    N v="Non-deliverable"
+    P v="Physical"
+    A-Z a="Delivery"
+     N v="Non-standardized"
+     S v="Standardized"
+     A-Z a="Standardized/non-standardized"
+R category="Entitlement (rights)"
+ A group="Allotment"
+  A-Z
+   A-Z
+    A-Z
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ D group="Depositary receipts on entitlements"
+  A v="Allotment"
+  M v="Others"
+  P v="Purchase rights"
+  S v="Subscription rights"
+  W v="Warrants"
+  A-Z a="Instrument dependency"
+   A-Z
+    A-Z
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ F group="Mini-future certificates, constant leverage certificates"
+  B v="Baskets"
+  C v="Currencies"
+  D v="Debt instruments/interest rates"
+  I v="Indices"
+  M v="Others"
+  S v="Equities"
+  T v="Commodities"
+  A-Z a="Underlying assets"
+   M v="Others"
+   N v="Barrier instrument based"
+   T v="Barrier underlying based"
+   A-Z a="Barrier dependency type"
+    C v="Long"
+    M v="Others"
+    P v="Short"
+    A-Z a="Long/short"
+     A v="American"
+     B v="Bermudan"
+     E v="European"
+     M v="Others"
+     A-Z a="Exercise option style"
+ M group="Others"
+  A-Z
+   A-Z
+    A-Z
+     A-Z
+ P group="Purchase rights"
+  B v="Bonds"
+  C v="Common/ordinary convertible shares"
+  F v="Preferred/preference convertible shares"
+  I v="Combined instruments"
+  M v="Others"
+  P v="Preferred/preference shares"
+  S v="Common/ordinary shares"
+  A-Z a="Assets"
+   A-Z
+    A-Z
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ S group="Subscription rights"
+  B v="Bonds"
+  C v="Common/ordinary convertible shares"
+  F v="Preferred/preference convertible shares"
+  I v="Combined instruments"
+  M v="Others"
+  P v="Preferred/preference shares"
+  S v="Common/ordinary shares"
+  A-Z a="Assets"
+   A-Z
+    A-Z
+     B v="Bearer"
+     M v="Others"
+     N v="Bearer/registered"
+     R v="Registered"
+     A-Z a="Form"
+ W group="Warrants"
+  B v="Baskets"
+  C v="Currencies"
+  D v="Debt instruments/interest rates"
+  I v="Indices"
+  M v="Others"
+  S v="Equities"
+  T v="Commodities"
+  A-Z a="Underlying assets"
+   C v="Covered warrants"
+   N v="Naked warrants"
+   T v="Traditional warrants"
+   A-Z a="Type"
+    B v="Call and put"
+    C v="Call"
+    P v="Put"
+    A-Z a="Call/put"
+     A v="American"
+     B v="Bermudan"
+     E v="European"
+     M v="Others"
+     A-Z a="Exercise option style"
+S category="Swaps"
+ C group="Credit"
+  B v="Basket"
+  I v="Index"
+  M v="Others"
+  U v="Single name"
+  V v="Index tranche"
+  A-Z a="Underlying assets"
+   C v="Credit default"
+   M v="Others"
+   T v="Total return"
+   A-Z a="Return or payout trigger"
+    C v="Corporate entity"
+    L v="Local"
+    S v="Sovereign entity"
+    A-Z a="Underlying issuer type"
+     A v="Auction"
+     C v="Cash"
+     P v="Physical"
+     A-Z a="Delivery"
+ E group="Equity"
+  B v="Basket"
+  I v="Index"
+  M v="Others"
+  S v="Single stock"
+  A-Z a="Underlying assets"
+   C v="CFD"
+   D v="Dividend"
+   L v="Volatility"
+   M v="Others"
+   P v="Price"
+   T v="Total return"
+   V v="Variance"
+   A-Z a="Return or payout trigger"
+    A-Z
+     C v="Cash"
+     E v="Elect at settlement"
+     P v="Physical"
+     A-Z a="Delivery"
+ F group="Foreign exchange"
+  A v="Spot-forward swap"
+  C v="Forward-forward swap"
+  M v="Others"
+  A-Z a="Underlying assets"
+   A-Z
+    A-Z
+     C v="Cash"
+     P v="Physical"
+     A-Z a="Delivery"
+ M group="Others"
+  M v="Others"
+  P v="Commercial property"
+  A-Z a="Underlying assets"
+   A-Z
+    A-Z
+     C v="Cash"
+     E v="Elect at settlement"
+     P v="Physical"
+     A-Z a="Delivery"
+ R group="Rates"
+  A v="Basis swap"
+  C v="Fixed-floating"
+  D v="Fixed-fixed"
+  G v="Inflation swap"
+  H v="Overnight index swap"
+  M v="Others"
+  Z v="Zero coupon"
+  A-Z a="Underlying assets"
+   C v="Constant"
+   D v="Amortizing"
+   I v="Accreting"
+   Y v="Custom"
+   A-Z a="Notional"
+    C v="Cross-currency"
+    S v="Single currency"
+    A-Z a="Single or multi-currency"
+     D v="Deliverable"
+     N v="Non-deliverable"
+     A-Z a="Delivery"
+ T group="Commodities"
+  A v="Agriculture"
+  B v="Basket – single-commodity"
+  C v="Basket – multi-commodity"
+  G v="Freight"
+  H v="Index – multi-commodity"
+  I v="Index – single-commodity"
+  J v="Energy"
+  K v="Metals"
+  M v="Others"
+  N v="Environmental"
+  P v="Polypropylene products"
+  Q v="Multi-commodity"
+  S v="Fertilizer"
+  T v="Paper"
+  A-Z a="Underlying assets"
+   C v="Contract for difference"
+   T v="Total return"
+   A-Z a="Return or payout trigger"
+    A-Z
+     C v="Cash"
+     E v="Elect at settlement"
+     P v="Physical"
+     A-Z a="Delivery"
+T category="Referential instruments"
+ B group="Baskets"
+  C v="Currencies"
+  D v="Debt instruments"
+  E v="Equities"
+  F v="CIVs"
+  I v="Indices"
+  M v="Others"
+  T v="Commodities"
+  A-Z a="Composition"
+   A-Z
+    A-Z
+     A-Z
+ C group="Currencies"
+  C v="Bullion coins"
+  L v="Legacy currency"
+  M v="Others"
+  N v="National currency"
+  A-Z a="Type"
+   A-Z
+    A-Z
+     A-Z
+ D group="Stock dividends"
+  C v="Common/ordinary convertible shares"
+  F v="Preferred/preference convertible shares"
+  K v="CIVs"
+  L v="Limited partnership units"
+  M v="Others"
+  P v="Preferred/preference shares"
+  S v="Common/ordinary shares"
+  A-Z a="Type of equity"
+   A-Z
+    A-Z
+     A-Z
+ I group="Indices"
+  C v="Currencies"
+  D v="Debt instruments"
+  E v="Equities"
+  F v="CIVs"
+  M v="Others"
+  R v="Real estate"
+  T v="Commodities"
+  A-Z a="Asset classes"
+   C v="Capitalization weighted"
+   E v="Equal weighted"
+   F v="Modified market capitalization weighted"
+   M v="Other weighting"
+   P v="Price weighted"
+   A-Z a="Weighting types"
+    G v="Gross total return"
+    M v="Others"
+    N v="Net total return"
+    P v="Price return"
+    A-Z a="Index return types"
+     A-Z
+ M group="Others"
+  A-Z
+   A-Z
+    A-Z
+     A-Z
+ R group="Interest rates"
+  F v="Fixed"
+  M v="Others"
+  N v="Nominal"
+  R v="Real"
+  V v="Variable"
+  A-Z a="Type of interest rates"
+   A v="Annually"
+   D v="Daily"
+   M v="Others"
+   N v="Monthly"
+   Q v="Quarterly"
+   S v="Semi-annually"
+   W v="Weekly"
+   A-Z a="Frequency of calculation"
+    A-Z
+     A-Z
+ T group="Commodities"
+  A v="Agriculture"
+  E v="Extraction resources"
+  H v="Generated resources"
+  I v="Industrial products"
+  M v="Others"
+  N v="Environmental"
+  P v="Polypropylene products"
+  S v="Services"
+  A-Z a="Type of commodity"
+   A-Z
+    A-Z
+     A-Z
diff --git a/stdnum/cfi.py b/stdnum/cfi.py
new file mode 100644
index 0000000..b960b69
--- /dev/null
+++ b/stdnum/cfi.py
@@ -0,0 +1,92 @@
+# cfi.py - functions for handling ISIN numbers
+#
+# Copyright (C) 2022 Arthur de Jong
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 USA
+
+"""CFI (ISO 10962 Classification of Financial Instruments).
+
+The CFI is a 6-character code used to classify financial instruments. It is
+issued alongside an ISIN and describes category such as equity or future and
+category-specific properties such as underlying asset type or payment status.
+
+More information:
+
+* https://en.wikipedia.org/wiki/ISO_10962
+* https://www.iso.org/standard/73564.html
+* 
https://www.six-group.com/en/products-services/financial-information/data-standards.html
+
+>>> validate('ELNUFR')
+'ELNUFR'
+>>> validate('ELNUFQ')
+Traceback (most recent call last):
+    ...
+InvalidComponent: ...
+>>> info('ELNUFR')['Payment status']
+'Fully paid'
+"""
+
+from stdnum import numdb
+from stdnum.exceptions import *
+from stdnum.util import clean
+
+
+# our open copy of the CFI database
+_cfidb = numdb.get('cfi')
+
+
+def compact(number):
+    """Convert the number to the minimal representation. This strips the
+    number of any valid separators and removes surrounding whitespace."""
+    return clean(number, ' -').strip().upper()
+
+
+def info(number):
+    """Look up information about the number."""
+    number = compact(number)
+    info = _cfidb.info(number)
+    if len(info) != 6:
+        raise InvalidComponent()
+    properties = {}
+    properties.update(info[0][1])
+    properties.update(info[1][1])
+    for nr, found in info[2:]:
+        if nr != 'X' and 'v' not in found:
+            raise InvalidComponent()
+        if 'v' in found:
+            properties[found['a']] = found['v']
+    return properties
+
+
+def validate(number):
+    """Check if the number provided is valid. This checks the length and
+    format."""
+    number = compact(number)
+    if not all(x in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' for x in number):
+        raise InvalidFormat()
+    if len(number) != 6:
+        raise InvalidLength()
+    info(number)
+    return number
+
+
+def is_valid(number):
+    """Check if the number provided is valid. This checks the length and
+    check digit."""
+    try:
+        return bool(validate(number))
+    except ValidationError:
+        return False
diff --git a/tests/test_cfi.doctest b/tests/test_cfi.doctest
new file mode 100644
index 0000000..e6513ff
--- /dev/null
+++ b/tests/test_cfi.doctest
@@ -0,0 +1,175 @@
+test_cfi.doctest - more detailed doctests for the stdnum.cfi module
+
+Copyright (C) 2022 Arthur de Jong
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA
+
+
+This file contains more detailed doctests for the stdnum.cfi module. It
+tries to validate a number of numbers that have been found online.
+
+>>> import pprint
+>>> from stdnum import cfi
+>>> from stdnum.exceptions import *
+
+
+Check some obviously invalid numbers.
+
+>>> cfi.validate('123456')
+Traceback (most recent call last):
+    ...
+InvalidFormat: ...
+>>> cfi.validate('ELNUF')
+Traceback (most recent call last):
+    ...
+InvalidLength: ...
+>>> cfi.validate('AAAAAA')
+Traceback (most recent call last):
+    ...
+InvalidComponent: ...
+>>> cfi.validate('XXAAAA')
+Traceback (most recent call last):
+    ...
+InvalidComponent: ...
+>>> cfi.validate('IFXXXZ')
+Traceback (most recent call last):
+    ...
+InvalidComponent: ...
+
+
+Most characters can be replaced by an X.
+
+>>> cfi.validate('DTFNFR')
+'DTFNFR'
+>>> cfi.validate('DTXXXX')
+'DTXXXX'
+>>> cfi.validate('DTFNXX')
+'DTFNXX'
+>>> cfi.validate('DTXNFX')
+'DTXNFX'
+
+
+The info function returns useful information.
+
+>>> pprint.pprint(cfi.info('DTFNFR'))
+{'Form': 'Registered',
+ 'Guarantee or ranking': 'Senior',
+ 'Redemption/reimbursement': 'Fixed maturity',
+ 'Type of interest': 'Fixed rate',
+ 'category': 'Debt instruments',
+ 'group': 'Medium-term notes'}
+>>> pprint.pprint(cfi.info('IFXXXP'))
+{'Delivery': 'Physical', 'category': 'Spot', 'group': 'Foreign exchange'}
+>>> pprint.pprint(cfi.info('IFXXXX'))
+{'category': 'Spot', 'group': 'Foreign exchange'}
+>>> pprint.pprint(cfi.info('DBFNXR'))
+{'Form': 'Registered',
+ 'Guarantee or ranking': 'Senior',
+ 'Type of interest or cash payment': 'Fixed rate',
+ 'category': 'Debt instruments',
+ 'group': 'Bonds'}
+
+
+These should all be valid numbers.
+
+>>> numbers = '''
+...
+... CBMJXS
+... CBOIXS
+... CBOIXX
+... CBXIXX
+... CEMJXU
+... CEOIBU
+... CEOICU
+... CEOIEU
+... CEOIXU
+... CEOJCU
+... CEOJXU
+... CFOGIY
+... CFOIXX
+... CICXXX
+... CIOGBU
+... CIOGEU
+... CIOGEX
+... CIOGLU
+... CIOGLY
+... CIOIBX
+... CIOIEX
+... CIOILX
+... CIOIXX
+... CIOXMX
+... CMXXXX
+... DBFCXB
+... DBFNDB
+... DBFNFB
+... DBFNFR
+... DBFNGB
+... DBFNXR
+... DBFOFB
+... DBFPFB
+... DBFPGB
+... DBFQFB
+... DBFQGB
+... DBVQGB
+... DBVQQB
+... DBVQXB
+... DBVQXR
+... DCFPGB
+... DECXRB
+... DEDFRB
+... DEDFTB
+... DEEXRB
+... DEEXRS
+... DEEXTB
+... DEMFRB
+... DEMFRI
+... DEMVRI
+... DEMXRB
+... DEMXTB
+... DEMYRB
+... DGFSFB
+... DMXXXB
+... DNFNGB
+... DNFNXB
+... DSAFVX
+... DSAXVB
+... DSAXVI
+... DSAXVM
+... DSAXVT
+... DSAYVB
+... DSAYVI
+... DTFCGB
+... DTFNFB
+... DTFNFR
+... DTFNGB
+... DTFNXB
+... EDSNXR
+... ELNUFR
+... ELRUFR
+... ELVUFR
+... EPNNFR
+... EPNNPR
+... EYAYFI
+... EYAYFX
+... EYCXEB
+... EYMXFB
+... EYMXFI
+... EYMXFM
+... EYMXFT
+...
+... '''
+>>> [x for x in numbers.splitlines() if x and not cfi.is_valid(x)]
+[]
diff --git a/update/cfi.py b/update/cfi.py
new file mode 100755
index 0000000..f27bc4d
--- /dev/null
+++ b/update/cfi.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+
+# update/cfi.py - script to download CFI code list from the SIX group
+#
+# Copyright (C) 2022 Arthur de Jong
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 USA
+
+"""This script downloads the list of CFI codes as published by the SIX 
group."""
+
+import re
+
+import lxml.html
+import requests
+import xlrd
+
+
+# the location of the Statistical Classification file
+download_url = 
'https://www.six-group.com/en/products-services/financial-information/data-standards.html'
+
+
+def normalise(value):
+    """Clean and minimise attribute names and values."""
+    return re.sub(r' *[(\[\n].*', '', value, re.MULTILINE).strip()
+
+
+def get_categories(sheet):
+    """Get the list of top-level CFI categories."""
+    for row in sheet.get_rows():
+        if len(row[0].value) == 1 and row[1].value:
+            yield (row[0].value, row[1].value)
+
+
+def get_attributes(sheet):
+    """Get the list of characters and attributes from the group-specific 
sheet."""
+    attribute = None
+    value_list = []
+    values = None
+    for row in sheet.get_rows():
+        if row[0].value and not row[1].value and row[2].value:
+            attribute = normalise(row[2].value)
+            values = []
+            value_list.append((attribute, values))
+        elif attribute and row[1].value and row[2].value:
+            values.append((row[1].value, normalise(row[2].value)))
+    return value_list
+
+
+def print_attributes(attributes, index=0):
+    """Print the collected attributes in a nested structure."""
+    attribute, values = attributes[index]
+    if len(values) == 1 and values[0][0] == 'X':
+        print('%sA-Z' % (' ' * (index + 2)))
+    else:
+        for char, value in sorted(values):
+            print('%s%s v="%s"' % (' ' * (index + 2), char, value))
+        print('%sA-Z a="%s"' % (
+            ' ' * (index + 2), attribute))
+    if index < 3:
+        print_attributes(attributes, index + 1)
+
+
+if __name__ == '__main__':
+    # Download the page that contains the link to the current XLS file
+    response = requests.get(download_url)
+    response.raise_for_status()
+    # Find the download link
+    document = lxml.html.document_fromstring(response.content)
+    links = [a.get('href') for a in document.findall('.//a[@href]')]
+    link_url = next(a for a in links if re.match(r'.*/cfi/.*xlsx?$', a))
+    # Download and parse the spreadsheet
+    response = requests.get(link_url)
+    response.raise_for_status()
+    workbook = xlrd.open_workbook(file_contents=response.content)
+
+    print('# generated from %s, downloaded from' % link_url.split('/')[-1])
+    print('# %s' % download_url)
+
+    groups = sorted(x for x in workbook.sheet_names() if len(x) == 6 and 
x.endswith('XXXX'))
+    for category, name in 
sorted(get_categories(workbook.sheet_by_name('Categories'))):
+        print('%s category="%s"' % (category, name))
+        for group in (x for x in groups if x.startswith(category)):
+            sheet = workbook.sheet_by_name(group)
+            print(' %s group="%s"' % (group[1], normalise(sheet.cell(0, 
0).value)))
+            print_attributes(get_attributes(sheet))

https://arthurdejong.org/git/python-stdnum/commit/?id=219ff54156e7a86c6d6d44548a5bdce3bfafdebb

commit 219ff54156e7a86c6d6d44548a5bdce3bfafdebb
Author: Arthur de Jong <arthur@arthurdejong.org>
Date:   Sun Feb 13 18:02:57 2022 +0100

    Fix problem in numdb with missing sub-properties
    
    If a numdb data file line contains multiple values or ranges the
    sub-ranges were only applied to the last value in the range.

diff --git a/stdnum/numdb.py b/stdnum/numdb.py
index e22dce6..8d4f286 100644
--- a/stdnum/numdb.py
+++ b/stdnum/numdb.py
@@ -54,6 +54,8 @@ To split the number and get properties for each part:
 [('98', {'prop1': 'booz'}), ('89', {'prop2': 'foo'})]
 >>> pprint.pprint(dbfile.info('633322'))
 [('6', {'prop1': 'boo'}), ('333', {'prop2': 'bar', 'prop3': 'baz', 'prop4': 
'bla'}), ('22', {})]
+>>> pprint.pprint(dbfile.info('1200333'))
+[('1', {'prop1': 'foo'}), ('200', {'prop2': 'bar', 'prop3': 'baz'}), ('333', 
{'prop4': 'bax'})]
 
 """
 
@@ -106,7 +108,7 @@ class NumDB():
                     properties = {}
                     next_prefixes = []
                 properties.update(props)
-                next_prefixes.extend(children or [])
+                next_prefixes.extend(children)
         # return first part and recursively find next matches
         return [(part, properties)] + NumDB._find(number[len(part):], 
next_prefixes)
 
@@ -135,12 +137,13 @@ def _parse(fp):
         indent = len(match.group('indent'))
         ranges = match.group('ranges')
         props = dict(_prop_re.findall(match.group('props')))
+        children = []
         for rnge in ranges.split(','):
             if '-' in rnge:
                 low, high = rnge.split('-')
             else:
                 low, high = rnge, rnge
-            yield indent, len(low), low, high, props
+            yield indent, len(low), low, high, props, children
 
 
 def read(fp):
@@ -148,12 +151,11 @@ def read(fp):
     last_indent = 0
     db = NumDB()
     stack = {0: db.prefixes}
-    for indent, length, low, high, props in _parse(fp):
+    for indent, length, low, high, props, children in _parse(fp):
         if indent > last_indent:
-            # populate the children field of the last indent
-            stack[last_indent][-1][4] = []
+            # set our stack location to the last parent entry
             stack[indent] = stack[last_indent][-1][4]
-        stack[indent].append([length, low, high, props, None])
+        stack[indent].append([length, low, high, props, children])
         last_indent = indent
     return db
 
diff --git a/tests/numdb-test.dat b/tests/numdb-test.dat
index 366307e..4fe8bc3 100644
--- a/tests/numdb-test.dat
+++ b/tests/numdb-test.dat
@@ -3,6 +3,7 @@
 0-8 prop1="foo"
   100-999 prop2="bar"
   200,300-399 prop3="baz"
+    333 prop4="bax"
 6 prop1="boo"
   333 prop4="bla"
 90-99 prop1="booz"

https://arthurdejong.org/git/python-stdnum/commit/?id=fd32e61850022cc3c54945c2e513da5d577c407b

commit fd32e61850022cc3c54945c2e513da5d577c407b
Author: Arthur de Jong <arthur@arthurdejong.org>
Date:   Sun Feb 13 17:46:50 2022 +0100

    Also ensure that embedded certificates are shipped

diff --git a/setup.py b/setup.py
index 439a6e3..ebdcc2e 100755
--- a/setup.py
+++ b/setup.py
@@ -77,7 +77,7 @@ setup(
     ],
     packages=find_packages(),
     install_requires=[],
-    package_data={'': ['*.dat']},
+    package_data={'': ['*.dat', '*.crt']},
     extras_require={
         # The SOAP feature is only required for a number of online tests
         # of numbers such as the EU VAT VIES lookup, the Dominican Republic

-----------------------------------------------------------------------

Summary of changes:
 setup.py                              |    2 +-
 stdnum/cfi.dat                        | 1532 +++++++++++++++++++++++++++++++++
 stdnum/{ee/registrikood.py => cfi.py} |   74 +-
 stdnum/numdb.py                       |   14 +-
 tests/numdb-test.dat                  |    1 +
 tests/test_cfi.doctest                |  175 ++++
 update/cfi.py                         |   98 +++
 7 files changed, 1857 insertions(+), 39 deletions(-)
 create mode 100644 stdnum/cfi.dat
 copy stdnum/{ee/registrikood.py => cfi.py} (51%)
 create mode 100644 tests/test_cfi.doctest
 create mode 100755 update/cfi.py


hooks/post-receive
-- 
python-stdnum