class STOCKINFO(SECINFO): stocktype = OneOf('COMMON', 'PREFERRED', 'CONVERTIBLE', 'OTHER') yld = Decimal(4) dtyieldasof = DateTime() typedesc = String(32) assetclass = OneOf(*ASSETCLASSES) fiassetclass = String(32)
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)
def copyTRNRS(self, trnrs): """ Attach the data fields from the *TRNRS wrapper to the STMT """ self.uid = String(36).convert(trnrs.find('TRNUID').text) self.status = Aggregate.from_etree(trnrs.find('STATUS')) cltcookie = trnrs.find('CLTCOOKIE') if cltcookie is not None: self.cookie = String(36).convert(cltcookie.text) else: self.cookie = None
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 SECINFO(CURRENCY, SECID): # FIs abuse SECNAME/TICKER # Relaxing the length constraints from the OFX spec does little harm #secname = String(120, required=True) #ticker = String(32) secname = String(255, required=True) ticker = String(255) fiid = String(32) rating = String(10) unitprice = Decimal() dtasof = DateTime() memo = String(255)
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 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 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 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 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 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 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 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 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 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)
class INVACCTFROM(ACCTFROM): brokerid = String(22, required=True)
class BUYMF(INVBUY): buytype = OneOf(*BUYTYPES, required=True) relfitid = String(255)
class CCACCTFROM(ACCTFROM): acctkey = String(22)
class STATUS(Aggregate): code = Integer(6, required=True) severity = OneOf('INFO', 'WARN', 'ERROR', required=True) message = String(255)
class ACCTFROM(Aggregate): acctid = String(22, required=True)
class OTHERINFO(SECINFO): typedesc = String(32) assetclass = OneOf(*ASSETCLASSES) fiassetclass = String(32)
class BAL(CURRENCY): name = String(32, required=True) desc = String(80, required=True) baltype = OneOf('DOLLAR', 'PERCENT', 'NUMBER', required=True) value = Decimal(required=True) dtasof = DateTime()
class FIPORTION(Aggregate): fiassetclass = String(32) percent = Decimal()
class INVTRAN(TRAN): dttrade = DateTime(required=True) dtsettle = DateTime() reversalfitid = String(255) memo = String(255)
class FI(Aggregate): """ FI aggregates are optional in SONRQ/SONRS; not all firms use them. """ org = String(32) fid = String(32)
class SECID(Aggregate): uniqueid = String(32, required=True) uniqueidtype = String(10, required=True)
class TRAN(Aggregate): fitid = String(255, required=True) srvrtid = String(10)
class BANKACCTFROM(ACCTFROM): bankid = String(9, required=True) branchid = String(22) accttype = OneOf(*ACCTTYPES, required=True) acctkey = String(22)