Wednesday, November 13, 2013

stock stalker script

update 11/15/24:

it drives me crazy to have to display the chart of a stock one at a time. it takes forever and it's useless because i have very poor memory. by the time i display the chart of the 10th stock i already forgot the first 5 stocks. i need to be able to just scroll down the charts of 100 stocks in a few seconds. this is the most efficient way to get an overall landscape of the market. it's also ridiculous to analyze the chart of an individual stock by itself because everything is relative. example, if apple is down 2% for the month, then it's actually a strong stock if the market is down 10%. you can't just look at the price because you need to also get a picture of it's volatility and patterns relative to the volatility and patterns of other stocks. 

long time ago, i wrote a script that would automatically display in yahoo finance all the stocks under my radar. the stock market darth vaders probably found out it made playing the stock market too easy so in 2018, they removed a feature that would prevent my scripts to work. luckily, TD ameritrade had something called micro charts. it was more of a hassle but it was good enough for me. 

then a few months ago, the stock market darth vaders removed the microcharts feature because they probably realized it made it too easy for little guys like me to compete with the big guys. because why would they remove mirocharts? isn't adding and improving features the goal of every software or app? i had to stop trading and missed a lot of opportunities.

i've been looking for an alternative to microcharts. i found out that the trading platform thinkorswim can simulate microcharts. it's 10 times more of a hassle but at least it works. i don't think the stock market darth vaders will remove this feature because it's such a pain in the butt. a normal person would just give up. i'm the type of person who has the perseverance and grit to swim inside a septic tank just to get things done. only very few people are willing to swim in a septic tank. 

20 years ago, i was able to write a script where i can breeze through 100 stocks in a few seconds by simply double-clicking an icon in my desktop. today, with all the advancements in technology, i would need to do the following to achieve the same results. what drove me crazy was it took me a month to get copy-paste to work. it's supposed to be the easiest feature to implement and use. as it turns out, the problem was that the symbols need to be in ALL CAPS but my symbols were in lower caps. this is very stupid because there is no reason why they can't just make it case insensitive. what a bunch of assholes. i can't call them morons because i'm sure they did it in purpose so the little guys will never discover my strategy, which makes it very easy to compete with the big guys.

------------------------

STEPS TO GET MICROCHARTS TO WORK IN THINKORSWIM:

note there are 4 upper toolbars: main toolbar (support and setup toolbar, tabs toolbar, charts toolbar, and the symbol toolbar)

- click on the charts tab in the charts toolbar
- make sure ondemand is disabled by making sure it's in the rightmost end of the tabs toolbar. if it's near the middle, it's enabled. just click on it to disable it.

- at the rightmost end of the chart toolbar is the "chart actions" button. next to it is the "grid" button. at the rightmost end of the symbols toolbar is the "symbol actions" button. 

- click "chart actions/reset".
- enter any stock symbol in the upper left corner (e.g. nvda)
- click "symbol actions/style/settings
   - time-axis tab: 6 months, aggregation period is day
   - appearance tab/chart type = line
   - uncheck all checkboxes especially equities tab (this removes all annoying chart markers)
   - click ok
- click "symbol actions/style/set chart default", then (click yes)
- click "symbol actions/style/save style" then enter "clean 6-month chart"
- click "symbol actions/style/settings
set time-axis tab: 5 years, aggregation period is month
- click "symbol actions/style/save style" then enter "clean 5-year chart"
- click "symbol actions/style/load style/clean 6-month chart"

- go to watchlist on the right subwindow. if no right subwindow, click the middle of the right edge of the main window. 
- if no watchlist gadget, click the + button in the bottom of the right subwindow and add the watchlist gadget

- click the button next to watchlist to bring up the contex/pop-up menu
- if you already have a saved watchlist, hover above "personal" to bring up the drop down menu of your saved watchlists. 
- if you want to add a watchlist, click "create watchlist". note the first input box is for the name, not the symbols. this really screwed me because the box is strangely very long. enter the name you want and then click import. 
- you can then copy the list of stocks to the clipboard then click "paste symbols from clipboard". it took me a month to get this to work. as it turns out, the problem was that the symbols need to be in ALL CAPS but my symbols were in lower caps. this is very stupid because there is no reason why they can't just make it case insensitive. note the symbols can be separated by newline, comma, space, or semi-colon. 
- if you have a fideliy account, you can click the download button in upper right corner of portfolio view. then open the file from excel or wps so you can copy the symbol column to clipboard (in excel, you first need to open an empty workbook then click "data/from text" to open the csv file then set the delimiter to comma). make sure to delete any heading or cash/money market rows so they don't get included.
- we will be choosing the 7 X 4 grid, which means each watchlist cannot be more than 28 stocks. so if you want to look at the charts of more than 28 stocks, you will need to break it up. example, my watchlists from my fidelity IRA are ira1, ira2, and ira3
- click save

- click "chart actions/clear symbols"
- click "grid" then click the last square (bottom right)
- click "chart actions/load symbols to cells/personal/<your watchlist>
- click "grid/save grid as" then enter the name (e.g. ira1 6-month charts)
- clear the symbols again and repeat the steps to load and save the 6-month charts for other watchlists if any

- if the "symbol actions" button is not visible drag the right edge of any cell a little bit to the right so it becomes visible. 
- click "symbol actions/load style/clean 5-year chart"
- click "symbol actions/style/set chart default", then (click yes)
- click "chart actions/reset"
- click "grid" then click the last square (bottom right)
- click "chart actions/load symbols to cells/personal/<your watchlist>
- click "grid/save grid as" then enter the name (e.g. ira1 5-year charts)
- clear the symbols again and repeat the steps to load and save the 5-year charts for other watchlists if any

