SBYC Wet Wednesday May 8, 2019 on J70 Escape

SBYC Wet Wednesday, May 8, 2019, on J70 Escape. Had a good start and first leg.

Speed summary in Knots:

 Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
1.985   4.607   5.132   5.105   5.594   7.797

Youtube video processed with GoPro Quik and MP4Joiner:

Youtube video processed with RaceRenderer:

It takes a long time to render a video for youtube. I timed myself once. It is about five hours on a good day. It takes about twenty minutes to transfer close to 23 gigabytes of video. To make matters worse, GoPro records in chapters that are about 3.97 gigabytes long. The 78-minute video is five chapters.

It is not easy to create a long video. The tools for stitching the videos together with gauges and telemetry is lacking. If I create the video with GoPro’s Quik, I have to first turn on the gauges that I want, then create a clip. Lastly, I use a program called mp4joiner.

Another option would be the preferred Dashware. Problem with Dashware is just not supported. It does not extract the telemetry data properly.

I am currently trying out RaceRenderer. What is good about it is that it does join the videos, extract the telemetry properly and saves a CSV for later analysis. It has plenty of gauges. Problem is, I like the look of the gauges from GoPro’s quick better. Well, you can’t have it all.

If my team likes RaceRenderer better, I might just go forward. I have done the work for the template. It just might make it easy on me to get the job of processing the videos.

If you have an oppinion about the two methods, let me know in the comments.

SBCC Wet Wednesday on Escape April 17, 2019

This Wednesday was better than expected. All the weather reports suggested that the wind would be less than ten knots. We had some mild white caps instead.

We are doing better. We were not in the front of the pack, but we kept up with the others. On a downwind run, I allowed the boat behind us to steal wind. Plus I forgot that I was on starboard. I could have some fun on that one.

The video I got is time-lapsed. Not as fun (for me) than regular video. No sound.

I used to sail light. Now I have at least one more than necessary. I actually find it comforting not to have to worry about not having enough hands on board. I can single and double-hand my j70, just do not feel like it lately.

SBYC Wet Wednesday March 20, 2019 on J70 Escape

Last Wet Wednesday was special for me. We won. My boat Escape and my team were not even expected to come even close to the other three competors. I did not have my new regatta sails up. Yet we won. We had an excellent start. We sailed a conservative race. Our spinnaker douses where early so that we would not pass the mark. All in all, it was a good day.

Since the GPS data on my GoPro was a little wonky, this a summary from the extracted files with anything over 20 statute miles per hour deleted:

Speed summary in mph


1st Qu.



3rd Qu.








It 12+ mph or 11.3 knots is not bad!

I was surprised that we made it onto drone footage. It was very cool to see us on one of our better days! Starts at 15:08.

J/70 Boat Handling

Good videos for J/70 handling. Section 3 - Tack and Gybe is put first since it is basic sailing of the boat. I am adding more videos from North Sails that I feel is good for learning how to sail the boat.

Section 3 - Tack and Gybe

Step by step video on how to tack and gybe the J/70

Section 1 - Spinnaker Set Up

Step by step video on how to set up the J/70 spinnaker

Section 2 - Spinnaker Take Down

Step by step video on how to take down the J/70 spinnaker

Sailing Wing and Wing on a J/70

The fleet I sail in, all the top sailers do it. It may not be as fast or fun, but in the right conditions you cannot beat the VMG. A good article on VMG can be found here: Why VMG Matters

Generating O’Shaughnessy’s Trending Value w/R

This is my code for creating O’Shaughnessy’s Trending Value screen. Not my best code since it was origionally for my personal and private consumption. It uses AAII Stock Investor Pro's exported data. I figured that it might not be bad to share.

TrendValue.R (Source)

# Trend Value

#fix dplr undef13

rm(list = ls(all = TRUE))

# library(dplyr)
# library(quantmod)
# library(xlsx)

pacman::p_load(bindrcpp,dplyr, quantmod, xlsx, rio)

#Momentum will be Regression Relative Strength instead. 126 == 6 month

# 21,42,63,126,189
trenddays <- 126
SIGMA <- 0

       setwd("C:/Users/msghe/OneDrive/Stocks/R"), setwd("C:/Users/michael/SkyDrive/Stocks/R"))

stockdata <-
           header = FALSE,
           stringsAsFactors = FALSE,
           na.strings = '-99999999.990')
stocknames <-
    header = FALSE,
    stringsAsFactors = FALSE,
    na.strings = '-99999999.990'
stocknames[, 1]
names(stockdata) <- stocknames[, 1]

