{"id":20926830,"url":"https://github.com/nahime0/stock-market","last_synced_at":"2026-04-11T09:34:35.928Z","repository":{"id":210538286,"uuid":"726808496","full_name":"nahime0/stock-market","owner":"nahime0","description":"A simple implementation of the Alpha Vantage API in Laravel","archived":false,"fork":false,"pushed_at":"2023-12-04T16:19:38.000Z","size":290,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-19T18:24:07.226Z","etag":null,"topics":["alphavantage","alphavantage-api","alphavantage-rest-api","alpinejs","laravel","mock","python","tailwindcss"],"latest_commit_sha":null,"homepage":"https://www.alphavantage.co/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nahime0.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-03T13:18:40.000Z","updated_at":"2024-01-08T07:59:19.000Z","dependencies_parsed_at":"2024-11-19T06:06:26.796Z","dependency_job_id":null,"html_url":"https://github.com/nahime0/stock-market","commit_stats":null,"previous_names":["nahime0/stock-market"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nahime0%2Fstock-market","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nahime0%2Fstock-market/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nahime0%2Fstock-market/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nahime0%2Fstock-market/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nahime0","download_url":"https://codeload.github.com/nahime0/stock-market/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243319972,"owners_count":20272380,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alphavantage","alphavantage-api","alphavantage-rest-api","alpinejs","laravel","mock","python","tailwindcss"],"created_at":"2024-11-18T20:43:33.014Z","updated_at":"2025-12-25T09:46:38.650Z","avatar_url":"https://github.com/nahime0.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Stock market\n\n![Static analysis](https://github.com/nahime0/stock-market/actions/workflows/static.yml/badge.svg)\n![Automated testing](https://github.com/nahime0/stock-market/actions/workflows/tests.yml/badge.svg)\n\nThis application will periodically fetch stock prices from the [Alpha Vantage API](https://www.alphavantage.co/) and store them in a database. \nThe data can be accessed through a REST API.\n\nThis is just a PoC, should not be used in production.\n\n# Installation\n\nAfter cloning the repository, you need to install the dependencies using composer\n(refer to the composer documentation to install the tool):\n\n```bash\ncomposer install\n```\n\nClone the env file and edit it to match your environment:\n\n```bash\ncp .env.example .env\nvim .env\n```\n\nYou need to specify credential for the `MySQL` connection and for the `Alpha Vantage` API.\n```dotenv\nDB_CONNECTION=mysql\nDB_HOST=127.0.0.1\nDB_PORT=3306\nDB_DATABASE=stock_market\nDB_USERNAME=application\nDB_PASSWORD=application\n\n\nSTOCK_MARKET_ALPHA_VANTAGE_API_KEY=demo\nSTOCK_MARKET_ALPHA_VANTAGE_API_URL=https://www.alphavantage.co\n```\n\nThe application leverages the Laravel `Cache` module.\n\nThe ttl of the cached data can be set-up using the provided environment variable:\n\n```dotenv\nSTOCK_MARKET_CACHE_TTL=60\n```\n\nBy default the cache it's configured to use the `file` driver.\nIf you want to use a different driver, you can change it in the `.env` file:\n\nFor redis (the application already requires the needed predis/predis): \n\n```dotenv\nCACHE_DRIVER=redis\n\nREDIS_HOST=\nREDIS_PASSWORD=\nREDIS_PORT=6379\n```\n\nGenerate the application key:\n\n```bash\nphp artisan key:generate\n```\n\nRun the migrations:\n\n```bash\nphp artisan migrate\n```\n\nFill in the default Symbols: \n\n```bash\nphp artisan app:fill-symbols\n````\n\nAt this time you can run the application using either\na local web server (for example Laravel Valet or Laravel Herd)\nor using the built-in PHP web server:\n\n```bash\nphp artisan serve\n```\n\n# Running with Docker\n\nThe project can be run using `Docker`.\n\nIn the repository, a simple `docker-compose.yml` is provided.\nIt uses `mysql` for the database and a custom `php8.2-apache` image for the web server.\n\nDue to time contraints, the docker image is not optimized for production.\n\nA better solution would involve using nginx or caddy as a web server, and a separate container for php-fpm.\n\nIf you want to use docker, use the provided .env file:\n\n```bash\ncp .env.docker .env\n```\n\nThen run:\n\n```bash\ndocker-compose up --build\n```\n\nAt this point you need to run all the commands in the previous section, but using docker:\n\n```bash\ndocker-compose exec php composer install\ndocker-compose exec php php artisan key:generate\ndocker-compose exec php php artisan migrate\ndocker-compose exec php php artisan app:fill-symbols\n```\n\nTo fetch the pricing, you need to run the scheduler:\n\n```bash\ndocker-compose exec php php artisan schedule:work\n```\n\nor fetch one time\n\n```bash\ndocker-compose exec php php artisan app:fetch-pricing\n```\n\nRemember to adapt the `.env` file to match your environment.\nBy default the api will point to the host machine on port `5000`, on which\nthe mock server will be running (if started).\n\nThe mapped port for the application is `8085`. So, once started, you can access the application\nusing the browser and navigating to `http://localhost:8085`.\n\n# Usage\n\nOnce you have the list of the Symbol defined in the database, \nyou can start fetching the stock pricing using the following command:\n\n```bash\nphp artisan schedule:work\n```\n\nEach minute the pricing for all the symbols will be fetched and stored in the database.\nThe intraDay (with 1min interval) will be used.\n\nIf you want to manually fetch the pricing you can run:\n\n```bash\nphp artisan app:fetch-pricing\n```\n\n## Web interface\n\nThe project has a very simple web interface, that you can access using the browser and \nnavigating to the the app url of your project.\n\nThe web interface has a dashboard that shows the latest pricing for all the symbols in the database,\nwith the price variation from the previous period.\n\n## REST API\n\nAt ths point you can start using the REST API.\nFor simplicity, in the repository there is a `Postman` collection that you can use to test the API.\nYou can find it in the `var` folder.\n\nEdit the variables of the collection to match your environment.\n\nThere are three endpoints available:\n\n### GET /api/symbols\n\nThis endpoint will return the list of `Symbols` available in the database.\nThe response will be a JSON array with shape:\n```json\n[\n  {\n    \"symbol\": \"AAPL\",\n    \"name\": \"Apple Inc.\"\n  }\n]\n```\n\n### GET /api/history/{symbol}\n\nThis endpoint will return the pricing history for the given `Symbol`.\nThe response will be a JSON array with shape:\n```json\n{\n  \"data\": [\n    {\n      \"datetime\": \"2023-12-03 15:01:00\",\n      \"open\": \"0.0000\",\n      \"high\": \"0.0000\",\n      \"low\": \"0.0000\",\n      \"close\": \"0.0000\",\n      \"volume\": \"0\"\n    }\n  ]\n}\n```\n\n### GET /api/ticker/{symbol}\n\nThis endpoint will return the latest pricing for the given `Symbol`,\nand the price variation from the previous period.\n\nThis API endpoints uses the Laravel `Cache` to avoid hitting the database every time.\n\nThe response will be a JSON array with shape:\n```json\n{\n  \"current\": {\n    \"datetime\": \"2023-12-03 15:01:00\",\n    \"open\": \"0.0000\",\n    \"high\": \"0.0000\",\n    \"low\": \"0.0000\",\n    \"close\": \"0.0000\",\n    \"volume\": \"0\"\n  },\n  \"previous\": {\n    \"datetime\": \"2023-12-03 15:00:00\",\n    \"open\": \"0.0000\",\n    \"high\": \"0.0000\",\n    \"low\": \"0.0000\",\n    \"close\": \"0.0000\",\n    \"volume\": \"0\"\n  },\n  \"change\": \"0.0000\",\n  \"change_percent\": \"0.0000\"\n}\n```\n\n# Testing\n\n## Automated tests\n\nThe application is covered by unit and feature tests.\nThe tests have been created using the [pest](https://pestphp.com/) framework, a wrapper around phpunit.\nTo launch tests, just run:\n\n```bash\n./vendor/bin/pest\n```\n\nor use the composer shortcut:\n\n```bash\ncomposer test\n```\n\n## Static analysis\n\nThe application is covered by static analysis using phpstan.\nTo launch the static analysis, just run:\n\n```bash\n./vendor/bin/phpstan\n```\n\nor use the composer shortcut:\n\n```bash\ncomposer static\n```\n\n## Test real world scenario\n\nYou can test the application, also without the real Alpha Vantage API key.\nJust use the provided mock server.\n\n## Using the provided Alpha Vantage mock server\n\nIf you want to test the application, without using the real Alpha Vantage API endpoint,\nyou can use the provided python mock server.\n\nJust enter the `mock` folder, activate a python virtual environment, install requirements and\nyou are ready to start the server:\n\n```bash\ncd mock\npython -m venv venv\nsource venv/bin/activate\npip install -r requirements.txt\npython server.py\n```\n\nThe mock service will listen on the default python flask port `5000`\nYou can specify this mock server in the `.env` file:\n\n```dotenv\nSTOCK_MARKET_ALPHA_VANTAGE_API_KEY=mock\nSTOCK_MARKET_ALPHA_VANTAGE_API_URL=http://127.0.0.1:5000\n```\n\nThe Api Key can be anything, it will not be checked by the mock server.\n\n## Testing just the application with fake data\n\nIf you're just interested in testing the application, without fetching any data from the API,\nyou can fill the database with fake pricing using the following command:\n\n```bash\nphp artisan db:seed Database\\\\Seeders\\\\PriceSeeder\n```\n\nThe previous command will fill the pricing for all the `Symbols` in the database.\nThis works only if you already have the `Symbols` data in the database (see the installation section).\n\nIf you want to use also fake `Symbols` data, you can run:\n\n```bash\nphp artisan db:seed Database\\\\Seeders\\\\SymbolSeeder\n```\n\n# Information about the project\n\n## Architecture\n\nThe application is built using the `Laravel framework`.\nThe main logic for the Alpha Vantage API is located in the `app/AlphaVantage` folder.\n\nThe code has been written to be statically typed, using the `PHPStan` tool.\nThe architecture of each file is tested during the Unit testing.\n\nstrict_types has been used to enforce strict typing among the application.\n\nIt leverage the Laravel `Cache` to avoid hitting the database every time the `/api/ticker/{symbol}` endpoint is called.\n\n### Classes\n\n#### App\\AlphaVantage\\Client\\Client\n\nThis is the main class that interacts with the Alpha Vantage API.\nIt will handle communication with the API and data transformation.\nResults for every call will be a Laravel Collection of StockPrice objects.\n\nDependency injection for the class is handle in the `app\\Providers\\AppServiceProvider.php` file.\n\n#### App\\AlphaVantage\\Client\\StockPrice\n\nThis is the representation of a single Stock Price. It is valid either for \nthe intraDay and daily pricing. \nIt contains data fetched from the API, transormed in the right data type.\n\n#### App\\AlphaVantage\\Enums\\Functions\n\nThis Enum contains the functions of the Alpha Vantage API supported by the\napplication.\nThe method `jsonKey()` provides a convenient way of establishing the key of the\njson response that will be used to fetch the data.\n\n#### App\\AlphaVantage\\AlphaVantage\n\nThis is a Laravel Facade, with root accessors to the Alpha Vantage Client.\nThis is used to easily access the Alpha Vantage Client from the application.\n\n### Configuration\n\nThe configuration for the application is stored in the `config/stock_market.php` file.\nEach configuration key will be available in the application using the `config()` helper, \nand can be set-up using environment variables.\n\n### Commands\n\n#### App\\Console\\Commands\\FillSymbols\n\nThis command will fill the database with the default symbols.\nUsage:\n\n```bash\nphp artisan app:fill-symbols\n```\n\n#### App\\Console\\Commands\\FetchPricing\n\nThis command will fetch the pricing for all the symbols in the database.\nUsage:\n\n```bash\nphp artisan app:fetch-pricing\n```\n\nThis command is scheduled (in the `app/Console/Kernel.php` file) to run every minute.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnahime0%2Fstock-market","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnahime0%2Fstock-market","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnahime0%2Fstock-market/lists"}