- to make the micro-charts bigger, collapse the left and bottom subwindows (click the middle of the right edge and click the "down arrow" button in the upper left corner of each BOTTOM subwindow
- also make sure the "show sidebar in cells" is unchecked in the grid menu

- if you want to open more than 1 chart grid, click the "chart actions/detach". you will need to remove the sidebars again by unchecking "show sidebar in cells" in the grid menu.

- you can actually increase the grid size (e.g. 8 X 5 = 40 cells) by choosing the "flexible grid" tab instead of charts. just keep splitting the windows horizontally and vertically until you get the desired grid. to remove the splitter toolbar in each cell, click "show grid actions/customize grid" (click it again to show the toolbar). 



----------------------------------------------------------------------------------------

update 3/6/19:

yahoo finance does not allow ticker symbols on the URL anymore so all my previous scripts won't work. here's my new framework to manage a portfolio that has 50-70 stocks. first you only need to read the news of a stock if it goes down a lot relative to the market (to find out if your long term thesis is still intact or if it's broken).

example if alb is down 40% but only because the price of lithium is temporarily low but the long term thesis is still intact, then you can safely continue to range trade.

example when chipotle (cmg) went down 50% there really was no reason to sell especially if it's a very small percentage of your portfolio (you can easily afford to wait) because history shows stocks of food chains will always recover after a food safety issue. 4 children died of food poisoning outbreak of jack in the box in 1993 and the stock got chopped in half but it took only 3 years for the stock to recover and now it's up a whopping 1600% from it's lows.  similarly the stock of cmg have recovered after the food safety issues in 2015. while waiting for the stock to recover, you can continue to make money by range trading.

my range trading strategy is to buy when it beats the market significantly and it's down more than 5% from your last buy. sell when the market beats it significantly and it's up more than 5% from your last buy. the great thing about this is that chances are you don't end up buying too much when your stock goes down a lot over a period of time. also, if a stock bucks the market, chances are there is something significant going on. it's not always the case but it's like card counting in the casino where the odds are in your favor and given enough time you will beat the market.

the problem with this strategy is that if you have 100 stocks like me you will spend about 30-60 minutes a day doing this manually. but i wrote a script so that it will only take you a few seconds to decide which ones to buy and sell. all i do daily is double click an icon of a notepad file on my desktop, copy and paste my yahoo portfolios to this notepad, save it, then double click the icon of a script. here is a sample output:

C:\my\bin>perl c:\my\bin\stock-inspector.pl
spy percent change is +3.35

sell ba because it is up 62.74% from your last buy but today the market is beating it by -7.25%
ba,price=165.9,last_buy=101.94,pct_change_today=-4.30,pct_change_delta=-7.25,change_highs=-63.94%
note it is down 54.79% from your last sell

buy isrg because it is down 9.00% from your last buy and it beat the market by 0.84%
isrg,price=510.50,last_buy=560.97,pct_change_today=+4.19,pct_change_delta=0.84,change_highs=-17.53%
note it is UP 5.67% from your last sell

buy mdt because it is down 7.39% from your last buy and it beat the market by 1.75%
mdt,price=99.28,last_buy=107.2,pct_change_today=+5.10,pct_change_delta=1.75,change_highs=-18.72%
note it is UP 11.43% from your last sell

buy tndm because it is down 10.45% from your last buy and it beat the market by 1.55%
tndm,price=66.18,last_buy=73.9,pct_change_today=+4.90,pct_change_delta=1.55,change_highs=-27.79%
note it is UP 13.21% from your last sell

Press enter to continue:

my stock-inspector script has an option "full_report" that will report the percent change from 52 high, percent change from last buy (if owned), and percent change from last sell (if owned before). this is useful during volatile sessions such as the covid-19 pandemic you want to buy high quality stocks that are down big even if it did not beat the market that day. here is a sample output:

C:\my\bin>perl c:\my\bin\stock-inspector.pl full_report
Enter the percent down from last buy threshold filter (example, 10 would list all stocks down more than 10% from your last buy): 11
spy percent change is +3.35

panw, -29.85% from highs, -27.47% from last buy, 4.86% from last sell
pcrfy, -35.34% from highs, -25.17% from last buy, -0.33% from last sell
tsn, -38.02% from highs, -34.71% from last buy, 1.09% from last sell
uber, -42.78% from highs, -18.88% from last buy, 1.05% from last sell
Press enter to continue:

my stock-inspector script also has an option "lastgains" that lists all the stocks up more than 5% from your last buy. this is also useful during volatile sessions where you want to sell to raise cash when you think the market is doing a dead cat bounce. here is a sample output:

amzn gain of last buy is 27.62%
amt gain of last buy is 13.76%
avgo gain of last buy is 34.49%
awk gain of last buy is 9.06%
cci gain of last buy is 13.18%
crm gain of last buy is 5.25%
fb gain of last buy is 10.12%
fslr gain of last buy is 6.28%
goog gain of last buy is 11.37%
glw gain of last buy is 5.99%
lly gain of last buy is 9.98%
lw gain of last buy is 9.51%
mrvl gain of last buy is 19.19%
nvda gain of last buy is 18.55%
okta gain of last buy is 5.62%
smg gain of last buy is 10.63%
tsla gain of last buy is 64.33%
v gain of last buy is 59.09%
vrtx gain of last buy is 10.01%
xlnx gain of last buy is 11.63%

Press enter to continue:

here is the outline of my framework:

I. stock-inspector.pl script
II. stocks-history.txt
III stocks-copy-paste-list.sh
IV. yahoo portfolios
V. custom views
VI. using stock-inspector.pl
VII. using realized-gain.pl and unrealized-gain.pl
VIII. displaying all charts in 1 page

-----------------------------------------------------------------------------

below are the steps to setup and use my framework.

I. stock-inspector.pl script

copy and paste the following to a file named stock-inspector.pl

#------------------------------ stock-inspector.pl script -----------------------------------

$history = "c:/my/finance/docs/stocks-history.txt";
$quotes =  "c:/tmp/buffer.txt";
$mode = "own";

$arg1 = shift;

if ($arg1 eq "full_report") {
  print "Enter the percent down from last buy threshold filter (example, 10 would list all stocks down more than 10% from your last buy): ";
  $full_threshold = <STDIN>;
  chomp $full_threshold; 
}



# threshold in bucking the market
$threshold = .5;

# trading range
$trading_range = 5;

# extract the percent change of spy
$spy_pct_change = 0;
open my $fh, $quotes  or die "Can't open $quotes $!\n";
while (<$fh>) {
  ($symbol, $price, $spy_pct_change) = split;
  last if ( "spy" eq lc($symbol));


# remove %
$spy_pct_change =~ s/%//;
print "spy percent change is $spy_pct_change\n\n";

open(HISTORY, $history) or die "Can't open $history $!\n";

while (<HISTORY>) {

  chomp;

  ($stock,$last_buy) = split; 

  if ($stock)  {
    if ($stock !~ /^#/) {
      if (index($_, "(") != -1) {
        ($last_sell) = $_ =~ /(\(.*)/;
        ($last_sell) = split(/\s+/,$last_sell);
        ($last_sell) = $last_sell =~ /(\d.*)/;
        #print "first last_sell = $last_sell\n";
      } else {
        $last_sell = "";
      }

      # remove the prefix if any
      $last_buy = substr $last_buy, 1 if ($last_buy !~ /^[0-9]/);
      $stock = lc($stock);
      open my $fh, $quotes  or die "Can't open $quotes $!\n";
      while (<$fh>) {
        ($symbol, $price, $pct_change, $trailing_pe, $forward_pe, $peg, $price_book, $market_cap, $div, $change_lows, $change_highs) = split;
        $price =~ s/,//;
        if ( $stock eq lc($symbol)) {
          if ($arg1 eq "full_report") {
            $last_buy_str = "";
            if ($last_buy > 0) {
              $last_buy_delta = sprintf("%.2f", (($price - $last_buy)/$last_buy) * 100);
              $last_buy_str = ", $last_buy_delta% from last buy";
            }
            $last_sell_str = "";
            if ($last_sell > 0) {
              $last_sell_delta = sprintf("%.2f", (($price - $last_sell)/$last_sell) * 100);
              $last_sell_str = ", $last_sell_delta% from last sell";
            } 
            if ($last_buy_delta < -$full_threshold) {
              print "$stock, $change_highs from highs$last_buy_str$last_sell_str\n";
            }
          } else {
            $pct_change =~ s/%//;
            $delta = $pct_change - $spy_pct_change;
            $print_sell_delta = "";
            if ($mode eq "own") {
              if ($last_buy > 0) {
                $up_pct = sprintf("%.2f", (($price - $last_buy)/$last_buy) * 100);
              } else {
                $up_pct = $price;
              }
              if ($arg1 eq "last_gain") { 
                if ($up_pct > 5) {
                  # print the gain of the last buy
                  print "$stock gain of last buy is $up_pct%\n";
                }
              } else {
                # recommend a buy if beating the market and down more than the trading range from last buy 
                if (($delta >= $threshold) && ($last_buy > $price)) {
                  $down_pct = sprintf("%.2f", (($last_buy - $price)/$last_buy) * 100);
                  if (($down_pct > $trading_range) && ($pct_change > 0)) {
                    print "buy $stock because it is down $down_pct% from your last buy and it beat the market by $delta%\n";
                    print "$stock,price=$price,last_buy=$last_buy,pct_change_today=$pct_change,pct_change_delta=$delta,change_highs=$change_highs\n";
                    $print_sell_delta = "yes"; 
                  }
                # recommend a sell if the market is beating it and it's up more than the trading range from the last buy
                } elsif (($delta <= -$threshold) && ($last_buy < $price)) {
                  if (($up_pct > $trading_range) && ($pct_change < 0)) {
                    print "sell $stock because it is up $up_pct% from your last buy but today the market is beating it by $delta%\n";
                    print "$stock,price=$price,last_buy=$last_buy,pct_change_today=$pct_change,pct_change_delta=$delta,change_highs=$change_highs\n";
                    $print_sell_delta = "yes"; 
                  }
                } # if buy or sell
              } # if last_gain mode
            # not own core
            } else {
              #print "stock = $stock, last_sell=$last_sell\n";
              if ($delta >= $threshold) {
                print "buy $stock because it beat the market by $delta% and you don't own it yet\n";
                print "$stock,price=$price,pct_change_today=$pct_change,pct_change_delta=$delta,change_highs=$change_highs\n";
                $print_sell_delta = "yes";
              }
            } # if mode = own
            if ($print_sell_delta) {
              if ($last_sell > 0) {
                $sell_delta = sprintf("%.2f",(($last_sell - $price)/$last_sell) * 100);
                if ($sell_delta > 0) {
                  print "*** note it is down $sell_delta% from your last sell\n"
                } else {
                  $sell_delta = abs($sell_delta);
                  print "note it is UP $sell_delta% from your last sell\n"
                }
              }
              print "\n";
            }
            # uncomment if debugging
            #print "$stock,price=$price,last_buy=$last_buy,pct_change_today=$pct_change,pct_change_delta=$delta\n";
          } # if arg1 eq full_report
          last;  # some stocks appear in ameritrade and fidelity (report only once)
        } # if $stock found in buffer.txt quotes
      } # while searching buffer.txt quotes 
    } elsif ($stock eq "#---own-ira") {
      $mode = "own";
    } elsif ($stock eq "#---own-ameritrade") {
      $mode = "own";
    } elsif ($stock eq "#---not-own-cores") {
      $mode = "not-own";
    } elsif ($stock eq "#---watch1") {
      last;
    } # if not comment #
  } # if not empty line
} # while searching stocks-history.txt

print "Press enter to continue: ";
$enter = <STDIN>;

# --------------------------- end of inspector.pl script ------------------------------

then create a stock-inspector.bat file that calls the perl script. example (you may have a different location or path):
perl c:\my\bin\stock-inspector.pl
then create a shortcut on your desktop for the stock-inspector.bat file so you can conveniently just double click it.

also create a stock-inspector-full.bat file that calls
perl c:\my\bin\stock-inspector.pl full_report
then create a shortcut on your desktop to stock-inspector-full.bat

also create  stock-last-gains.bat that calls
perl c:\my\bin\stock-inspector.pl last_gains
then create a shortcut on  your desktop to stock-last-gains.bat

II. stocks-history.txt

create a text file stock-history.txt and create a link on your desktop. below is a sample. create a section for each group by adding a unique heading. example for the stocks i own in my ira account, the heading is:

#---own-ira

add the stock symbols under each group

note the legend for the tags. ! means 1k, # means 2k, no tag means 5k and @ means 10k.

when you sell, tag it with "s" and move both the buy and sell trades to the right of the "(" so it's easy to see the amounts of your holdings and the history of your buys and sells. if you sell all the shares for a certain stock, also copy and paste the line under ---not-own-cores. if you buy a stock you currently don't own, also copy and paste or add the line to the appropriate section.

----------------------------------------  stocks-history.txt -----------------

#---own-ira
aapl #292.48 !253.56 (s!286.85 !259.76 s!286.85 !277.48 s#243.64 #187.48 s!197.67 !177.67 s!196.5 !178.92 s!178.67 !169.64 s#173.08 #162.99 s!155.58 !148.65 s#182.57 #164.88 s#177.93 #167.15 s#174.16 #159.99
abt !85.66 (s!87.10 !80.71
alb !67 !85.77 !89.16 !97.22 !100.1 #116.48 #139.08 (s!63.61 !57.23 s!80.72 !71.55 s!82.72 !75.78 s!71.65 !64.03 s!67.31 !63.76 s!68 !63.03 s!71.44 !68.64 s!72.21 !69.09 s!88.15 !82.6 s#81.22 #77.15 s!76.78 !73.04 s#101.81 #96.96 s#97.79 #93.45 s#97.79 #93.45 s#100.26 #97.69 s#96.86 #94.67 s#99.51 #96.38 s#113.88 #108.51 s#131.28 #130.1)
amzn !1789.18 (s#1747.02 #1008.85 (s#1850.52 #1790.23 s#1817.35 #1656.96 s!1503.69 !1394.3 s!1644 !1533.26)
amt #224.25 (s!250.02 !226.86 (s!228.68 !207.39 s#223.12 #210.96
avgo !199 (!309.86 !290.93
awk !122.51 (s!135.44 !116.43 s#123.93 #116.81 (s#112.92 #107.36 (s93 89.07
ba !147.21 !170.73 !308.37 !332.65 #376.85 (s!165.9 !101.94 s!365.35 !339.01 s!375.95 !343.3 s#394.61 #260.73 (s!361.37 !331.59 s#342.38 #325.19 s157.43 144.56)(s125.14 123.94 s#137.98 #131.57 s133.79 123.35)(s#130.3 s#124.57 #121.24 #126.6)
cag #33.3 (s!30.28 !27.67 s!33.54 !29.53 (s!33.63 !28.03 s!28.86 !26 s!29.85 !25.6 (s#44.45 #37.72) (s#37.83 s#35.07 #33.76 #36.18)
cci !146.47 (s!147.75 !137.53 
crm #149.85 (s#150.61 #98.92 (s#144.87 #140.75 s!135.05 !124.33 s!136.98 !124.39 s#120.45 #115.57 s57.27 s!57.25 !59 50)(s#57.71 #56)
ctva !29.95 !0 (s!26.13 !24.7 s!28.51 !26.89 s!26.57 !25.1
dal !24.43 !36.88 !45.78 (s!32.1 !24.25 s!59.06 !55.69 (s!49.87 !49.7 (s#42.93 #42.06 s#46.51 #44.12 s#47.21 #44.76)
ew !233.9 (s!215.99 !192.52 s!236.66 !221.93 (s#217.01 #191.31 (s!183.42 !170.71 s#168.47 #150.27 s#128.58 #104.99 s#117.35 #113.08 s111.27 96.51
fb !161.79 #172.54 (s!191.45 !178.54 s#186.66 #175.11 (s#190.82 #182.91 s#179.22 #166.6  s#165.92 #147.78 s!150.37 !142.71 s!142.36 !128.71 s!143.41 !135.91 s#175.74 #171.3 s#167.95 #158.31 #178.26 #174.97
fdx !139.68 !162.12 #185.61 !224.45 #257.58 (s!123.39 !111.63 s!158.63 !150.71 s!161.05 !152.42 s!156.98 !146.12 s!173.73 !159.59 s!174.25 !159.86 s#229.94 #215.01 s#242.1 #225.01 s#240.84 #222.3 s#185 #176.32) (s#171.33 #166.3 s#164.89 s#142.225 #127.5 #131.08)
fmc  !83.85 #94.72 (s!76.45 !68.26 s!96.63 !85.28 (s!83.65 !78.63(s!80.25 !72.5 s80.25 77.83 s77.88 @66.45 (s!85.14 !80.34 s!85.99 !79.75 s#82.79 #76.83 s#91.39 #86.93 s#87.07 #80.36 s#87.085 #83.41 s#83.22 #80.7 s#97.34 #57.61 s#95.55 #89.31 s90.78 70 (s#49.95 s#41.59 #37.77 #41.78 S#62.89 #57.55 s!56.6 !54)
fslr #39.63 (s!57.02 !53.65 (s#65.43 #62.76 (s#62.07 #59.6 (s56.34 53.74 (s#54.49 s#68.77 50.67 s!46.15 !43.78 s!47.05 !42.7 s!43.24 !38.9 s#68.17 #63.24 s#65.39 #62.09 s59.2 s#58.33 s#46.88 #42.09 #51.03 s#46.95 #46.5 72)(s!44.91 !42.74)
goog !1139.7 #1236.54 (s#1265.25 #991.4 (s!1134.73 !1085.95 s!1115.59 !1040.33 s!1114.01 !1038.23 s#1081.73 s#1081.73 #1039.12 #1024.24s#1098.78 #1054.58 s#682.96 s#657.4 s#548.42 #537 592)
glw !19.53 #30 (s!29.38 !27.69 s#33.54 #30.51 (s!33.16 !31.10 s#33.14 #31.39 s#33.27 #27.77 #31.98 30.48
isrg !560.97 (s!483.13 !416.51 s#537.37 #510.86 (s#462.63 #373.2 s#430.1 #406.81 s#416.42 #398.2
jpm  !118.71 (s!95.13 !97.5 s106.31 110.5 (s118.15 117.82 s110.09 108.16 s#110.18 #104.97 s#113.21 #109.49
lly !137.4 (s#143.13 #127.89 (s!139.84 !117.54 s!121.56 !112.98 s#118.19 #110.34
loco #15.62 (s!10.685 !9.62 s!14.86 !13.05 s!11.92 !10.98 s!11.68 !10.83 s!11.68 !10.89  s#21.33 (s#12.42 #12.25 s!12.42 !12.58 s!11.4 !10.8 s#10.8 #10.3 s#10.35 #9.68 s!25.45 !22.5)
lw !55.43 #87.44 (s!58.39 !48.37 s!82.28 !77.4 (s#76.12 #71.64 (s!72.93 !67.85 s!63.94 !60.52 s#77.29 #55.48 s54.35 #57.19 #47.94)
lyft !49.03 !53.94 !61.22 #58 (s!30.33 !27.4 s!28.98 !20.49 s!53.68 !46.32 s!44.66 !42.12 !58.12 !55.28
mdt !107.2 (s!89.1 !79.3 s#97.43 #88.84 (#82.23 #80.5 (s81.5 75.08
mrvl !21.42 !26.61 #28.08 (s!25.72 !24.27  s!26.57 !25.18
nclh !56.08 (s!12.17 !10.92 s!17.67 !10.87 s!55.73 !52.02 s!54.51 !50.44 s!54.51 !48.62 s#55.11 #52.63 (s#50.29 #46.29
nsrgy !106.69 (s!99.6 !95.01 
nvda !239.51 (s!259.47 !239.51 s!254 !216.66 s!237.25 !212.01 s!218.4 !199.93 s!202.85 !187.36 s!202.85 !199.93 s!192.36 !176.53 163.78 !151.95 s!174.24 !157.77 s!163.38 !155.16 s#146.62 #139.37 !188 !169.15 s!174.5 !153.7 s!174.5 !161.36 s!139.04 !134.44 s!157.92 !145.82 s#211.04 #194.56 s#236.31 #232.14 s#227.73 #193.08 s#204.36 #197.27)
okta !132.4 (s!119.97 !108.81 s!129.57 !121.52 s!128.74 !107.25 s!115.16 !101.74 s!115.16 !107.55 s!127.31 !83.22
panw !242.87 (s!167.99 !147.93 s!232.35 !211.92 s!220.64 !203.47 s!209.5 !184.95
pcrfy !10.17 #11.5 (s!7.635 !6.91 s!11.37 !9.7 s!11.37 !9.98 s!9.55 !8.94 s!9.25 !8.29 s!8.38 !7.82 s!14.74 !14.74 s#14.74 #14.92 (s#15.45 #14.73)
pgf @18.3 @18.3
podd #179.08 (s!167.57 !141.47 s!187.47 !173.89 (s!177.16 !156.16 (s!163 !152.14 (s!162.57 !118.13 (s#118.39 #86.02 (s#96.17 #88.14 (s!85.83 !82.5 s#85.83 #86.55 (s!82.02 !74 s#84.22 #74.24  s#68.42 #60.28) (s!58.95 !43.27 s58.95 48.3) (s#29.53 #30.35 s#29.05 #27.74 s#34.68 #32.8)
ppg !92.49 #105.87 (s95.69 227.28/113.64)(s231.83 223.73 s220.7 192.3)
pypl  !109.81 (s!108.32 !101.11 s#114.15 #68.08 (s#80.01 #77.78 s79.24 #78.51 s#78.05 #75.85 s#64.1 (#39.39)(s#38 #34.17)
smg !102.38 !109.97 (s!122.53 !106.22 (s!102.69 !97.7 s!110.06 !98.77 (s#97.15 #92.23 (s!89.1 !78.7 (s#80.14 #76.09 (s#73.44 #64.69 (s#75.75 #71.69
swks #91.61 (s!87.13 !76.11 s!120.36 !106.86 (s!116.62 !106.86 s!118.68 !96.34 s!98.95 !89.91 s#98.05 #103.19 s!84.71 !84.76 s!84.71 !84.7 s!84.73 !76.72 s!82.15 !76.98 s!80.7 !76.17 s!75.05 !70.05 s#87.82 #85.26 s!80.227 !70.42 s#90.3 #83.1 s#90.3 #88.15 s102.35 96.33 s#99.62 #97)
tndm !73.9 (s!58.46 !51.38 s!67.98 !60.82 s!66.88 !63.9 s!62.62 !58.57 s!70.71 !63.67 s!66.25 !61.09 s!63.19 !55.74
tsla #432 625.67 (s#536.28 #432 s!315.31 !266.1 s#315.31 #282.25 s!257.04 !243.81 s!246.37 !220.21 c311.45 s338.5 (s!212.69 !185.7 s!212.69 !196.02 c350 s333.4 c340.67 s351.77 c321 s337)
tsn !89.46 !92.45 (!57.78 !84.83 s!63.11 !58 s!55.55 !42.99 s!92.14 !86.04 s#79.6 #76.25 (s#73.45 #70.91 s#65 #61.24 s!61.77 !57.57 s#62.94 #59.62 #62.94 #62.56 s#80.8 62.56 (s#73.57 #74.73 s43.51 41.35)
twlo !95.6 !111.38 !131.05 (s!97.56 !72.36 s!119.24 !114.08 s!119.02 !97.46 s!119.02 !107.01 s#103.99 #92.82 s!145 !138.64 (s!139.78 !129.85 (s#129.28 #117.07
uber !33.21 !41.81 !46.67 (s!26.66 !20.43 s!36.48 !34.63 s!33.97 !31.33 s!29.56 !26.47 s!32.80 !29.44 s!43.06 !40.49
unp !142.03 !170.47 (s#97.97 #101.12)
v !109.76 (s!173.88 !109.76 s!166.54 !154.47 s!136.95 !124.76 s#121.13 #108.54 s#122.67 #118.26 s68.11 65.5 s#67.45 #63.88split4x)(s261.56 213.2)
vrtx !238.53 
vz 57.27 (s#59.97 s#52.53 49.97 s#50.51 #48.24)
wday !145.23 !191.5 (s!142.63 !129.14 s!187.82 !173 s!178.48 !159.8 s#219.42 #205.09 (s!217.86 !202.85 (s#198 #192.75 (s!203.48 !181.2 s#188.83 #126.6
wix 107.59 !144.34 (s!115.17 !101.4 s!140.29 !124.48 s!147.52 !126.5 (s#120.32 #115.67
xlnx !76.97 !88.07 !99.74 !106.22 (s!100.07 !92.69 s116.94 !118.68 !118.42 #115.02 (s#111.27 #105.64 s#110.10 #67.89 (s!87.65 !81.28 s#75.01 #70.63 s71.01 68.75 s73.48 71.39 s#67.17 #65.16 s#73.24 #69.14 s46.69 46.47)
xpo #61.56 #100.69 (s!54.3 !45.2 s#93.79 #86.15 s!78.72 !72.53 s!74.9 !67.48 s#66.41 !57.04 !63.24 s!57.18 !53.48 s!55.98 !53.09 s#61.54 #49.48 s#59.96 #47.5 s#59.96 #55.43 s#110.95 #104.42 s#76.28 #66.69
zts !126.85 (s!127.96 !104.87 s!133 !120.06 s#112.76 #88.47 (s#93.43 #84.22 s#79.01 s#72.22 65.17

#---own-ameritrade

gld  128.25 (s@120.93 #118.8 123.88 121.87  s115.4 113.04 s#116.37 #112.53 s128.5 124.94 s#128.3 #125.55 s#124.95 #119.41 s#125 #111.89 s127.49 s#118.54 @123.67 s#118.54 #115.4 s118.12 104.41 s109.96 105.12 s#115.7 #111.9 s#118.52 #114.7 s#125 #117.92 112.85 #123.67
pgf @18.37 (s@19 @18.89 s@18.945 @18.35 (s@18.6 @18.24)

#---not-own-cores

pld (s!89.67 !71.54 
bac (s!23.55 !21.95 (s#28.68 #29.04 (s!29.13 !25.96 s@27.14 @27.16 s31.685 #29.41 s#31.23 #29.97 s#32.05 #30.84 s#28.07 #24.41 s22.13 s14.54 13.58 s#17.44 17.22) (s#16.72 s#16.05 #15.45 #16.2 s#16.73 #15.25 s#16.09 #15.32)
nxpi (!87.9 !76.54 (s#91.32 #91.99 (s!83.8 !78.22 s!78.81 !74.75 s!82.2 !81.89 s#82.5 #73.71 s#115.42 #115.83
dxcm (s!243.23 !215.46 (s!203.73 !154.06 (s!172.71 !163 (s!153.32 !147.34 (s!152.27 !124.21
wm (s#110.5 #102.16 (#93.02 #87.06 s#85.49 #77.7 s#51.5 #49.36)
mrk (s!85.06 !80.82
gsk (s#45.3 #40.9
bkng (s#1880.8 #1728.8 (s#1864.3 #1899.03
tip (s@@@@@114.7 @@@@@114.4 (s@109.29 @110.54 s@112.03 @111.28 s@112.59 @113.39 s@112.64 @111.51 @114.23 @113.46 s@@@@@114.28 @@@@@114.07) (s@112.04 @112.4 s@114.5 @113)
payx (s#66.41 #64.59
clx  (s#145.45 #145.6 (s#142.22 #142.12 s#135.87 #132.27 s#119.83 #115.38
fiw (s30.7 32.3
ebay (s36.43 #38.63 #38.06 (s#36.83 #34.41 s!33.56 !29.76 s!29.55 !28.1 s#43.51 #40 s35.92 32.51) (s31.11 24.21 s#60 59.86)
ups (s97.07 97.58)
abbv (s#78.64 #113.2 (s#100.38 #100.06 s#118.15 #111.95
nflx (s!298.3 !302.95 s!298.3 !333.85 s#298.3 #364.78 (s!285.22 !266.36 s#356.5 #198.07 (s#329.62 #316.45 s!316.36 !274.19 s!291.76 !277.42 s#363.8 #338.75
d (s70.35 66.59
gild (s#105.9 #101.7)(s71.83 #75.9 #92.75)
wmt
pep
adp
intu
fivn
now
msft
ed
aep
jnj
mdlz
unh
hca
cnc
qcom
logi 
amd 
qcom 
pfe 
mrk
low 
hd

#---watch1

spy
lmt (s#334.18 #334.21 (s!29.31 !297.18 s!270.2 !253.28
uri (s90.86 90.86)
sq (s#74.38 #77.08 (s#76.23 #75.29 (s!75.15 !72.45 s#75.15 #76.64 (s!72.07 !61.79 s%62.6 %56.43 !69.32 !63.3)
shop (s!397.56 !262.9 (s!329.96 !319.14 (s!307.81 !286.56 (s!304.98 !203.09
cmi s#170.9 #166.97
t (s35.1 32.71)
xlu s54.7 48.35
epr s#67.95 #71.30
adsk s!150 !150.44 (s!171.76 !159.4
vmw (s!102.29 !98.58 s#102.29 #125.65 s#102.29 #175.15 s#102.29 #193.08 (s!156.84 !149.17 s!167.16 !158.58 s!159.52 !147.36 s!153.96 !136.03 s!153.96 !144.74 s!177.42 !165.29 s!198.27 !185.93
dow (s!28.49 !23.19 s#28.49 #40.8 s!28.49 !49.53 s!28.49 !54.41 (!53.96 !0 (s!55.51 !49.32 s!46.85 !44.46

algn (!261.59 !266.09 !261.59 !291.64 (s!291.99 !274.87 s!243.84 !203.41 s!212.29 !179.53 s#285.55 #316.21 (s#293.81 #293.19 s!246 !228.68 s!218 !217.27 s!220.09 !198.18 s#244.3 #223.09 s#255.10 #226.83 s#273.45 #254.25 s#233.06 #210.02

(sample output cut short for brevity)

------------------------------- end of stocks-history.txt ----------------------------------------
................ (i cut the file short for brevity sake)



III. stocks-copy-paste-list.sh

copy and paste the script below to a file c:\my\bin\stocks-copy-paste-list.sh. also create stocks-copy-paste-lists.bat in the same directory containing this one line:

sh c:/my/bin/stocks-copy-paste-lists.sh

also create a link to stocks-copy-paste-lists.bat on your desktop (for convenience).

# --------------------------------- stocks-copy-paste-lists.sh -------------------------

echo ""
echo "Listing stocks you own in IRA ..."
list=""
for i in `cat c:/my/finance/docs/stocks-history.txt | sed -n '/^---own-ira/,/^---own-ameritrade/p' | grep -v "^\-\-\-" | sed "s/~//g" | awk '{print $1}'`
do
  list="$i,$list"
done
echo $list | sed "s/,$//"
echo $list | sed "s/,$//" | clip
echo ""
echo count:
echo $list | sed "s/,/ /g" | wc -w
read enter?"The list is now in the clipboard. Enter to continue: "

echo ""
echo "Listing stocks you own in ameritrade ..."
list=""
for i in `cat c:/my/finance/docs/stocks-history.txt | sed -n '/^---own-ameritrade/,/^---not-own-cores/p' | grep -v "^\-\-\-" | sed "s/~//g" | awk '{print $1}'`
do
  list="$i,$list"
done
echo $list | sed "s/,$//"
echo $list | sed "s/,$//" | clip
echo ""
echo count:
echo $list | sed "s/,/ /g" | wc -w
read enter?"The list is now in the clipboard. Enter to continue: "

echo ""
echo "Listing cores you do not own ..."
list=""
for i in `cat c:/my/finance/docs/stocks-history.txt | sed -n '/^---not-own-cores/,/^---watch1/p' | grep -v "^\-\-\-" | sed "s/~//g" | awk '{print $1}'`
do
  list="$i,$list"
done
echo $list | sed "s/,$//"
echo $list | sed "s/,$//" | clip
echo ""
echo count:
echo $list | sed "s/,/ /g" | wc -w
read enter?"The list is now in the clipboard. Enter to continue: "

echo ""
echo "Listing watch1 ..."
list=""
for i in `cat c:/my/finance/docs/stocks-history.txt | sed -n '/^---watch1/,/^---watch2/p' | grep -v "^\-\-\-" | sed "s/~//g" | awk '{print $1}'`
do
  list="$i,$list"
done
echo $list | sed "s/,$//"
echo $list | sed "s/,$//" | clip
echo ""
echo count:
echo $list | sed "s/,/ /g" | wc -w
read enter?"The list is now in the clipboard. Enter to continue: "

echo ""
echo "Listing watch2 ..."
list=""
for i in `cat c:/my/finance/docs/stocks-history.txt | sed -n '/^---watch2/,/^---end-watch2/p' | grep -v "^\-\-\-" | sed "s/~//g" | awk '{print $1}'`
do
  list="$i,$list"
done
echo $list | sed "s/,$//"
echo $list | sed "s/,$//" | clip
echo ""
echo count:
echo $list | sed "s/,/ /g" | wc -w
read enter?"The list is now in the clipboard. Enter to continue: "

read enter?"The list is now in the clipboard. Enter to continue: "

# ------------------------------ end of stocks-copy-paste-lists.sh ---------------------------

IV. create the portfolios

create portfolios on yahoo finance similar to this:


double click the stocks-copy-paste-lists.bat icon on your desktop. each prompt will have the list for that group already on the clipboard so you only have to paste (ctrl-v) on the "add symbol" edit box in each of your portfolio.

note that you can link a yahoo portfolio to your brokerage account. unfortunately you need to keep on relinking every time you add or remove a stock so it's better to just update manually. a portfolio linked to a brokerage account also cannot use your custom view so this is another reason why i don't link to my brokerage account.

V. create the custom view

create a custom view similar to the following:


click "create new view" then add the fields or columns. i use search and replace feature of the browser to quickly find the column names.

for the columns to show up, make sure you are logged in to your yahoo account or email account on another tab in the browser. or else you just get the standard columns. sometimes you also need to refresh the browser to populate the columns.

if you choose to inspect the stocks manually it's not really that bad. usually on an average trading day only 5-10 stocks buck the market trend. it's color coded (red for down, green for up) so it's much easier and faster. you could also click the "change %" column to sort it so you just have to look at the top and bottom to quickly see which stocks significantly bucked the market. but the stock-inspector script is still useful because you still need to check how much is changed from your last buy.

VI. using stock-inspector script

create a notepad file and create an icon on the desktop. mine is c:\tmp\buffer.txt.  this is where you copy and paste your yahoo portfolio(s).

change the $history (e.g. c:/my/finance/docs/stocks-history.txt) and $quotes (e.g. c:/tmp/buffer.txt) variables in the beginning of stock-inspector.pl to reflect the name and location of your notepad files.

to get recommendations on which stocks to buy and sell that day, simply double click the buffer notepad file, delete any previous content, copy and paste your yahoo portfolio(s) to buffer.txt and then double click the stock-inspector.pl script.

the buffer notepad file should look something like this:

LLY 151.11 +4.63% 16.99 19.57 1.84 52.60 144.618B 2.05% +49.08% -0.29% 1.44
AMZN 2,283.32 +5.28% 99.23 57.50 2.37 18.32 1.137T - +40.42% -0.38% 0.74
CCI 165.78 +5.56% 92.61 60.73 3.52 6.57 69.089B 3.06% +45.19% -1.76% 2.18
VRTX 262.41 +4.02% 58.18 25.83 1.19 11.17 68.035B - +60.32% -1.88% 1.58
AMT 255.10 +2.14% 60.17 51.02 2.78 22.35 113.125B 1.59% +46.34% -2.05% 1.08
ABT 89.14 +4.27% 43.27 24.69 3.06 5.05 157.192B 1.68% +44.68% -3.58% 1.26
AWK 133.61 +5.01% 38.95 31.51 4.17 3.95 24.186B 1.57% +45.23% -5.71% 1.26
NSRGY 107.61 +1.75% 40.24 - - 5.80 310.076B 2.61% +22.28% -6.32% -
CAG 33.34 +4.32% 21.17 14.69 1.72 2.09 16.239B 2.66% +46.04% -6.32% 1.86
VZ 58.14 +2.59% 12.50 11.51 3.77 3.92 240.7B 4.34% +19.04% -6.56% 1.07

(sample output cut short for brevity)
............

VII. using realized-gain.pl and unrealized-gain.pl

even if you made a lot of money on a stock through range trading, your brokerage portfolio will usually show a loss for that stock because it only takes into account your current holding and not the previous sells where you made a profit. even quicken is very poor at tracking your overall gains/loss for a specific stock because it does not include the specific lots for a transaction when it imports the data from the brokerage (that is if your brokerage allows you to assign specific lots and you are disciplined enough to always assign the correct lots. tdameritrade does not allow you to assign specific lots, just those useless LIFO and FIFO options). so i wrote a simple script to assist you in doing this.

i did not really automate it that much. it still involves some minor editing after you copy and paste to the buffer but this is ok because you only do this very rarely and it's not important. what's important is the overall growth of your portfolio. i only use these scripts to see how much is my total gain/loss of a stock when i have to take it off my core list because the thesis is broken. example, after my classmate jay montecillo informed me all theatres in america are now in imax, i wondered why the stock is still around 50% from it's highs. i haven't been to america in 4 years so i researched it and found out there are already many alternatives to imax and those are the ones being installed instead of imax. so my long term thesis of "in the future all theatres will be imax" has been broken. i sold imax at $22. my last buy was at $37. looks like a big loss but when i computed all my range trading profits using the realized-gain.pl script, turns out i just broke even.

here's the realized-gain.pl script: (installing it is similar to stock-inspector.pl):

open(BUF, "c:/tmp/buffer.txt") or die "Can't open $ARGV[0].csv $!\n";

$total = 0;

while (<BUF>) {

  print;
  chomp;

  ($s,$b) = split;
  if ($s) {
    $s =~ s/s//;
    $s =~ s/\(//;
    $s =~ s/\)//;
     
    $hasprefix = 1;
    $prefix = substr($s,0,1);
    if ($prefix eq "%") {
      $cost = 500;
    } elsif ($prefix eq "!") {
      $cost = 1000;
    } elsif ($prefix eq "#") {
      $cost = 2000;
    } elsif ($prefix eq "@") {
      $cost = 10000;
    } else {
      $cost = 5000;
      $hasprefix = 0;
    }
  
    if ($hasprefix) {
      $s = substr($s,1);
      $b = substr($b,1);
    }
  
    #print "s=$s, b=$b, prefix=$prefix\n";
  
    $gain = ((($s - $b) / $b) * $cost) - 9;
    
    $total = $total + $gain;
  
    printf("%.2f\n",$gain);
  }
}
print "total:\n";
printf("%.2f\n",$total);

print "Press enter to continue: ";
$enter = <STDIN>;

just copy and paste the realized transactions to buffer.txt and then break it up into "sell - buy" pairs by putting the cursor on each "s" character and pressing enter. example the imax line:

(s#22 #37.7 (s!22.41 !21.37 s!23.22 !20.61 s!20.01 !18.55 s#20.55 #20.7 s#22.96 #20.77 s!25 !22.75 (s#31.99 #30.22 s#34.92 #31.98 s#42.54 #40.85)

becomes:

s#22 #37.7 (
s!22.41 !21.37 
s!23.22 !20.61 
s!20.01 !18.55 
s#20.55 #20.7 
s#22.96 #20.77 
s!25 !22.75 (
s#31.99 #30.22 
s#34.92 #31.98 
s#42.54 #40.85)

then you simply double click the "realized-gain.bat" icon on your desktop. here's the output for the example above:

C:\my\bin>perl c:\my\bin\realized-gain.pl
s#22 #37.7 (
-841.89
s!22.41 !21.37
39.67
s!23.22 !20.61
117.64
s!20.01 !18.55
69.71
s#20.55 #20.7
-23.49
s#22.96 #20.77
201.88
s!25 !22.75 (
89.90
s#31.99 #30.22
108.14
s#34.92 #31.98
174.86
s#42.54 #40.85)
73.74
total:
10.16
Press enter to continue:

if a sell transaction involves multiple buy lots, then just break it up. example if i have "s#30 !25 !27" then break it up into:

s!30 !25
s!30 !27

as i said earlier, the total gain/loss in your brokerage or quicken portfolio is useless. to know the true unrealized gain/loss, use unrealized-gain.pl (setting it up is also similar to realized-gain.pl):

open(BUF, "c:/tmp/buffer.txt") or die "Can't open $ARGV[0].csv $!\n";

$total = 0;

print "Enter the current price: ";
$price = <STDIN>;

while (<BUF>) {

  print;
  chomp;

  @buys = split;

  foreach (@buys) {

    print "$_\n";
    $hasprefix = 1;
    $prefix = substr($_,0,1);
    if ($prefix eq "%") {
      $cost = 500;
    } elsif ($prefix eq "!") {
      $cost = 1000;
    } elsif ($prefix eq "#") {
      $cost = 2000;
    } elsif ($prefix eq "@") {
      $cost = 10000;
    } else {
      $cost = 5000;
      $hasprefix = 0;
    }
  
    if ($hasprefix) {
      $buy = substr($_,1);
    } else {
      $buy = $_;
    }

    $gain = ((($price - $buy) / $buy) * $cost) - 9;
    
    $total = $total + $gain;
  
    printf("gain: %.2f\n\n",$gain);
  }
}
print "total:\n";
printf("%.2f\n",$total);

print "Press enter to continue: ";
$enter = <STDIN>;

simply copy and paste the unsold lots into the buffer. this is the string in between the stock name and "(". then double click the unrealized-gain.bat icon on your desktop.

the scripts ignore commented lines that start with #. so i can put miscellaneous notes in stocks-history.txt. example is total gain/loss on the stocks that show up as a big loss in my brokerage account:

#alb @63.68 1,290 gain - 3,292 = 2,002 loss
#ba @141 3,042 gain - 2,586 loss = 456 gain
#fdx @125 1,713 gain - 2,459 loss = 746 loss
#pcrfy @7.45 664 gain - 971 loss = 307 loss
#xpo @58.13 2,383 gain - 956 loss = 1,427 gain
#uber @27.75 682 gain - 986 loss = 304 loss
#tsn @61.41 1,307 gain - 649 loss = 658 gain
#dal @24.54 592 gain - 794 loss = 202 loss
#nclh @12.35 1,111 gain - 792 loss = 319 gain
#lw @60.7 1,408 gain - 516 loss = 892 gain
#glw @20.7 636 gain - 560 loss = 76 gain
#fslr: 1,418 realized gain

xpo and ba appears as a huge loss in my brokerage account but i actually made lots of money on those 2 stocks because of range trading. note alb (lithium) is an example of a stock where i have a big loss but i'm not selling because the thesis is not broken. i believe electric cars and lithium batteries will be the future.

VIII. displaying all charts in 1 page

if you want to see the charts of 50 stocks  in 1 page without having to click a thousand times, use the micro charts feature of ameritrade (although i rarely use charts nowadays because the 52 week low/high % change columns is good enough for me). just create a watch list in ameritrade and add the stocks using copy and paste (stocks-copy-paste-lists.sh). then just delete the entire watch list because chances are when you come back to view the charts again the lists are already very different. it's quicker to just delete and recreate using stocks-copy-plaste-list than edit the list. there is a limit of 50 stocks per watch list in ameritrade so stocks-copy-paste-list copys to clipboard 50 at a time. sample output:

C:\my\bin>sh c:\my\bin\stocks-copy-paste-lists.sh

Listing stocks you own in IRA ...
v,unp,uber,adp,tsn,tsla,tndm,swks,smg,pypl,ppg,podd,pgf,pcrfy,panw,okta,nvda,nvcr,nsrgy,nclh,mrvl,mdt,lyft,lw,loco,lly,jpm,isrg,glw,goog,fslr,fmc,fdx,fb,ew,wmt,dal,ctva,crm,cci,cag,mcd,ba,awk,avgo,amt,amzn,alb,abt,aapl

count: 50
The list is now in the clipboard. Enter to continue:

zts,cost,xpo,xlnx,etn,wday,vz,vrtx

count: 8
The list is now in the clipboard. Enter to continue:





----------------------------------- obsolete ----------------------------------------------------------------

update on 6/3/17:

oh crap the day has finally arrived. no more magic magic for me. as i expected yahoo finally upgraded from static to dynamic pages. so my stock stalker script is dead and will be laid to rest. it's still usable but much slower and less convenient. just change stock-charts.sh to the script below. instead of 1 page showing all the charts in the list, it will open a separate tab for each stock, so instead of taking just a few seconds to review a list of 20 stocks it can now take around 15 minutes. yikes !!! if you have ameritrade account you can use the micro chart feature of watch list to instantly display all the charts in a single page. you can still use the centralized text file, just delete and create a new watch list every time so you can just blindly copy and paste the list (ok to include commas).

# stock stalker script
# by ian crystal

list=c:/my/finance/docs/mm-categ.txt
i=1
lc=`wc -l $list | awk '{print $1}'`
while [ "$i" -le "$lc" ]
do
  line=`sed -n "${i}p" $list | sed "s/ //g"`
  if [ ! "$line" = "" ]
  then
    stocks=`echo $line | sed "s/.*;//"`
    if [ ! "$stocks" = "" ]
    then
      categ=`echo $line | sed "s/;.*//"`
      echo ""
      echo ""
      echo ""
      echo "$categ   $stocks"
      echo ""
      read enter?"Enter to continue,s to skip: "
      if [ ! "$enter" = s ] && [ ! "$enter" = S ]
      then
        stock_list=`echo $stocks | sed "s/,/ /g"`
        for s in $stock_list
        do
          echo $s
          #read enter?"Enter to continue,s to skip: "
          #if [ ! "$enter" = s ] && [ ! "$enter" = S ]
          #then
            "C:/Program Files/Google/Chrome/Application/chrome.exe" https://finance.yahoo.com/quote/$s
          #fi
        done
      fi
    fi
  fi
  i=`expr $i + 1`
done


original post:

i wrote a simple yet very powerful shell script to easily monitor stocks. i can monitor 50 stocks in less than 10 minutes a day. this tool is used in conjuction with my blog article "investing 101".
------------------------------------------------------------------
# stock stalker script
# by ian crystal

list=c:/my/finance/docs/mm-categ.txt

i=1
lc=`wc -l $list | awk '{print $1}'`
while [ "$i" -le "$lc" ]
do
  line=`sed -n "${i}p" $list | sed "s/ //g"`
  if [ ! "$line" = "" ]
  then
    stocks=`echo $line | sed "s/.*;//"`
    if [ ! "$stocks" = "" ]
    then
      categ=`echo $line | sed "s/;.*//"`
      echo ""
      echo ""
      echo ""
      echo "$categ   $stocks"
      echo ""
      read enter?"Enter to continue,s to skip: "
      if [ ! "$enter" = s ] && [ ! "$enter" = S ]
      then
        "C:/Program Files/Google/Chrome/Application/chrome.exe" http://finance.yahoo.com/quotes/$stocks/view/dv
      fi
    fi
  fi
  i=`expr $i + 1`
done
-----------------------------------------------------------------------

i maintain a text file containing the stock symbols. this file is actually the input to the script above. each line contains a sector, group or category. the group name and stock symbols are separated by a semicolon and the stock symbols are separated by commas. i usually rank the stocks and the sectors, moving and shuffling their position using basic copy and paste as their rank changes, except for the pseudo groups which i always keep on top.

my pseudo groups are:
1) own - stocks i own
2) sold - stocks i don't own anymore
3) radar - stocks i put under my radar
4) sector etfs - i use this to monitor sector rotations

an example of my category file is at the end of this article. for added convenience, i created a one line .bat file (sh c:\my\bin\stock-charts.sh) that calls this script and created a link in my desktop. i also created a desktop link to the category file. this way when i want to edit the file, i just double click on the link in the desktop and when i want to see the charts i just double click the link of the bat file in the desktop.

here is a video demo - http://youtu.be/uyiQb-8S8K4

the most important information you need to monitor daily is which stocks bucked the market. in fact, i even ignore everything else. whenever a stock  significantly goes against the market movement, i check the headlines to see what's going on. usually on an average day only 2 or 3 stocks buck the market trend so usually it just takes me less than 10 minutes to check my 40+ stocks.

i click on the "basic" view tab and quickly scan through the % change column to see if any stock bucked the market significantly. example, if the market is up 0.5%, then i look for any that is down at least 0.5%. if it's only down like 0.2%, i just ignore it. however if it's up more than 2% then that would also catch my attention and i look at the headlines for that stock to find out what's going on.

i use a similar technique to easily view the charts of the stocks in my fidelity account. i create a dummy container text file and add a link to it in my desktop. to view the charts i simply double click the link to the dummy file in my desktop, then copy and paste the "positions" table from the fidelity web page to this text file, then double click on the a link in the desktop that runs a .bat file containing "sh c:\my\bin\stocks-own.sh". the following are the contents of the stocks-own.sh script:

# stocks-own script 
# by ian crystal
list=""
for i in `cat c:/tmp/tmp-paste.txt | grep -i "show lots for" | sed "s/.* //"`
do
  list="$list,$i"
done
"C:\Program Files\Google\Chrome\Application\chrome.exe" http://finance.yahoo.com/quotes/$list/view/dv

To compare stocks or sectors with the overall market (SPY), i use this script (the implementation is similar to the scripts above.  the demo is included in the video):

-----------------------------------------------------------------------

#stock-charts-compare script
#by ian crystal

echo ""
echo ""
# possible values: 1d 5d 1m 3m 6m 1y 2y 5y my
read range?"Enter the time range. Possible values: 1d 5d 1m 3m 6m 1y 2y 5y my (my is maximum). default is 1m: "
if [ "$range" = "" ]
then
  range=1m
fi

list=c:/my/finance/docs/mm-categ.txt
i=1
lc=`wc -l $list | awk '{print $1}'`
while [ "$i" -le "$lc" ]
do
  line=`sed -n "${i}p" $list | sed "s/ //g"`
  if [ ! "$line" = "" ]
  then
    stocks=`echo $line | sed "s/.*;//" | sed "s/,/ /g"`
    if [ ! "$stocks" = "" ]
    then
      categ=`echo $line | sed "s/;.*//"`
      while echo $stocks | grep -i "[a-z]"  > /dev/null
      do
        five=`echo $stocks | awk '{print $1,$2,$3,$4,$5}'`
        stocks=`echo $stocks | awk '{print $6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25}'`
        echo ""
        echo ""
        echo ""
        echo "$categ   $five"
        echo ""
        read enter?"Enter to continue,s to skip: "
        if [ ! "$enter" = s ] && [ ! "$enter" = S ]
        then
          five=`echo $five | sed "s/ /%2C/g"`
         "C:/Program Files/Google/Chrome/Application/chrome.exe" "http://finance.yahoo.com/q/bc?s=SPY&t=$range&l=on&z=l&q=l&c=$five"
        fi
      done
    fi
  fi
  i=`expr $i + 1`
done

--------------------------------- sample category file --------------------------------------------

own;spy,AAPL,abt,adp,ALB,AMZN,awk,BA,BAC,clx,crm,ebay,ew,FB,fdx,FMC,FSLR,GLD,GLW,GOOG,gsk,IMAX,isrg,lmt,LNG,lly,lw,mdt,nclh,NFLX,nvda,nue,nxpi,payx,pcrfy,pep,pgf,podd,PYPL,rht,smg,sq,SWKS,THM,ttip,TSN,unp,V,VZ,wday,wm,XLNX,xpo,zts

etfs;ephe,lit,fiw,gld,slv,pgf,ibb,xph,tip,xlu,tlt,hyg,jnug,tan,qqq,ixp,xlf,xle,xlk,xli,xlv,xlp,xlb,rth,xhb,iyr,soxx,oih,uso,ung,jjc,moo,fxe,fxi,corn,ctnn,cane,cafe

* exclude those inside () - they are just for reference purposes

utilities:water;awk,(fiw)
energy:natgas-export;lng,d,(glng,glog)
tech:cloud:software;wday,crm,rht,ctxs,vmw,(dbx,box,now,splk)
tech:semis;nvda,xlnx,amd,qcom,avgo(cy,tsm,intc)
healthcare:devices;ew,mdt,abt,isrg
healthcare:diabetes;lly,podd,dxcm(nvo)
transports:aerospace;ba
healthcare:asthma;gsk
industrial:chemical;dwdp,(ppg)
selfies;algn,(ulta,elf)
pets;zt,(idxx,hsic,woof,frpt,pets,trup)
defense;lmt,ba,(rtn,noc)
tech:5g;swks,vz,glw,cien,acia,amt,cci,xlnx,mrvl,aapl,qcom
batteries;fmc,alb,pcrfy,tsla
energy:solar;fslr,(csiq,scty,tan)
creditcards;v,(dfs,ma,axp)
fintech;pypl,(sq)
telco:carrier;vz,(t,s,tmus)
ecommerce:logistics;xpo,pld
ecommerce:delivery;fdx,(ups)
ecommerce:retail;amzn,wmt,(ebay,etsy,baba,shop,meli)
internet:advertising;goog,fb,(bidu)
leisure:movies:streaming;nflx
food:agriculture;fmc,(mon,bg,de)
payroll;payx,adp
leisure:theme-parks;fun,(dis,six)
leisure:travel:cruise-ships;nclh,(ccl,rcl)
internet:security;panw(feye,ftnt,pfpt,chkp,cybr)
tech:sw:subscription;intu,adsk,adbe
transports:rails;unp,(csx)
cellphones;aapl

(no moat but overwhelming demand or winning brands)
food;tsn,lw,(mkc,khc,hsy,calm,bgs,hain,cag,gis,k,hrl)
healthcare:hospitals;hca
consumer.staples;clx,(cl,kmb,hele,pg,un)
food:bev:alcohol;stz,(deo,bf.b,beam,bud)
food:bev:coffee;ko,(sbux)
food:bev;pep,(ko,mnst)
internet:travel;bkng,(expe)
datacenters;amd,nvda,(eqix,cone,cor,dlr)

------- watch list (don't buy)  --------------

(too tough)
healthcare:drugs;abbv,biib,gild,pfe,jnj,mrk,bmy

(political risk)
*healthcare:hmo;unh,cnc,wlp,aet,syk
*commodities:steel;nue,x,aks

(industry/economic cycle)
*airlines;dal,luv,ual,jblu
infrastructure;vmc,uscr,uri,flr,fwlt,jec
industrial;cat,emr,hon,utx,tkr,ge,sna,etn,mmm,joy,ir,spw,ph,col,cbe,dov
tech:cloud:hardware;ntap,csco,jnpr,rvbd,emc,ibm,tdc,mlnx,ffiv
transports:trucks;pcarr,cmi,nav
natgas.buyers;ppg,pol,ce
transports:dry-shipping;dsx,balt,drys
housing;shw,tol,len,hd,low,usg,wy,swk,mas,twx,spf,bbby,pir,dhi
reits;nly,arcp,hta,lry,agnc,slrc,kfn,bdn,aec,wre,egp,frt,vtr,hcn,pcl,arct,kim
tech:sw:pc:msft
specialty-metals;aa,arnc,ati

(lack of recurring purchase or need to keep producing hits)
tech:video-games;ttwo,(ea,gme)
tools;sna,itw,swk
guns;cab,aobc

(no moat, fickle consumers, difficult to game)
marijuana;cgc,gwph,smg
food:chains;mcd,dpz,cmg,shak,bwld,jack,dnkn,yum,dri,pnra
retail:dollar-stores;five,dg,dltr
transports:food-delivery;grub
hotels;hot,wyn
casinos;lvs,wynn,mgm
healthcare:dialysis;dva
healthcare:biotech:generics;prgo,teva
auto;tsla,gm,f,tm,mga,jci,kmx,axl,dan,lad
insurance;aig,met,pru,pfg,lnc,gnw,hig
ultra.discretionary;kors,coh,rl,pii,wsm,bc
apparel:retail:lowend;rost,tjx
apparel;ua,vfc,lulu
apparel:shoes;nke,skx,ua,ads
apparel:blue-collar;ctas,www,hbi
apparel:retail:midend;pvh,tgt,m,asna,gps,kss,chs,sks,jwn
apparel:retail:teen;anf,expr,aeo,hott,psun
retail:drugs;wag,cvs,esrx
food:groceries;cost,swy,wfm

(industry threatened)
*movies-theatres;imax,amc
*autoparts:retail;azo,orly,pby,jci,mga
*finance:banks;bac,jpm,san,wfc,usb,c,gs,key
entertainment:cable-satellite;cmcsa,chtr,dish
telco:towers;amt,cci,sbac
commod:mining;fcx,bhp,nem,ng
tech:sw:enterprise;sap,ibm,orcl,tibx,acn
cigarettes;pm,mo
utilities:electricity;xlu,d,ngg,duk,aep,ed,te,so,fe,cpl,at
*energy:oil;eog,rds.a,xom,cop,cvx,bp,nbl,xec,cog,gpor,sto,wll,sd,sto,enb,mro
energy:oil:service;slb,hal,clb,keg,esv,sdrl,nov,wft
energy:natgas;swn,dvn,chk,cop,upl
energy:natgas:spec;clne,gtls,wprt,se
energy:mlp-pipelines:energy;kmi,mmp,enb,paa,etp,wes,sdr,eroc
transports:rails:oiltanks;arii,trn
transports:shipping:oil;nat



(for more of my knowledge bombs, click the "ian's knowledge bombs" banner at the top of this article and choose any article in the table of contents that piques your interest)


No comments:

Post a Comment