#clean ticker name for yahoo finance
stockdata$TICKER <- gsub('.', '-', stockdata$TICKER, fixed = TRUE)
# Remove bad tickers

#NA bad data
# stockdata[stockdata == -99999999.990] <- NA

stockdata <- stockdata[complete.cases(stockdata$TICKER),]

#Create all stock universe

# All stocks is 150 million in  1995 $$. It is adjusted to todays dollors. All
# stocks exclude over the counter.

# min.mark.cap <- quantile(stockdata$MKTCAP, na.rm = TRUE)[[2]]

#find inflation Market Cap 150 @ 1995
getSymbols("CPIAUCSL", src = "FRED")
deflator  <-
  last(Cl(to.yearly(CPIAUCSL)))[[1]] / Cl(to.yearly(CPIAUCSL))['1995'][[1]]

tvminmarketcap <- 150 * deflator

allstock <- stockdata[stockdata$MKTCAP >  tvminmarketcap,]

# stockdata[stockdata$MKTCAP > quantile(stockdata$MKTCAP, na.rm = TRUE)[[4]],]

#Minimum market cap for later sanity

#I will not invest in over the counter
condition <- c("N - New York", "A - American", "M - Nasdaq")
allstock <- filter(allstock, EXCHG_DESC %in% condition)
# min.mark.cap <- median(allstock$MKTCAP, na.rm = TRUE)
# min.mark.cap <- quantile(allstock$MKTCAP, na.rm = TRUE)[[2]]
#add market cap requirement
# allstock <- filter(allstock, MKTCAP > min.mark.cap)
#Minimum Market Cap

#Start Ranking the stocks

#Calculate VC2
#subtract ntile from 101 to reverse (correct) Order. So Small is big
allstock$PBVPS.Rank <- 101 - ntile(allstock$PBVPS, 100)
allstock$PE.Rank <- 101 - ntile(allstock$PE, 100)
allstock$PSPS.Rank <- 101 - ntile(allstock$PSPS, 100)
allstock$EVEDA_12M.Rank <- 101 - ntile(allstock$EVEDA_12M, 100)
allstock$PCFPS.Rank <- 101 - ntile(allstock$PCFPS, 100)
allstock$SHY.Rank <- ntile(allstock$SHY, 100)

#Stocks with no rank get 50
allstock$PBVPS.Rank[$PBVPS.Rank)] <- 50
allstock$PE.Rank[$PE.Rank)] <- 50
allstock$PSPS.Rank[$PSPS.Rank)] <- 50
allstock$EVEDA_12M.Rank[$EVEDA_12M.Rank)] <- 50
allstock$PCFPS.Rank[$PCFPS.Rank)] <- 50
allstock$SHY.Rank[$SHY.Rank)] <- 50

#Sum the Ranks
allstock$SumRank <-
  allstock$PBVPS.Rank + allstock$PE.Rank + allstock$PSPS.Rank + allstock$EVEDA_12M.Rank + allstock$PCFPS.Rank + allstock$SHY.Rank

# Calculate VC2
allstock$VC2 <- ntile(allstock$SumRank, 100)

#Get top 10% of allstock

tvstocks <- filter(allstock, VC2 > 70)

#I like Fscore >= 5, Z score >=3
# However, just use Fscore >= 7

#Clean data
tvstocks <- tvstocks[complete.cases(tvstocks$FSCORE_12M),]
# tvstocks <- tvstocks[complete.cases(tvstocks$ZSCORE_Q1),]
#Zscore Prime
# tvstocks <- tvstocks[complete.cases(tvstocks$UDEF13),]

#weed out must sells
# tvstocks <- filter(tvstocks, FSCORE_12M >= 4, ZSCORE_Q1 >= 1.8)
tvstocks <- filter(tvstocks, FSCORE_12M >= 7)
#My Market Cap Needs
# tvstocks <- filter(tvstocks, MKTCAP > min.mark.cap)
# tvstocks <- filter(, YIELD > 0)

#Final Cleaning
# tvstocks <- tvstocks[complete.cases(tvstocks$RPS_6M),]
# tvstocks <- tvstocks[complete.cases(tvstocks$RS_26W),]
# tvstocks <- filter(tvstocks,RS_26W > 0)
# tvstocks <- filter(tvstocks,RS_26W >= median(allstock$PRCHG_26W, na.rm = TRUE))
tvstocks <- filter(tvstocks,PRCHG_13W >= median(allstock$PRCHG_13W, na.rm = TRUE))

# head((screen[order(as.numeric(screen$SCORE), decreasing =  TRUE),]),25) #[1]
# head((screen[order(as.numeric(screen$SCORE), decreasing =  TRUE),]),25) #[1]

