Giter VIP home page Giter VIP logo

dalal-street-server's Introduction

CircleCI build status Go Report Card

Server for Dalal Street

Prerequisites

  • Go 1.16
  • Protocol buffers
  • MySQL

Build instructions

  • Setting up server

Refer Setup Wiki for setting up Dalal-Street-Server

  • Setup submodules
git submodule init
git submodule update --recursive
  • Create databases and run migrations
mysql -u root -p -e "CREATE DATABASE dalalstreet_dev; CREATE DATABASE dalalstreet_test;"
migrate -path "./migrations" -database "mysql://root:YOUR_MYSQL_PASSWORD@/dalalstreet_dev" up
  • Generate proto files
./scripts/build_proto.sh
  • Run cp config.json.example config.json
  • Fill in the database credentials in the Dev section of config.json.
  • Run the server
    • development - Install air for live reload
      air
    • production
      go run main.go

Create Migrations

migrate create -ext sql -dir ./migrations MIGRATION_NAME

Tests

  • Run the test script locally before pushing commits.
./scripts/test.sh

Docker usage instructions

  • Install docker and docker-compose.

  • Run cp .env.example .env and cp config.json.example config.json.

  • Fill in the DB_PASS in .env and make any additional changes if necessary.

  • Use the same credentials in Docker section config.json (DbPassword)

  • Running server

docker-compose up
  • Once the containers are up, you can get shell access by using
docker exec -it <CONTAINER_NAME> bash
docker-compose build
docker-compose up

(might require sudo, depending on permissions of volume mount './docker/' )

  • To view all running docker containers:
docker ps
  • Server logs are present in ./docker/logs/

GoMock usage instructions

  • To generate mock for a file using mockgen, place this comment after import statement
 //go:generate mockgen -source {YOUR_FILE_NAME}.go -destination ../mocks/{YOUR_FILE_NAME}.go -package mocks
  • To generate mocks for all packages that has above comment
go generate ./...

  • To manually generate a mock package
mockgen -destination=mocks/{YOUR_FILE_NAME}.go -package=mocks {PATH_TO_YOUR_FILE}

dalal-street-server's People

Contributors

0149sailesh avatar abesheknarayan avatar adwaith007 avatar akspi avatar ar-sibi avatar coderick14 avatar gauthamk97 avatar harsh2098 avatar hedhav avatar ishanisri avatar kelpikz avatar nimishagarwal76 avatar pranavshriram avatar rahulzoldyck avatar sandy9999 avatar simmiggrwl avatar siva2204 avatar sudhindra3000 avatar thakkarparth007 avatar varunram avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dalal-street-server's Issues

Allow users to set custom price alerts

It'd be nice to let users set price alerts for the stocks they're interested in. For example, if the price of "X" changes by 1000, then notify me. The user will get a notification on his app, and/or web.

Tests for grpc API

Low priority, because anyway clients will be testing the API, but it's good to have automated tests.

Complete Bot class and Bot Manager class

Bot Manager needs to work with IndicatorManager. It also needs to manage states of bots, or should it?

Bot class needs to be defined to allow real bots to be able to inherit it.

Images for Companies, News from Server

Need to add company images (logo, and maybe banner images). Images for news as well.

Need to update the APIs. Or serve the images from the static content server.

News page component

Show news, along with images. Images support will be added on the server, so if server isn't ready by the time this starts, assume a reasonable API (mostly a new field added to the MarketEvent model)

Tests for matching engine and streams!

These two are risky systems. Need to test them properly. It should be easy to do that now because I've decoupled them. Matching engine still talks to the db directly for stoploss orders, and that needs to be fixed somehow. It should be done separately, or at least a better way should be there.

  • Tests for Matching engine
  • Tests for Streams

Clean up bloat from bundle.js

The grpc-web library uses some TextEncoding library which uses a heck lot of space. And grpc-web uses it only to decode a Uint8Slice from to utf-8. There's absolutely no need for using that entire library (700-800kb) for that. Need to remove it somehow.

