Phil Schatzmann https://www.pschatzmann.ch/home Tue, 12 Feb 2019 22:21:51 +0000 en-US hourly 1 https://wordpress.org/?v=5.2.4 Identity Management and Authentication for Java Webservices and Javascript GUIs https://www.pschatzmann.ch/home/2019/02/12/identity-management-and-authentications/ https://www.pschatzmann.ch/home/2019/02/12/identity-management-and-authentications/#respond Tue, 12 Feb 2019 17:10:27 +0000 https://www.pschatzmann.ch/home/?p=954 I am currently working on a new project which uses Vue.js on the frontend and JAX-RS Webservices implemented in Java in the backend. Both, the frontend and the backend will be deployed with Docker. The solution will need to manage customers, users and provide authentication to protect the web application […]

The post Identity Management and Authentication for Java Webservices and Javascript GUIs appeared first on Phil Schatzmann.

]]>
I am currently working on a new project which uses Vue.js on the frontend and JAX-RS Webservices implemented in Java in the backend. Both, the frontend and the backend will be deployed with Docker.

The solution will need to manage customers, users and provide authentication to protect the web application and web services. It does not make any sense to build my own solution for this so I decided to base my architecture on some existing open source tools.

Open Source Identity Management Tools

There is quite an impressive list of potential Open Source Identity Management Tools. I also included LDAP based tools into the evaluation:

Criteria

In order to evaluate the best fitting solution I defined my evaluation criteria

  • Manage our Customers with custom attributes
  • Manage Users with custom attributes
  • Java API to manage Customers and Users
  • Basic Processes: User Registration, Password Reset
  • Basic Authentication functionality with Password Policies, Brute Force Detection
  • Authentication support with OpenID Connect
  • Integration with LDAP
  • Support of external Identity Providers (Microsoft, Google etc)
  • Easy to use
  • Integration with Vue.js for Authentication
  • Integration with Java Webservices (JAX-RS) for Authentication
  • Easy to deploy with Docker
  • Integration with WordPress
  • Open Source

Result

LDAP is quite popular but it is quite painful to extend the schema and it is missing most of my defined criteria.

There is basically only one tool which turned out to be the perfect match: Keycloak. The user, roles and user groups provide dynamic key values so it is easy to store our custom attributes with the help of a Java API or with some web services.

Usually my Webservices are based on Jersey. Unfortunately it turned out that the Keycloak API was based on RestEasy and it did not feel right to have two JAX-RS frameworks in parallel so I moved my solution to RestEasy as well.

In order to simplify the deployment of the web services in Docker I usually integrate an embedded server.  For RestEasy I could use the UndertowJaxrsServer and with 2 lines of code I had my embedded web server running as well

UndertowJaxrsServer server = new UndertowJaxrsServer().deploy(new Application());

server.start(Undertow.builder().addHttpListener(Integer.parseInt(port), host));

The post Identity Management and Authentication for Java Webservices and Javascript GUIs appeared first on Phil Schatzmann.

]]>
https://www.pschatzmann.ch/home/2019/02/12/identity-management-and-authentications/feed/ 0
Docker and Treafik – A Comprehensive Tutorial https://www.pschatzmann.ch/home/2019/01/18/docker-and-treafik-a-comprehensive-tutorial/ https://www.pschatzmann.ch/home/2019/01/18/docker-and-treafik-a-comprehensive-tutorial/#respond Fri, 18 Jan 2019 08:01:52 +0000 https://www.pschatzmann.ch/home/?p=900 In Docker you expose functionality by specifying a port mapping and then you can address the application on the physical host with the mapped port. I am using Docker quite some time now and this was getting a little bit too tedious because each mapped port needs to be unique […]

The post Docker and Treafik – A Comprehensive Tutorial appeared first on Phil Schatzmann.

]]>
In Docker you expose functionality by specifying a port mapping and then you can address the application on the physical host with the mapped port.

I am using Docker quite some time now and this was getting a little bit too tedious because each mapped port needs to be unique and then you need to remember the port numbers to be able to start your application. So I wanted to simpler way by using speaking host names. E.g. http://svnclient.docker.local should display the svnclient and this should work from all my clients in my local network.

It took me a full day to put all the pieces together into a working solution. Therefore I am writing this down in the hope that it might prevent someone else to fall into the same traps. Here is the complete solution:

Treafik Overview

