STOCK GLASSES – Focused and Simplified Stock Analysis

“Everything should be made as simple as possible, but no simpler.”

-Albert Einstein

I’ve been working on a project to play around with Python and Flask and it snowballed into a full blown web app which I’ve deployed.

The app is called Stock Glasses, and it’s purpose is to provide a tool for focused and simplified stock analysis based on concepts in respected financial investing books such as “The Intelligent Investor” by Benjamin Graham and “The Intelligent Asset Allocator” by William Bernstein.

Use the working app here – https://stock-glasses.com

Follow on Twitter: @GlassesStock

Also see the Stock Glasses YouTube Channel for demonstrations of using the app to analyze stocks.

Inspired by First Principles thinking and the quote by Einstein above, the goal is to eliminate noise and focus on the essentials to evaluate a company.  Basically the app focuses on analysis of these fundamentals:

  1. Top Line – Revenue
  2. Bottom Line – Profit/Net Income
  3. Financial Health – Current Assets vs. Total Debt

For a full explanation of how to use the app, visit the How To Use Page of the app.

Future plans for this project include turning it into a progressive web app for offline use and playing around with comparison analysis further.

The app was built with React/Redux, Python Flask and utilizes Firestore for persisting data.

I welcome any feedback, particularly from finance people who might be able to  critique or offer suggestions/improvements on the metrics and analysis tools offered by the app.

Usual disclaimers apply: I’m not a financial advisor or pro investor, so use and invest at your own risk.  I do think it is a potentially useful tool for learning about basic stock analysis, understanding some common metrics and a good introduction to Value Investing.

Additional resources which inspired the app:

 

 

Firestore Security Rules – Protecting User Data

Question: How in the Sam Hill do I restrict access to data in Firestore to only the user who is requesting it?

Answer: Do this.

service cloud.firestore {
  match /databases/{database}/documents {
    match /collectionName1/{userId=**} {     
      allow create, update: if request.auth.uid == request.resource.data.uid;
      allow delete: if request.auth.uid == resource.data.uid
      allow read: if request.auth.uid != null;
    }

    match /collectionName2/{userId=**} {
      allow create, update: if request.auth.uid == request.resource.data.uid;
      allow delete: if request.auth.uid == resource.data.uid
      allow read: if request.auth.uid != null;
    }
  }
}
  • Attach the user id from Firebase Auth(this is what I use for authentication) as a property on the document data you are sending with every request.
  • For the delete rule, check the uid on the resource already stored
  • This is what is used in the rules to verify that the user authorized  is the same user sending items from the frontend.

 

  • A Non-authorized user will not be able to send documents without knowing the user id of the data they are trying to overwrite or update.
  • The read rule will protect against users not logged in with Firebase Auth, however, if a user wants to read items not belonging to them, they would need to know the user id of the other party to access that data (since the data is organized by user under their uid.)

After frustrating hours scouring Stack Overflow and reading the Firebase documentation getting the dreaded Missing or insufficient permissions error, I finally was able to only allow authorized users to access data belonging to them in the Firestore database for a project I’ve been working on.

I am using the built in Firebase Auth feature on the front end (you can find a great video tutorial by The Net Ninja here).

  • Firebase Auth sends the authenticated user id after they’ve logged in with every request to Firebase,
  • You can access the user id token on the request object in the rules using: request.auth.uid
  • Send the user uid from Firebase Auth on the front end with every resource sent to Firestore (in the case of updating, creating, or deleting a document).  You can access this property in the rules on: request.resource.data.[your uid prop here]
  • The read rule is needed in addition separately because you can’t match the auth uid on the request provided by Firebase Auth with any resource property, since no resource is sent with a GET read query.

NOTE: The context of these rules works if the database structure is:

/CollectionName/[UserIdStringMatchingLoggedInUser]/Documents

Just for completeness of example here is an example of a get and create/update query I am making from the front end:

// Attach user uid to the document data you are sending to Firebase:
const data = { myData: "stuff", uid: "[userUidFromFirebaseAuth]" }
export const getSavedData = (uid) => {
  return db.collection(`dataCollection/${uid}/usersData`)
     .get()
     .then(snapshot => {
        const data = snapshot.docs.map(snap => snap.data());
        return data;
    });
};
export const saveData = (data) => {
  return db.collection(`dataCollection/${data.uid}/usersData`)
      .doc(data.name)
      .set(data)
      .then(snapshot => {
          return "Data Saved!";
      })
      .catch(e => {
          console.error("Error saving data", e);
          return "Error saving data";
      });
};