Not getting fired isn’t enough

Last week was the first day of my last semester before I get my degree, and I’ve already managed to miss two days of classes, one because I had the time wrong, and the second because my youngest was sick. The New Year has seen little activity at my day job, save for some scrambling around the end of life for Windows 7. And despite my best efforts, I’ve still managed to pick up a few projects to add to my already overloaded schedule.

Most of my side work right now is around website hosting. Maintaining domains, SSL certs, installing WordPress; nothing too complicated. I’m using Infinite WordPress to keep an eye on security updates and backups, and have a year membership for Envato to access all their premium themes and other assets. It’s low hanging fruit, I’ll admit.

I’m also close to closing a deal for setting up digital infrastructure for a local school board candidate. One of the perks for having run for office myself is the ability to get paid to do the same work.

Each day that goes by brings home the realization that I’m all but checked out from my day job. The last few months of 2019 I was busy furiously trying to find ways to automate operations as much as possible. Not now. There’s no urgency. I’ve spent a lot of time thinking about core values, trying to figure out what kind of culture we have at my job, and the answers I’ve found have been lacking. I take a lot of the blame for the way I’ve acted that have led to a toxic work environment, which has caused any efforts to enforce discipline to fail.

Perhaps part of it is going on several years now without a boost in compensation. I’ve been working with the same salary for about five years now, which is crazy. I’ve told myself that I’m comfortable with this because of the freedom I have, I’m able to work from home and don’t have to worry about how many hours I actually work. It’s well under thirty five a week. Even the sparse goals that I’ve set for myself for billable time have gone unchecked.

There is an old adage: people work only as hard enough as to not get fired, and employees pay them only enough not to quit. It’s not enough for me anymore. My main concern right now is doubling my income before the end of the year. Wish me luck.

Programmer Discipline

So my productivity has been shot to hell the last two days while I try to familiarize and setup not one, but two new programming environments. I’ve got Javascript for the CCXT/Safe.Trade library, and just got assigned a C++ module for one of my classes.

I have a somewhat convoluted setup. I like to work from one of two machines. My desktop is for gaming and personal or school projects, and my laptop has a Windows VM that I use for my day job. I also have an Ubuntu server that I’m running a file share and other services on. It’s got Docker running over ssh, but I was pounding my head today trying to figure out how to get IntelliJ to talk to it so I could use the integrated run tools instead of the copy/paste garbage I’ve been dealing with as I try to catch up on 20 years of Javascript changes and Node.

For one of my final classes I’ve got to implement Gaussian Elimination in C++ as part of a larger library that will be part of my final grade. I said goodby to CodeBlocks and Eclipse a while back, but I haven’t started a project in C++ in years. The only time I looked at it all has been for the PennyKoin updates. I’ve never spent the time to understand make lists and linking, so I just spent a painful hour trying to get Googletest integrated with this new project. Cause of course I’m going to write a test before I put down anything more complicated than ‘hello world’.

Of course I am.

I’ve spent the last week going over a series of videos on Clean Code by Uncle Bob C. Martin. It’s a good one that I really enjoyed. Martin is really good up on stage — and funny — and I was disappointed when I finished the last one and realized that there weren’t any more. There’s much more on his CleanCoder site for sale that I might dive into, but I want to read his Clean Code and Clean Architecture books first.

Highly recommended if you have several hours to spare.