Traefik is a modern HTTP reverse proxy and load balancer that makes deploying microservices easy. It provides some predefined “providers” and Docker is one of them.

1. Network

Treafik automatically sets up the routing from frontends to backends. Therefore is is necessary that the Treafik container and the Application containers are on the same Docker Network so that they can communicate with each other!.

Therefore I created my docker network first with

    docker network create web

2. Treafik Coniguration File

I am using the following traefik.toml configuration file:

################################################################
# Global configuration
################################################################

# Enable debug mode
#
# Optional
# Default: false
#
# debug = true

# Log level
#
# Optional
# Default: "ERROR"
#
# logLevel = "DEBUG"

# Entrypoints to be used by frontends that do not specify any entrypoint.
# Each frontend can specify its own entrypoints.
#
# Optional
# Default: ["http"]
#
# defaultEntryPoints = ["http", "https"]

################################################################
# Entrypoints configuration
################################################################

# Entrypoints definition
#
# Optional
# Default:
[entryPoints]
    [entryPoints.http]
    address = ":80"

################################################################
# Traefik logs configuration
################################################################

# Traefik logs
# Enabled by default and log to stdout
#
# Optional
#
# [traefikLog]

# Sets the filepath for the traefik log. If not specified, stdout will be used.
# Intermediate directories are created if necessary.
#
# Optional
# Default: os.Stdout
#
# filePath = "log/traefik.log"

# Format is either "json" or "common".
#
# Optional
# Default: "common"
#
# format = "common"

################################################################
# Access logs configuration
################################################################

# Enable access logs
# By default it will write to stdout and produce logs in the textual
# Common Log Format (CLF), extended with additional fields.
#
# Optional
#
# [accessLog]

# Sets the file path for the access log. If not specified, stdout will be used.
# Intermediate directories are created if necessary.
#
# Optional
# Default: os.Stdout
#
# filePath = "/path/to/log/log.txt"

# Format is either "json" or "common".
#
# Optional
# Default: "common"
#
# format = "common"

################################################################
# API and dashboard configuration
################################################################

# Enable API and dashboard
[api]

  # Name of the related entry point
  #
  # Optional
  # Default: "traefik"
  #
  # entryPoint = "traefik"

  # Enabled Dashboard
  #
  # Optional
  # Default: true
  #
  # dashboard = false

################################################################
# Ping configuration
################################################################

# Enable ping
[ping]

  # Name of the related entry point
  #
  # Optional
  # Default: "traefik"
  #
  # entryPoint = "traefik"

################################################################
# Docker Provider
################################################################

# Enable Docker Provider.
[docker]

# Docker server endpoint. Can be a tcp or a unix socket endpoint.
#
# Required
#
endpoint = "unix:///var/run/docker.sock"

# Default base domain used for the frontend rules.
# Can be overridden by setting the "traefik.domain" label on a container.
#
# Optional
#
domain = "docker.local"

# Enable watch docker changes.
#
# Optional
#
watch = true

# Override default configuration template.
# For advanced users :)
#
# Optional
#
# filename = "docker.tmpl"

# Override template version
# For advanced users :)
#
# Optional
# - "1": previous template version (must be used only with older custom templates, see "filename")
# - "2": current template version (must be used to force template version when "filename" is used)
#
# templateVersion = 2

# Expose containers by default in Traefik.
# If set to false, containers that don't have `traefik.enable=true` will be ignored.
#
# Optional
# Default: true
#
exposedByDefault = false

# Use the IP address from the binded port instead of the inner network one.
#
# In case no IP address is attached to the binded port (or in case 
# there is no bind), the inner network one will be used as a fallback.     
#
# Optional
# Default: false
#
usebindportip = true

# Use Swarm Mode services as data provider.
#
# Optional
# Default: false
#
swarmMode = false

# Polling interval (in seconds) for Swarm Mode.
#
# Optional
# Default: 15
#
swarmModeRefreshSeconds = 15

# Define a default docker network to use for connections to all containers.
# Can be overridden by the traefik.docker.network label.
#
# Optional
#
network = "web"

# Enable docker TLS connection.
#
# Optional
#
#  [docker.tls]
#  ca = "/etc/ssl/ca.crt"
#  cert = "/etc/ssl/docker.crt"
#  key = "/etc/ssl/docker.key"
#  insecureSkipVerify = true

I would like to highlight the following settings:

  • domain = “docker.local”: This defines the suffix for the host name
  • exposedByDefault = false: I think it is good practise that I can decide which applications to expose
  • network = “web”: This is the network name that I created in step 1. If you are not happy with this name you can change it here.

