/* Copyright (c) 2005-2026 Steven Meyer */

/* === INSERT LICENSE ===
ib_ytd_anal program for analyzing Interactive Brokers format downloaded
Year to Date .csv format spread sheet file.

Copyright © 2005-2026 Tachyon Design Automation Corp.
All Rights reserved.  Licensed software subject to prohibitions and
restrictions.

The intent of this document is to state the conditions under which the
ib_ytd_anal trade analysis C program may be copied and executed such that
the Copyright Holder Tachyon Design Automation maintains distribution and
artistic control over the use and development as granted by Copyright law. 

Licensee may make modifications to ib_ytd_anal for internal use.  ib_ytd_anal
may not be sold without obtaining a sales license from Tachyon DA. 
All forms of indirect sales such as bundling or executing on a shared
cloud are prohibited.  Other uses of ib_ytd_anal program require written
permission from Tachyon Design Automation.

 DISCLAIMER OF WARRANTIES: THIS SOFTWARE IS PROVIDED "AS IS" AND
WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION,
THE IMPLIED WARRANTIES OF MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE,
OR NON-INFRINGEMENT.  THE COPYRIGHT HOLDER SHALL NOT BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY
OUT OF THE USE OF THE SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.

=== END INSERT === */

#define TRUE 1
#define FALSE 0
#define RECLEN 16384
#define MAXCSVFLDS 256
#define MAXTRFLDS 256
#define MAXFLDSIZ 512

#define MAXSECS 500
#define SIZ_TRAN_TAB 8000
#define SIZ_SYMNDX 8000 

/* currency type */ 
#define CUR_NONE 0
#define CUR_USD 1
#define CUR_CAD 2
#define CUR_GBP 3

/* acct type */ 
#define ACCT_NONE 0
#define ACCT_IB 1
#define ACCT_S_IRA 2
#define ACCT_S_MARGIN 3

// need record type
/* transaction type - trade, deposit, withdraw etc. */
#define TRTYP_NONE 0
#define TRTYP_OPPOS 1    /* open position on date when run */
#define TRTYP_TRADE 2
#define TRTYP_DIV 3
#define TRTYP_INLIEU_DIV 4
#define TRTYP_DIVACRU 5 
#define TRTYP_FEE 6      
#define TRTYP_TAX 7
#define TRTYP_DEPOSIT 8
#define TRTYP_WITHDRAW 9
#define TRTYP_INTEREST 10
#define TRTYP_BALANCE 11

/* transaction instrument type - stock, option, fee etc. */
#define TRITYP_NONE 0
#define TRITYP_STOCK 1
#define TRITYP_FUT 2
#define TRITYP_OPT 3
#define TRITYP_FUTOPT 4
#define TRITYP_CREDIT 5
#define TRITYP_DEBIT 6
#define TRITYP_BAL_CASH 7
#define TRITYP_BAL_ACCT 8

/* information in IB CS file - need to pass it to cod tran file for new port */
// ADDME
#define PORT_UNKN 0
#define PORT_OP_BUY 1
#define PORT_OP_SELL 2
#define PORT_CL_SELL 3
#define PORT_CL_BUYBACK 4

/* SJM 09-28-20 - maybe need security class - for asset alloc? */

typedef unsigned long word32;
typedef long sword32;
typedef int int32;
typedef unsigned long word64;
typedef unsigned long long word128;
typedef long sword64;
typedef unsigned char byte;

/* mth and day start at 1 so prints without changing - yr is dd (last 2 digs) */
struct date_t {
 int32 month;
 int32 day;
 int32 year;
};

/* 24 hour clk */
struct clktime_t {
 int32 hr;
 int32 min;
 int32 sec;
};

struct map_t {
 char *str;
 int32 mval;
};

/* for a tran trade close - num and tran ndx list els */
struct trclndx_t { 
 int32 numcl;
 int32 optrndx;
};

