Beispiel #1
0
    def question_4(self):
        self._qst(4, "How much cash if we sell it all (starting with the expensive NSOs)?")
        orders = myMeager.sales_orders_all(self.m,
                                           nso_first=True,
                                           cheap_first=False)

        self.m.override(self.e.sales_orders, orders)
        self.rep.print_grants()
        self.rep.print_tax_summary()
        print()
        print("Share Price:  $ %.2f" % m.ipo_price_usd)
        print("NSOs Sold:      %s" % comma(m.shares_sold_nso_n,
                                           dec=False, white=False))
        print("NSO Income:   $ %s" % comma(m.nso_income_usd,
                                           dec=False, white=False))
        print("ISOs Sold:      %s" % comma(m.shares_sold_iso_n,
                                           dec=False, white=False))
        print("ISO Income:   $ %s" % comma(m.iso_sales_income_usd,
                                           dec=False, white=False))
        print("RSUs Sold:      %s" % comma(m.shares_sold_rsu_n,
                                           dec=False, white=False))
        print("RSU Income:   $ %s" % comma(m.rsu_income_usd,
                                           dec=False, white=False))
        print("Sale Income:  $ %s" % comma(m.rsu_income_usd
                                           + m.nso_income_usd
                                           + m.iso_sales_income_usd,
                                          dec=False, white=False))
        print("Owed:         $ %s" % comma(m.outstanding_taxes_usd,
                                          dec=False, white=False))
        print("We Clear:     $ %s"%comma(m.cleared_from_sale_usd, dec=False, white=False))
        print()
        print("This is AFTER paying all outstanding taxes.")