3. Docker Compose for Treafik

I am using docker compose to start my containers. So here is my docker-compose.yml:

    version: '3.4'

    services:
        traefik:
          image: traefik:alpine
          container_name: traefik
          ports:
            - "80:80"
            - "8080:8080"
          volumes:
            - /var/run/docker.sock:/var/run/docker.sock
            - /srv/traefik/traefik.toml:/traefik.toml
          labels:
            - traefik.enable=true
            - traefik.port=8080
            - traefik.frontend.rule=Host:traefik.docker.local
          restart: always
          networks:
          - web
          - sparknet

    networks:
      web:
        external:
          name: web
      sparknet:
        external:
          name: sparknet

I started with a default network (as explained in the next chapter) but I changed the network setup to explicitly enumerate the networks that should be used to communicate with the applications.
I will explain the labels in the next chapter because I just treat Treafik like any other Application

4. Docker Compose for the Subversion Container

Here is the docker-compose.yml for my demo application. I am using a dockerized svnserve and websvn as web application to access the content of Subversion:

    version: '3.4'
    services:
        svnserve:
            image: pschatzmann/svnserve
            container_name: svnserve
            ports:
                - "3690:3690"
            environment:
                - SVN_REPONAME=my-repo
            volumes:
                - /srv/svn:/srv/svn
            restart: always

        websvn:
            image: pschatzmann/websvn
            container_name: websvn
            ports:
                - "8003:80"
            environment:
                - repository=svn://my-secret
                - user=me
                - password=i-dont-tell
            labels:
                - traefik.enable=true
                - traefik.frontend.rule=Host:websvn.docker.local
            restart: always

    networks:
      default:
        external:
          name: web

The key settings for the support of Traefik are the following:

  • traefik.enable=true: to Activate the support of Traefik for the web Gui
  • The Default network which is making sure that Treafik can reach this application
  • traefik.frontend.rule=Host:websvn.docker.local (Optional) I did not like the automatically generated address so I just replaced it with my shorter more speaking one
  • You could enter a label to specifiy the port: traefik.port=80. But this is only necessary if treafik can not pick the right port automatically.

We are ready to start both applications with

    docker-compose up -d

Both application should now have an entry in the list of frontend and backend in the Traefik Dashboard which is available with http://your_host:8080.

5. Name Resolution

So with the current setup the usual tutorials stop and demo that the solution is working by using curl in the following way:

    curl -H Host:websvn.docker.local http://docker.local

But I wanted that the websvn.docker.local address is working in my Browser which actually does not work (yet).
So far I have identified the following solution approaches:

  • Use a Proxy in your Browser: e.g. websvn.docker.local SwitchyOmega: This solution approach depends on your Web Browser and need to be set up on each client separately
  • Use DNSMASQ: There are quite a few tutorials available (which are dependent on your Operating System) and usually this is easy to setup – unless you are on a recent version of Ubuntu. Unfortunately I was using Ubuntu and I gave this one up because it was getting too messy.
  • Use a DNS Server and setup a wildcard host address.

To setup a local Bind Server was always a low priority item on my todo list. So I went for this solution which I will describe next. Fortunately webmin has some easy to use Web GUI which made the process quite painless:
1. set other DNS to point to my Zystel router which provides DHCP
2. create a new master zone: local
3. create a new address: docker.local with ip address 10.147.17.177
4. create a new address: nuc.local with ip address 10.147.17.177 (which is the physical server)
5. add reverse address: ip address to docker.local to 10.147.17.177
6. create name alias: *.docker.local with docker.local
7. Start of restart Bind DNS Server
8. Change Network Settings in my local McBook to use 10.147.17.177 as DNS.

This was generating the following entries in /var/lib/bind/local.hosts

    $ttl 38400
    local.  IN  SOA nuc.local. phil\.schatzmann.gmail.com. (
                1547743979
                10800
                3600
                604800
                38400 )
    local.  IN  NS  nuc.local.
    docker.local.   IN  A   10.147.17.177
    nuc.local.  IN  A   10.147.17.177
    10.147.17.177.local.    IN  PTR docker
    *.docker.local. IN  CNAME   docker.local.