/* struct for transaction read built from the various csv files */
/* not using malloc fields for now because if bad do not add to tab */
/* no ptrs here since copying it with simple memcpy */
struct trans_t {
 unsigned acc_typ : 8;    /* IB or Schwab etc. */
 unsigned tr_typ : 8;     /* trans type - trade, open pos. fee etc. */
 unsigned tr_ityp : 8;    /* stock, option, fee etc. */
 unsigned cur_typ : 4;    /* need to handle other currencies */
 /* now cod separates buy/sell - for cash moves insis deb or cred */
 unsigned is_buy : 1;     /* T for buy also op pos long */
 unsigned is_put_opt : 1; /* if option T put, F call */
 unsigned op_last_yr : 1; /* T => cross yr boundary open pos of this */
 unsigned cl_tr_in_tots : 1;/* T for opt cl trs with no base tr, done */
 unsigned tdy_pseudo_cl : 1; /* add tr pseudo cl if open tdy */
 int32 fut_expmth;        /* for future, expiration month */
 int32 fut_expyr;         /* for future, expiration year - 0 is 2000 */
 char symbol[MAXFLDSIZ];     /* underlying sym */
 char futsym[MAXFLDSIZ];     /* for futures the base commodity type name */
 char sort_sym[MAXFLDSIZ];   /* unique sort order sym opts and futs */
 char tr_code[10];        /* when needed separates op and cl trans */
 struct date_t tdate;     /* for chg in div accrual declare date */
 struct clktime_t ttime;
 double tr_quant;
 double tr_price;         /* for trades, tr pr, for op pos buy pr */
 double tr_tdy_closepr;
 double tr_yday_closepr;  /* from yday open pos. file */  
 double tr_comm;
 double tr_amount;        /* for yr pos tot divs, for tr, div typ rec */
 double op_unrlz_gain;    /* for open pos. today unrealized gain */
 int32 trcl_ndxi;         /* for cl trade, ndx of list of cl froms */
 int32 op_tdy_trcl_ndxi;/* if still op, the tr if cl ndx */ 

 double opt_strike; 
 struct date_t opt_exp_dt;
 /* these are not in coded trans file? */
 double tr_mult;          /* opts and futs need multiplier */
// ====
 double tr_xdiv_amt;      /* for chg in div acc trans, tot amount of div */
 struct date_t xdiv_dt;   /* for chg in div accrual xdiv not decl dt */
 struct date_t div_pay_dt;/* for chg in div accrual date paid (re) */
 double last_div_amt;     /* for open pos. last div paid amt */  
 struct date_t last_div_pay_dt; /* and when last paid */
// ====
 /* calculated fields */
 double not_cl_share_no;  /* num to close after this one */
 double this_still_op;    /* for cl, no. in op not cl */
 double op_avg_sh_pr;     /* in cl tran, avg. op pr from tr cl ndx */
 double cl_gain_per_sh;   /* for all cl gain per share */ 
 char trans_desc_string[MAXFLDSIZ];
 char trline[MAXFLDSIZ]; 
 int32 lno;
};

/* index of sort syms - needed for calc values to put in trans tab */
struct symndx_t {
 unsigned sip_bas : 1;    /* bas is either stk/fut or if none 1st */
 unsigned in_sipgrp : 1;  /* T => this symndx el already in sgrp */
 unsigned bas_has_options : 1;/* current base has at least 1 option */
 char *ndxsnamp;          /* ptr to sort sym in trans record */  
 int32 tr_bi;             /* begin and tran tab index for sort sym */  
 int32 tr_ei;
 int32 bas_sgrp_ndxi;     /* if sip bas on, 1st el of sgrp list */
 double rlzgain_tot;      /* tot rlz gain for sort sym stk/fut/opt*/ 
 double mth_rlzgain[13];  /* per month realized gain - jan is 1*/
 double rlz_traded_shares;/* closed no. of traded sh can be frac */
 int32 rlz_traded_opts;   /* closed no. of options as int */
 double ytd_tot_divs;     /* amount of ytd divs for stock only */
 double mth_divs[13];     /* per sym ndx, tot divs per mth - jan=1*/
 double unrlz_gain;       /* this sort sym op tr_ei - pseudo cl gain */ 
 double opt_unrlz_gain;
 double opt_pot_income;   /* if go to 0, pot. opt open income */
 struct date_t op_xdiv_dt;/* acru unpd xdiv and pay dts nd for not paying */ 
 struct date_t op_div_pay_dt;/* for chg in div accrual date paid (re) */
 double open_stk_acru_div;/* for stock after x div but not paid div */

 /* can get unrlz gain from sip pseudo cl trade */
 int32 num_bas_ins;       /* no. of instruments with this base */
 double bas_rlzgain_tot;  /* for bas rlz gain is stk and opt tots */
 double bas_mth_rlzgain[13];/* also per mth */
 double bas_opt_rlzgain_tot;/* bas tot opt only riz gain */
 double bas_opt_mth_rlzgain[13]; 
 double bas_rlz_traded_shares;
 int32 bas_rlz_traded_opts;
 double bas_all_unrlz_gain; /* base sym opt and underlying gain */
 double bas_op_opt_unrlz_gain;/* this opt open gain */
 double bas_investment_tot; /* for bas with opn, tot val of longs */
 /* stks and futures do not have potential income */
 double bas_opt_pot_income; /* bas sym total of opt pot income */
 int32 bas_open_opt_num;    /* num. of open options for this bas */ 
 double bas_ldiv_persh;
 struct date_t bas_last_div_pay_dt;
};