I came to realize that the tests that I wrote for the GBTC Estimator were too tightly coupled to the module code, and that the module code was coupled to the input (IEX via Pandas DataReader class. So I’ve been trying to decouple it so that so that it works with a dataframe from my broker’s API. I’m taking some hints from a mocking talk I saw that made me realize that I need to break out dependencies even more.

Safe.Trade integration with CCXT

Cryptocurrency exchange automation library

I’m still operating a two year old crypto mining rig here at the house. For the couple months I’ve had it mining Arrow, a Zcash clone that has all of the non-private transactions turned off. I’ve accumulated quite a bit of it, and found out this past week that it was released on the Safe.Trade exchange. Me being me, I immediately went looking for the API docs to see what was available.

I have yet to sell any of the accumulated tokens since I turned the rig on, but feel like I have enough of a stockpile that it’s time for me to start selling some of it for Bitcoin. So what I would like to do is write a program that will interface with my Arrow mining wallet, see how much has been deposited in that day, and transfer said amount over to the Exchange. From there, place a market order, and transfer the proceeds to my bitcoin hard wallet.

Usually I would just open up Pycharm and start building an API wrapper for the exchange, but I’ve been using the excellent CCXT cryptoexchange libary, and wanted to try my hand at adding an exchange to that. The library is very well designed, exchanges are added via a single Javascript file that performs authentication and API calls to CCXTs unified specifications. It seems simple enough, but I haven’t done JS development in fifteen years.

I managed to download the CCXT Docker image and run the tests, but figuring out how to do test driven development in Node is going to be a bit more than I had originally bargained for. I’m going to have to spend a few days figuring out how to set things up and get in the flow.

Of course, yesterday was also the first day of school, so it’s going to be interesting figuring out how to fit all this in. I’m also still doing work with the Value Average and GBTC Estimators, so I’ll have to balance doing all that as well. Still, having a commit in the CCXT library would be like a badge of honor, so I’m going to give it a shot.

We will keep you posted.

Estimating GBTC price from BTC after-hours activity

Grayscale Bitcoin Trust (GBTC) is the name of a publicly traded OTC investment product listed on the public OTC markets. It’s a way for US investors to take a position in Bitcoin through brokerage and retirement accounts like IRAs. A lot of OG crypto-types scoff at the prospect of purchasing such an asset, since you don’t actually control the BTC or the private keys, but for some this is an attractive option, or an only one. I’ve been personally taking positions in GBTC over the past 3 or so years through my retirement IRA. One of the most underlooked qualities of GBTC through an IRA is that all transactions are tax-free. I can take profits in my IRA at any time without worrying about tax liability, which is not something I can say for my actual crypto holdings.

Two of the downsides of GBTC is that Grayscale takes a two percent management fee. This isn’t a big deal to me because of the expected gains in a bull run. The other is that there is a premium on GBTC over the underlying asset value. Each share of GBTC represents .00096884 Bitcoin, but the GBTC’s price is usually 30-10% higher than the value of the underlying asset.

One of the main differences between the equities and crypto markets is the fact that crypto is 24/7. Often, during times when BTC has made a big price movement, I’ve wondered what the corresponding change in the price of GBTC would be (and in my portfolio!) So, I have written a small Python package to calculate this that I call GBTC Estimator.

I have it setup to get public BTC prices from Gemini (via the excellent CCXT package). Right now it’s using IEX’s daily GBTC data (and required an IEX API key), so it only has access to daily OHLCV (open, high, low, close, volume) data. We take the close price of GBTC, and divide it by the price of BTC at the same time (4PM EST) to come up with the actual BTC per share. This number is then used with the current BTC price to come up with the estimated GBTC value.

This current version is run from the command line and returns the estimated price as well as the difference from the last close in dollars and percentage. I have plans to put this up as a website that updates automatically, but first I think I’m going to do some backtesting to see how accurate this is. I think there may be some arbitrage opportunities to be found here. I’ve already started refactoring and will have more updates to follow.

Nation Magazine: September 9/16 2019

Yea, I know, we’ve got a stack of magazines from last fall that we’ve been procrastinating on, and they keep getting bigger and bigger. It’s obviously too much to keep up with. Nation’s publishing schedule is pretty prolific, and their subject matter is quite a step from Time Magazine. Couple of interesting articles in this one:

INDIVISIBLE, by Joan Walsh: Covers the post-Trump activist org of the same name, and schisms between their national leadership and grassroots organizers. This seems to be a recurring theme with liberal organizations; I wonder if Conservatives have the same problems?

Indivisible’s work has earned it enormous political capital; now its national leaders want to figure out how to use it. But since so much of that capital has been earned at the local level, the leadership has to be careful about spending it—and whether it is theirs to spend at all.

I’ve got nothing but respect for the work that Indivisible has done; the local chapter here has done political work for my causes in the past, and they’re a great group of committed activists. The issue here seems to be with how the national leadership wants to leverage Indivisible’s political capital as part of a 2020 presidential endorsement process. The issue with some of the larger cohorts is that an endorsement will likely alienate some members.

Interestingly, after this issue was released, Indivisible released their 2020 Candidate Scorecard. Warren and Bernie take the top two spots, with Biden dead last in the rankings. Apparently Biden declined to participate, so their ranking is based on ‘research into his public record.’ Oops.

To Stay Or Go, by Mara Kardas-Nelson: Environmental racism is the focus here, as the author details the battles that communities in Cancer Alley go through against their own elected officials and the corporation who are poisoning the water and air with the highest concentration of petrochemical plants in the United States. Of course, the prevalence of increased Cancer and other sickness in this region has lead to a flight of citizens out of the area, leaving most of rest with few options. As the population has fled, those remaining have fewer options to sell homes, and communities see their young people and entrepreneurs dwindle.

Of course people shouldn’t have to flee the homes that they’ve made, but it seems that people of places like St. James Parish seem to be fighting a losing battles. While there are some activists trying to fight back via court challenges and electoral battles, the current situation for these communities is quite dire. It’s a situation that we’ve seen play out in other places around the world.

Our Shared Fate, by Suzy Hansen: Review of What You Have Heard Is True, by Carolyn Forche: You may remember this exchange between Ilhan Omar and the Trump administration’s special envoy to Venezuela, where she pressed him over his involvement in the Iran-Contra Affair and in El Salvador’s civil war.

The massacre that isn’t mentioned by name in the above clip is the 1981 El Mozote massacre, an event during the El Savador civil war in which a village of 800 men, women and children were raped and murdered by a US-backed Salvadoran army battalion.

What You Have Heard is True is the memoir of American poet Carolyn Forche, who spent several years in El Salvador during this period. It is one that more Americans need to be aware of, given our complicity in the events there. It puts a different perspective on the immigrants who are fleeing from there to this day, trying to enter the United States and being caught up in family separation.

Fair Open Source

Last night I had the pleasure of meeting Travis Oliphant, one of the primary creators of Numpy and and founder of Anaconda. He’s currently the CEO of OpenTeams, a company attempting to change the relationship between open source software and the companies that build on top of it. I found out about the lecture and was interested in it because of an article I had read in Wired about technology’s free rider problem, and went to the event without knowing anything much at all about Mr. Oliphant. I soon found out who he was and was very grateful that I had come. I’ve spent a lot of time using Numpy, and I’ll admit I was a bit starstruck.

Travis’s lecture spawned from his experience working on Numpy. He basically gave up tenure track at Brigham Young University to work on it, and had to find other ways to support his family for the two years that he was working on the initial release. As was noted elsewhere, much of the tech boom over the past 20 years has been built on top of the contributions of FOSS developers like Travis and others. He’s a big believer of profit, and thinks that the lack of financial incentives in the FOSS space has caused several problems, including developer to burnout, leading to a lack of proper maintenance of these projects. Many of these projects, like Numpy, have become crucially important to the scientific and business community.

Tim Oliphant’s Pycon 2019 Lighting Talk about Quansight

Oliphant’s goal is to make open source sustainable. Quansight is a venture fund for companies that rely on OSS, one of the ones they’ve funded is a public benefit corporation called FairOSS, which hopes to support OSS developers through contributions from companies that use OSS. He’s also doing something very similar with OpenTeams, hoping to follow Red Hat’s model of supporting Open Source by providing support contracts for various projects.

These are all very worthy goals, and I was both impressed and inspired by his talk. It’s opened up some interesting career opportunities. I recently took my first developer payment through GitCoin recently, and it was a bit of a rush. Getting paid to work on Open Source Software seems like an awesome opportunity, and I’ll be keeping an eye on this for potential post-graduate plans.

Thanks to supporters

I hate to use the term ‘life changing’ to describe what’s happened lately, but I’ve seen a few orders roll in for the EICAR products that I put together and it has really made my week. I’ve been dreaming of leaving the rat race and having some sort of self-sustaining revenue streams to help me escape wage-slavery or whatever you want to call it. I’m not being very eloquent right now, but the plan is to escape the need to trade time for money, and seeing these orders come through and be fulfilled without any additional effort on my part seems like a dream come true.

Love him or hate him, Tim Ferriss has been a huge influence on me. I read the Four Hour Workweek when it first came out, but for whatever reason I’d never been able to take that leap and to full bore into something that could do that type of revenue-generation. About the closest I’ve ever come to it has been investing, whether buying stocks or crypto and seeing things take off of their own accord. (The 15% rally in BTC this past week is no doubt affecting my mood.)

I’ll be honest, I won’t be paying the grocery bill with the proceeds from the sales that I did, but this past week is very inspiring and helps reinforce that another way is possible.

Automating value average stock investing

I spent most of the winter break working on automating a value averaging algorithm that I wrote about several months ago. Back in October we started scaling into three positions that we identified based on our work with some predictions we did using Facebook’s Prophet earlier. My goal was to develop a protocol and work out any kinks in the process manually while I worked on building out code that would eventually take over. While I’m not ready to release the modules to the public yet, I have managed to get the general order calculation and order placement up and running.

To start, I setup a Google Sheet with the details of each position: start date, number of days to run, and the total amount to invest. I used Alexander Elder’s Two Percent Rule, as usual to come up with this number. Essentially each position would be small enough that I wouldn’t need to setup stop losses. From there, the sheet would keep track of the number of business days (as a proxy for trading days) and would compute the target position size for that day. I would update a cell with the current instrument price, and the sheet would compute whether my asset holding was above or below the target, and calculate the buy or sell quantities accordingly.

After market open, I would update the price for each stock and put in the orders for each position. This took a few minutes each day, and became part of my morning routine over the past two months or so. Ideally, this process should have only taken five minutes out of my day, but we ran into some challenges due to the decisions we made that required us to rework things and audit our order history several times.

The first of these was based around the type of orders we placed. I decided that I didn’t want to market buy everything, and instead put ‘good-until-cancelled’ limit orders in. When there was no spread between the bid and the ask, I would just match whichever end I was on, and if there was a split I would put my order price one penny in the spread. As a result, some orders would go unfilled, and required some overly complicated spreadsheet calculations to keep track of which orders were filled, what my actual number of shares was ‘supposed’ to be, and so on. I also started using a prorated target, based on the number of days with actual filled orders. This became a problem to track. Also, some days there were large spreads, and my buy orders were way lower than anything that would get filled. There were times when the price fell for a few days and picked up some of these, but keeping track of these filled/unfilled orders was a huge pain in the butt.

One of the reasons that it took me so long to develop a working product was due to the challenges I had with existing Python support for my brokerage. The only feasible module that I could find on Pypi had basic functionality and required a lot of work. It had no order-placing capabilities, so I had to write those. I also got lost working through Ameritrade’s non-compliant schema definitions, and I almost gave up hope entirely when I found out that they were getting bought out. The module still has a lot of improvements needed before it can be run in a completely automated manner, but more on that later.

So far I’ve got just under a thousand lines of code — not as many tests as I should have written — that allows me to process a list of positions, tuples with stock ticker, days to run, start date, and total capital to invest. It calculates the ideal target, gets the current value of the position, and then calculates the difference and number of shares to buy or sell. It then places the order. I’m still manually keeping an eye on things and tracking my orders in the sheet as I’ve been doing, but there’s too much of a discrepancy between the Python algorithm and my spreadsheet. I don’t anticipate trying to wade through my transaction history to try to program around all of the mistakes and adjustments that I made during the development process. I’ll just have to live without the prorated targets for the time being.

I think priorities for the next few commits will be improving the brokerage module. Right now it requires Chromedriver to generate the authentication tokens; this can be done using straight up request sessions. There’s also no error checking; session expiration is a common problem and I had to write a function to use to refresh it without reauthentication. So first priority will be getting the the order placement calls and token handling improvements put in and a PR back into the main module.

From there, I’d like to clean up the Quicktype-generated objects and get them moved over to the brokerage package where they belong. I don’t know that most people are going to want to use Python objects instead or dictionaries, but I put enough work into it that I want it out there.

Lastly, I’ll need to figure out how to separate any of the broker-specific function calls from the value averaging functions. Right now it’s too intertwined to be used for anything other than my brokerage, so I’ll see about getting it generalized in such a way that it can be used with Tensortrade or other algorithmic trading platforms.

I’m not sure how much of this I can get done over the spring. Classes for my final semester at school start next Monday, and it will be May before I’m done with classes. But I will keep posting updates.

Will this image break automatic camera scanner systems?

EICAR antivirus test string

The image above is a QR-encoded representation of the EICAR antivirus test string. The string (`X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*`) is used to check the effectiveness of antivirus systems without using actual malware. It was brought to my attention via a Tweet by computer security Rob Rosenberger in which he placed QR code on his car during a recent road trip. The intention here being to get automated scanners to read and insert the string into their databases, hopefully causing them to crash.

A few people mentioned how they wanted these on hats or shirts, so I spent some time today putting a couple of products up on the ecommerce site. After I put this out, someone noted that this string only works if it is the only data in a file, which reduces the likelihood that it will actually cause any havok.

Still, if the idea of trashing facial recognition systems or license plate scanners sounds like fun to you, then perhaps you’ll be interested in this.

2020 Goals

I’m 40 years old, which means that I’ve spent half of my life in the 20th century and half of it in the 21st. Perhaps that’s why I wasn’t excited with the fact that we last night we moved into a new decade. I was reading a book last night when midnight came; my family was asleep. There had been pops of fireworks going off before midnight, but there was a point when they started firing off continuously when I knew that the New Year had come. I wasn’t sure whether it was the City or the nearby military base where they were going off, but after about what was likely the official display ceased, what sounded like small arms fire kept going on for another twenty or fourty minutes. I imagined handguns or semiautomatic rifles being fired off in the air. (I once found a spent 9mm bullet laying on my porch step, no idea where it came from.) The explosions were punctuated with the sound of sirens as emergency personnel responded, either to the illegal fireworks, firearms, or perhaps to some actual injury.

  1. Finish my degree: I’m one semester away from getting my bachelors in computer science. I’ll likely finish with a >3.5 GPA. This should open up some opportunities, but the worst thing about it will be that my loans will come due. This will likely cause some financial hardship until I accomplish #2…
  2. Get a raise: I’ve been at the same job and salary for four or five years now. My wife outearns me by a great deal, and it’s not a problem, pride-wise, as much as it is a difference in lifestyle. My budget is extremely tight and is a subject of stress, while she seems to have a lot more discrecion in how she handles her finance. I know that even with my lack of anything more than an associates degree I’m underpaid, but the freedom I have with my current job makes up for it. That freedom has downsides though, and it’s time to step up. Unfortunatley, I’ve come to recognize that my current job is with a zombie firm, which is why item #3 is…
  3. Find a new job: I’ve been with my current job for 7 years, which is longer than I’ve ever held a position anywhere else. I tell my wife I’m unfireable because of key-man risk, but I’ve come to realize that everyone else on my small team is as well, and that’s not a good thing. I’ll have to expand on this later. I have no desire to go back to a corporate position where I have to work more than 30 hours a week, so I will have to make sure to focus on #4…
  4. Pickup more freelance/contracting work: Until the next Bitcoin bull run makes me independently wealthy, I’m going to have to focus on expanding my independent work and pick up some actual clients. I just need to pick up sixteen clients at $250/month retainer to replace my current real job, so I’ll just need to focus on picking up a few more and staying on top of things while I work on a few more large development projects.
  5. Get my daughter sleeping in her bed: She’s three years old now, and still can’t fall asleep on her own. I don’t know if we broke the first one doing it, but at least she goes to bed without having to lay down next to her for twenty minutes. This will be a long hard fought battle, especially until I can get my wife on board.
  6. Deal with my defiant child: I have two daughters. My boss has two as well, and often tells me that I have no idea what kind of shit I’ll have to deal with when they become teenagers. He assumes they’ll live that long. I would suspect that my eldest has oppositional defiant disorder save for the fact that she’s an angel with everyone but my wife and I, so I just assume it’s our lack of parenting skills. I’ve got some books that I’m reading and some strategies that I’ll be working through, so we’ll see how that goes.
  7. Continue to meditate: Such a simple thing to do that has such a good impact on my well-being. I don’t know that I’ll be doing hour-long sessions, but twenty minutes a day seems like such a no-brainer. Figuring out how to make it part of my daily routine and get the kids involved will be key.
  8. Exercise regularly: I’ve been through so many phases on this that it’s ridiculous. I’m really going to need to prioritize this, along with meditation, to make sure that it gets done on a regular basis. When I’ve done so in the past, the results have been tremendous, but it’s been so hit or miss lately.
  9. The drink: the hundred-plus days off the wagon that I did late last summer was one of the best things I’ve done for my health. I’ve already accepted the fact that I’m an alcoholic (an addict might be a better description,) so I have to figure out whether I want to continue being a functioning alcoholic or what.
  10. Up my piano skills: music has always been part of my life, and I’m finally getting to the point where I can sight read. Besides a few pop tunes that I’ve been playing around with, I’ve almost mastered a Bach minuet. I really want my kids to pick this up by my example, but I’m having difficulty figuring out what an appropriate goal for me would be. Bach’s Inventions should be something I can achieve this year.
  11. Write: I am going to start a 1000-day goal to write at least 200 words to this blog.

Wish me luck!