So finally I can test if the resolution is working correctly by

    ping websvn.docker.local
    PING docker.local (10.147.17.177): 56 data bytes
    64 bytes from 10.147.17.177: icmp_seq=0 ttl=64 time=8.144 ms
    64 bytes from 10.147.17.177: icmp_seq=1 ttl=64 time=6.181 ms
    64 bytes from 10.147.17.177: icmp_seq=2 ttl=64 time=1.893 ms

And finally when I enter http://websvn.docker.local in my browser I get the expected result:

The post Docker and Treafik – A Comprehensive Tutorial appeared first on Phil Schatzmann.

]]>
https://www.pschatzmann.ch/home/2019/01/18/docker-and-treafik-a-comprehensive-tutorial/feed/ 0
NFS in Docker-Compose https://www.pschatzmann.ch/home/2019/01/16/nfs-in-docker-compose/ https://www.pschatzmann.ch/home/2019/01/16/nfs-in-docker-compose/#respond Wed, 16 Jan 2019 14:52:28 +0000 https://www.pschatzmann.ch/home/?p=883 My main Docker deployments are on a single linux server. I have a central ‘data’ directory where I keep my common data. The application specific data or settings are stored in /srv/. But for testing or demos I am usually using local Docker installations on my McBook or McBook Air […]

The post NFS in Docker-Compose appeared first on Phil Schatzmann.

]]>
My main Docker deployments are on a single linux server. I have a central ‘data’ directory where I keep my common data. The application specific data or settings are stored in /srv/.

But for testing or demos I am usually using local Docker installations on my McBook or McBook Air under OS/X. I am using NFS to access the shared central data.

In this Blog I give a quick overview of the setup:

  • Install the NFS Server. There are plenty of good tutorials on the Internet that describe how to do this. I was using this. It would even be an option to run the NFS Server as Docker Container.

  • Create Exports for the Directories on the Server. Fortunately I could use the NFS Exports screen from Webmin. Here is the definition for sharing the /srv directory:

I am using a Zerotier virtual Network so that I can access my local resources also from the public Internet. Therefore I was defining the corresponding IP network and netmask.

  • Now we are ready to use the exported directories. Here is the docker-compose.yml file which is using NFS volumes:
    version: '3.2'
    services:
      beakerx:
        image: pschatzmann/data-science:1.2.0
        container_name: beakerx
        hostname: beakerx
        restart: always
        ports:
          - 8007:8888
          - 9000:9000
        volumes:
          - nfs-srv:/home/beakerx
          - nfs-data:/data
        environment:
          - TZ=Europe/Zurich
        dns:
          - 8.8.8.8
        extra_hosts:
          - "nuc.local:10.147.17.177"
    
    volumes:
      nfs-srv:
         driver: local
         driver_opts:
           type: nfs
           device: ":/srv/data-science"
           o: "addr=10.147.17.177,nolock,soft,rw"
    
      nfs-data:
         driver: local
         driver_opts:
           type: nfs
           device: ":/data"
           o: "addr=10.147.17.177,nolock,soft,rw"
    

The post NFS in Docker-Compose appeared first on Phil Schatzmann.

]]>
https://www.pschatzmann.ch/home/2019/01/16/nfs-in-docker-compose/feed/ 0
Using the ‘Smart EDGAR’ Library to Access EDGAR Filings https://www.pschatzmann.ch/home/2019/01/15/usage-of-smart-edgar-as-library-to-access-edgar-filings/ https://www.pschatzmann.ch/home/2019/01/15/usage-of-smart-edgar-as-library-to-access-edgar-filings/#comments Tue, 15 Jan 2019 15:52:14 +0000 https://www.pschatzmann.ch/home/?p=849 The initial concept of Smart EDGAR was to provide the tools to download the data from the EDGAR website and – store the information as local files – store the information in a SQL database – provide reporting functionality from this data We have extended the functionality a little bit […]

The post Using the ‘Smart EDGAR’ Library to Access EDGAR Filings appeared first on Phil Schatzmann.

]]>
The initial concept of Smart EDGAR was to provide the tools to download the data from the EDGAR website and
– store the information as local files
– store the information in a SQL database
– provide reporting functionality from this data

We have extended the functionality a little bit so that the Smart EDGAR Library can be used without having any data available locally. So we also provide
– an API which retrieves the information directly from the EDGAR Website.
– Company KPIs from the EDGAR Website or pulling the data from a REST webservice

The details can be found in the following Gist