Beispiel #2
0
    def question_6(self):
        self._qst(6, "If we sell it all, how many ISOs can we buy w/o AMT?")
        orders = myMeager.sales_orders_all(self.m)
        self.m.override(self.e.sales_orders, orders)

        self.rep.print_grants()
        self.rep.print_tax_summary()
        print()

        print("Just using the first ISO strike price we find for starters.")

        cleared = m.cleared_from_sale_usd
        (amt, n, strike, cost) = self.amt_free_iso()
        remaining = cleared - cost

        print("AMT Income Gap:     $ %s" % comma(amt, dec=False, white=False))
        print("Exercisable shares:   %s" % comma(n, dec=False, white=False))
        print("Strike Price:       $ %s" % comma(strike,
                                                 dec=True, white=False))
        print("Exercise Cost:      $ %s" % comma(cost, dec=False, white=False))
        print("Cash Cleared:       $ %s" % comma(cleared,
                                                 dec=False, white=False))
        print("Cash Remaining:     $ %s" % comma(remaining,
                                               dec=False, white=False))
    def question_9(self):
        self._qst(9, "What does exercisable ISOs look like vs IPO price?")

        m = self.m
        e = m.enum

        # Set up the loop
        lo = 12.0  # low fmv
        hi = 15.0  # high fmv
        up = 100
        orig = m.ipo_price_usd
        x = []
        y_iso_n = []
        y_gross = []
        y_tax = []
        y_cleared = []
        y_ex_cost = []
        y_rem = []
        y_test = []
        y_amt_diff = []
        m.override(self.e.query_date, '3/15/21')
        #m.override(self.e.query_date, '12/31/35')

        # triggers for vertical lines
        amt_exemption_rolloff = -1
        amt_exemption_gone = -1
        iso_saturated = -1
        rolloff_val = -1
        gone_val = -1

        for i in range(up):
            fmv = (i * (hi - lo) / up) + lo
            x.append(fmv)

            m.override(e.ipo_price_usd, fmv)
            orders_all = myMeager.sales_orders_all(m,
                                                   nso_first=True,
                                                   cheap_first=False,
                                                   prefer_exercise=True,
                                                   restricted=False,
                                                   price=fmv)
            orders_opts = myMeager.sales_orders_options(m,
                                                        nso_first=True,
                                                        cheap_first=False,
                                                        prefer_exercise=True,
                                                        restricted=False,
                                                        price=fmv)
            orders_rsu = myMeager.sales_orders_rsu(m, price=fmv)
            self.m.override(self.e.sales_orders, orders_all)

            (amt, iso, strike, cost) = self.amt_free_iso()

            if (0 > amt_exemption_rolloff and m.amt_base_income_usd >
                    m.amt_exemption_rolloff_threshhold_usd -
                    10 * m.ipo_price_usd and m.amt_base_income_usd <
                    m.amt_exemption_rolloff_threshhold_usd +
                    10 * m.ipo_price_usd):
                amt_exemption_rolloff = fmv
                rolloff_val = iso

            if (0 > amt_exemption_gone and 0 < amt_exemption_rolloff
                    and m.amt_exemption_usd == 0):
                amt_exemption_gone = fmv
                gone_val = iso

            if ((0 > iso_saturated)
                    and (iso >= m.shares_vested_outstanding_iso_n)):
                iso_saturated = fmv

            m.override(self.e.iso_exercise_income_usd, amt)

            a = m.fed_reg_income_taxes_usd
            b = m.amt_taxes_usd

            y_iso_n.append(iso)
            cleared = m.cleared_from_sale_usd

            y_gross.append(m.total_income_usd)
            # y_tax.append(m.outstanding_taxes_usd)
            y_cleared.append(cleared)
            y_ex_cost.append(cost)
            # y_rem.append(cleared - cost)

        m.override(e.ipo_price_usd, orig)

        # Let's make our plots
        fig, ax_shares = plt.subplots()
        ax_shares.set_xlabel('Share Price (USD)')

        ax_shares.set_ylabel('ISOs (n)')
        ax_shares.plot(x,
                       y_iso_n,
                       label='AMT Free ISO Exercises',
                       color='tab:purple')

        color = 'tab:green'
        ax_dollars = ax_shares.twinx()
        ax_dollars.set_ylabel('Value ($k)')

        y_cleared = [x / 1000 for x in y_cleared]
        y_gross = [x / 1000 for x in y_gross]
        y_ex_cost = [x / 1000 for x in y_ex_cost]
        y_rem = [x / 1000 for x in y_rem]
        ax_dollars.set_ylim(0, y_gross[-1] * 1.1)

        ax_dollars.plot(x, y_gross, label='Pre-Tax Income')
        ax_dollars.plot(x, y_cleared, label='Post-Tax Cash from Sale')
        # ax_dollars.plot(x, y_tax, label='Taxes Owed')
        # ax_dollars.plot(x, y_cleared, label='Post-Tax Income')
        #ax_dollars.plot(x, y_ex_cost, label='Cost to Exercise')
        # ax_dollars.plot(x, y_rem, label='Remaining')

        if 0 < amt_exemption_rolloff:
            ax_shares.axvline(amt_exemption_rolloff)
            ax_shares.text(amt_exemption_rolloff,
                           rolloff_val * 1.05,
                           'AMT Rolloff',
                           rotation=45)

        if 0 < amt_exemption_gone:
            ax_shares.axvline(amt_exemption_gone)
            ax_shares.text(amt_exemption_gone,
                           gone_val * .95,
                           'AMT Exemp. Gone',
                           rotation=45)

        if 0 < iso_saturated:
            ax_shares.axvline(iso_saturated)
            ax_shares.text(iso_saturated,
                           m.shares_vested_outstanding_iso_n * .95,
                           "All ISO's Available",
                           rotation=0)

        fig.suptitle('ISO Outlook vs FMV')
        ax_shares.legend(loc=3)
        ax_dollars.legend()

        fname = 'iso.png'
        path = os.path.join('.', fname)
        fig.savefig(path, transparent=False, dpi=600)
    def question_8(self, rsu_only=False):
        augment = "RSU + NSO"
        if rsu_only: augment = "RSU Only"
        self._qst(8, "Basic financials vs share price (%s)" % augment)

        m = self.m
        e = m.enum

        # Set up the loop
        lo = 5.0  # low fmv
        hi = 25.0  # high fmv
        up = 100
        orig = m.ipo_price_usd

        x = []
        y_gross = []
        y_net = []
        y_tax = []
        y_amti = []

        amt_exemption_rolloff = -1
        amt_exemption_gone = -1

        for i in range(up + 1):
            fmv = (i * (hi - lo) / up) + lo
            x.append(fmv)

            m.override(e.ipo_price_usd, fmv)
            orders = myMeager.sales_orders_all(m,
                                               nso_first=True,
                                               cheap_first=False,
                                               prefer_exercise=True,
                                               restricted=True,
                                               price=fmv)
            if rsu_only:
                orders = myMeager.sales_orders_rsu(self.m, price=fmv)
            self.m.override(self.e.sales_orders, orders)

            if (0 > amt_exemption_rolloff and m.amt_base_income_usd >
                    m.amt_exemption_rolloff_threshhold_usd):
                amt_exemption_rolloff = fmv

            if (0 > amt_exemption_gone and m.amt_exemption_usd == 0):
                amt_exemption_gone = fmv

                m.override(e.iso_exercise_income_usd, 0)
                m.override(e.ext_amt_income_usd, 0)

            y_gross.append(m.total_income_usd - m.reg_income_usd)
            y_tax.append(m.outstanding_taxes_usd)
            y_amti.append(m.amt_taxable_income_usd)
            y_net.append(m.cleared_from_sale_usd)

        # Reset our state
        m.override(e.ipo_price_usd, orig)

        # Let's make our plots
        fig, ax = plt.subplots()
        ax.set_ylabel('Value (USD)')

        ax.plot(x, y_gross, label='Gross Sales Income (post Withholding)')
        ax.plot(x, y_tax, label='Outstanding Tax Bill')
        ax.plot(x, y_amti, label='AMTI')
        ax.plot(x, y_net, label='Net Income from Sale')

        if 0 < amt_exemption_rolloff:
            ax.axvline(amt_exemption_rolloff)
            ax.text(amt_exemption_rolloff,
                    m.amt_exemption_rolloff_threshhold_usd * 1.1,
                    'AMT Rolloff',
                    rotation=45)

        if 0 < amt_exemption_gone:
            ax.axvline(amt_exemption_gone)
            ax.text(amt_exemption_gone,
                    m.amt_exemption_rolloff_threshhold_usd * 1.1,
                    'AMT Exemp. Gone',
                    rotation=45)

        ax.grid()
        fig.suptitle('Financials vs FMV (%s)' % augment)
        ax.legend()

        fname = 'fin_all.png'
        if rsu_only: fname = 'fin_rsu.png'
        path = os.path.join('.', fname)
        fig.savefig(path, transparent=False, dpi=600)