class STOCKINFO(SECINFO): stocktype = OneOf('COMMON', 'PREFERRED', 'CONVERTIBLE', 'OTHER') yld = Decimal(4) dtyieldasof = DateTime() typedesc = String(32) assetclass = OneOf(*ASSETCLASSES) fiassetclass = String(32) def __init__(self, elem): """ Rename 'yield' (Python reserved word) to 'yld' """ extra_attrs = {} # Do all XPath searches before removing nodes from the tree # which seems to mess up the DOM in Python3 and throw an # AttributeError on subsequent searches. yld = elem.find('./YIELD') if yld is not None: # Rename; save for later extra_attrs['yld'] = yld.text elem.remove(yld) super(STOCKINFO, self).__init__(elem) # Add back data previously stripped/mangled for attr, val in extra_attrs.items(): setattr(self, attr, val)
class OPTINFO(SECINFO): opttype = OneOf('CALL', 'PUT', required=True) strikeprice = Decimal(required=True) dtexpire = DateTime(required=True) shperctrct = Integer(required=True) assetclass = OneOf(*ASSETCLASSES) fiassetclass = String(32)
class OPTINFO(SECINFO): opttype = OneOf('CALL', 'PUT', required=True) strikeprice = Decimal(required=True) dtexpire = DateTime(required=True) shperctrct = Integer(required=True) assetclass = OneOf(*ASSETCLASSES) fiassetclass = String(32) def __init__(self, elem): """ Strip SECID of underlying so it doesn't overwrite SECID of option during _flatten() """ # Do all XPath searches before removing nodes from the tree # which seems to mess up the DOM in Python3 and throw an # AttributeError on subsequent searches. secid = elem.find('./SECID') if secid is not None: # A <SECID> aggregate referring to the security underlying the # option is, in general, *not* going to be contained in <SECLIST> # (because you don't necessarily have a position in the underlying). # Since the <SECID> for the underlying only gives us fields for # (uniqueidtype, uniqueid) we can't really go ahead and use this # information to create a corresponding SECINFO instance (since we # lack information about the security subclass). It's unclear that # the SECID of the underlying is really needed for anything, so we # disregard it. elem.remove(secid) super(OPTINFO, self).__init__(elem)
class STOCKINFO(SECINFO): stocktype = OneOf('COMMON', 'PREFERRED', 'CONVERTIBLE', 'OTHER') yld = Decimal(4) dtyieldasof = DateTime() typedesc = String(32) assetclass = OneOf(*ASSETCLASSES) fiassetclass = String(32)
class CLOSUREOPT(INVTRAN, SECID): optaction = OneOf('EXERCISE', 'ASSIGN', 'EXPIRE') units = Decimal(required=True) shperctrct = Integer(required=True) subacctsec = OneOf(*INVSUBACCTS, required=True) relfitid = String(255) gain = Decimal()
class INCOME(INVTRAN, SECID, ORIGCURRENCY): incometype = OneOf(*INCOMETYPES, required=True) total = Decimal(required=True) subacctsec = OneOf(*INVSUBACCTS, required=True) subacctfund = OneOf(*INVSUBACCTS, required=True) taxexempt = Bool() withholding = Decimal() inv401ksource = OneOf(*INV401KSOURCES)
class SPLIT(INVTRAN, SECID): subacctsec = OneOf(*INVSUBACCTS, required=True) oldunits = Decimal(required=True) newunits = Decimal(required=True) numerator = Decimal(required=True) denominator = Decimal(required=True) fraccash = Decimal() subacctfund = OneOf(*INVSUBACCTS) inv401ksource = OneOf(*INV401KSOURCES)
class INVPOS(SECID, CURRENCY): heldinacct = OneOf(*INVSUBACCTS, required=True) postype = OneOf('SHORT', 'LONG', required=True) units = Decimal(required=True) unitprice = Decimal(4, required=True) mktval = Decimal(required=True) dtpriceasof = DateTime(required=True) memo = String(255) inv401ksource = OneOf(*INV401KSOURCES)
class TRANSFER(INVTRAN, SECID): subacctsec = OneOf(*INVSUBACCTS, required=True) units = Decimal(required=True) tferaction = OneOf('IN', 'OUT', required=True) postype = OneOf('SHORT', 'LONG', required=True) avgcostbasis = Decimal() unitprice = Decimal() dtpurchase = DateTime() inv401ksource = OneOf(*INV401KSOURCES)
class REINVEST(INVTRAN, SECID, ORIGCURRENCY): incometype = OneOf(*INCOMETYPES, required=True) total = Decimal(required=True) subacctsec = OneOf(*INVSUBACCTS) units = Decimal(required=True) unitprice = Decimal(4, required=True) commission = Decimal() taxes = Decimal() fees = Decimal() load = Decimal() taxexempt = Bool() inv401ksource = OneOf(*INV401KSOURCES)
def __init__(self, bankid, acctid, accttype): self._acct = OrderedDict.fromkeys(self.acctkeys) accttype = accttype.upper() accttype = OneOf(*ACCTTYPES).convert(accttype) self._acct['ACCTTYPE'] = OneOf(*ACCTTYPES).convert(accttype) bankid = str(bankid) if not self.routingre.match(bankid): raise ValueError('Invalid bankid %s' % bankid) self._acct['BANKID'] = bankid assert acctid self._acct['ACCTID'] = str(acctid)
class DEBTINFO(SECINFO): parvalue = Decimal(required=True) debttype = OneOf('COUPON', 'ZERO', required=True) debtclass = OneOf('TREASURY', 'MUNICIPAL', 'CORPORATE', 'OTHER') couponrt = Decimal(4) dtcoupon = DateTime() couponfreq = OneOf('MONTHLY', 'QUARTERLY', 'SEMIANNUAL', 'ANNUAL', 'OTHER') callprice = Decimal(4) yieldtocall = Decimal(4) dtcall = DateTime() calltype = OneOf('CALL', 'PUT', 'PREFUND', 'MATURITY') ytmat = Decimal(4) dtmat = DateTime() assetclass = OneOf(*ASSETCLASSES) fiassetclass = String(32)
class ORIGCURRENCY(CURRENCY): curtype = OneOf('CURRENCY', 'ORIGCURRENCY') def __init__(self, elem): """ See OFX spec section 5.2 for currency handling conventions. Flattening the currency definition leaves only the CURRATE/CURSYM elements, leaving no indication of whether these were sourced from a CURRENCY aggregate or ORIGCURRENCY. Since this distinction is important to interpreting transactions in foreign correncies, we preserve this information by adding a nonstandard curtype element. """ super(ORIGCURRENCY, self).__init__(elem) currency = elem.find('*/CURRENCY') origcurrency = elem.find('*/ORIGCURRENCY') if (currency is not None) and (origcurrency is not None): raise ValueError("<%s> may not contain both <CURRENCY> and \ <ORIGCURRENCY>" % elem.tag) curtype = currency if curtype is None: curtype = origcurrency if curtype is not None: curtype = curtype.tag self.curtype = curtype
class INVBUY(INVTRAN, SECID, ORIGCURRENCY): units = Decimal(required=True) unitprice = Decimal(4, required=True) markup = Decimal() commission = Decimal() taxes = Decimal() fees = Decimal() load = Decimal() total = Decimal(required=True) subacctsec = OneOf(*INVSUBACCTS, required=True) subacctfund = OneOf(*INVSUBACCTS, required=True) loanid = String(32) loanprincipal = Decimal() loaninterest = Decimal() inv401ksource = OneOf(*INV401KSOURCES) dtpayroll = DateTime() prioryearcontrib = Bool()
class SONRS(FI, STATUS): dtserver = DateTime(required=True) userkey = String(64) tskeyexpire = DateTime() language = OneOf(*LANG_CODES) dtprofup = DateTime() dtacctup = DateTime() sesscookie = String(1000) accesskey = String(1000)
class INVSELL(INVTRAN, SECID, ORIGCURRENCY): units = Decimal(required=True) unitprice = Decimal(4, required=True) markdown = Decimal() commission = Decimal() taxes = Decimal() fees = Decimal() load = Decimal() withholding = Decimal() taxexempt = Bool() total = Decimal(required=True) gain = Decimal() subacctsec = OneOf(*INVSUBACCTS, required=True) subacctfund = OneOf(*INVSUBACCTS, required=True) loanid = String(32) statewithholding = Decimal() penalty = Decimal() inv401ksource = OneOf(*INV401KSOURCES)
class PAYEE(Aggregate): name = String(32, required=True) addr1 = String(32, required=True) addr2 = String(32) addr3 = String(32) city = String(32, required=True) state = String(5, required=True) postalcode = String(11, required=True) country = OneOf(*COUNTRY_CODES) phone = String(32, required=True)
class STMTTRN(TRAN, ORIGCURRENCY): trntype = OneOf('CREDIT', 'DEBIT', 'INT', 'DIV', 'FEE', 'SRVCHG', 'DEP', 'ATM', 'POS', 'XFER', 'CHECK', 'PAYMENT', 'CASH', 'DIRECTDEP', 'DIRECTDEBIT', 'REPEATPMT', 'OTHER', required=True) dtposted = DateTime(required=True) dtuser = DateTime() dtavail = DateTime() trnamt = Decimal(required=True) correctfitid = Decimal() correctaction = OneOf('REPLACE', 'DELETE') checknum = String(12) refnum = String(32) sic = Integer() payeeid = String(12) name = String(32) memo = String(255) inv401ksource = OneOf(*INV401KSOURCES) payee = None bankacctto = None ccacctto = None
class MFINFO(SECINFO): mftype = OneOf('OPENEND', 'CLOSEEND', 'OTHER') yld = Decimal(4) dtyieldasof = DateTime() mfassetclass = [] fimfassetclass = [] def __init__(self, elem): """ Strip MFASSETCLASS/FIMFASSETCLASS - lists that will blow up _flatten() Rename 'yield' (Python reserved word) to 'yld' """ extra_attrs = {} # Do all XPath searches before removing nodes from the tree # which seems to mess up the DOM in Python3 and throw an # AttributeError on subsequent searches. mfassetclass = elem.find('./MFASSETCLASS') fimfassetclass = elem.find('./FIMFASSETCLASS') yld = elem.find('./YIELD') if mfassetclass is not None: # Convert PORTIONs; save for later extra_attrs['mfassetclass'] = [ Aggregate.from_etree(p) for p in mfassetclass ] elem.remove(mfassetclass) if fimfassetclass is not None: # Convert FIPORTIONs; save for later extra_attrs['fimfassetclass'] = [ Aggregate.from_etree(p) for p in fimfassetclass ] elem.remove(fimfassetclass) if yld is not None: # Rename; save for later extra_attrs['yld'] = yld.text elem.remove(yld) super(MFINFO, self).__init__(elem) # Add back data previously stripped/mangled for attr, val in extra_attrs.items(): setattr(self, attr, val)
class MFINFO(SECINFO): mftype = OneOf('OPENEND', 'CLOSEEND', 'OTHER') yld = Decimal(4) dtyieldasof = DateTime() mfassetclass = [] fimfassetclass = [] def __init__(self, elem, strict=True): """ Strip MFASSETCLASS/FIMFASSETCLASS - lists that will blow up _flatten() """ extra_attrs = {} # Do all XPath searches before removing nodes from the tree # which seems to mess up the DOM in Python3 and throw an # AttributeError on subsequent searches. mfassetclass = elem.find('./MFASSETCLASS') fimfassetclass = elem.find('./FIMFASSETCLASS') if mfassetclass is not None: # Convert PORTIONs; save for later extra_attrs['mfassetclass'] = [ Aggregate.from_etree(p) for p in mfassetclass ] elem.remove(mfassetclass) if fimfassetclass is not None: # Convert FIPORTIONs; save for later extra_attrs['fimfassetclass'] = [ Aggregate.from_etree(p) for p in fimfassetclass ] elem.remove(fimfassetclass) super(MFINFO, self).__init__(elem, strict=strict) # Staple MFASSETCLASS/FIMFASSETCLASS onto MFINFO for attr, val in extra_attrs.items(): setattr(self, attr, val)
class JRNLSEC(INVTRAN, SECID): subacctto = OneOf(*INVSUBACCTS, required=True) subacctfrom = OneOf(*INVSUBACCTS, required=True) units = Decimal(required=True)
class STATUS(Aggregate): code = Integer(6, required=True) severity = OneOf('INFO', 'WARN', 'ERROR', required=True) message = String(255)
class JRNLFUND(INVTRAN): subacctto = OneOf(*INVSUBACCTS, required=True) subacctfrom = OneOf(*INVSUBACCTS, required=True) total = Decimal(required=True)
class MARGININTEREST(INVTRAN, ORIGCURRENCY): total = Decimal(required=True) subacctfund = OneOf(*INVSUBACCTS, required=True)
class POSOPT(INVPOS): secured = OneOf('NAKED', 'COVERED')
class RETOFCAP(INVTRAN, SECID, ORIGCURRENCY): total = Decimal(required=True) subacctsec = OneOf(*INVSUBACCTS, required=True) subacctfund = OneOf(*INVSUBACCTS, required=True) inv401ksource = OneOf(*INV401KSOURCES)
class SELLDEBT(INVSELL): sellreason = OneOf('CALL', 'SELL', 'MATURITY', required=True) accrdint = Decimal()
class SELLSTOCK(INVSELL): selltype = OneOf(*SELLTYPES, required=True)
class SELLOPT(INVSELL): optselltype = OneOf('SELLTOCLOSE', 'SELLTOOPEN', required=True) shperctrct = Integer(required=True) relfitid = String(255) reltype = OneOf('SPREAD', 'STRADDLE', 'NONE', 'OTHER') secured = OneOf('NAKED', 'COVERED')
class SELLMF(INVSELL): selltype = OneOf(*SELLTYPES, required=True) avgcostbasis = Decimal() relfitid = String(255)