The post Using the ‘Smart EDGAR’ Library to Access EDGAR Filings appeared first on Phil Schatzmann.

]]>
https://www.pschatzmann.ch/home/2019/01/15/usage-of-smart-edgar-as-library-to-access-edgar-filings/feed/ 2
MLLib – Prediction of Stock Prices from Financial KPIs https://www.pschatzmann.ch/home/2019/01/11/mmlib-prediction-of-stock-prices-using-financial-kpis/ https://www.pschatzmann.ch/home/2019/01/11/mmlib-prediction-of-stock-prices-using-financial-kpis/#respond Fri, 11 Jan 2019 12:11:56 +0000 https://www.pschatzmann.ch/home/?p=844 Financial KPIs can be used to drive investment decisions. So it was my goal to create a comprehensive set of KPIs across different dimensions. In this document we will use EDGAR to calculate KPIs to measure the following dimensions of a reporting company – Profitability – Liquidity – Efficiency – […]

The post MLLib – Prediction of Stock Prices from Financial KPIs appeared first on Phil Schatzmann.

]]>
Financial KPIs can be used to drive investment decisions. So it was my goal to create a comprehensive set of KPIs across different dimensions. In this document we will use EDGAR to calculate KPIs to measure the following dimensions of a reporting company
– Profitability
– Liquidity
– Efficiency
– Innovation
– Growth
– Leadereship
– Surprises

It is the expectation that the stock price of companies with better KPIs will grow faster than their competitors: So in this document we will evaluate the KPIs against the stock prices.
The solution is based on the following functionality

The result can be found in the following Gist.

The post MLLib – Prediction of Stock Prices from Financial KPIs appeared first on Phil Schatzmann.

]]>
https://www.pschatzmann.ch/home/2019/01/11/mmlib-prediction-of-stock-prices-using-financial-kpis/feed/ 0
Smart EDGAR: Definition of a Comprehensive Set of Financial KPIs https://www.pschatzmann.ch/home/2019/01/08/edgar-definition-of-a-comprehensive-set-of-financial-kpis/ https://www.pschatzmann.ch/home/2019/01/08/edgar-definition-of-a-comprehensive-set-of-financial-kpis/#respond Tue, 08 Jan 2019 18:45:08 +0000 https://www.pschatzmann.ch/home/?p=828 A long time ago, when I was studying “Management and Business Administration” in Switzerland, I thought it would be cool to be able to calculate Financial KPIs in order to compare different companies within one sector or to be able to identify sector specific differences. Well, in Switzerland we still […]

The post Smart EDGAR: Definition of a Comprehensive Set of Financial KPIs appeared first on Phil Schatzmann.

]]>
A long time ago, when I was studying “Management and Business Administration” in Switzerland, I thought it would be cool to be able to calculate Financial KPIs in order to compare different companies within one sector or to be able to identify sector specific differences.

Well, in Switzerland we still don’t have any requirement to file the Financial Reports electronically and unfortunately this will not change anytime soon. Fortunately there are countries which are more progressive, like e.g. the US which makes the information available via EDGAR or the UK with CompaniesHouse. A complete overview of countries which support XBRL can be found here.

This information might be useful to drive investment decisions. So it was my goal to create a comprehensive set of KPIs across different dimensions which can be used by machine learning. In this document we will use EDGAR to calculate KPIs to measure the following dimensions of a reporting company
– Profitability
– Liquidity
– Efficiency
– Innovation
– Growth
– Leadership
– Surprises

The solution has been implemented with JupyterLab using the BeakerX Scala kernel with the following additional libraries:
Smart EDGAR (to access the EDGAR data)
– jupyter-jdk-extensions (to display our custom tables in BeakerX)

The result can be find in the following Gist

It is the expectation that the stock price of companies with better KPIs will grow faster than their competitors. So in my next blog we will evaluate the KPIs against the stock prices.

The post Smart EDGAR: Definition of a Comprehensive Set of Financial KPIs appeared first on Phil Schatzmann.

]]>
https://www.pschatzmann.ch/home/2019/01/08/edgar-definition-of-a-comprehensive-set-of-financial-kpis/feed/ 0
Smart EDGAR: Calculation of Surprises https://www.pschatzmann.ch/home/2019/01/06/smart-edgar-calculation-of-surprises/ https://www.pschatzmann.ch/home/2019/01/06/smart-edgar-calculation-of-surprises/#respond Sun, 06 Jan 2019 11:45:14 +0000 https://www.pschatzmann.ch/home/?p=819 Financial KPIs can be used to drive investment decisions. So it was my goal to create a comprehensive set of KPIs across different dimensions that are based on the information which can be determined from EDGAR: – Profitability – Liquidity – Efficiency – Innovation – Growth – Leadership – Surprises […]