/* extern storage definitions - declarations in main file */
extern long __mem_use;        /* counts allocated mem for debugging */
extern long __mem_str_use;    /* counts allocated string memory */
extern int __line_cnt;        /* current line number */
extern char __curfnam[RECLEN];/* current token input file name */  
extern int __error_cnt;       /* error count */
extern int __warn_cnt;        /* warning count */
extern int __inform_cnt;      /* no. informs (usually only cnted) */
extern int __nowarns;         /* T => do not emit warnings */
extern int __noinforms;       /* T => do not emit informs */
extern FILE *__log_s;         /* log file and stream */
extern char __logfnam[RECLEN];/* name of log file */
extern FILE *__trout_s;       /* transaction out file */
extern char __cod_trans_fnam[RECLEN]; /* coded trans file name */
extern char __cur_fnam[RECLEN];/* current input file name */
extern char __cur_line[RECLEN];/* cur work line from a .csv file */
extern char __brkrnam[RECLEN]; /* broker for misc msgs */
extern char __s_run_dtstr[RECLEN];/* dt string from schwab file name */
extern char __s_allpos_fnam[RECLEN];/* Schwab all pos fnam - end .CSV */
extern FILE *__s_allpos_s;
extern char __s_iratrans_fnam[RECLEN];/* Schwab ytd ira trans fnam */
extern FILE *__s_iratrans_s;
extern char __s_indtrans_fnam[RECLEN];/* Schwab ytd indiv trans fnam */
extern FILE *__s_indtrans_s;
extern double __start_nav;    /* starting NAV - jan. 1 of year */
extern double __end_nav;      /* ending NAV day report run */
extern double __tot_ib_ytd_pandl;/* tot YTD p&L - deduct expense?*/
extern double __ib_weight_pct_gain; /* IB weighted by time profit % */
extern double __ib_end_settled_cash; /* today cash- available */   
extern double __end_mtm_profit; /* IB MTM - NAV increase - profit? */
extern double __end_dep_and_wdraw; /* total cash added or removed */
extern double __end_ib_divs;  /* what IB say YTD dividends are */ 
extern double __end_ib_interest;/* what IB say YTD interest is */
extern int32 __some_revs_sep;   /* some revs add tr to 0 then tr */
extern int32 __adj_tdy_op_trans; /* add virutal pseudo cl for tdy op */
extern char **__csvfldtab;    /* tab for line broken into flds */
extern int32 __lastcsvfld;    /* last used csv separated fld */ 
/* tran tab is ptr to a table of ptrs to alloc tran records */
extern struct trans_t **__trantab; /* trans from reading csv file */
extern int32 __last_trani;
extern struct trclndx_t *__trclndx; 
extern int32 __last_trcli;
extern struct symndx_t **__symndx;
extern int32 __last_symndxi;
extern int32 *__basgrpndx;       /* tab with same grp bas sym ndxes */
extern int32 __last_sgrpndxi;    /* last used grp sym ndx tab el */
extern struct trans_t **__posndx;/* tab of ptrs to op pos trans */
extern int32 __last_posndxi;

/* various calculated portfoilio totals */
extern double __ytd_open_gain;
extern double __ytd_open_stk_gain;
extern double __ytd_open_fut_gain; 
extern double __ytd_open_opt_gain;
extern double __ytd_open_futopt_gain; 
extern double __tot_opt_pot_income;
extern double __tot_futopt_pot_income;
extern double __tot_open_acru_divs;

extern double __tot_ytd_rlz_gain;
extern double __mth_tot_rlz_gain[13];
extern double __tot_stk_rlz_gain;
extern double __mth_stk_rlz_gain[13];
extern double __tot_opt_rlz_gain;
extern double __mth_opt_rlz_gain[13];
extern double __tot_fut_rlz_gain; 
extern double __mth_fut_rlz_gain[13];
extern double __tot_futopt_rlz_gain; 
extern double __mth_futopt_rlz_gain[13];

extern double __tot_tdy_net_val;
extern double __tot_tdy_gross_val;
extern int32 __cur_mth_num;      /* mth num of run for per mth out */
extern double __mth_tot_divs[13]; /* tot divis by month - jan is 1 */  
extern double __ytd_tot_divs;     /* total divs for all instruments */
extern double __tot_ytd_opt_gain;/* closed total ytd option gain */ 
extern double __ytd_tot_debits;  /* comms and data fees */
extern double __ytd_tot_int;     /* interest and dividends */
extern double __ytd_tot_income;   /* divs plus interest */


extern int32 __today_jdt;       /* tdy convert to julian dt format */
extern struct date_t __today_dt; /* today as date record */
extern struct date_t __when_gen_dat;
extern struct date_t __marg_tr_when_gen_dat;
extern struct date_t __ira_tr_when_gen_dat;
extern struct clktime_t __when_gen_tim;

extern struct date_t __stmt_start_dat;
extern struct date_t __stmt_end_dat;
extern struct date_t __codfil_start_dat;
extern struct date_t __codfil_end_dat;
