### Standard installation of ofxtools Source: https://ofxtools.readthedocs.io/en/latest/_sources/installation.rst.txt Installs the most recent release of ofxtools from PyPI. Use --user for single-user installation. ```bash $ pip install --user ofxtools ``` -------------------------------- ### Install keyring dependencies Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Install the python-keyring package to enable secure password storage. ```bash $ pip install --user keyring ``` -------------------------------- ### Standard system-wide installation of ofxtools Source: https://ofxtools.readthedocs.io/en/latest/installation.html Installs the most recent release of ofxtools from PyPI system-wide. Requires root privileges. ```bash $ pip install ofxtools ``` -------------------------------- ### Example ofxget.cfg configuration Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Manual configuration format for the ofxget.cfg file based on discovered institution requirements. ```ini [etrade] version = 102 [usaa] version = 151 unclosedelements = true [vanguard] version = 203 pretty = true ``` -------------------------------- ### System-wide installation of ofxtools Source: https://ofxtools.readthedocs.io/en/latest/_sources/installation.rst.txt Installs ofxtools system-wide. Requires root privileges. ```bash $ pip install ofxtools ``` -------------------------------- ### Configuration File Formats Source: https://ofxtools.readthedocs.io/en/latest/client.html Examples of manual configuration file entries using server details or OFX Home IDs. ```ini # American Express [amex] url: https://online.americanexpress.com/myca/ofxdl/desktop/desktopDownload.do?request_type=nl_ofxdownload org: AMEX fid: 3101 ``` ```ini # American Express [amex] ofxhome: 424 ``` -------------------------------- ### Bleeding edge installation of ofxtools Source: https://ofxtools.readthedocs.io/en/latest/_sources/installation.rst.txt Installs the most recent prerelease version of ofxtools by downloading and installing from the source archive. ```bash $ pip install --user . ``` -------------------------------- ### Standard user installation of ofxtools Source: https://ofxtools.readthedocs.io/en/latest/installation.html Installs the most recent release of ofxtools from PyPI for a single user. This is the recommended method for general use. ```bash $ pip install --user ofxtools ``` -------------------------------- ### Request Statements with OFXClient Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Example of initializing an OFXClient instance and requesting multiple statement types programmatically. ```python >>> import datetime; import ofxtools >>> from ofxtools.Client import OFXClient, StmtRq, CcStmtEndRq >>> client = OFXClient("https://ofx.chase.com", userid="MoMoney", ... org="B1", fid="10898", ... version=220, prettyprint=True, ... bankid="111000614") >>> dtstart = datetime.datetime(2015, 1, 1, tzinfo=ofxtools.utils.UTC) >>> dtend = datetime.datetime(2015, 1, 31, tzinfo=ofxtools.utils.UTC) >>> s0 = StmtRq(acctid="1", accttype="CHECKING", dtstart=dtstart, dtend=dtend) >>> s1 = StmtRq(acctid="2", accttype="SAVINGS", dtstart=dtstart, dtend=dtend) >>> c0 = CcStmtEndRq(acctid="3", dtstart=dtstart, dtend=dtend) >>> response = client.request_statements("t0ps3kr1t", s0, s1, c0) ``` -------------------------------- ### Developer installation of ofxtools Source: https://ofxtools.readthedocs.io/en/latest/installation.html Installs ofxtools in development mode after cloning the source repository. Includes installing development-specific requirements. ```bash $ git clone https://github.com/csingley/ofxtools.git ``` ```bash $ cd ofxtools ``` ```bash $ pip install -e . ``` ```bash $ pip install -r ofxtools/requirements-development.txt ``` -------------------------------- ### Bleeding edge installation of ofxtools Source: https://ofxtools.readthedocs.io/en/latest/installation.html Installs the most recent prerelease version of ofxtools from a downloaded and unzipped source. Use this to access the latest features and bug fixes. ```bash $ pip install --user . ``` -------------------------------- ### Locate ofxget installation path Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Use the Python interpreter to find the absolute file path of the installed ofxget script. ```python >>> from ofxtools.scripts import ofxget >>> print(ofxget.__file__) ``` -------------------------------- ### Developer installation of ofxtools Source: https://ofxtools.readthedocs.io/en/latest/_sources/installation.rst.txt Installs ofxtools in development mode, suitable for users who plan to modify the source code. Also installs development requirements. ```bash $ git clone https://github.com/csingley/ofxtools.git ``` ```bash $ cd ofxtools ``` ```bash $ pip install -e . ``` ```bash $ pip install -r ofxtools/requirements-development.txt ``` -------------------------------- ### Get ofxget User Configuration Path Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Open a Python interpreter and use this command to print the exact path where ofxget is looking for its configuration file. ```python >>> from ofxtools.scripts import ofxget >>> print(ofxget.USERCONFIGPATH) ``` -------------------------------- ### Implement Specific Transaction Wrappers Source: https://ofxtools.readthedocs.io/en/latest/contributing.html Example implementation of INTRATRNRQ and INTRATRNRS using base classes with required and optional mutex constraints. ```python from ofxtools.models.wrapperbases import TrnRq, TrnRs class INTRATRNRQ(TrnRq): """ OFX section 11.7.1.1 """ intrarq = SubAggregate(STMTRQ) intramodrq = SubAggregate(INTRAMODRQ) intracanrq = SubAggregate(INTRACANRQ) requiredMutexes = [ ["intrarq", "intramodrq", "intracanrq"], ] class INTRATRNRS(TrnRs): """ OFX section 11.7.1.2 """ intrars = SubAggregate(INTRARS) intramodrs = SubAggregate(INTRAMODRS) intracanrs = SubAggregate(INTRACANRS) optionalMutexes = [ ["intrars", "intramodrs", "intracanrs", "intermodrs", "intercanrs", "intermodrs"], ] ``` -------------------------------- ### Install certifi package Source: https://ofxtools.readthedocs.io/en/latest/_sources/installation.rst.txt Recommended for Mac users to install the certifi package for SSL certificate validation, especially when using Python 3.6. ```bash $ pip install certifi ``` -------------------------------- ### Install certifi package Source: https://ofxtools.readthedocs.io/en/latest/installation.html Recommended for Mac users to manage SSL certificate validation. This ensures the Python ssl module uses up-to-date trust certificates. ```bash $ pip install certifi ``` -------------------------------- ### Get OFX Profile with Specific Details Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Use this command to establish basic connectivity by requesting an OFX profile from a specific financial institution using its ORG and FID. This does not require authentication. ```bash $ ofxget prof --org AMEX --fid 3101 --url https://online.americanexpress.com/myca/ofxdl/desktop/desktopDownload.do?request_type=nl_ofxdownload ``` -------------------------------- ### Get OFX Profile Using Nickname Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt If the OFX server is known to ofxget, you can use its nickname for a simplified command to retrieve the profile. ```bash $ ofxget prof amex ``` -------------------------------- ### INI Configuration for American Express (URL) Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt This is an example of a manually created INI configuration file for American Express, specifying the URL, ORG, and FID. ```ini # American Express [amex] url: https://online.americanexpress.com/myca/ofxdl/desktop/desktopDownload.do?request_type=nl_ofxdownload org: AMEX fid: 3101 ``` -------------------------------- ### Successful OFX Login Response Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt This is an example of a successful XML response after authenticating with an OFX server, indicating a successful login and providing server details. ```xml 0 INFO Login successful 20190430093324.000[-7:MST] ENG AMEX 3101 ``` -------------------------------- ### Get OFX Profile Using OFX Home ID Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt If the server is known to OFX Home, you can use its database ID to fetch the OFX profile. This simplifies the command by referencing OFX Home's data. ```bash $ ofxget prof --ofxhome 424 ``` -------------------------------- ### Successful OFX account information response Source: https://ofxtools.readthedocs.io/en/latest/client.html This is an example of a successful response from an OFX server after requesting account information. It includes details about the financial institution and a list of accounts. ```xml 0 INFO Login successful 20190430093324.000[-7:MST] ENG AMEX 3101 2a3cbf11-23da-4e77-9a55-2359caf82afe 0 INFO 20190430093324.150[-7:MST] 888888888888888 Y N N ACTIVE 999999999999999 Y N N ACTIVE ``` -------------------------------- ### Configure and download statements Source: https://ofxtools.readthedocs.io/en/latest/client.html Initialize account information in the configuration file and subsequently download statements for configured accounts. ```bash $ ofxget acctinfo -u --write $ ofxget stmt ``` -------------------------------- ### Creating a Configuration File Source: https://ofxtools.readthedocs.io/en/latest/client.html Methods to save connection parameters to a configuration file for future use. ```bash $ ofxget prof myfi --write --org AMEX --fid 3101 --url https://online.americanexpress.com/myca/ofxdl/desktop/desktopDownload.do\?request_type\=nl_ofxdownload ``` ```bash ofxget prof myfi --ofxhome 424 --write ``` -------------------------------- ### Run project tests Source: https://ofxtools.readthedocs.io/en/latest/_sources/contributing.rst.txt Execute the test suite to verify changes. Use the make command for a simplified interface. ```bash python `which nosetests` -dsv --with-coverage --cover-package ofxtools ``` ```bash make test ``` -------------------------------- ### Run tests with make Source: https://ofxtools.readthedocs.io/en/latest/contributing.html A convenient shortcut to execute the project's test suite via the Makefile. ```makefile make test ``` -------------------------------- ### Automatically Updating Configuration with Account Info Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt This command fetches account information and automatically updates the ofxget configuration file with the retrieved account details. ```bash $ ofxget acctinfo amex --user --write ``` -------------------------------- ### Initialize and Use OFXClient for Statement Requests Source: https://ofxtools.readthedocs.io/en/latest/client.html Initialize OFXClient with connection parameters and make a request for statements using StmtRq and CcStmtEndRq. Ensure correct password and request objects are provided. ```python import datetime; import ofxtools from ofxtools.Client import OFXClient, StmtRq, CcStmtEndRq client = OFXClient("https://ofx.chase.com", userid="MoMoney", org="B1", fid="10898", version=220, prettyprint=True, bankid="111000614") dtstart = datetime.datetime(2015, 1, 1, tzinfo=ofxtools.utils.UTC) dtend = datetime.datetime(2015, 1, 31, tzinfo=ofxtools.utils.UTC) s0 = StmtRq(acctid="1", accttype="CHECKING", dtstart=dtstart, dtend=dtend) s1 = StmtRq(acctid="2", accttype="SAVINGS", dtstart=dtstart, dtend=dtend) c0 = CcStmtEndRq(acctid="3", dtstart=dtstart, dtend=dtend) response = client.request_statements("t0ps3kr1t", s0, s1, c0) ``` -------------------------------- ### Automatically write configuration to ofxget.cfg Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Use the --write flag to have ofxget automatically update the configuration file for a given URL. ```bash $ ofxget scan myfi --write --url https://ofx.mybank.com/download ``` -------------------------------- ### Simplified Statement Request Using Configuration Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt This command requests a statement using parameters defined in the configuration file (e.g., for 'amex'). ```bash $ ofxget stmt amex ``` -------------------------------- ### Requesting Statements for All Accounts Using --all Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt This command requests statements for all accounts found in the ACCTINFO response and can optionally write these parameters to the config file. ```bash $ ofxget stmt amex --user --all ``` -------------------------------- ### Configure Vanguard Connection in ofxget.cfg Source: https://ofxtools.readthedocs.io/en/latest/client.html Manually configure the Vanguard connection settings in the `ofxget.cfg` file, specifying the OFX version and pretty print option. ```ini [vanguard] version = 203 pretty = true ``` -------------------------------- ### Requesting Statements within a Specific Date Range Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Use the --start and --end arguments to restrict the statement request to a specific period. Dates should be in YYYYmmdd format. ```bash $ ofxget stmt amex --start 20140101 --end 20140630 > 2014-04_amex.ofx ``` -------------------------------- ### Create Bank Statement Response - Part 1 Source: https://ofxtools.readthedocs.io/en/latest/_sources/generating.rst.txt Initialize core OFX components like ledger balance and bank account information. Ensure datetimes are timezone-aware using UTC. ```python In [1]: from ofxtools.models import * In [2]: from ofxtools.utils import UTC In [3]: from decimal import Decimal In [4]: from datetime import datetime In [5]: ledgerbal = LEDGERBAL(balamt=Decimal('150.65'), dtasof=datetime(2015, 1, 1, tzinfo=UTC)) In [6]: acctfrom = BANKACCTFROM(bankid='123456789', acctid='23456', accttype='CHECKING') # OFX Section 11.3.1 In [7]: stmtrs = STMTRS(curdef='USD', bankacctfrom=acctfrom, ledgerbal=ledgerbal) ``` -------------------------------- ### Configure E*Trade Connection in ofxget.cfg Source: https://ofxtools.readthedocs.io/en/latest/client.html Manually configure the E*Trade connection settings in the `ofxget.cfg` file, specifying the OFX version. ```ini [etrade] version = 102 ``` -------------------------------- ### List available financial institutions Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Display the list of financial institutions supported by the current configuration. ```bash $ ofxget list ``` -------------------------------- ### Create OFX Bank Statement Response - Part 1 Source: https://ofxtools.readthedocs.io/en/latest/generating.html Initializes core components for an OFX bank statement response, including ledger balance and account information. Ensure datetimes are timezone-aware. ```python from ofxtools.models import * from ofxtools.utils import UTC from decimal import Decimal from datetime import datetime ledgerbal = LEDGERBAL(balamt=Decimal('150.65'), dtasof=datetime(2015, 1, 1, tzinfo=UTC)) acctfrom = BANKACCTFROM(bankid='123456789', acctid='23456', accttype='CHECKING') # OFX Section 11.3.1 stmtrs = STMTRS(curdef='USD', bankacctfrom=acctfrom, ledgerbal=ledgerbal) ``` -------------------------------- ### Full CLI Statement Request with URL and Credentials Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Constructs a full credit card statement request using explicit URL, organization, financial institution ID, username, and credit card numbers. ```bash $ export URL="https://online.americanexpress.com/myca/ofxdl/desktop/desktopDownload.do\?request_type\=nl_ofxdownload" $ ofxget stmt --url $URL --org AMEX --fid 3101 -u -c 888888888888888 -c 999999999999999 $ unset URL ``` -------------------------------- ### Login and Request Account Information Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Use this command to log into the OFX server with your username and password to retrieve a list of accounts for which statements can be downloaded. Replace with your actual username. ```bash $ ofxget acctinfo amex --user ``` -------------------------------- ### Save Connection Parameters to Configuration File Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Append the --write option to your CLI invocation to save connection parameters to a configuration file. A server nickname must be provided. ```bash $ ofxget prof myfi --write --org AMEX --fid 3101 --url https://online.americanexpress.com/myca/ofxdl/desktop/desktopDownload.do?request_type=nl_ofxdownload ``` -------------------------------- ### Requesting an OFX Profile Source: https://ofxtools.readthedocs.io/en/latest/client.html Commands to establish basic connectivity by requesting an OFX profile from a server. ```bash $ ofxget prof --org AMEX --fid 3101 --url https://online.americanexpress.com/myca/ofxdl/desktop/desktopDownload.do\?request_type\=nl_ofxdownload ``` ```bash $ ofxget prof amex ``` ```bash $ ofxget prof --ofxhome 424 ``` -------------------------------- ### Configuring Multiple Credit Card Accounts in ofxget.cfg Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt This INI configuration shows how to specify multiple credit card account numbers for a given profile (e.g., 'amex') using a comma-separated list. ```ini # American Express [amex] url: https://online.americanexpress.com/myca/ofxdl/desktop/desktopDownload.do?request_type=nl_ofxdownload org: AMEX fid: 3101 user: creditcard: 888888888888888,999999999999999 ``` -------------------------------- ### Download statements for a financial institution Source: https://ofxtools.readthedocs.io/en/latest/client.html Perform a quick download of all available statements for a specific server. ```bash $ ofxget stmt -u --all ``` -------------------------------- ### Define ORM models and parse OFX data Source: https://ofxtools.readthedocs.io/en/latest/sqlalchemy.html Demonstrates defining SQLAlchemy models and using the OFXTree parser to process financial data from an OFX client request. ```python from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import ( Column, Integer, String, Text, DateTime, Numeric, ForeignKey, Enum, ) from sqlalchemy.orm import (relationship, sessionmaker, ) from sqlalchemy import create_engine from ofxtools.models.i18n import CURRENCY_CODES from ofxtools.Client import (OFXClient, InvStmtRq, ) from ofxtools.Parser import OFXTree from ofxtools.models.investment import (BUYSTOCK, SELLSTOCK) # Data model Base = declarative_base() class Account(Base): id = Column(Integer, primary_key=True) brokerid = Column(String, nullable=False, unique=True) number = Column(String, nullable=False) name = Column(String) class Security(Base): id = Column(Integer, primary_key=True) name = Column(String) ticker = Column(String) uniqueidtype = Column(String, nullable=False) uniqueid = Column(String, nullable=False) class Transaction(Base): id = Column(Integer, primary_key=True) uniqueid = Column(String, nullable=False, unique=True) datetime = Column(DateTime, nullable=False) dtsettle = Column(DateTime) type = Column(Enum('returnofcapital', 'split', 'spinoff', 'transfer', 'trade', 'exercise', name='transaction_type'), nullable=False) memo = Column(Text) currency = Column(Enum(*CURRENCY_CODES, name='transaction_currency')) cash = Column(Numeric) account_id = Column(Integer, ForeignKey('account.id', onupdate='CASCADE'), nullable=False) account = relationship('Account', foreign_keys=[account_id], backref='transactions') security_id = Column(Integer, ForeignKey('security.id', onupdate='CASCADE'), nullable=False) security = relationship('Security', foreign_keys=[security_id], backref='transactions') units = Column(Numeric) # Import client = OFXClient('https://ofxs.ameritrade.com/cgi-bin/apps/OFX', org='Ameritrade Technology Group', fid='AIS', brokerid='ameritrade.com') stmtrq = InvStmtRq(acctid='999999999') response = client.request_statements(user='elmerfudd', password='T0PS3CR3T', invstmtrqs=[stmtrq]) parser = OFXTree() parser.parse(response) ofx = parser.convert() ``` -------------------------------- ### Scan for Vanguard OFX Connection Formats Source: https://ofxtools.readthedocs.io/en/latest/client.html Use the `ofxget scan` command to discover OFX connection requirements for Vanguard. This command sends multiple HTTP requests and may result in IP throttling. ```bash $ ofxget scan vanguard ``` -------------------------------- ### Scan for sign-on information Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Identify specific sign-on requirements like CLIENTUID by scanning institutions. ```bash $ ofxget scan bofa [{"versions": [102], "formats": [{"pretty": false, "unclosedelements": true}, {"pretty": false, "unclosedelements": false}, {"pretty": true, "unclosedelements": true}, {"pretty": true, "unclosedelements": false}]}, {"versions": [], "formats": []}, {"chgpinfirst": false, "clientuidreq": true, "authtokenfirst": false, "mfachallengefirst": false}] $ ofxget scan chase [{"versions": [], "formats": []}, {"versions": [200, 201, 202, 203, 210, 211, 220], "formats": [{"pretty": false}, {"pretty": true}]}, {"chgpinfirst": false, "clientuidreq": true, "authtokenfirst": false, "mfachallengefirst": false}] ``` -------------------------------- ### Define ORM models and extract OFX data Source: https://ofxtools.readthedocs.io/en/latest/_sources/sqlalchemy.rst.txt Demonstrates defining SQLAlchemy models and parsing OFX data to populate them. Requires the ofxtools library and a configured SQLAlchemy environment. ```python from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import ( Column, Integer, String, Text, DateTime, Numeric, ForeignKey, Enum, ) from sqlalchemy.orm import (relationship, sessionmaker, ) from sqlalchemy import create_engine from ofxtools.models.i18n import CURRENCY_CODES from ofxtools.Client import (OFXClient, InvStmtRq, ) from ofxtools.Parser import OFXTree from ofxtools.models.investment import (BUYSTOCK, SELLSTOCK) # Data model Base = declarative_base() class Account(Base): id = Column(Integer, primary_key=True) brokerid = Column(String, nullable=False, unique=True) number = Column(String, nullable=False) name = Column(String) class Security(Base): id = Column(Integer, primary_key=True) name = Column(String) ticker = Column(String) uniqueidtype = Column(String, nullable=False) uniqueid = Column(String, nullable=False) class Transaction(Base): id = Column(Integer, primary_key=True) uniqueid = Column(String, nullable=False, unique=True) datetime = Column(DateTime, nullable=False) dtsettle = Column(DateTime) type = Column(Enum('returnofcapital', 'split', 'spinoff', 'transfer', 'trade', 'exercise', name='transaction_type'), nullable=False) memo = Column(Text) currency = Column(Enum(*CURRENCY_CODES, name='transaction_currency')) cash = Column(Numeric) account_id = Column(Integer, ForeignKey('account.id', onupdate='CASCADE'), nullable=False) account = relationship('Account', foreign_keys=[account_id], backref='transactions') security_id = Column(Integer, ForeignKey('security.id', onupdate='CASCADE'), nullable=False) security = relationship('Security', foreign_keys=[security_id], backref='transactions') units = Column(Numeric) # Import client = OFXClient('https://ofxs.ameritrade.com/cgi-bin/apps/OFX', org='Ameritrade Technology Group', fid='AIS', brokerid='ameritrade.com') stmtrq = InvStmtRq(acctid='999999999') response = client.request_statements(user='elmerfudd', password='T0PS3CR3T', invstmtrqs=[stmtrq]) parser = OFXTree() parser.parse(response) ofx = parser.convert() # Extract def make_security(secinfo): return Security( name=secinfo.secname, ticker=secinfo.ticker, uniqueidtype=secinfo.uniqueidtype, uniqueid=secinfo.uniqueid) securities = {(sec.uniqueidtype, sec.uniqueid): make_security(sec) for sec in ofx.securities} stmt = ofx.statements[0] account = Account(brokerid=stmt.brokerid, number=stmt.acctid) def make_trade(invtran): security = securities[(invtran.uniqueidtype, invtran.uniqueid)] return Transaction( uniqueid=invtran.fitid, datetime=invtran.dttrade, dtsettle=invtran.dtsettle, type='trade', memo=invtran.memo, ``` -------------------------------- ### Generate CLIENTUID with ofxget Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Commands to generate and save a global or FI-specific CLIENTUID for OFX authentication. ```bash # The following generates a global default CLIENTUID $ ofxget scan chase --write # So does this $ ofxget prof chase --write # The following additionally generates a Chase-specific CLIENTUID $ ofxget acctinfo chase -u --savepass --clientuid --write ``` -------------------------------- ### Download statements with ofxget Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Commands for downloading OFX data, including a quick one-time download and a standard workflow for recurring use. ```bash $ ofxget stmt -u --all ``` ```bash $ ofxget acctinfo -u --write $ ofxget stmt ``` -------------------------------- ### Use Navigational Conveniences Source: https://ofxtools.readthedocs.io/en/latest/_sources/parser.rst.txt Utilize proxy attributes and human-friendly aliases provided by Aggregate subclasses to simplify access to deeply nested data. ```python In [12]: stmts = ofx.statements # All {``STMTRS``, ``CCSTMTRS``, ``INVSTMTRS``} in the response In [13]: txs = stmts[0].transactions # The relevant ``*TRANLIST`` In [14]: acct = stmts[0].account # The relevant ``*ACCTFROM`` In [15]: balances = stmts[0].balances # ``INVBAL`` - use ``balance`` for bank statement ``LEDGERBAL`` In [16]: securities = ofx.securities # ``SECLIST`` In [17]: len(securities) Out[17]: 5 In [18]: len(txs) Out[18]: 6 In [19]: tx = txs[-1] In [20]: tx.trnamt Out[20]: Decimal('4.7') In [21]: tx = txs[1] In [22]: type(tx) Out[22]: ofxtools.models.invest.transactions.TRANSFER In [23]: tx.invtran.dttrade # Who wants to remember where to find the trade date? Out[23]: datetime.datetime(2015, 9, 8, 17, 14, 8, tzinfo=) In [24]: tx.dttrade # That's more like it Out[24]: datetime.datetime(2015, 9, 8, 17, 14, 8, tzinfo=) In [25]: tx.secid.uniqueid # Yet more layers Out[25]: '403829104' In [26]: tx.uniqueid # Flat access is less cognitively taxing Out[26]: '403829104' In [27]: tx.uniqueidtype Out[27]: 'CUSIP' ``` -------------------------------- ### Create Bank Statement Response - Part 2 Source: https://ofxtools.readthedocs.io/en/latest/_sources/generating.rst.txt Assemble the complete OFX message by adding status, transaction details, and financial institution information. The FI element is required for Quicken compatibility. ```python In [8]: status = STATUS(code=0, severity='INFO') In [9]: stmttrnrs = STMTTRNRS(trnuid='5678', status=status, stmtrs=stmtrs) In [10]: bankmsgsrs = BANKMSGSRSV1(stmttrnrs) In [11]: fi = FI(org='Illuminati', fid='666') # Required for Quicken compatibility In [12]: sonrs = SONRS(status=status, dtserver=datetime(2015, 1, 2, 17, tzinfo=UTC), language='ENG', fi=fi) In [13]: signonmsgs = SIGNONMSGSRSV1(sonrs=sonrs) In [14]: ofx = OFX(signonmsgsrsv1=signonmsgs, bankmsgsrsv1=bankmsgsrs) ``` -------------------------------- ### Generate Global Default CLIENTUID Source: https://ofxtools.readthedocs.io/en/latest/client.html Use the '--write' option with 'ofxget scan' or 'ofxget prof' to automatically generate and save a global default CLIENTUID to your configuration file. ```bash # The following generates a global default CLIENTUID $ ofxget scan chase --write ``` ```bash # So does this $ ofxget prof chase --write ``` -------------------------------- ### Scan for E*Trade OFX Connection Formats Source: https://ofxtools.readthedocs.io/en/latest/client.html Use the `ofxget scan` command to discover OFX connection requirements for E*Trade. This command sends multiple HTTP requests and may result in IP throttling. ```bash # E*Trade $ ofxget scan https://ofx.etrade.com/cgi-ofx/etradeofx ``` -------------------------------- ### Save password to system keyring Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Use the --savepass flag to store credentials securely during an account information request. ```bash $ ofxget acctinfo -u --write --savepass ``` -------------------------------- ### Save OFX Home Connection to Configuration File Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt This command saves connection parameters using an OFX Home ID to the configuration file, simplifying future connections. ```bash ofxget prof myfi --ofxhome 424 --write ``` -------------------------------- ### Parse OFX into ElementTree Source: https://ofxtools.readthedocs.io/en/latest/_sources/parser.rst.txt Initialize an OFXTree parser and parse an OFX file. The resulting structure follows the standard ElementTree API. ```python In [1]: from ofxtools.Parser import OFXTree In [2]: parser = OFXTree() In [3]: with open('2015-09_amtd.ofx', 'rb') as f: # N.B. need to open file in binary mode ...: parser.parse(f) ...: In [4]: parser.parse('2015-09_amtd.ofx') # Can also use filename directly In [5]: type(parser._root) Out[5]: xml.etree.ElementTree.Element In [6]: parser.find('.//STATUS')[:] # The full ElementTree API can be used, including XPath Out[6]: [, , ] ``` -------------------------------- ### Generate FI-Specific CLIENTUID and Save Source: https://ofxtools.readthedocs.io/en/latest/client.html To generate an FI-specific CLIENTUID, use the '--clientuid' option along with '--write' when fetching account information. This ensures the specific UID is saved to your configuration for consistent use. ```bash # The following additionally generates a Chase-specific CLIENTUID $ ofxget acctinfo chase -u --savepass --clientuid --write ``` -------------------------------- ### Configure USAA Connection in ofxget.cfg Source: https://ofxtools.readthedocs.io/en/latest/client.html Manually configure the USAA connection settings in the `ofxget.cfg` file, specifying the OFX version and unclosed elements. ```ini [usaa] version = 151 unclosedelements = true ``` -------------------------------- ### Scan for USAA OFX Connection Formats Source: https://ofxtools.readthedocs.io/en/latest/client.html Use the `ofxget scan` command to discover OFX connection requirements for USAA. This command sends multiple HTTP requests and may result in IP throttling. ```bash $ ofxget scan usaa ``` -------------------------------- ### Scan financial institutions for OFX compatibility Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Use the scan command to discover supported OFX versions and formatting requirements. Exercise caution as this command performs multiple HTTP requests. ```bash $ # E*Trade $ ofxget scan https://ofx.etrade.com/cgi-ofx/etradeofx [{"versions": [102], "formats": [{"pretty": false, "unclosedelements": true}, {"pretty": false, "unclosedelements": false}]}, {"versions": [], "formats": []}, {"chgpinfirst": false, "clientuidreq": false, "authtokenfirst": false, "mfachallengefirst": false}] $ ofxget scan usaa [{"versions": [102, 151], "formats": [{"pretty": false, "unclosedelements": true}, {"pretty": true, "unclosedelements": true}]}, {"versions": [200, 202], "formats": [{"pretty": false}, {"pretty": true}]}, {"chgpinfirst": false, "clientuidreq": false, "authtokenfirst": false, "mfachallengefirst": false}] $ ofxget scan vanguard [{"versions": [102, 103, 151, 160], "formats": [{"pretty": false, "unclosed_elements": true}, {"pretty": true, "unclosed_elements": true}, {"pretty": true, "unclosed_elements": false}]}, {"versions": [200, 201, 202, 203, 210, 211, 220], "formats": [{"pretty": true}]}, {}] ``` -------------------------------- ### Create OFX Bank Statement Response - Part 2 Source: https://ofxtools.readthedocs.io/en/latest/generating.html Adds wrapper elements and metadata to the OFX response, including status, transaction details, and financial institution information. This is required for compatibility with applications like Quicken. ```python status = STATUS(code=0, severity='INFO') stmttrnrs = STMTTRNRS(trnuid='5678', status=status, stmtrs=stmtrs) bankmsgsrs = BANKMSGSRSV1(stmttrnrs) fi = FI(org='Illuminati', fid='666') # Required for Quicken compatibility sonrs = SONRS(status=status, dtserver=datetime(2015, 1, 2, 17, tzinfo=UTC), language='ENG', fi=fi) signonmsgs = SIGNONMSGSRSV1(sonrs=sonrs) ofx = OFX(signonmsgsrsv1=signonmsgs, bankmsgsrsv1=bankmsgsrs) ``` -------------------------------- ### Requesting Statements for Multiple Credit Cards Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt Use this command to request activity statements for multiple credit card accounts by repeating the --creditcard argument. ```bash $ ofxget stmt amex --user --creditcard 888888888888888 --creditcard 999999999999999 ``` -------------------------------- ### Persist Data to Database Source: https://ofxtools.readthedocs.io/en/latest/sqlalchemy.html Uses SQLAlchemy to create a database engine and session to persist the extracted account, securities, and trades. ```python engine = create_engine('') Session = sessionmaker(bind=engine) session = Session() session.add(account) session.add_all(securities.values()) session.add_all(trades) session.commit() ``` -------------------------------- ### Persist Data with SQLAlchemy Source: https://ofxtools.readthedocs.io/en/latest/_sources/sqlalchemy.rst.txt Configures a database engine and session to commit account, security, and trade objects. ```python # Persist engine = create_engine('') Session = sessionmaker(bind=engine) session = Session() session.add(account) session.add_all(securities.values()) session.add_all(trades) session.commit() ``` -------------------------------- ### Run tests with nose Source: https://ofxtools.readthedocs.io/en/latest/contributing.html Executes the test suite using nosetests with coverage tracking enabled for the ofxtools package. ```bash python `which nosetests` -dsv --with-coverage --cover-package ofxtools ``` -------------------------------- ### Sign-on information JSON structure Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt The structure of the sign-on information extracted from the profile, showing flags like clientuidreq. ```json { "chgpinfirst": false, "clientuidreq": true, "authtokenfirst": false, "mfachallengefirst": false } ``` -------------------------------- ### Add XFERPROF to BANKMSGSETV1 in Python Source: https://ofxtools.readthedocs.io/en/latest/contributing.html Adds the XFERPROF aggregate as a sub-aggregate to the BANKMSGSETV1 class. This integrates the funds transfer profile into the banking message set definition. ```python class BANKMSGSETV1(Aggregate): """ OFX section 11.13.2.1 """ ... xferprof = SubAggregate(XFERPROF) ... ``` -------------------------------- ### Create Trade Objects from Transactions Source: https://ofxtools.readthedocs.io/en/latest/_sources/sqlalchemy.rst.txt Instantiates trade objects using transaction data and filters them by model class. ```python currency=invtran.currency, cash=invtran.total, account=account, security=security, units=invtran.units) trades = [make_trade(tx) for tx in stmt.transactions if isinstance(tx, (BUYSTOCK, SELLSTOCK))] # dispatch by model class ``` -------------------------------- ### Navigate OFX Hierarchy Source: https://ofxtools.readthedocs.io/en/latest/parser.html Navigates the OFX hierarchy using Python dotted-attribute access and slice notation for lists. This allows direct access to specific data points within the OFX structure. ```python tx = ofx.invstmtmsgsrsv1[0].invstmtrs.invtranlist[-1] ``` ```python tx.dtposted ``` ```python tx.trnamt ``` -------------------------------- ### Import currency codes Source: https://ofxtools.readthedocs.io/en/latest/_sources/contributing.rst.txt Import international currency codes for use in response aggregates. ```python from ofxtools.models.i18n import CURRENCY_CODES ``` -------------------------------- ### Convert ElementTree to OFX Models Source: https://ofxtools.readthedocs.io/en/latest/_sources/parser.rst.txt Convert the parsed ElementTree structure into a hierarchy of custom OFX model class instances. ```python In [7]: ofx = parser.convert() In [8]: type(ofx) Out[8]: ofxtools.models.ofx.OFX ``` -------------------------------- ### Extend BANKMSGSRQV1 with Transaction Aggregates Source: https://ofxtools.readthedocs.io/en/latest/_sources/contributing.rst.txt Extends the BANKMSGSRQV1 class to include various transaction and synchronization request aggregates using ListAggregate for multiple occurrences. ```python class BANKMSGSRQV1(List): """ OFX section 11.13.1.1.1 """ ... intratrnrq = ListAggregate(INTRATRNRQ) recintratrnrq = ListAggregate(RECINTRATRNRQ) intrasyncrq = ListAggregate(INTRASYNCRQ) recintrasyncrq = ListAggregate(RECINTRASYNCRQ) ... ``` -------------------------------- ### Generate coverage report Source: https://ofxtools.readthedocs.io/en/latest/contributing.html Displays a terminal report showing which parts of the codebase lack test coverage. ```bash coverage report -m ``` -------------------------------- ### INI Configuration for American Express (OFX Home ID) Source: https://ofxtools.readthedocs.io/en/latest/_sources/client.rst.txt This INI configuration uses the OFX Home database ID to define connection parameters for American Express, allowing ofxget to look up the details. ```ini # American Express [amex] ofxhome: 424 ``` -------------------------------- ### Define XFERINFO Aggregate Source: https://ofxtools.readthedocs.io/en/latest/contributing.html Defines the XFERINFO aggregate with sub-aggregates and required mutexes for account selection. ```python from ofxtools.models.base import Aggregate, SubAggregate from ofxtools.Types import String, Decimal, DateTime, OneOf from ofxtools.models.bank.stmt import ( BANKACCTFROM, BANKACCTFROM, CCACCTFROM, CCACCTTO, ) class XFERINFO(Aggregate): """ OFX section 11.3.5 """ bankacctfrom = SubAggregate(BANKACCTFROM) ccacctfrom = SubAggregate(CCACCTFROM) bankacctto = SubAggregate(BANKACCTTO) ccacctto = SubAggregate(CCACCTTO) trnamt = Decimal(required=True) dtdue = DateTime() requiredMutexes = [ ["bankacctfrom", "ccacctfrom"], ["bankacctto", "ccacctto"], ] ``` -------------------------------- ### Prepend OFX Header Source: https://ofxtools.readthedocs.io/en/latest/_sources/generating.rst.txt Generate and prepend the standard OFX header to the serialized XML message. This is the final step before sending the OFX response. ```python In [19]: from ofxtools.header import make_header In [20]: header = str(make_header(version=220)) In [21]: header Out[21]: '\r\n\r\n' In [22]: response = header + message In [23]: response Out[23]: '\r\n\r\n0INFO20150102170000ENGIlluminati66656780INFOUSD12345678923456CHECKING150.6520150101000000' ``` -------------------------------- ### Parse OFX Data to ElementTree Source: https://ofxtools.readthedocs.io/en/latest/parser.html Parses serialized OFX data into a Python data structure using OFXTree. The file must be opened in binary mode. The full ElementTree API, including XPath, can be used on the resulting structure. ```python from ofxtools.Parser import OFXTree parser = OFXTree() with open('2015-09_amtd.ofx', 'rb') as f: parser.parse(f) ``` ```python parser.parse('2015-09_amtd.ofx') ``` ```python parser.find('.//STATUS')[:] ``` -------------------------------- ### Extend BANKMSGSRSV1 with Transaction Aggregates Source: https://ofxtools.readthedocs.io/en/latest/_sources/contributing.rst.txt Extends the BANKMSGSRSV1 class to include various transaction and synchronization response aggregates using ListAggregate for multiple occurrences. ```python class BANKMSGSRSV1(List): """ OFX section 11.13.1.1.2 """ ... intratrnrs = ListAggregate(INTRATRNRS) recintratrnrs = ListAggregate(RECINTRATRNRS) intrasyncrs = ListAggregate(INTRASYNCRS) recintrasyncrs = ListAggregate(RECINTRASYNCRS) ... ``` -------------------------------- ### Add OFX Header and Finalize Response Source: https://ofxtools.readthedocs.io/en/latest/generating.html Prepends the necessary OFX header to the generated XML message. The `make_header` function from `ofxtools.header` is used for this purpose. ```python from ofxtools.header import make_header header = str(make_header(version=220)) response = header + message ```