The post Smart EDGAR: Calculation of Surprises appeared first on Phil Schatzmann.

]]>
Financial KPIs can be used to drive investment decisions. So it was my goal to create a comprehensive set of KPIs across different dimensions that are based on the information which can be determined from EDGAR:
– Profitability
– Liquidity
– Efficiency
– Innovation
– Growth
– Leadership
– Surprises

In this document we demonstrate the approach on how to calculate the Surprises

The post Smart EDGAR: Calculation of Surprises appeared first on Phil Schatzmann.

]]>
https://www.pschatzmann.ch/home/2019/01/06/smart-edgar-calculation-of-surprises/feed/ 0
Smart EDGAR: Calculation of Growth Parameters https://www.pschatzmann.ch/home/2019/01/05/smart-edgar-calculation-of-growth-parameters/ https://www.pschatzmann.ch/home/2019/01/05/smart-edgar-calculation-of-growth-parameters/#respond Sat, 05 Jan 2019 11:12:59 +0000 https://www.pschatzmann.ch/home/?p=815 Financial KPIs can be used to drive investment decisions. So it was my goal to create a comprehensive set of KPIs across different dimensions that are based on the information which can be determined from EDGAR: Profitibility Liquidity Efficiency Innovation Growth Leadereship Surprises In this document we demonstrate the approach […]

The post Smart EDGAR: Calculation of Growth Parameters appeared first on Phil Schatzmann.

]]>
Financial KPIs can be used to drive investment decisions. So it was my goal to create a comprehensive set of KPIs across different dimensions that are based on the information which can be determined from EDGAR:

  • Profitibility
  • Liquidity
  • Efficiency
  • Innovation
  • Growth
  • Leadereship
  • Surprises

In this document we demonstrate the approach on how to calculate the Growth Parameters

The post Smart EDGAR: Calculation of Growth Parameters appeared first on Phil Schatzmann.

]]>
https://www.pschatzmann.ch/home/2019/01/05/smart-edgar-calculation-of-growth-parameters/feed/ 0
Smart EDGAR File API https://www.pschatzmann.ch/home/2019/01/03/smart-edgar-file-api/ https://www.pschatzmann.ch/home/2019/01/03/smart-edgar-file-api/#respond Thu, 03 Jan 2019 15:42:48 +0000 https://www.pschatzmann.ch/home/?p=806 So far we have seen how to use the database related API of Smart EDGAR. In this Gist I give a quick overview of the core functionality of the File based API which does not require any DBMS.

The post Smart EDGAR File API appeared first on Phil Schatzmann.

]]>
So far we have seen how to use the database related API of Smart EDGAR.
In this Gist I give a quick overview of the core functionality of the File based API which does not require any DBMS.

The post Smart EDGAR File API appeared first on Phil Schatzmann.

]]>
https://www.pschatzmann.ch/home/2019/01/03/smart-edgar-file-api/feed/ 0
Calculating the Market Share of US Companies with the Help of EDGAR https://www.pschatzmann.ch/home/2018/12/28/calculating-the-market-share-with-edgar/ https://www.pschatzmann.ch/home/2018/12/28/calculating-the-market-share-with-edgar/#respond Fri, 28 Dec 2018 19:41:15 +0000 https://www.pschatzmann.ch/home/?p=793 Edgar is classifying the reporting companies by SIC (Standard Industrial Classification) Code. We can use this information to calculate the total sales per sector and then calculate the % share of the individual company. This is helping us to identify the companies with a big market share. The result (which […]

The post Calculating the Market Share of US Companies with the Help of EDGAR appeared first on Phil Schatzmann.

]]>
Edgar is classifying the reporting companies by SIC (Standard Industrial Classification) Code. We can use this information to calculate the total sales per sector and then calculate the % share of the individual company.

This is helping us to identify the companies with a big market share.

The result (which uses Spark) can be found in the following Gist. Alternatively here is a version which purely relies on Scala and Smart EDGAR

The post Calculating the Market Share of US Companies with the Help of EDGAR appeared first on Phil Schatzmann.

]]>
https://www.pschatzmann.ch/home/2018/12/28/calculating-the-market-share-with-edgar/feed/ 0