NAME

Finance::NFS::File::AccountBalance - Read Account Balance Records into data structures

SYNOPSYS

my $balance = Finance::NFS::File::AccountBalance
  ->new(
        client_id        => 'A7T',
        filename         => $path_to_file,
        account_callback => sub{ ... }, #optional
       );
my $fbsi_cycle_date = $balance->file_date;
my $records = eval { $balance->records };
die("There was an error reading the file: $@") unless defined $records;

for my $acct ( @{  }){
   #insert records into database or whatever
   my $branch = $acct->{branch}; #etc..
}

A note about Finance::NFS::File::*

This family of modules is intended to help developers in the financial industry deal with the standard transmission files provided by National Financial Services (NFS)

This module focuses on the Account Balance Transmission File.

The file layout version this moduled was designed with in mind is 4.6.4

ACCOUNT KEYS

Filler fields are discarded; where appropriate, fields are trimed of whitespace; where applicable, balance figures are merged with their signs and divided by a hundred to indicate full dollar amounts. Dates is the MMDDYY format are converted to DateTime objects.

The keys available in the account hashref follow, ordered by record of origin and order whithin that record.

Record 01

  • branch

  • acct_num

  • last_update_d

  • networth

  • cash_collected

  • collected

  • net_trade_date

  • networth_mkt_val

  • cash_money_mkts

Record 02

  • option_mkt_val

  • option_in_money

  • memo_adjustments

  • margin_available

  • corp_bond_buying_power

  • muni_bond_buying_power

  • govt_bond_buying_power

Record 03

  • house_surplus_call

  • nyse_surplus_call

  • sma_fed_call

  • min_equity_call

  • core_money_mkt

  • margin_equity

  • margin_liquid_equity

Record 04

  • margin_equity_pct

  • fed_call_reduction

  • house_call_reduction

  • nyse_call_reduction

  • uncollected

  • min_equity_call_reduction

  • transfer_legend_code

  • margin_papers_switch

  • position_switch

  • unpriced_switch

  • acct_type_switch

  • short_pos_switch

  • long_pos_switch

  • memo_entries_switch

  • day_trades_switch

  • possible_liquidations_switch

  • min_fed_call_switch

  • irs_number

  • irs_code

Record 05

  • short_name

  • acct_class

  • owning_rr

  • exec_rr

  • agency_code

  • prod_level

  • reg_type

  • available_cash

  • available_cash_margin

  • available_non_margin

Record 06-10

Account Records 06-10 contain the type level balance information and are stored in the the type_level key as a hashref where the key is the account type (0-9) and the value is a hashref with the following keys:

  • mkt_value

  • td_balance

  • sd_balance

ATTRIBUTES

client_id

Required read-only string value of a 3 character length, usually your Super Branch ID.

filename

Required read-only string that represents the path to the file you wish to read.

account_callback

has_account_callback - predicate

Optional read-only code reference that will be called after the last record of every account. Will be passed two arguments, $the current instance of the file parser (so you can access file properties) and a hashref representing the account as described above.

You can use this to reduce the memory foot print of your program by keeping only the current account record in memory. Example:

my $callback = sub{
    my($instance, $acct) = @_;
    #process data here;
    %$acct = ();
};
my $balance = Finance::NFS::File::AccountBalance
  ->new(client_id => 'A7T', filename => $file, account_callback => $callback);

#by the time this returns a callback will have been executed for each account
my $records = $balance->records;

The downside of this method is that if the file is currupted later on, you will have to catch the exception and rollback manually. Partially transmitted files are NOT that uncommon! Make sure you have a rollback mechanism.

records

clear_records - clearer
has_records - predicate
_build_records - builder

An array reference containing all of the accounts in the structure described above. This read-only attribute builds lazyly the first time it is requested by actually going through the while file and reading it. If any errors are encountered while reading the file or the file appears to be truncated an exception will be thrown.

file_date

_file_date - set accessor
has_file_date - predicate

The date of the FBSI cycle is contained in the header record. When the header record is processed this attribute is automatically set. This happens when you first instantiate the object.

_file_handle

_clear_file_handle - clearer
_has_file_handle - predicate
_build__file_handle - builder

This is the IO::File object that holds our filehandle. DO NOT TOUCH THIS. If you mess with this I can alsmost guarantee you will break something.

METHODS

new

Creates a new instance. Takes a list of key / value pairs as arguments. The keys accepted are the attributes listed above.

BUILD

At instantiation time this method is called and it opens the file handle and reads the header of the file to get the file date.

See Moose for more information about how BUILD works.

_process_header

This private method reads the first line of the file and processes the header. It also sets the file_date attribute.

check_file

Takes one argument, a file name, and opens and checks the record structure to make sure it is correctly formed. Returns 1 if the file is correctly formed and a throw an exception if it is not.

clean_date

This will convert a MMDDYY date to a DateTime object. In the future this method may move to an external module so it can be shared amongst the many file processors I plan on eventually writting.

meta

See Moose

TODO

Tests are not yet in place, but I use this module in production. As soon as I have time to create test data files with bogus data I will include better test coverage.
I am considering replacing the confess calls with an error variable and return; to make it less painful to deal with malformed files, which is not unheard of, but it does happen sometimes. on the otherhand, I do like throwing exceptions, it works well for me.

KNOWN ISSUES

The caveat of converting dates is that if you process a 100 yeard old January 1st file on December 31st while you are on a timezone behind Fidelity's, such that their cycle year is yours + 1, the processor will think the date file is actually today's file. This is likely to never happen in the real world. I really hope nobody is using this program on FBSI's 100 year anniversary to process 100 year old files.

Dates before the UNIX epoch are not guaranteed to work, but I think that's OK.

AUTHOR

Guillermo Roditi (groditi) <groditi@cpan.org>

Your name could be here (please contribute!)

BUGS, FEATURE REQUESTS AND CONTRIBUTIONS

Google Code Project Page - http://code.google.com/p/finance-nfs-file-accountbalance/

LICENSE

You may distribute this code under the same terms as Perl itself.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 560:

You forgot a '=back' before '=head1'