# names(stockdata) <- stocknames$V1
# screen.rpt <- left_join(screen, stockdata, by = "TICKER")
# screen.rpt <- arrange(screen.rpt, desc(as.numeric(SCORE)))
# screen.rpt$SCORE <- round(as.numeric(screen.rpt$SCORE), 4)
# # screen.rpt <- arrange(screen.rpt, desc(as.numeric(PRCHG_26W)))
# nrow(screen.rpt)

# stockenv <- new.env()
# getSymbols(tvstocks$TICKER, env = stockenv, adjust=TRUE)
# getSymbols(tvstocks$TICKER, env = stockenv)

# rm(screen)
# Keep it simple, stop using RRS
# tvstocks[,"krs26"] <- NA
# for (i in ls(stockenv)) {
#     print(i)
#     # tvstocks[tvstocks$TICKER == i,"krs26"] <- last(Ad(stockenv[[i]]),1)[[1]]/last(SMA(Ad(stockenv[[i]]),126),1)[[1]]
#     tvstocks[tvstocks$TICKER == i,"krs26"] <- last(Ad(stockenv[[i]]),1)[[1]]/ mean(last(Ad(stockenv[[i]]),126))
# }

screen.rpt <- arrange(tvstocks,desc(as.numeric(PRCHG_26W)))
# screen.rpt <- arrange(tvstocks,desc(as.numeric(RPS_6M)))
# screen.rpt <- arrange(tvstocks,desc(as.numeric(krs26)))

screen.rpt <-


  head(screen.rpt, 25),
  sheetName = "Money",
  append = FALSE,
  row.names = FALSE

rio::export(head(screen.rpt, 25),"MoneyPicks.csv")

Popular Objects

Out of boredom on a rainy Saturday, I had reconfigured my blog. I kept the s3 bucket, but changed DNS providers and started using CloudFront. One of the reports is called: CloudFront Popular Objects Report. Sad to say, the most popular object had to do with a WordPress live writer exploit.


SBYC CHRF Spring 2 on J70 Escape

This Sunday we sailed out for SBYC 2019 CHRF Spring 2. We knew that there was a gale and small craft warning during the race. Santa Barbara forecasts tend to be iffy. You really cannot decide till the time of the race and sometimes afterward.

Issued: 2:32 PM Feb. 16, 2019 – National Weather Service


\* Winds...Northwest winds 20 to 30 kt with gusts to 40 kt are

expected when winds are strongest.

\* Seas...Combined seas of 8 to 10 feet with periods around 9
seconds are expected when waves are largest.



A Gale Warning means winds of 34 to 47 knots are imminent or
occurring. Operating a vessel in gale conditions requires
experience and properly equipped vessels. It is highly recommended
that mariners without the proper experience seek safe harbor
prior to the onset of gale conditions.

We were a little lite Sunday. Could have used an extra 150 to 200 pounds on the boat. I am still happy that everyone wanted to go out. The call to go in was because I did not feel we could hold the boat down with just the main alone.

Some wind stats from Sunday:

Lighthouse 4 on Sterns Wharf








24 mph

1:15 PM




2 mph

9:00 PM


Wind Gust


34 mph

1:15 PM


Wind Gust


7 mph

7:20 AM


SB East Buoy








29 mph

1:50 PM




13 mph

8:20 AM


Wind Gust


38 mph

1:40 AM


Wind Gust


16 mph

8:40 AM


Weather Reports and Race Days

Just a notice to anyone sailing races with me on my J70 Escape. I try to run a safe boat. I rarely call off sailing based on a weather report. I use weather reports more as advisement. The reason is that weather reports in the Santa Barbara area are not that accurate. Also, SBYC always runs a race. The responsibility is on the boat owner. To quote the SI for CHRF:

Immediately prior to any race, the decision to race or not race is the sole responsibility of the boat owner or the owner’s designee. At all times during a race, it is the boat owner’s responsibility to continue or to retire based on unexpected conditions or equipment failure. Boat owners must advise crew members of their responsibility to decide for themselves whether to race or not based on their own competence level

I take this seriously. Example, the first Hot Rum of 2019, I did not fly the kite. I was not confident that it would be safe to sail with it up. I think we were very close to last on a day where j70s screamed with the kite flying.

This is the text I sent to my crew this morning. This verbiage will tend to apply to almost all races:

There is a forecast for heavy wind. Problem with SB is that forecasts are not very accurate. I plan to sail unless actual conditions say otherwise.

I mention this, because I have had crew cancel because of a weather report, and it turned out to be a fun day.