Not thoroughly tested but here is the one with even more capabilities … Python
v3.x with yfinance, lxml, logging, and gzip libraries will be needed to work
which will create prices.csv in current directory.
# --- Start of script ---
from lxml import etree
import logging
import gzip
import sys
import yfinance as yf
onlyMultiple = True
createQuotes = False
if len(sys.argv) > 3:
if "quotes" in sys.argv[3].lower():
createQuotes = True
if len(sys.argv) > 2:
if "all" in sys.argv[2].lower():
onlyMultiple = False
if len(sys.argv) > 1:
data_file = sys.argv[1]
else:
print ("\nProvide one or two positional parameters:")
print (" Required first argument: GNC data file.")
print (" Required second argument: 'all' to display all tickers, not just
those with multiple namespaces; else any non blank string.")
print (" Optional third argument: 'quotes' to create an importable
'prices.csv' file.\n")
exit()
namespaces = dict()
logger = logging.getLogger("yfinance")
logger.disabled = True
logger.propagate = False
try:
with gzip.open(data_file, "rb") as f:
context = etree.iterparse(f,
tag='{http://www.gnucash.org/XML/gnc}commodity')
for event, elem in context:
symbol = elem[1].text
namespace = elem[0].text
elem.clear()
if symbol in namespaces:
namespaces[symbol] = namespaces[symbol] + ", " +namespace
else:
namespaces[symbol] = namespace
with open("prices.csv", "w", encoding="utf-8") as file:
if not file.writable():
createQuotes = False
for ticker in sorted(namespaces.keys()):
if onlyMultiple:
if namespaces[ticker].count(",") > 0:
print ("{}:{}".format(ticker, namespaces[ticker]))
else:
print ("{}:{}".format(ticker, namespaces[ticker]))
namespace = namespaces[ticker].split(",")[0]
if namespace != "CURRENCY" and createQuotes:
try:
quotes = yf.Ticker(ticker)
info = quotes.info
prices = quotes.history(period="1wk", auto_adjust=True)
if not prices.empty:
currency = "USD"
prices.reset_index(inplace=True)
prices['Date'] = prices['Date'].dt.strftime('%m/%d/%Y')
prices.drop(['Dividends','Stock Splits'], inplace=True,
axis=1)
prices.to_dict(orient='records')
infoAttr = info.keys()
if 'financialCurrency' in infoAttr:
currency = info['financialCurrency']
if 'currency' in infoAttr:
currency = info['currency']
for i in prices.index:
close = prices['Close'][i]
date = prices['Date'][i]
high = prices['High'][i]
low = prices['Low'][i]
volume = prices['Volume'][i]/100
with open("prices.csv", "a", encoding="utf-8") as file:
file.write('"{}","{}","{}",{},"{}"\n'.format(namespace, ticker, date, close,
currency))
except Exception as e:
pass
except Exception as e:
print ("Error: {}".format(e))
# --- End of script ---
From: David T. <[email protected]>
Sent: Thursday, August 13, 2026 12:20 AM
To: Kalpesh Patel <[email protected]>; [email protected]; 'Wm Tarr'
<[email protected]>
Subject: RE: [GNC] Trading accounts
Well, I guess I was able to goad the sleepyhead to up his game! ;)
Thanks for the upgrade!
David T.
On August 13, 2026 2:48:23 AM GMT+05:30, Kalpesh Patel <[email protected]
<mailto:[email protected]> > wrote:
David – yeah I think the guy that wrote the script was probably sleep deprived
when he did it 😊 …. here is the one that meets new requirements as well as a
bit more 😊.
Since spacing matters in Python, attached one should fully run if saved as a
file.
# --- Start of script ---
from lxml import etree
import gzip
import sys
onlyMultiple = True
if len(sys.argv) > 2:
if "all" in sys.argv[2].lower():
onlyMultiple = False
if len(sys.argv) > 1:
data_file = sys.argv[1]
else:
print ("\nProvide one or two positional parameters:")
print (" File name as the first argument.")
print (" Optional second argument: 'all' to display all tickers, not just
those with multiple namespaces.\n")
exit()
namespaces = dict()
try:
with gzip.open(data_file, "rb") as f:
context = etree.iterparse(f,
tag='{http://www.gnucash.org/XML/gnc}commodity')
for event, elem in context:
symbol = elem[1].text
namespace = elem[0].text
elem.clear()
if symbol in namespaces:
namespaces[symbol] = namespaces[symbol] + ", " +namespace
else:
namespaces[symbol] = namespace
for ticker in sorted(namespaces.keys()):
if onlyMultiple:
if
namespaces[ticker].count(",") > 0:
print
("{}:{}".format(ticker, namespaces[ticker]))
else:
print ("{}:{}".format(ticker,
namespaces[ticker]))
except Exception as e:
print ("Error: {}".format(e))
# --- End of script ---
From: David T. <[email protected] <mailto:[email protected]> >
Sent: Wednesday, August 12, 2026 2:06 AM
To: [email protected] <mailto:[email protected]> ; Kalpesh Patel
<[email protected] <mailto:[email protected]> >; 'Wm Tarr'
<[email protected] <mailto:[email protected]> >
Subject: Re: [GNC] Trading accounts
Kalpesh,
It is nice to see how a user could use Python to get at this information, but
it seems to me that having to supply a list of symbols to the script defeats
the point of trying to find those symbols that have secondary namespaces.
I wonder whether there is a Python analog for "find all securities that are not
currencies" that Wm provided in his SQL...
David
On August 12, 2026 3:13:55 AM GMT+05:30, Kalpesh Patel <[email protected]
<mailto:[email protected]> > wrote:
Script attached in-case spaces gets munged up by the list server which I
already show done so.
-----Original Message-----
From: Kalpesh Patel <[email protected] <mailto:[email protected]> >
Sent: Tuesday, August 11, 2026 4:34 PM
To: 'Wm Tarr' <[email protected] <mailto:[email protected]> >;
'[email protected]' <[email protected]
<mailto:[email protected]> >
Subject: RE: [GNC] Trading accounts
Here is the Python script that will do so. You'll need to provide full path to
your compressed XML data file as the first argument, followed by list of
symbols to find namespace(s) for. All parameters separated by one or more
spaces.
Example
c:\CloudDrives\OneDrive\QuickenStuff\HELPERS>python display_namespaces.py
c:\data\gnucash\example.gnucash NANC NANC:CBOE NANC:CBOE - US
You will need Python 3.X installed, along with lxml and gzip libraries
installed in Python for the script to work. You would copy & paste everything
between '# ---' delimiters to a file for a fully running script.
Now you have both ways to do it. Hope these helps.
# --- Start of Script
from lxml import etree
import gzip
import sys
if len(sys.argv) > 2:
tickers = [ticker.strip() for ticker in sys.argv[2:]]
data_file = sys.argv[1]
else:
print ("\nProvide two positional parameters:")
print (" File name as the first.")
print (" Specify one or more tickers as second and onward separated by a
space.")
exit()
with gzip.open(data_file, "rb") as f:
context = etree.iterparse(f,
tag='{http://www.gnucash.org/XML/gnc}commodity')
for event, elem in context:
symbol = elem[1].text
namespace = elem[0].text
elem.clear()
if any(symbol.lower() == ticker.lower() for ticker in tickers):
print ("{}:{}".format(symbol, namespace)) # --- End of
Script
-----Original Message-----
From: Wm Tarr <[email protected] <mailto:[email protected]> >
Sent: Monday, August 10, 2026 12:56 PM
To: [email protected] <mailto:[email protected]>
Subject: Re: [GNC] Trading accounts
I don't think you can do it in gnc but here is some SQL that does it
_____
with m_cnt as (
select mnemonic, count(*) as cnt
from commodities
group by mnemonic
having cnt > 1
)
select namespace, mnemonic
from commodities
where mnemonic in (select mnemonic from m_cnt)
;
_____
Wm
On 2026-08-10 01:36, Fred Tydeman wrote:
Anyone know of a way to find stocks in more than one Namespace?
# --- Start of script ---
from lxml import etree
import logging
import gzip
import sys
import yfinance as yf
onlyMultiple = True
createQuotes = False
if len(sys.argv) > 3:
if "quotes" in sys.argv[3].lower():
createQuotes = True
if len(sys.argv) > 2:
if "all" in sys.argv[2].lower():
onlyMultiple = False
if len(sys.argv) > 1:
data_file = sys.argv[1]
else:
print ("\nProvide one or two positional parameters:")
print (" Required first argument: GNC data file.")
print (" Required second argument: 'all' to display all tickers, not just
those with multiple namespaces; else any non blank string.")
print (" Optional third argument: 'quotes' to create an importable
'prices.csv' file.\n")
exit()
namespaces = dict()
logger = logging.getLogger("yfinance")
logger.disabled = True
logger.propagate = False
try:
with gzip.open(data_file, "rb") as f:
context = etree.iterparse(f,
tag='{http://www.gnucash.org/XML/gnc}commodity')
for event, elem in context:
symbol = elem[1].text
namespace = elem[0].text
elem.clear()
if symbol in namespaces:
namespaces[symbol] = namespaces[symbol] + ", " +namespace
else:
namespaces[symbol] = namespace
with open("prices.csv", "w", encoding="utf-8") as file:
if not file.writable():
createQuotes = False
for ticker in sorted(namespaces.keys()):
if onlyMultiple:
if namespaces[ticker].count(",") > 0:
print ("{}:{}".format(ticker, namespaces[ticker]))
else:
print ("{}:{}".format(ticker, namespaces[ticker]))
namespace = namespaces[ticker].split(",")[0]
if namespace != "CURRENCY" and createQuotes:
try:
quotes = yf.Ticker(ticker)
info = quotes.info
prices = quotes.history(period="1wk", auto_adjust=True)
if not prices.empty:
currency = "USD"
prices.reset_index(inplace=True)
prices['Date'] = prices['Date'].dt.strftime('%m/%d/%Y')
prices.drop(['Dividends','Stock Splits'], inplace=True,
axis=1)
prices.to_dict(orient='records')
infoAttr = info.keys()
if 'financialCurrency' in infoAttr:
currency = info['financialCurrency']
if 'currency' in infoAttr:
currency = info['currency']
for i in prices.index:
close = prices['Close'][i]
date = prices['Date'][i]
high = prices['High'][i]
low = prices['Low'][i]
volume = prices['Volume'][i]/100
with open("prices.csv", "a", encoding="utf-8") as file:
file.write('"{}","{}","{}",{},"{}"\n'.format(namespace, ticker, date, close,
currency))
except Exception as e:
pass
except Exception as e:
print ("Error: {}".format(e))
# --- End of script ---
_______________________________________________
gnucash-user mailing list
[email protected]
To update your subscription preferences or to unsubscribe:
https://lists.gnucash.org/mailman/listinfo/gnucash-user
-----
Please remember to CC this list on all your replies.
You can do this by using Reply-To-List or Reply-All.