- A service to track the performance of a single person's portfolio
- The P/L and average price are calculated using the same method as described in this Robinhood article
- A user can have multiple orders for the same symbol, but we keep only 1 position for each symbol (e.g. IBKR does not allow multiple positions for the same symbol, they get collapsed into a single position)
- A group of symbols can be placed into a 'bucket'
- The service template used: conjure-java-example
- docker image is available at docker hub
- run the below 2 commands in the terminal:
docker pull chomutovskij/portfolio-service-server:<version>
docker run -p 8345:8345 -p 8346:8346 chomutovskij/portfolio-service-server:<version>
- in a separate terminal window, run the curls, but first read the note on certificates just below
- The certificates are self-signed, which means you will have to pass in
-k
in the below curl commands (if you are calling the service viahttps
) - If you don't want to pass in
-k
, you can call the service viahttp
(change the port number from8345
to8346
)- e.g.
curl -X GET -H "Content-Type: application/json" "http://localhost:8346/api/v1/dates/all/NVDA" | jq
- e.g.
- For more information on how these certificates were generated, refer to the certificates section
Available dates for a symbol (needed for order request):
curl -k -X GET -H "Content-Type: application/json" "https://localhost:8345/api/v1/dates/all/NVDA" | jq
create a new empty bucket (optional, bucket can also be created when an order is submitted)
curl -k -X POST "https://localhost:8345/api/v1/buckets/create/BucketA"
curl -k -X GET -H "Content-Type: application/json" "https://localhost:8345/api/v1/buckets/all" | jq
curl -k -X DELETE -H "Content-Type: application/json" "https://localhost:8345/api/v1/buckets/delete/BucketA"
curl -k -X POST -H "Content-Type: application/json" -d '{"type": "SELL", "symbol": "AMZN", "quantity": 3, "date": "2023-08-29T00:00:00Z", "buckets": ["BucketA"]}' "https://localhost:8345/api/v1/position/add"
curl -k -X POST -H "Content-Type: application/json" -d '{"type": "BUY", "symbol": "NVDA", "quantity": 10, "date": "2023-08-29T00:00:00Z", "buckets": ["BucketB"]}' "https://localhost:8345/api/v1/position/add"
curl -k -X POST -H "Content-Type: application/json" -d '{"type": "BUY", "symbol": "TSLA", "quantity": 5, "date": "2023-08-29T00:00:00Z", "buckets": []}' "https://localhost:8345/api/v1/position/add"
curl -k -X GET -H "Content-Type: application/json" "https://localhost:8345/api/v1/position/stock?symbol=NVDA" | jq
curl -k -X GET -H "Content-Type: application/json" "https://localhost:8345/api/v1/position/bucket?name=BucketB" | jq
curl -k -X PUT -H "Content-Type: application/json" -d '{"symbol": "NVDA", "buckets": ["BucketA"]}' "https://localhost:8345/api/v1/position/add_to_buckets"
curl -k -X PUT -H "Content-Type: application/json" -d '{"symbol": "NVDA", "buckets": ["BucketB"]}' "https://localhost:8345/api/v1/position/remove_from_buckets"
This service uses the following tools and libraries, please consult their respective documentation for more information.
- conjure - IDL for defining APIs once and generating client/server interfaces in different languages.
- conjure-java-runtime - conjure libraries for HTTP&JSON-based RPC using Retrofit, Feign, OkHttp as clients and Jetty/Jersey as servers
- conjure-java - conjure generator for java clients and servers
- conjure-typescript - conjure generator for typescript clients
- gradle - a highly flexible build tool. Some of the gradle plugins applied are:
- gradle-conjure - a gradle plugin that contains tasks to generate conjure bindings.
- gradle-baseline - a gradle plugin for configuring code quality tools in builds and projects.
- undertow - a simple framework for building web services
-
portfolio-service-api
- a sub-project that defines portfolio-service APIs in Conjure and generates both java and typescript bindings.This is what the api project looks like:
├── portfolio-service-api │ ├── build.gradle │ ├── portfolio-service-api-dialogue │ ├── portfolio-service-api-objects │ ├── portfolio-service-api-typescript │ ├── portfolio-service-api-undertow │ └── src │ └── main │ └── conjure │ └── portfolio-service-api.yml
build.gradle
- a gradle script that- configures sub-projects with needed dependencies to generate java bindings. e.g.
portfolio-service-api-dialogue
- configures
publishTypescript
task to generate.npmrc
in the generated root folder,portfolio-service-api-typescript/src
for publishing the generated npm module. - modifies the
conjure
extension to specify the package name under which the npm module will be published.
- configures sub-projects with needed dependencies to generate java bindings. e.g.
portfolio-service-api-dialogue
- the sub-project where all generated service interfaces live.portfolio-service-api-objects
- the sub-project where all generated object classes live.portfolio-service-api-typescript
- the sub-project where all generated typescript bindings live.src/main/conjure
- directory containing conjure definition yml files where recipe APIs are defined, please refer to specification.md for more details.
-
portfolio-service-server
- an Undertow application project that uses conjure generated Undertow binding for resource class implementationThis is what the server project looks like:
├── portfolio-service-server │ ├── build.gradle │ ├── src │ │ ├── main/java │ │ └── test/java │ └── var │ └── conf │ └── conf.yml
build.gradle
- configures the project with needed dependencies and applies thegradle-conjure
andapplication plugins
, so we can run the server locally or in IDE.src/main/java
- source classes for the Undertow application. e.g.portfolioBookingResource.java
classimplements
the generated Undertow interface.test/main/java
- test source classes for simple integration tests that uses generated jersey interface for client interaction.var/conf/conf.yml
- the Undertow application configuration yml file
-
build.gradle
- the root level gradle script where a set of gradle plugins are configured, including gradle-conjure. -
settings.gradle
- the gradle settings file where all sub projects are configured. -
versions.props
- a property file of the nebula version recommender plugin with which we can specify versions of project dependencies, including conjure generators.
./gradlew tasks
for tasks available in this project../gradlew idea
for IntelliJ./gradlew eclipse
for Eclipse./gradlew run
for running the server or use IDE to debug it
/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\
/!\ Please do not use these certificates in prod! /!\
/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\
The certificates presented with this server are an example so that the tests run in HTTPs. These were generated by following the steps below. All passwords are "changeit"
keytool -genkey -alias bmc -keyalg RSA -keystore keystore.jks -keysize 2048 -dname "CN=localhost,OU=AQ,O=AQ,C=AQ" -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -validity 3650
openssl req -new -x509 -keyout ca-key -out ca-cert
keytool -keystore KeyStore.jks -alias bmc -certreq -file cert-file
openssl x509 -req -CA ca-cert -CAkey ca-key -in cert-file -out cert-signed -days 365 -CAcreateserial -passin pass:changeit
keytool -keystore KeyStore.jks -alias CARoot -import -file ca-cert
keytool -keystore KeyStore.jks -alias bmc -import -file cert-signed
keytool -keystore truststore.jks -alias bmc -import -file ca-cert