Also need to optimize the size of bundle.js besides just this issue. (https://www.man42.net/blog/2016/06/webpack-bundle-size-reduction/) provides a good way to find out stats about the dependencies:
webpack --production --json > stats.json

Price Alerts API on Server

Allow users to be able to get notifications when price of their favourite stocks fluctuates by a given amount.

Affects Server, UI, App

Reserve/Deposit money/stocks when making an order

Problem:

Currently when PlaceAskOrder is called, the server checks if the user has enough cash/stocks to fulfill that order, leaving that money/stocks still in the user's ownership. This is problematic because if my balance is Rs. 1000, then I can make several orders at the same time whose total value is Rs. 1000. For example one order for buying 10 stocks at 100 each, and another order for buying 5 stocks at 200 each.

While the PerformOrderFillTransaction checks if the order is cancelled that's wasteful. And it also gives an incentive to the user to make random orders without thinking.

Change to be made:

I'd like to reserve the relevant money/stocks that the user has once he makes an order. So for example if he makes an order of buying 10 stocks at 100 each, the cash he has is 1000 lesser than what he had. Instead, this 1000 gets paid to the exchange as a deposit. Similarly if he wants to sell 10 stocks at 100 each, he will have 10 lesser stocks than what he had before making order.

How to go about changing:

On a high level we'll need to introduce two new types of transactions - PlaceOrderTransaction and CancelOrderTransaction.

PlaceOrderTransaction will have only (Price, StockQuantity) or (Total) fields non-zero. If it is an Ask order, (Price, StockQuantity) will be set to the respective values, and Total will be zero. If it is a Bid order only the Total field will be set.

CancelOrderTransaction transaction will also have only one of (Price, StockQuantity) or (Total) fields non-zero. However, the signs will differ. In PlaceOrderTransaction the signs will be negative (StockQuantity, or Total - one of them. Price is never negative). In CancelOrderTransaction, since the stocks/money is going back to the user, the signs will be positive.

We've to take care that the following properties are maintained:

  1. Sum(Total) of a user's transactions should equal the cash he has in hand (not deposited for buying).
  2. Sum(StockQuantity) of a user's transactions for a given stock should equal the stocks he has in his own control (not deposited for selling or mortgaged)

Since we also want to be able to link the PlaceOrderTransaction and CancelOrderTransaction transactions to the relevant orders, we'll have to have a mapping between Orders and Transactions table. The best way I thought was to introduce a new table called Order_DepositWithdrawalTransactions (or some better name). There will be three columns - OrderId, TransactionId and TransactionType (PlaceOrderTransaction/CancelOrderTransaction). All three together uniquely determine a row.

What things to update:

This change will affect the following:

  1. migrations:
    a. Update Users table to add a new column - cash_in_orders.
    b. Update Transactions table to have two new types of transactions (alter the enum values) - PlaceOrderTransaction and CancelOrderTransaction.
    c. Create a new table called Order_DepositWithdrawalTransactions (or some better name) with fields OrderId, TransactionId and TransactionType (PlaceOrderTransaction/CancelOrderTransaction)

  2. models.User: Introduce a new field: CashInOrders (take care of casing convention - pascal case in Go, snake case in database table)

  3. proto/models.User: Make the same change in the proto/models/User.proto. Make sure the ToProto method in Users model is in sync, including the test.

  4. models.TransactionType: Make the transaction type include more values. Update the proto as well.

  5. models.Order_DepositWithdrawalTransaction: Make a new model for this table. Give a better name to it I think. It's super lengthy, though conveys the point. This will be used while making the transactions. Also make sure you have the correct foreign key integrity checks. It's super important!

  6. models.PlaceAskOrder: Update the logic to make a PlaceOrderTransaction transaction to the database. Also update user's cash and cash_in_orders. You'll need to insert a row in the Order_DepositWithdrawalTransactions table.

  7. models.PlaceBidOrder: Update the logic to make a PlaceOrderTransaction transaction to the database. You'll need to insert a row in the Order_DepositWithdrawalTransactions table.

  8. models.CancelOrder: Update the logic to refund the cash or stocks to the user. You'll need to insert a row in the Order_DepositWithdrawalTransactions table.

  9. models.OrderFillTransaction: This function currently checks if the user has enough balance or stocks. We don't need to do that anymore and can be dropped (however let the code for checking if order is closed or not be there). Also, the OrderFillTransaction it creates in the Transactions table will have to have only one of the fields set (StockQuantity,Price) or (Total). If it's an Ask order, Total will be set to a positive value. Vice versa.

Remember the convention regarding transactions table - StockQuantity positive means stocks go to the user. Same way, Total positive means cash goes to the user. Negative is reverse.

Master Layout Completition

Need to have a sidebar,topbar,main_container layout ready, along with routing.

Make the respective React components as well.

Needn't bother about Logged/Logged out status as of now. Just the UI component is required for this piece of work.

Search component for Trading Terminal on Frontend

Search component should display the stocks available, along with their prices and up/down symbol with differences. Selecting a stock in this component should update the chart, market depth, buy/sell and open orders components.

Bots Control Panel Frontend

Need to build the dashboard to be able to create, launch, pause, view status & logs of, update, validate bots.

Stock history recording and retrieval needs to be fixed

Problem

We do not have a proper mechanism to handle stock history. We returned entire history of the stock last year, but that's a terrible thing to do.

How other sites solve it

Most stock sites provide you to specify the ranges of the stock history (1day, 5day, 1month, 3month, 6month, 1yr, 2yr, 5yr, Max - these are standard ranges, some offer lesser, some more). We'll follow the same. However, our game will be of only 10-14 days (mostly 10) and will run for 5-6 hours a day, so people won't be using most of the ranges except for looking at how the company did in the past. So maybe we should change our ranges to something more relevant (like have more short term ranges starting from 1 hour). We'll still need long-term ranges for completeness and for giving the gameplay some story factor.

Also, for each range the granularity/interval (we'll call it interval from now on) will be pre-decided. For example, in 1day range, stock prices of every minute will be shown. In 5day range, stock prices of every 5min interval will be shown, etc.

To get a feel of these, checkout any site - yahoo finance is pretty good, or http://gdax.com/trade/ETH-USD

Candlesticks business

Also, we'll be showing price candlesticks on the frontend. These require 4 things - Open, High, Low, Close prices for each interval. Open is the price at the start of the interval, High is the highest price during the interval, Low is the Lowest price during the interval. Close is the price at the close of the interval (this will coincide with the Open price of the next interval). Look up stock candlesticks if you're still confused.

And, I'd like the trade volume to be stored as well. But that'll be part of another PR.


Parts of the problem

  1. First part of this feature would be to figure out what ranges & corresponding intervals we want to support.

  2. Second part would be to figure out how we'd be querying the data.

  3. Third part will be the actual coding. It'll affect models and proto and gRPC API.

Datastreams - loss of data after login but before subscribing

Currently the login response returns a starting state. The client is supposed to subscribe to streams to get live data feed. But after the login response and before the subscription, a few updates might go missing and that could create bad situations.

Need to modify Datastreams API so that client can ask for "get updates since id". Will affect Notifications, Transactions, others?

Changes to be made to proto files, and the data streams logic.

Deploy a test server

Need to deploy a test server for android clients, bots, and playing around with web clients as well.

Heroku might be a good option.

This will force us to write scripts for filling up dummy data as well - that's super important.

Portfolio page component

Need to show user's portfolio, transaction history, total wealth, cash stuck in orders, stocks stuck in orders, (stocks stuck in mortgage?)

Make mortgage involve interests

Currently mortgaging doesn't require users to pay any interest. It'd be fun to have them pay interest as well. Need to think this through.

Leaderboard page component

Make react component to show leaderboard. Handle pagination, and talking with server. Leaderboard data updates every 2 min (or something like that - check), so a timer showing that should also be made available.

Cleaning up error handling part of the API

Currently the server returns both gRPC errors and custom errors. Need to find a better way, or need to document the exact form of error handling.

Currently the server will return grpc.UNAUTHENTICATED error if the request doesn't have a valid session id metadata set, and grpc.INTERNAL_ERROR sometimes.

Most of the times it returns grpc.STATUS_OK, with custom error inside the Response object. This is bad.

Either we should return grpc's error codes entirely, with error message string. Or have a clear division of errors.

Reserve/Deposit money/stocks when making an order

Problem:

Currently when PlaceAskOrder is called, the server checks if the user has enough cash/stocks to fulfill that order, leaving that money/stocks still in the user's ownership. This is problematic because if my balance is Rs. 1000, then I can make several orders at the same time whose total value is Rs. 1000. For example one order for buying 10 stocks at 100 each, and another order for buying 5 stocks at 200 each.

While the PerformOrderFillTransaction checks if there is sufficient balance to execute the order, that's wasteful. And it also gives an incentive to the user to make random orders without thinking.

Change to be made:

I'd like to reserve the relevant money/stocks that the user has once he makes an order. So for example if he makes an order of buying 10 stocks at 100 each, the cash he has is 1000 lesser than what he had. Instead, this 1000 gets paid to the exchange as a deposit. Similarly if he wants to sell 10 stocks at 100 each, he will have 10 lesser stocks than what he had before making order.

How to go about changing:

On a high level we'll need to introduce two new types of transactions - PlaceOrderTransaction and CancelOrderTransaction.

PlaceOrderTransaction will have only (Price, StockQuantity) or (Total) fields non-zero. If it is an Ask order, (Price, StockQuantity) will be set to the respective values, and Total will be zero. If it is a Bid order only the Total field will be set.

CancelOrderTransaction transaction will also have only one of (Price, StockQuantity) or (Total) fields non-zero. However, the signs will differ. In PlaceOrderTransaction the signs will be negative (StockQuantity, or Total - one of them. Price is never negative). In CancelOrderTransaction, since the stocks/money is going back to the user, the signs will be positive.

We've to take care that the following properties are maintained:

  1. Sum(Total) of a user's transactions should equal the cash he has in hand (not deposited for buying).
  2. Sum(StockQuantity) of a user's transactions for a given stock should equal the stocks he has in his own control (not deposited for selling or mortgaged)

Since we also want to be able to link the PlaceOrderTransaction and CancelOrderTransaction transactions to the relevant orders, we'll have to have a mapping between Orders and Transactions table. The best way I thought was to introduce a new table called Order_DepositWithdrawalTransactions (or some better name). There will be three columns - OrderId, TransactionId and TransactionType (PlaceOrderTransaction/CancelOrderTransaction). All three together uniquely determine a row.

What things to update:

This change will affect the following:

  1. migrations:
    a. Update Users table to add a new column - cash_in_orders.
    b. Update Transactions table to have two new types of transactions (alter the enum values) - PlaceOrderTransaction and CancelOrderTransaction.
    c. Create a new table called Order_DepositWithdrawalTransactions (or some better name) with fields OrderId, TransactionId and TransactionType (PlaceOrderTransaction/CancelOrderTransaction)

  2. models.User: Introduce a new field: CashInOrders (take care of casing convention - pascal case in Go, snake case in database table)

  3. proto/models.User: Make the same change in the proto/models/User.proto. Make sure the ToProto method in Users model is in sync, including the test.

  4. models.TransactionType: Make the transaction type include more values. Update the proto as well.

  5. models.Order_DepositWithdrawalTransaction: Make a new model for this table. Give a better name to it I think. It's super lengthy, though conveys the point. This will be used while making the transactions. Also make sure you have the correct foreign key integrity checks. It's super important!

  6. models.PlaceAskOrder: Update the logic to make a PlaceOrderTransaction transaction to the database. Also update user's cash and cash_in_orders. You'll need to insert a row in the Order_DepositWithdrawalTransactions table.

  7. models.PlaceBidOrder: Update the logic to make a PlaceOrderTransaction transaction to the database. You'll need to insert a row in the Order_DepositWithdrawalTransactions table.

  8. models.CancelOrder: Update the logic to refund the cash or stocks to the user. You'll need to insert a row in the Order_DepositWithdrawalTransactions table.

  9. models.OrderFillTransaction: This function currently checks if the user has enough balance or stocks. We don't need to do that anymore and can be dropped (however let the code for checking if order is closed or not be there). Also, the OrderFillTransaction it creates in the Transactions table will have to have only one of the fields set (StockQuantity,Price) or (Total). If it's an Ask order, Total will be set to a positive value. Vice versa.

Remember the convention regarding transactions table - StockQuantity positive means stocks go to the user. Same way, Total positive means cash goes to the user. Negative is reverse.

Need to decide storyline, stocks available etc

We've to decide which stocks to pick.

  1. Should we pick real ones? Fake ones? How many?
  2. We need to get starting data for the stocks - orders, price history, volume history
  3. Need to decide a way to publish news, market events. Automated? Manual? Format of news - images and all?
  4. Cryptocurrencies?

Trade volume to be recorded in history

Need to update the DB schema, the code that records the stock history, and also the APIs that return the stock history to the clients.

Affects #79. This should be completed before #79

Make stock history a stream

Currently the client is supposed to look at stock prices stream and generate a local stock history to update the graph. This will create problems because the stock prices stream doesn't give all the prices, but updates every 15s (interval will be reduced later).

This needs to be updated to a stream.

Remove price cap checks for Market order

Currently, in PlaceAskOrder and PlaceBidOrder, we are placing a check for the order price to be within a certain threshold margin of the current price. These checks need to be removed for Market orders.

Bots Control panel backend

Backend will interact with BotManager and maybe Market Messenger.
Need to be able to create, launch, pause, view status & logs of, update, validate, bots.

Dividend Transactions

Currently dividend transactions related code has been commented out in models/User.go. Check if it makes sense to have them, and if so, fix the code and make it work.

Fake login for bots

For bots, we need to be able to specify that it is bot X that is making the current request. This needs to be done by specifying a bot_secret and a bot_user_id in the metadata of every request.

This will be done by creating a Fake Session because all request handlers require a Session and use at least the userId field set in it.

Chart Component for Trading Terminal on Frontend

Make the react component showing a candelsticks chart, and a line chart with stock volume (volume data format needs to be decided. It's not provided by the server currently).

Needn't integrate with the server. Just need to make the React component.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.