LibOFX
ofxdump.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  ofxdump.cpp
3  -------------------
4  copyright : (C) 2002 by Benoit GrĂ©goire
5  email : benoitg@coeus.ca
6 ***************************************************************************/
22 /***************************************************************************
23  * *
24  * This program is free software; you can redistribute it and/or modify *
25  * it under the terms of the GNU General Public License as published by *
26  * the Free Software Foundation; either version 2 of the License, or *
27  * (at your option) any later version. *
28  * *
29  ***************************************************************************/
30 #include <iostream>
31 #include <iomanip>
32 #include <cstdlib>
33 #include <cstring>
34 #include <string>
35 #include "libofx.h"
36 #include <stdio.h> /* for printf() */
37 #include <config.h> /* Include config constants, e.g., VERSION TF */
38 #include <errno.h>
39 
40 #include "cmdline.h" /* Gengetopt generated parser */
41 
42 using namespace std;
43 
44 
45 int ofx_proc_security_cb(struct OfxSecurityData data, void * security_data)
46 {
47  char dest_string[255];
48  cout << "ofx_proc_security():\n";
49  if (data.unique_id_valid == true)
50  {
51  cout << " Unique ID of the security: " << data.unique_id << "\n";
52  }
53  if (data.unique_id_type_valid == true)
54  {
55  cout << " Format of the Unique ID: " << data.unique_id_type << "\n";
56  }
57  if (data.unique_id2_valid == true)
58  {
59  cout << " Unique ID of the underlying security: " << data.unique_id2 << "\n";
60  }
61  if (data.unique_id2_type_valid == true)
62  {
63  cout << " Format of the underlying Unique ID: " << data.unique_id2_type << "\n";
64  }
65  if (data.security_type_valid == true)
66  {
67  if (data.security_type == OfxSecurityData::OFX_DEBT_SECURITY)
68  strncpy(dest_string, "DEBTINFO: Debt security", sizeof(dest_string));
69  else if (data.security_type == OfxSecurityData::OFX_FUND_SECURITY)
70  strncpy(dest_string, "MFINFO: Mutual fund security", sizeof(dest_string));
71  else if (data.security_type == OfxSecurityData::OFX_OPTION_SECURITY)
72  strncpy(dest_string, "OPTINFO: Option security", sizeof(dest_string));
73  else if (data.security_type == OfxSecurityData::OFX_STOCK_SECURITY)
74  strncpy(dest_string, "STOCKINFO: Stock security", sizeof(dest_string));
75  else if (data.security_type == OfxSecurityData::OFX_OTHER_SECURITY)
76  strncpy(dest_string, "OTHERINFO: Other type of security", sizeof(dest_string));
77  else
78  strncpy(dest_string, "ERROR: unrecognized", sizeof(dest_string));
79  cout << " Security type: " << dest_string << "\n";
80  }
81  if (data.secname_valid == true)
82  {
83  cout << " Name of the security: " << data.secname << "\n";
84  }
85  if (data.ticker_valid == true)
86  {
87  cout << " Ticker symbol: " << data.ticker << "\n";
88  }
89  if (data.rating_valid == true)
90  {
91  cout << " Rating of the security: " << data.rating << "\n";
92  }
93  if (data.unitprice_valid == true)
94  {
95  if (data.security_type_valid == true
96  && data.security_type == OfxSecurityData::OFX_DEBT_SECURITY)
97  cout << " Price (percent of par): " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(4) << data.unitprice << "%\n";
98  else
99  cout << " Price of each unit of the security: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.unitprice << "\n";
100  }
101  if (data.date_unitprice_valid == true)
102  {
103  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.date_unitprice)));
104  cout << " Date as of which the unitprice is valid: " << dest_string << "\n";
105  }
106  if (data.amounts_are_foreign_currency_valid == true)
107  {
108  cout << " Amounts are in foreign currency: " << (data.amounts_are_foreign_currency ? "Yes" : "No") << "\n";
109  }
110  if (data.currency_valid == true)
111  {
112  cout << " Currency: " << data.currency << "\n";
113  }
114  if (data.currency_ratio_valid == true)
115  {
116  cout << " Ratio of default currency to currency: " << data.currency_ratio << "\n";
117  }
118  if (data.memo_valid == true)
119  {
120  cout << " Extra security information (memo): " << data.memo << "\n";
121  }
122  if (data.asset_class_valid == true)
123  {
124  if (data.asset_class == OfxSecurityData::OFX_ASSET_CLASS_DOMESTICBOND)
125  strncpy(dest_string, "DOMESTICBOND: Domestic bond", sizeof(dest_string));
126  else if (data.asset_class == OfxSecurityData::OFX_ASSET_CLASS_INTLBOND)
127  strncpy(dest_string, "INTLBOND: International bond", sizeof(dest_string));
128  else if (data.asset_class == OfxSecurityData::OFX_ASSET_CLASS_LARGESTOCK)
129  strncpy(dest_string, "LARGESTOCK: Large cap stock", sizeof(dest_string));
130  else if (data.asset_class == OfxSecurityData::OFX_ASSET_CLASS_SMALLSTOCK)
131  strncpy(dest_string, "SMALLSTOCK: Small cap stock", sizeof(dest_string));
132  else if (data.asset_class == OfxSecurityData::OFX_ASSET_CLASS_INTLSTOCK)
133  strncpy(dest_string, "INTLSTOCK: International stock", sizeof(dest_string));
134  else if (data.asset_class == OfxSecurityData::OFX_ASSET_CLASS_MONEYMRKT)
135  strncpy(dest_string, "MONEYMRKT: Money market", sizeof(dest_string));
136  else if (data.asset_class == OfxSecurityData::OFX_ASSET_CLASS_OTHER)
137  strncpy(dest_string, "OTHER: Other", sizeof(dest_string));
138  else
139  strncpy(dest_string, "ERROR: unrecognized", sizeof(dest_string));
140  cout << " Asset class: " << dest_string << "\n";
141  }
142  if (data.fiasset_class_valid == true)
143  {
144  cout << " FI defined asset class: " << data.fiasset_class << "\n";
145  }
146  if (data.par_value_valid == true)
147  {
148  cout << " Par value: " << data.par_value << "\n";
149  }
150  if (data.debt_type_valid == true)
151  {
152  if (data.debt_type == OfxSecurityData::OFX_DEBT_TYPE_COUPON)
153  strncpy(dest_string, "COUPON: Coupon debt", sizeof(dest_string));
154  else if (data.debt_type == OfxSecurityData::OFX_DEBT_TYPE_ZERO)
155  strncpy(dest_string, "ZERO: Zero coupon debt", sizeof(dest_string));
156  else
157  strncpy(dest_string, "ERROR: unrecognized", sizeof(dest_string));
158  cout << " Debt type: " << dest_string << "\n";
159  }
160  if (data.debt_class_valid == true)
161  {
162  if (data.debt_class == OfxSecurityData::OFX_DEBTCLASS_TREASURY)
163  strncpy(dest_string, "TREASURY: Treasury debt", sizeof(dest_string));
164  else if (data.debt_class == OfxSecurityData::OFX_DEBTCLASS_MUNICIPAL)
165  strncpy(dest_string, "MUNICIPAL: Municipal debt", sizeof(dest_string));
166  else if (data.debt_class == OfxSecurityData::OFX_DEBTCLASS_CORPORATE)
167  strncpy(dest_string, "CORPORATE: Corporate debt", sizeof(dest_string));
168  else if (data.debt_class == OfxSecurityData::OFX_DEBTCLASS_OTHER)
169  strncpy(dest_string, "OTHER: Other debt class", sizeof(dest_string));
170  else
171  strncpy(dest_string, "ERROR: unrecognized", sizeof(dest_string));
172  cout << " Debt class: " << dest_string << "\n";
173  }
174  if (data.coupon_rate_valid == true)
175  {
176  cout << " Coupon rate: " << data.coupon_rate << "%\n";
177  }
178  if (data.date_coupon_valid == true)
179  {
180  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.date_coupon)));
181  cout << " Date for the next coupon: " << dest_string << "\n";
182  }
183  if (data.coupon_freq_valid == true)
184  {
185  if (data.coupon_freq == OfxSecurityData::OFX_COUPON_FREQ_MONTHLY)
186  strncpy(dest_string, "MONTHLY: Monthly coupon", sizeof(dest_string));
187  else if (data.coupon_freq == OfxSecurityData::OFX_COUPON_FREQ_QUARTERLY)
188  strncpy(dest_string, "QUARTERLY: Quarterly coupon", sizeof(dest_string));
189  else if (data.coupon_freq == OfxSecurityData::OFX_COUPON_FREQ_SEMIANNUAL)
190  strncpy(dest_string, "SEMIANNUAL: Semiannual coupon", sizeof(dest_string));
191  else if (data.coupon_freq == OfxSecurityData::OFX_COUPON_FREQ_ANNUAL)
192  strncpy(dest_string, "ANNUAL: Annual coupon", sizeof(dest_string));
193  else if (data.coupon_freq == OfxSecurityData::OFX_COUPON_FREQ_OTHER)
194  strncpy(dest_string, "OTHER: Other frequency", sizeof(dest_string));
195  else
196  strncpy(dest_string, "ERROR: unrecognized", sizeof(dest_string));
197  cout << " Coupon frequency: " << dest_string << "\n";
198  }
199  if (data.call_price_valid == true)
200  {
201  cout << " Call price (unit price): " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.call_price << "\n";
202  }
203  if (data.yield_to_call_valid == true)
204  {
205  cout << " Yield to next call (rate): " << data.yield_to_call << "%\n";
206  }
207  if (data.call_date_valid == true)
208  {
209  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.call_date)));
210  cout << " Date for the next call: " << dest_string << "\n";
211  }
212  if (data.call_type_valid == true)
213  {
214  if (data.call_type == OfxSecurityData::OFX_CALL_TYPE_CALL)
215  strncpy(dest_string, "CALL: Call", sizeof(dest_string));
216  else if (data.call_type == OfxSecurityData::OFX_CALL_TYPE_PUT)
217  strncpy(dest_string, "PUT: Put", sizeof(dest_string));
218  else if (data.call_type == OfxSecurityData::OFX_CALL_TYPE_PREFUND)
219  strncpy(dest_string, "PREFUND: Prefund", sizeof(dest_string));
220  else if (data.call_type == OfxSecurityData::OFX_CALL_TYPE_MATURITY)
221  strncpy(dest_string, "MATURITY: Maturity", sizeof(dest_string));
222  else
223  strncpy(dest_string, "ERROR: unrecognized", sizeof(dest_string));
224  cout << " Call type: " << dest_string << "\n";
225  }
226  if (data.yield_to_maturity_valid == true)
227  {
228  cout << " Yield to maturity (rate): " << data.yield_to_maturity << "%\n";
229  }
230  if (data.maturity_date_valid == true)
231  {
232  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.maturity_date)));
233  cout << " Maturity date: " << dest_string << "\n";
234  }
235  if (data.mutual_fund_type_valid == true)
236  {
237  if (data.mutual_fund_type == OfxSecurityData::OFX_MFTYPE_OPENEND)
238  strncpy(dest_string, "OPENEND: Open ended", sizeof(dest_string));
239  else if (data.mutual_fund_type == OfxSecurityData::OFX_MFTYPE_CLOSEEND)
240  strncpy(dest_string, "CLOSEEND: Closed ended", sizeof(dest_string));
241  else if (data.mutual_fund_type == OfxSecurityData::OFX_MFTYPE_OTHER)
242  strncpy(dest_string, "OTHER: Other type", sizeof(dest_string));
243  else
244  strncpy(dest_string, "ERROR: unrecognized", sizeof(dest_string));
245  cout << " Mutual fund type: " << dest_string << "\n";
246  if (data.stock_type_valid == true)
247  {
248  if (data.stock_type == OfxSecurityData::OFX_STOCKTYPE_COMMON)
249  strncpy(dest_string, "COMMON: Common stock", sizeof(dest_string));
250  else if (data.stock_type == OfxSecurityData::OFX_STOCKTYPE_PREFERRED)
251  strncpy(dest_string, "PREFERRED: Preferred stock", sizeof(dest_string));
252  else if (data.stock_type == OfxSecurityData::OFX_STOCKTYPE_CONVERTIBLE)
253  strncpy(dest_string, "CONVERTIBLE: Convertable stock", sizeof(dest_string));
254  else if (data.stock_type == OfxSecurityData::OFX_STOCKTYPE_OTHER)
255  strncpy(dest_string, "OTHER: Other type", sizeof(dest_string));
256  else
257  strncpy(dest_string, "ERROR: unrecognized", sizeof(dest_string));
258  cout << " Stock type: " << dest_string << "\n";
259  }
260  }
261  if (data.yield_valid == true)
262  {
263  cout << " Current yield (rate): " << data.yield << "%\n";
264  }
265  if (data.yield_asof_date_valid == true)
266  {
267  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.yield_asof_date)));
268  cout << " Date for which current yield is valid: " << dest_string << "\n";
269  }
270  if (data.option_type_valid == true)
271  {
272  if (data.option_type == OfxSecurityData::OFX_OPTION_TYPE_CALL)
273  strncpy(dest_string, "CALL: Call option", sizeof(dest_string));
274  else if (data.option_type == OfxSecurityData::OFX_OPTION_TYPE_PUT)
275  strncpy(dest_string, "PUT: Put option", sizeof(dest_string));
276  else
277  strncpy(dest_string, "ERROR: unrecognized", sizeof(dest_string));
278  cout << " Option type: " << dest_string << "\n";
279  }
280  if (data.strike_price_valid == true)
281  {
282  cout << " Strike price: " << data.strike_price << "\n";
283  }
284  if (data.date_expire_valid == true)
285  {
286  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.date_expire)));
287  cout << " Expiration date: " << dest_string << "\n";
288  }
289  if (data.shares_per_cont_valid == true)
290  {
291  cout << " Shares per contract: " << data.shares_per_cont << "\n";
292  }
293  cout << "\n";
294  return 0;
295 }
296 
297 int ofx_proc_transaction_cb(struct OfxTransactionData data, void * transaction_data)
298 {
299  char dest_string[255];
300  cout << "ofx_proc_transaction():\n";
301 
302  if (data.account_id_valid == true)
303  {
304  cout << " Account ID : " << data.account_id << "\n";
305  }
306 
307  if (data.transactiontype_valid == true)
308  {
309  if (data.transactiontype == OFX_CREDIT)
310  strncpy(dest_string, "CREDIT: Generic credit", sizeof(dest_string));
311  else if (data.transactiontype == OFX_DEBIT)
312  strncpy(dest_string, "DEBIT: Generic debit", sizeof(dest_string));
313  else if (data.transactiontype == OFX_INT)
314  strncpy(dest_string, "INT: Interest earned or paid (Note: Depends on signage of amount)", sizeof(dest_string));
315  else if (data.transactiontype == OFX_DIV)
316  strncpy(dest_string, "DIV: Dividend", sizeof(dest_string));
317  else if (data.transactiontype == OFX_FEE)
318  strncpy(dest_string, "FEE: FI fee", sizeof(dest_string));
319  else if (data.transactiontype == OFX_SRVCHG)
320  strncpy(dest_string, "SRVCHG: Service charge", sizeof(dest_string));
321  else if (data.transactiontype == OFX_DEP)
322  strncpy(dest_string, "DEP: Deposit", sizeof(dest_string));
323  else if (data.transactiontype == OFX_ATM)
324  strncpy(dest_string, "ATM: ATM debit or credit (Note: Depends on signage of amount)", sizeof(dest_string));
325  else if (data.transactiontype == OFX_POS)
326  strncpy(dest_string, "POS: Point of sale debit or credit (Note: Depends on signage of amount)", sizeof(dest_string));
327  else if (data.transactiontype == OFX_XFER)
328  strncpy(dest_string, "XFER: Transfer", sizeof(dest_string));
329  else if (data.transactiontype == OFX_CHECK)
330  strncpy(dest_string, "CHECK: Check", sizeof(dest_string));
331  else if (data.transactiontype == OFX_PAYMENT)
332  strncpy(dest_string, "PAYMENT: Electronic payment", sizeof(dest_string));
333  else if (data.transactiontype == OFX_CASH)
334  strncpy(dest_string, "CASH: Cash withdrawal", sizeof(dest_string));
335  else if (data.transactiontype == OFX_DIRECTDEP)
336  strncpy(dest_string, "DIRECTDEP: Direct deposit", sizeof(dest_string));
337  else if (data.transactiontype == OFX_DIRECTDEBIT)
338  strncpy(dest_string, "DIRECTDEBIT: Merchant initiated debit", sizeof(dest_string));
339  else if (data.transactiontype == OFX_REPEATPMT)
340  strncpy(dest_string, "REPEATPMT: Repeating payment/standing order", sizeof(dest_string));
341  else if (data.transactiontype == OFX_OTHER)
342  strncpy(dest_string, "OTHER: Other", sizeof(dest_string));
343  else
344  strncpy(dest_string, "Unknown transaction type", sizeof(dest_string));
345  cout << " Transaction type: " << dest_string << "\n";
346  }
347 
348 
349  if (data.date_initiated_valid == true)
350  {
351  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.date_initiated)));
352  cout << " Date initiated: " << dest_string << "\n";
353  }
354  if (data.date_posted_valid == true)
355  {
356  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.date_posted)));
357  cout << " Date posted: " << dest_string << "\n";
358  }
359  if (data.date_funds_available_valid == true)
360  {
361  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.date_funds_available)));
362  cout << " Date funds are available: " << dest_string << "\n";
363  }
364  if (data.amount_valid == true)
365  {
366  cout << " Total money amount: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.amount << "\n";
367  }
368  if (data.units_valid == true)
369  {
370  if (data.invtransactiontype_valid)
371  {
372  cout << " # of units: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(4) << data.units;
373  strncpy(dest_string, " (bonds: face value; options: contracts; all others: shares)", sizeof(dest_string));
374  if (data.security_data_valid == true)
375  {
376  if (data.security_data_ptr->security_type_valid == true)
377  {
378  if (data.security_data_ptr->security_type == OfxSecurityData::OFX_DEBT_SECURITY)
379  strncpy(dest_string, " (face value)", sizeof(dest_string));
380  else if (data.security_data_ptr->security_type == OfxSecurityData::OFX_FUND_SECURITY ||
381  data.security_data_ptr->security_type == OfxSecurityData::OFX_STOCK_SECURITY ||
382  data.security_data_ptr->security_type == OfxSecurityData::OFX_OTHER_SECURITY)
383  strncpy(dest_string, " (shares)", sizeof(dest_string));
384  else if (data.security_data_ptr->security_type == OfxSecurityData::OFX_OPTION_SECURITY)
385  strncpy(dest_string, " (contracts)", sizeof(dest_string));
386  }
387  }
388  cout << dest_string;
389  }
390  else
391  cout << " # of units: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.units;
392  cout << "\n";
393  }
394  if (data.oldunits_valid == true)
395  {
396  if (data.invtransactiontype_valid)
397  cout << " # of units before split: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(4) << data.oldunits << "\n";
398  else
399  cout << " # of units before split: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.oldunits << "\n";
400  }
401  if (data.newunits_valid == true)
402  {
403  cout << " # of units after split: " << setprecision(4) << data.newunits << "\n";
404  }
405  if (data.unitprice_valid == true)
406  {
407  if (data.invtransactiontype_valid)
408  {
409  cout << " Unit price: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(4) << data.unitprice;
410  strncpy(dest_string, " (bonds: % of par; options: premium per share of underlying; all others: price per share)\n", sizeof(dest_string));
411  if (data.security_data_valid == true)
412  {
413  if (data.security_data_ptr->security_type_valid == true)
414  {
415  if (data.security_data_ptr->security_type == OfxSecurityData::OFX_DEBT_SECURITY)
416  {
417  strncpy(dest_string, "% (% of par)\n", sizeof(dest_string));
418  }
419  else if (data.security_data_ptr->security_type == OfxSecurityData::OFX_FUND_SECURITY ||
420  data.security_data_ptr->security_type == OfxSecurityData::OFX_STOCK_SECURITY ||
421  data.security_data_ptr->security_type == OfxSecurityData::OFX_OTHER_SECURITY)
422  strncpy(dest_string, " (price per share)\n", sizeof(dest_string));
423  else if (data.security_data_ptr->security_type == OfxSecurityData::OFX_OPTION_SECURITY)
424  strncpy(dest_string, " (premium per share of underlying)\n", sizeof(dest_string));
425  }
426  }
427  cout << dest_string;
428  }
429  else
430  cout << " Unit price: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.unitprice << "\n";
431  }
432  if (data.fees_valid == true)
433  {
434  cout << " Fees: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.fees << "\n";
435  }
436  if (data.commission_valid == true)
437  {
438  cout << " Commission: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.commission << "\n";
439  }
440  if (data.amounts_are_foreign_currency_valid == true)
441  {
442  cout << " Amounts are in foreign currency: " << (data.amounts_are_foreign_currency ? "Yes" : "No") << "\n";
443  }
444  if (data.currency_valid == true)
445  {
446  cout << " Currency: " << data.currency << "\n";
447  }
448  if (data.currency_ratio_valid == true)
449  {
450  cout << " Ratio of default currency to currency: " << data.currency_ratio << "\n";
451  }
452  if (data.fi_id_valid == true)
453  {
454  cout << " Financial institution's ID for this transaction: " << data.fi_id << "\n";
455  }
456  if (data.fi_id_corrected_valid == true)
457  {
458  cout << " Financial institution ID replaced or corrected by this transaction: " << data.fi_id_corrected << "\n";
459  }
460  if (data.fi_id_correction_action_valid == true)
461  {
462  cout << " Action to take on the corrected transaction: ";
463  if (data.fi_id_correction_action == DELETE)
464  cout << "DELETE\n";
465  else if (data.fi_id_correction_action == REPLACE)
466  cout << "REPLACE\n";
467  else
468  cout << "ofx_proc_transaction(): This should not happen!\n";
469  }
470  if (data.invtransactiontype_valid == true)
471  {
472  cout << " Investment transaction type: ";
473  if (data.invtransactiontype == OFX_BUYDEBT)
474  strncpy(dest_string, "BUYDEBT (Buy debt security)", sizeof(dest_string));
475  else if (data.invtransactiontype == OFX_BUYMF)
476  strncpy(dest_string, "BUYMF (Buy mutual fund)", sizeof(dest_string));
477  else if (data.invtransactiontype == OFX_BUYOPT)
478  strncpy(dest_string, "BUYOPT (Buy option)", sizeof(dest_string));
479  else if (data.invtransactiontype == OFX_BUYOTHER)
480  strncpy(dest_string, "BUYOTHER (Buy other security type)", sizeof(dest_string));
481  else if (data.invtransactiontype == OFX_BUYSTOCK)
482  strncpy(dest_string, "BUYSTOCK (Buy stock)", sizeof(dest_string));
483  else if (data.invtransactiontype == OFX_CLOSUREOPT)
484  strncpy(dest_string, "CLOSUREOPT (Close a position for an option)", sizeof(dest_string));
485  else if (data.invtransactiontype == OFX_INCOME)
486  strncpy(dest_string, "INCOME (Investment income is realized as cash into the investment account)", sizeof(dest_string));
487  else if (data.invtransactiontype == OFX_INVEXPENSE)
488  strncpy(dest_string, "INVEXPENSE (Misc investment expense that is associated with a specific security)", sizeof(dest_string));
489  else if (data.invtransactiontype == OFX_JRNLFUND)
490  strncpy(dest_string, "JRNLFUND (Journaling cash holdings between subaccounts within the same investment account)", sizeof(dest_string));
491  else if (data.invtransactiontype == OFX_MARGININTEREST)
492  strncpy(dest_string, "MARGININTEREST (Margin interest expense)", sizeof(dest_string));
493  else if (data.invtransactiontype == OFX_REINVEST)
494  strncpy(dest_string, "REINVEST (Reinvestment of income)", sizeof(dest_string));
495  else if (data.invtransactiontype == OFX_RETOFCAP)
496  strncpy(dest_string, "RETOFCAP (Return of capital)", sizeof(dest_string));
497  else if (data.invtransactiontype == OFX_SELLDEBT)
498  strncpy(dest_string, "SELLDEBT (Sell debt security. Used when debt is sold, called, or reached maturity)", sizeof(dest_string));
499  else if (data.invtransactiontype == OFX_SELLMF)
500  strncpy(dest_string, "SELLMF (Sell mutual fund)", sizeof(dest_string));
501  else if (data.invtransactiontype == OFX_SELLOPT)
502  strncpy(dest_string, "SELLOPT (Sell option)", sizeof(dest_string));
503  else if (data.invtransactiontype == OFX_SELLOTHER)
504  strncpy(dest_string, "SELLOTHER (Sell other type of security)", sizeof(dest_string));
505  else if (data.invtransactiontype == OFX_SELLSTOCK)
506  strncpy(dest_string, "SELLSTOCK (Sell stock)", sizeof(dest_string));
507  else if (data.invtransactiontype == OFX_SPLIT)
508  strncpy(dest_string, "SPLIT (Stock or mutial fund split)", sizeof(dest_string));
509  else if (data.invtransactiontype == OFX_TRANSFER)
510  strncpy(dest_string, "TRANSFER (Transfer holdings in and out of the investment account)", sizeof(dest_string));
511  else if (data.invtransactiontype == OFX_INVBANKTRAN)
512  strncpy(dest_string, "INVBANKTRAN (Transfer cash in and out of the investment account)", sizeof(dest_string));
513  else
514  strncpy(dest_string, "ERROR, this investment transaction type is unknown. This is a bug in ofxdump", sizeof(dest_string));
515 
516  cout << dest_string << "\n";
517  }
518  if (data.unique_id_valid == true)
519  {
520  cout << " Unique ID of the security being traded: " << data.unique_id << "\n";
521  }
522  if (data.unique_id_type_valid == true)
523  {
524  cout << " Format of the Unique ID: " << data.unique_id_type << "\n";
525  }
526  if (data.server_transaction_id_valid == true)
527  {
528  cout << " Server's transaction ID (confirmation number): " << data.server_transaction_id << "\n";
529  }
530  if (data.check_number_valid == true)
531  {
532  cout << " Check number: " << data.check_number << "\n";
533  }
534  if (data.reference_number_valid == true)
535  {
536  cout << " Reference number: " << data.reference_number << "\n";
537  }
538  if (data.standard_industrial_code_valid == true)
539  {
540  cout << " Standard Industrial Code: " << data.standard_industrial_code << "\n";
541  }
542  if (data.payee_id_valid == true)
543  {
544  cout << " Payee_id: " << data.payee_id << "\n";
545  }
546  if (data.name_valid == true)
547  {
548  cout << " Name of payee or transaction description: " << data.name << "\n";
549  }
550  if (data.memo_valid == true)
551  {
552  cout << " Extra transaction information (memo): " << data.memo << "\n";
553  }
554  if (data.accrued_interest_valid == true)
555  {
556  cout << " Accrued Interest: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.accrued_interest << "\n";
557  }
558  if (data.avg_cost_basis_valid == true)
559  {
560  cout << " Average cost basis: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.avg_cost_basis << "\n";
561  }
562  if (data.buy_type_valid == true)
563  {
564  if (data.buy_type == OfxTransactionData::OFX_BUY_TYPE_BUY)
565  strncpy(dest_string, "BUY: Buy", sizeof(dest_string));
566  else if (data.buy_type == OfxTransactionData::OFX_BUY_TYPE_BUYTOCOVER)
567  strncpy(dest_string, "BUYTOCOVER: Buy to cover", sizeof(dest_string));
568  else if (data.buy_type == OfxTransactionData::OFX_BUY_TYPE_BUYTOOPEN)
569  strncpy(dest_string, "BUYTOOPEN: Buy to open", sizeof(dest_string));
570  else if (data.buy_type == OfxTransactionData::OFX_BUY_TYPE_BUYTOCLOSE)
571  strncpy(dest_string, "BUYTOCLOSE: Buy to close", sizeof(dest_string));
572  else
573  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
574  cout << " Buy type: " << dest_string << "\n";
575  }
576  if (data.denominator_valid == true)
577  {
578  cout << " Stock split ratio denominator: " << data.denominator << "\n";
579  }
580  if (data.date_payroll_valid == true)
581  {
582  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.date_payroll)));
583  cout << " Date 401(k) funds were deducted from payroll: " << dest_string << "\n";
584  }
585  if (data.date_purchase_valid == true)
586  {
587  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.date_purchase)));
588  cout << " Original purchase date of the security: " << dest_string << "\n";
589  }
590  if (data.gain_valid == true)
591  {
592  cout << " Average cost basis: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.gain << "\n";
593  }
594  if (data.cash_for_fractional_valid == true)
595  {
596  cout << " Average cost basis: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.cash_for_fractional << "\n";
597  }
598  if (data.income_type_valid == true)
599  {
600  if (data.income_type == OfxTransactionData::OFX_CGLONG)
601  strncpy(dest_string, "CGLONG: Long term capital gains", sizeof(dest_string));
602  else if (data.income_type == OfxTransactionData::OFX_CGSHORT)
603  strncpy(dest_string, "CGSHORT: Short term capital gains", sizeof(dest_string));
604  else if (data.income_type == OfxTransactionData::OFX_DIVIDEND)
605  strncpy(dest_string, "DIVIDEND", sizeof(dest_string));
606  else if (data.income_type == OfxTransactionData::OFX_INTEREST)
607  strncpy(dest_string, "INTEREST", sizeof(dest_string));
608  else if (data.income_type == OfxTransactionData::OFX_MISC)
609  strncpy(dest_string, "MISC: Miscellaneous", sizeof(dest_string));
610  else
611  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
612  cout << " Income type: " << dest_string << "\n";
613  }
614  if (data.inv_401k_source_valid == true)
615  {
616  if (data.inv_401k_source == OfxTransactionData::OFX_401K_SOURCE_PRETAX)
617  strncpy(dest_string, "PRETAX", sizeof(dest_string));
618  else if (data.inv_401k_source == OfxTransactionData::OFX_401K_SOURCE_AFTERTAX)
619  strncpy(dest_string, "AFTERTAX", sizeof(dest_string));
620  else if (data.inv_401k_source == OfxTransactionData::OFX_401K_SOURCE_MATCH)
621  strncpy(dest_string, "MATCH", sizeof(dest_string));
622  else if (data.inv_401k_source == OfxTransactionData::OFX_401K_SOURCE_PROFITSHARING)
623  strncpy(dest_string, "PROFITSHARING", sizeof(dest_string));
624  else if (data.inv_401k_source == OfxTransactionData::OFX_401K_SOURCE_ROLLOVER)
625  strncpy(dest_string, "ROLLOVER", sizeof(dest_string));
626  else if (data.inv_401k_source == OfxTransactionData::OFX_401K_SOURCE_OTHERVEST)
627  strncpy(dest_string, "OTHERVEST", sizeof(dest_string));
628  else if (data.inv_401k_source == OfxTransactionData::OFX_401K_SOURCE_OTHERNONVEST)
629  strncpy(dest_string, "OTHERNONVEST", sizeof(dest_string));
630  else
631  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
632  cout << " Source of 401(k) money: " << dest_string << "\n";
633  }
634  if (data.load_valid == true)
635  {
636  cout << " Load (amount): " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.load << "\n";
637  }
638  if (data.loan_id_valid == true)
639  {
640  cout << " 401(k) loan id: " << data.loan_id << "\n";
641  }
642  if (data.loan_interest_valid == true)
643  {
644  cout << " 401(k) loan interest (amount): " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.loan_interest << "\n";
645  }
646  if (data.loan_principal_valid == true)
647  {
648  cout << " 401(k) loan principle (amount): " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.loan_principal << "\n";
649  }
650  if (data.markdown_valid == true)
651  {
652  cout << " Markdown (unitprice): " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.markdown << "\n";
653  }
654  if (data.markup_valid == true)
655  {
656  cout << " Markup (unitprice): " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.markup << "\n";
657  }
658  if (data.numerator_valid == true)
659  {
660  cout << " Stock split ratio numerator: " << data.numerator << "\n";
661  }
662  if (data.opt_action_valid == true)
663  {
664  if (data.opt_action == OfxTransactionData::OFX_OPTACTION_EXERCISE)
665  strncpy(dest_string, "EXERCISE", sizeof(dest_string));
666  else if (data.opt_action == OfxTransactionData::OFX_OPTACTION_ASSIGN)
667  strncpy(dest_string, "ASSIGN", sizeof(dest_string));
668  else if (data.opt_action == OfxTransactionData::OFX_OPTACTION_EXPIRE)
669  strncpy(dest_string, "EXPIRE", sizeof(dest_string));
670  else
671  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
672  cout << " Option action: " << dest_string << "\n";
673  }
674  if (data.penalty_valid == true)
675  {
676  cout << " Penalty withheld (amount): " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.penalty << "\n";
677  }
678  if (data.pos_type_valid == true)
679  {
680  if (data.pos_type == OfxTransactionData::OFX_POSTYPE_LONG)
681  strncpy(dest_string, "LONG", sizeof(dest_string));
682  else if (data.pos_type == OfxTransactionData::OFX_POSTYPE_SHORT)
683  strncpy(dest_string, "SHORT", sizeof(dest_string));
684  else
685  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
686  cout << " Position Type: " << dest_string << "\n";
687  }
688  if (data.prior_year_contrib_valid == true)
689  {
690  cout << " Prior year 401(k) contribution: " << (data.prior_year_contrib ? "Yes" : "No") << "\n";
691  }
692  if (data.related_fi_tid_valid == true)
693  {
694  cout << " Related transaction TID: " << data.related_fi_tid << "\n";
695  }
696  if (data.related_type_valid == true)
697  {
698  if (data.related_type == OfxTransactionData::OFX_RELTYPE_SPREAD)
699  strncpy(dest_string, "SPREAD", sizeof(dest_string));
700  else if (data.related_type == OfxTransactionData::OFX_RELTYPE_STRADDLE)
701  strncpy(dest_string, "STRADDLE", sizeof(dest_string));
702  else if (data.related_type == OfxTransactionData::OFX_RELTYPE_NONE)
703  strncpy(dest_string, "NONE", sizeof(dest_string));
704  else if (data.related_type == OfxTransactionData::OFX_RELTYPE_OTHER)
705  strncpy(dest_string, "OTHER", sizeof(dest_string));
706  else
707  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
708  cout << " Related Option Type: " << dest_string << "\n";
709  }
710  if (data.option_secured_valid == true)
711  {
712  if (data.option_secured == OfxTransactionData::OFX_SECURED_NAKED)
713  strncpy(dest_string, "NAKED", sizeof(dest_string));
714  else if (data.option_secured == OfxTransactionData::OFX_SECURED_COVERED)
715  strncpy(dest_string, "COVERED: Cash covered", sizeof(dest_string));
716  else
717  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
718  cout << " How is the option secured: " << dest_string << "\n";
719  }
720  if (data.sell_reason_valid == true)
721  {
722  if (data.sell_reason == OfxTransactionData::OFX_SELLREASON_CALL)
723  strncpy(dest_string, "CALL: the debt was called", sizeof(dest_string));
724  else if (data.sell_reason == OfxTransactionData::OFX_SELLREASON_SELL)
725  strncpy(dest_string, "SELL: the debt was sold", sizeof(dest_string));
726  else if (data.sell_reason == OfxTransactionData::OFX_SELLREASON_MATURITY)
727  strncpy(dest_string, "MATURITY: the debt reached maturity", sizeof(dest_string));
728  else
729  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
730  cout << " Reason for the debt sell: " << dest_string << "\n";
731  }
732  if (data.sell_type_valid == true)
733  {
734  if (data.sell_type == OfxTransactionData::OFX_SELL_TYPE_SELL)
735  strncpy(dest_string, "SELL: Sell", sizeof(dest_string));
736  else if (data.sell_type == OfxTransactionData::OFX_SELL_TYPE_SELLSHORT)
737  strncpy(dest_string, "SELLSHORT: Sell short", sizeof(dest_string));
738  else if (data.sell_type == OfxTransactionData::OFX_SELL_TYPE_SELLTOOPEN)
739  strncpy(dest_string, "SELLTOOPEN: Sell to open", sizeof(dest_string));
740  else if (data.sell_type == OfxTransactionData::OFX_SELL_TYPE_SELLTOCLOSE)
741  strncpy(dest_string, "SELLTOCLOSE: Sell to close", sizeof(dest_string));
742  else
743  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
744  cout << " Sell type: " << dest_string << "\n";
745  }
746  if (data.shares_per_cont_valid == true)
747  {
748  cout << " Shares per option contract: " << data.shares_per_cont << "\n";
749  }
750  if (data.state_withholding_valid == true)
751  {
752  cout << " State taxes withheld: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.state_withholding << "\n";
753  }
754  if (data.subacct_from_valid == true)
755  {
756  if (data.subacct_from == OfxTransactionData::OFX_SUBACCT_CASH)
757  strncpy(dest_string, "CASH", sizeof(dest_string));
758  else if (data.subacct_from == OfxTransactionData::OFX_SUBACCT_MARGIN)
759  strncpy(dest_string, "MARGIN", sizeof(dest_string));
760  else if (data.subacct_from == OfxTransactionData::OFX_SUBACCT_SHORT)
761  strncpy(dest_string, "SHORT", sizeof(dest_string));
762  else if (data.subacct_from == OfxTransactionData::OFX_SUBACCT_OTHER)
763  strncpy(dest_string, "OTHER", sizeof(dest_string));
764  else
765  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
766  cout << " From sub account type: " << dest_string << "\n";
767  }
768  if (data.subacct_funding_valid == true)
769  {
770  if (data.subacct_funding == OfxTransactionData::OFX_SUBACCT_CASH)
771  strncpy(dest_string, "CASH", sizeof(dest_string));
772  else if (data.subacct_funding == OfxTransactionData::OFX_SUBACCT_MARGIN)
773  strncpy(dest_string, "MARGIN", sizeof(dest_string));
774  else if (data.subacct_funding == OfxTransactionData::OFX_SUBACCT_SHORT)
775  strncpy(dest_string, "SHORT", sizeof(dest_string));
776  else if (data.subacct_funding == OfxTransactionData::OFX_SUBACCT_OTHER)
777  strncpy(dest_string, "OTHER", sizeof(dest_string));
778  else
779  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
780  cout << " Funding sub account type: " << dest_string << "\n";
781  }
782  if (data.subacct_security_valid == true)
783  {
784  if (data.subacct_security == OfxTransactionData::OFX_SUBACCT_CASH)
785  strncpy(dest_string, "CASH", sizeof(dest_string));
786  else if (data.subacct_security == OfxTransactionData::OFX_SUBACCT_MARGIN)
787  strncpy(dest_string, "MARGIN", sizeof(dest_string));
788  else if (data.subacct_security == OfxTransactionData::OFX_SUBACCT_SHORT)
789  strncpy(dest_string, "SHORT", sizeof(dest_string));
790  else if (data.subacct_security == OfxTransactionData::OFX_SUBACCT_OTHER)
791  strncpy(dest_string, "OTHER", sizeof(dest_string));
792  else
793  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
794  cout << " Security sub account type: " << dest_string << "\n";
795  }
796  if (data.subacct_to_valid == true)
797  {
798  if (data.subacct_to == OfxTransactionData::OFX_SUBACCT_CASH)
799  strncpy(dest_string, "CASH", sizeof(dest_string));
800  else if (data.subacct_to == OfxTransactionData::OFX_SUBACCT_MARGIN)
801  strncpy(dest_string, "MARGIN", sizeof(dest_string));
802  else if (data.subacct_to == OfxTransactionData::OFX_SUBACCT_SHORT)
803  strncpy(dest_string, "SHORT", sizeof(dest_string));
804  else if (data.subacct_to == OfxTransactionData::OFX_SUBACCT_OTHER)
805  strncpy(dest_string, "OTHER", sizeof(dest_string));
806  else
807  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
808  cout << " To sub account type: " << dest_string << "\n";
809  }
810  if (data.taxes_valid == true)
811  {
812  cout << " Tax on the trade (amount): " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.taxes << "\n";
813  }
814  if (data.tax_exempt_valid == true)
815  {
816  cout << " Tax exempt: " << (data.tax_exempt ? "Yes" : "No") << "\n";
817  }
818  if (data.transfer_action_valid == true)
819  {
820  if (data.transfer_action == OfxTransactionData::OFX_TFERACTION_IN)
821  strncpy(dest_string, "IN", sizeof(dest_string));
822  else if (data.transfer_action == OfxTransactionData::OFX_TFERACTION_OUT)
823  strncpy(dest_string, "OUT", sizeof(dest_string));
824  else
825  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
826  cout << " Action for the transfer: " << dest_string << "\n";
827  }
828  if (data.unit_type_valid == true)
829  {
830  if (data.unit_type == OfxTransactionData::OFX_UNITTYPE_SHARES)
831  strncpy(dest_string, "SHARES", sizeof(dest_string));
832  else if (data.unit_type == OfxTransactionData::OFX_UNITTYPE_CURRENCY)
833  strncpy(dest_string, "CURRENCY", sizeof(dest_string));
834  else
835  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
836  cout << " Type of the Units value: " << dest_string << "\n";
837  }
838  if (data.withholding_valid == true)
839  {
840  cout << " Federal tax withheld (amount): " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.withholding << "\n";
841  }
842  if (data.security_data_valid == true)
843  {
844  ofx_proc_security_cb(*(data.security_data_ptr), NULL );
845  }
846  cout << "\n";
847  return 0;
848 }//end ofx_proc_transaction()
849 
850 int ofx_proc_position_cb(struct OfxPositionData data, void * position_data)
851 {
852  char dest_string[255];
853  cout << "ofx_proc_position():\n";
854  if (data.account_id_valid == true)
855  {
856  cout << " Account ID: " << data.account_id << "\n";
857  }
858  if (data.unique_id_valid == true)
859  {
860  cout << " Unique ID of the security: " << data.unique_id << "\n";
861  }
862  if (data.unique_id_type_valid == true)
863  {
864  cout << " Format of the Unique ID: " << data.unique_id_type << "\n";
865  }
866  if (data.heldinaccount_type_valid == true)
867  {
868  if (data.heldinaccount_type == OfxPositionData::OFX_HELDINACCT_CASH)
869  strncpy(dest_string, "CASH: Cash subaccount", sizeof(dest_string));
870  else if (data.heldinaccount_type == OfxPositionData::OFX_HELDINACCT_MARGIN)
871  strncpy(dest_string, "MARGIN: Margin subaccount", sizeof(dest_string));
872  else if (data.heldinaccount_type == OfxPositionData::OFX_HELDINACCT_SHORT)
873  strncpy(dest_string, "SHORT: Short subaccount", sizeof(dest_string));
874  else if (data.heldinaccount_type == OfxPositionData::OFX_HELDINACCT_OTHER)
875  strncpy(dest_string, "OTHER: Other subaccount", sizeof(dest_string));
876  else
877  strncpy(dest_string, "ERROR: unrecognized", sizeof(dest_string));
878  cout << " Held in account type: " << dest_string << "\n";
879  }
880  if (data.position_type_valid == true)
881  {
882  if (data.position_type == OfxPositionData::OFX_POSITION_SHORT)
883  strncpy(dest_string, "SHORT: Short (writer for options, short for all others)", sizeof(dest_string));
884  else if (data.position_type == OfxPositionData::OFX_POSITION_LONG)
885  strncpy(dest_string, "LONG: Long (holder for options, long for all others)", sizeof(dest_string));
886  else
887  strncpy(dest_string, "ERROR: unrecognized", sizeof(dest_string));
888  cout << " Position type: " << dest_string << "\n";
889  }
890  if (data.units_valid == true)
891  {
892  cout << " Units: " << setprecision(4) << data.units;
893  strncpy(dest_string, " (bonds: face value; options: contracts; all others: shares)\n", sizeof(dest_string));
894  if (data.security_data_valid == true)
895  {
896  if (data.security_data_ptr->security_type_valid == true)
897  {
898  if (data.security_data_ptr->security_type == OfxSecurityData::OFX_DEBT_SECURITY)
899  strncpy(dest_string, " (face value)\n", sizeof(dest_string));
900  else if (data.security_data_ptr->security_type == OfxSecurityData::OFX_FUND_SECURITY ||
903  strncpy(dest_string, " (shares)\n", sizeof(dest_string));
904  else if (data.security_data_ptr->security_type == OfxSecurityData::OFX_OPTION_SECURITY)
905  strncpy(dest_string, " (contracts)\n", sizeof(dest_string));
906  }
907  }
908  cout << dest_string;
909  }
910  if (data.unit_price_valid == true)
911  {
912  if (data.security_data_valid == true)
913  {
914  cout << " Unit price: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(4) << data.unit_price;
915  strncpy(dest_string, " (bonds: % of par; options: premium per share of underlying; all others: price per share)\n", sizeof(dest_string));
916  if (data.security_data_ptr->security_type_valid == true)
917  {
918  if (data.security_data_ptr->security_type == OfxSecurityData::OFX_DEBT_SECURITY)
919  strncpy(dest_string, "% (% of par)\n", sizeof(dest_string));
920  else if (data.security_data_ptr->security_type == OfxSecurityData::OFX_FUND_SECURITY ||
923  strncpy(dest_string, " (price per share)\n", sizeof(dest_string));
924  else if (data.security_data_ptr->security_type == OfxSecurityData::OFX_OPTION_SECURITY)
925  strncpy(dest_string, " (premium per share of underlying)\n", sizeof(dest_string));
926  }
927  cout << dest_string;
928  }
929  else
930  cout << " Unit price: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.unit_price << "\n";
931  }
932  if (data.market_value_valid == true)
933  {
934  cout << " Market Value: " << data.market_value << "\n";
935  }
936  if (data.amounts_are_foreign_currency_valid == true)
937  {
938  cout << " Amounts are in foreign currency: " << (data.amounts_are_foreign_currency ? "Yes" : "No") << "\n";
939  }
940  if (data.currency_valid == true)
941  {
942  cout << " Currency: " << data.currency << "\n";
943  }
944  if (data.currency_ratio_valid == true)
945  {
946  cout << " Ratio of default currency to currency: " << data.currency_ratio << "\n";
947  }
948  if (data.date_unit_price_valid == true)
949  {
950  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.date_unit_price)));
951  cout << " Date of unit price: " << dest_string << "\n";
952  }
953  if (data.memo_valid == true)
954  {
955  cout << " Extra position information (memo): " << data.memo << "\n";
956  }
957  if (data.inv_401k_source_valid == true)
958  {
959  if (data.inv_401k_source == OfxPositionData::OFX_401K_POSN_SOURCE_PRETAX)
960  strncpy(dest_string, "PRETAX", sizeof(dest_string));
961  else if (data.inv_401k_source == OfxPositionData::OFX_401K_POSN_SOURCE_AFTERTAX)
962  strncpy(dest_string, "AFTERTAX", sizeof(dest_string));
963  else if (data.inv_401k_source == OfxPositionData::OFX_401K_POSN_SOURCE_MATCH)
964  strncpy(dest_string, "MATCH", sizeof(dest_string));
965  else if (data.inv_401k_source == OfxPositionData::OFX_401K_POSN_SOURCE_PROFITSHARING)
966  strncpy(dest_string, "PROFITSHARING", sizeof(dest_string));
967  else if (data.inv_401k_source == OfxPositionData::OFX_401K_POSN_SOURCE_ROLLOVER)
968  strncpy(dest_string, "ROLLOVER", sizeof(dest_string));
969  else if (data.inv_401k_source == OfxPositionData::OFX_401K_POSN_SOURCE_OTHERVEST)
970  strncpy(dest_string, "OTHERVEST", sizeof(dest_string));
971  else if (data.inv_401k_source == OfxPositionData::OFX_401K_POSN_SOURCE_OTHERNONVEST)
972  strncpy(dest_string, "OTHERNONVEST", sizeof(dest_string));
973  else
974  strncpy(dest_string,"ERROR: unrecognized", sizeof(dest_string));
975  cout << " Source of 401(k) money: " << dest_string << "\n";
976  }
977  if (data.security_data_valid == true)
978  {
979  ofx_proc_security_cb(*(data.security_data_ptr), NULL );
980  }
981  cout << "\n";
982  return 0;
983 }// end of ofx_proc_position()
984 
985 int ofx_proc_statement_cb(struct OfxStatementData data, void * statement_data)
986 {
987  char dest_string[255];
988  cout << "ofx_proc_statement():\n";
989  if (data.currency_valid == true)
990  {
991  cout << " Default Currency: " << data.currency << "\n";
992  }
993  if (data.account_id_valid == true)
994  {
995  cout << " Account ID: " << data.account_id << "\n";
996  }
997  if (data.date_asof_valid == true)
998  {
999  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.date_asof)));
1000  cout << " Statement as-of date: " << dest_string << "\n";
1001  }
1002  if (data.date_start_valid == true)
1003  {
1004  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.date_start)));
1005  cout << " Start date of this statement: " << dest_string << "\n";
1006  }
1007  if (data.date_end_valid == true)
1008  {
1009  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.date_end)));
1010  cout << " End date of this statement: " << dest_string << "\n";
1011  }
1012  if (data.ledger_balance_valid == true)
1013  {
1014  cout << " Ledger balance: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.ledger_balance << "\n";
1015  }
1016  if (data.ledger_balance_date_valid == true)
1017  {
1018  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.ledger_balance_date)));
1019  cout << " Ledger balance date: " << dest_string << "\n";
1020  }
1021  if (data.available_balance_valid == true)
1022  {
1023  cout << " Available balance: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.available_balance << "\n";
1024  }
1025  if (data.available_balance_date_valid == true)
1026  {
1027  strftime(dest_string, sizeof(dest_string), "%c %Z", localtime(&(data.available_balance_date)));
1028  cout << " Available balance date: " << dest_string << "\n";
1029  }
1030  if (data.margin_balance_valid == true)
1031  {
1032  cout << " Margin balance: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.margin_balance << "\n";
1033  }
1034  if (data.short_balance_valid == true)
1035  {
1036  cout << " Short balance: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.short_balance << "\n";
1037  }
1038  if (data.buying_power_valid == true)
1039  {
1040  cout << " Buying power: " << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << data.buying_power << "\n";
1041  }
1042  if (data.marketing_info_valid == true)
1043  {
1044  cout << " Marketing information: " << data.marketing_info << "\n";
1045  }
1046  cout << "\n";
1047  return 0;
1048 }//end ofx_proc_statement()
1049 
1050 int ofx_proc_account_cb(struct OfxAccountData data, void * account_data)
1051 {
1052  cout << "ofx_proc_account():\n";
1053  if (data.account_id_valid == true)
1054  {
1055  cout << " Account ID: " << data.account_id << "\n";
1056  cout << " Account name: " << data.account_name << "\n";
1057  }
1058  if (data.account_type_valid == true)
1059  {
1060  cout << " Account type: ";
1061  switch (data.account_type)
1062  {
1064  cout << "CHECKING\n";
1065  break;
1067  cout << "SAVINGS\n";
1068  break;
1070  cout << "MONEYMRKT\n";
1071  break;
1073  cout << "CREDITLINE\n";
1074  break;
1076  cout << "CMA\n";
1077  break;
1079  cout << "CREDITCARD\n";
1080  break;
1082  cout << "INVESTMENT\n";
1083  break;
1084  default:
1085  cout << "ofx_proc_account() WRITEME: This is an unknown account type!";
1086  }
1087  }
1088  if (data.currency_valid == true)
1089  {
1090  cout << " Default Currency: " << data.currency << "\n";
1091  }
1092 
1093  if (data.bank_id_valid)
1094  cout << " Bank ID: " << data.bank_id << endl;;
1095 
1096  if (data.branch_id_valid)
1097  cout << " Branch ID: " << data.branch_id << endl;
1098 
1099  if (data.account_number_valid)
1100  cout << " Account #: " << data.account_number << endl;
1101 
1102  cout << "\n";
1103  return 0;
1104 }//end ofx_proc_account()
1105 
1106 
1107 
1108 int ofx_proc_status_cb(struct OfxStatusData data, void * status_data)
1109 {
1110  cout << "ofx_proc_status():\n";
1111  if (data.ofx_element_name_valid == true)
1112  {
1113  cout << " Ofx entity this status is relevant to: " << data.ofx_element_name << " \n";
1114  }
1115  if (data.severity_valid == true)
1116  {
1117  cout << " Severity: ";
1118  switch (data.severity)
1119  {
1120  case OfxStatusData::INFO :
1121  cout << "INFO\n";
1122  break;
1123  case OfxStatusData::WARN :
1124  cout << "WARN\n";
1125  break;
1126  case OfxStatusData::ERROR :
1127  cout << "ERROR\n";
1128  break;
1129  default:
1130  cout << "WRITEME: Unknown status severity!\n";
1131  }
1132  }
1133  if (data.code_valid == true)
1134  {
1135  cout << " Code: " << data.code << ", name: " << data.name << "\n Description: " << data.description << "\n";
1136  }
1137  if (data.server_message_valid == true)
1138  {
1139  cout << " Server Message: " << data.server_message << "\n";
1140  }
1141  cout << "\n";
1142  return 0;
1143 }
1144 
1145 
1146 int main (int argc, char *argv[])
1147 {
1148  gengetopt_args_info args_info;
1149 
1150  /* let's call our cmdline parser */
1151  if (cmdline_parser (argc, argv, &args_info) != 0)
1152  exit(1) ;
1153 
1154  // if (args_info.msg_parser_given)
1155  // cout << "The msg_parser option was given!" << endl;
1156 
1157  // cout << "The flag is " << ( args_info.msg_parser_flag ? "on" : "off" ) <<
1158  // "." << endl ;
1159 
1160  ofx_PARSER_msg = bool(args_info.msg_parser_flag);
1161  ofx_DEBUG_msg = bool(args_info.msg_debug_flag);
1162  ofx_WARNING_msg = bool(args_info.msg_warning_flag);
1163  ofx_ERROR_msg = bool (args_info.msg_error_flag);
1164  ofx_INFO_msg = bool(args_info.msg_info_flag);
1165  ofx_STATUS_msg = bool(args_info.msg_status_flag);
1166 
1167  bool skiphelp = false;
1168 
1169  if (args_info.list_import_formats_given)
1170  {
1171  skiphelp = true;
1172  cout << "The supported file formats for the 'input-file-format' argument are:" << endl;
1173  for (int i = 0; LibofxImportFormatList[i].format != LAST; i++)
1174  {
1175  cout << " " << LibofxImportFormatList[i].description << endl;
1176  }
1177  }
1178 
1179  LibofxContextPtr libofx_context = libofx_get_new_context();
1180 
1181  //char **inputs ; /* unamed options */
1182  //unsigned inputs_num ; /* unamed options number */
1183  if (args_info.inputs_num > 0)
1184  {
1185  //const char* filename = args_info.inputs[0];
1186 
1187  ofx_set_statement_cb(libofx_context, ofx_proc_statement_cb, 0);
1188  ofx_set_account_cb(libofx_context, ofx_proc_account_cb, 0);
1189  ofx_set_transaction_cb(libofx_context, ofx_proc_transaction_cb, 0);
1190  ofx_set_security_cb(libofx_context, ofx_proc_security_cb, 0);
1191  ofx_set_status_cb(libofx_context, ofx_proc_status_cb, 0);
1192  ofx_set_position_cb(libofx_context, ofx_proc_position_cb, 0);
1193 
1194  enum LibofxFileFormat file_format = libofx_get_file_format_from_str(LibofxImportFormatList, args_info.import_format_arg);
1196  if (args_info.inputs_num > 1)
1197  {
1198  cout << "Sorry, currently, only the first file is processed as the library can't deal with more right now. The following files were ignored:" << endl;
1199  for ( unsigned i = 1 ; i < args_info.inputs_num ; ++i )
1200  {
1201  cout << "file: " << args_info.inputs[i] << endl ;
1202  }
1203  }
1204  // FIXME: failure is ignored!
1205  libofx_proc_file(libofx_context, args_info.inputs[0], file_format);
1206  }
1207  else
1208  {
1209  if ( !skiphelp )
1210  cmdline_parser_print_help();
1211  }
1212  return 0;
1213 }
char fiasset_class[OFX_FIASSET_CLASS_LENGTH]
Definition: inc/libofx.h:449
time_t ledger_balance_date
Definition: inc/libofx.h:1083
int msg_info_flag
Output informational messages about the progress of the library (default=on).
An abstraction of an account.
Definition: inc/libofx.h:276
enum LibofxFileFormat libofx_get_file_format_from_str(const struct LibofxFileFormatInfo format_list[], const char *file_type_string)
libofx_get_file_type returns a proper enum from a file type string.
char currency[OFX_CURRENCY_LENGTH]
Definition: inc/libofx.h:1244
char unique_id_type[OFX_UNIQUE_ID_TYPE_LENGTH]
Definition: inc/libofx.h:1181
double shares_per_cont
Definition: inc/libofx.h:986
int msg_warning_flag
Output warning messages about abnormal conditions and unknown constructs (default=on).
char * import_format_arg
Force the file format of the file(s) specified (default=&#39;AUTODETECT&#39;).
Where the command line options are stored.
enum LibofxFileFormat format
Definition: inc/libofx.h:138
char reference_number[OFX_REFERENCE_NUMBER_LENGTH]
Definition: inc/libofx.h:791
void ofx_set_position_cb(LibofxContextPtr ctx, LibofxProcPositionCallback cb, void *user_data)
double available_balance
Definition: inc/libofx.h:1095
int amounts_are_foreign_currency
Definition: inc/libofx.h:1254
time_t date_coupon
Definition: inc/libofx.h:521
char unique_id[OFX_UNIQUE_ID_LENGTH]
Definition: inc/libofx.h:738
An abstraction of a security position held in an account.
Definition: inc/libofx.h:1161
char account_id[OFX_ACCOUNT_ID_LENGTH]
Definition: inc/libofx.h:290
char account_id[OFX_ACCOUNT_ID_LENGTH]
Definition: inc/libofx.h:1164
const char * description
Definition: inc/libofx.h:140
time_t call_date
Definition: inc/libofx.h:544
const char * description
Definition: inc/libofx.h:230
char unique_id2[OFX_UNIQUE_ID_LENGTH]
Definition: inc/libofx.h:597
char currency[OFX_CURRENCY_LENGTH]
Definition: inc/libofx.h:316
char check_number[OFX_CHECK_NUMBER_LENGTH]
Definition: inc/libofx.h:786
char name[OFX_TRANSACTION_NAME_LENGTH]
Definition: inc/libofx.h:801
double call_price
Definition: inc/libofx.h:536
char marketing_info[OFX_MARKETING_INFO_LENGTH]
Definition: inc/libofx.h:1131
char memo[OFX_MEMO2_LENGTH]
Definition: inc/libofx.h:805
FiIdCorrectionAction fi_id_correction_action
Definition: inc/libofx.h:775
int msg_debug_flag
Output messages meant for debugging (default=off).
unsigned int list_import_formats_given
Whether list-import-formats was given.
char currency[OFX_CURRENCY_LENGTH]
Definition: inc/libofx.h:409
time_t maturity_date
Definition: inc/libofx.h:562
time_t date_unit_price
Definition: inc/libofx.h:1217
double currency_ratio
Definition: inc/libofx.h:413
LibofxContextPtr libofx_get_new_context()
Initialise the library and return a new context.
double strike_price
Definition: inc/libofx.h:579
int amounts_are_foreign_currency
Definition: inc/libofx.h:835
long int standard_industrial_code
Definition: inc/libofx.h:794
char account_id[OFX_ACCOUNT_ID_LENGTH]
Definition: inc/libofx.h:1072
double short_balance
Definition: inc/libofx.h:1108
char memo[OFX_MEMO2_LENGTH]
Definition: inc/libofx.h:422
void ofx_set_statement_cb(LibofxContextPtr ctx, LibofxProcStatementCallback cb, void *user_data)
struct OfxSecurityData * security_data_ptr
Definition: inc/libofx.h:1258
char unique_id[OFX_UNIQUE_ID_LENGTH]
Definition: inc/libofx.h:1179
void ofx_set_status_cb(LibofxContextPtr ctx, LibofxProcStatusCallback cb, void *user_data)
double cash_for_fractional
Definition: inc/libofx.h:871
void ofx_set_account_cb(LibofxContextPtr ctx, LibofxProcAccountCallback cb, void *user_data)
char account_id[OFX_ACCOUNT_ID_LENGTH]
Definition: inc/libofx.h:690
char unique_id[OFX_UNIQUE_ID_LENGTH]
Definition: inc/libofx.h:379
char rating[OFX_SECURITY_RATING_LENGTH]
Definition: inc/libofx.h:401
char fi_id[OFX_FITID_LENGTH]
Definition: inc/libofx.h:726
char memo[OFX_MEMO_LENGTH]
Definition: inc/libofx.h:1227
char account_name[OFX_ACCOUNT_NAME_LENGTH]
Definition: inc/libofx.h:297
time_t available_balance_date
Definition: inc/libofx.h:1100
char * server_message
Definition: inc/libofx.h:247
time_t date_unitprice
Definition: inc/libofx.h:404
time_t date_expire
Definition: inc/libofx.h:583
char server_transaction_id[OFX_SVRTID2_LENGTH]
Definition: inc/libofx.h:780
double shares_per_cont
Definition: inc/libofx.h:587
char bank_id[OFX_BANKID_LENGTH]
Definition: inc/libofx.h:324
char related_fi_tid[OFX_FITID_LENGTH]
Definition: inc/libofx.h:944
int msg_error_flag
Output error messages (default=on).
double state_withholding
Definition: inc/libofx.h:990
An abstraction of an OFX STATUS element.
Definition: inc/libofx.h:214
time_t yield_asof_date
Definition: inc/libofx.h:481
void ofx_set_security_cb(LibofxContextPtr ctx, LibofxProcSecurityCallback cb, void *user_data)
int amounts_are_foreign_currency
Definition: inc/libofx.h:419
double unitprice
Definition: inc/libofx.h:397
double accrued_interest
Definition: inc/libofx.h:842
unsigned inputs_num
unamed options number
char unique_id_type[OFX_UNIQUE_ID_TYPE_LENGTH]
Definition: inc/libofx.h:382
char unique_id2_type[OFX_UNIQUE_ID_TYPE_LENGTH]
Definition: inc/libofx.h:602
int msg_status_flag
Output status messages (default=on).
double market_value
Definition: inc/libofx.h:1213
double yield_to_maturity
Definition: inc/libofx.h:558
double currency_ratio
Definition: inc/libofx.h:1248
int msg_parser_flag
Output file parsing messages (default=off).
double margin_balance
Definition: inc/libofx.h:1104
char ticker[OFX_TICKER_LENGTH]
Definition: inc/libofx.h:394
char payee_id[OFX_SVRTID2_LENGTH]
Definition: inc/libofx.h:798
An abstraction of a security, such as a stock, mutual fund, etc.
Definition: inc/libofx.h:358
int ofx_element_name_valid
Definition: inc/libofx.h:222
void ofx_set_transaction_cb(LibofxContextPtr ctx, LibofxProcTransactionCallback cb, void *user_data)
int main(int argc, char *argv[])
Definition: ofxdump.cpp:1146
An abstraction of a transaction in an account.
Definition: inc/libofx.h:682
time_t date_funds_available
Definition: inc/libofx.h:762
LibofxFileFormat
Definition: inc/libofx.h:126
double par_value
Definition: inc/libofx.h:490
char currency[OFX_CURRENCY_LENGTH]
Definition: inc/libofx.h:825
int libofx_proc_file(LibofxContextPtr libofx_context, const char *p_filename, enum LibofxFileFormat ftype)
libofx_proc_file is the entry point of the library.
char ** inputs
unamed options (options without names)
const char * name
Definition: inc/libofx.h:229
char account_number[OFX_ACCTID_LENGTH]
Definition: inc/libofx.h:320
char unique_id_type[OFX_UNIQUE_ID_TYPE_LENGTH]
Definition: inc/libofx.h:740
char currency[OFX_CURRENCY_LENGTH]
Definition: inc/libofx.h:1069
double ledger_balance
Definition: inc/libofx.h:1080
double yield_to_call
Definition: inc/libofx.h:540
An abstraction of an account statement.
Definition: inc/libofx.h:1057
char fi_id_corrected[OFX_FITID_LENGTH]
Definition: inc/libofx.h:770
double coupon_rate
Definition: inc/libofx.h:517
char secname[OFX_SECNAME_LENGTH]
Definition: inc/libofx.h:386
char loan_id[OFX_LOANID_LENGTH]
Definition: inc/libofx.h:901