{"id":15854237,"url":"https://github.com/denis256/trade-validator","last_synced_at":"2026-05-09T04:33:00.705Z","repository":{"id":90056821,"uuid":"76584230","full_name":"denis256/trade-validator","owner":"denis256","description":"Trades validation service","archived":false,"fork":false,"pushed_at":"2017-03-05T13:47:26.000Z","size":140,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-01T18:56:15.437Z","etag":null,"topics":["java","java8","spring","spring-boot"],"latest_commit_sha":null,"homepage":null,"language":"Java","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/denis256.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":"2016-12-15T18:15:00.000Z","updated_at":"2017-05-20T23:20:40.000Z","dependencies_parsed_at":null,"dependency_job_id":"932bf605-eb66-4807-b8a6-5259e3dc058e","html_url":"https://github.com/denis256/trade-validator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/denis256/trade-validator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denis256%2Ftrade-validator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denis256%2Ftrade-validator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denis256%2Ftrade-validator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denis256%2Ftrade-validator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/denis256","download_url":"https://codeload.github.com/denis256/trade-validator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denis256%2Ftrade-validator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32807227,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"online","status_checked_at":"2026-05-09T02:00:06.633Z","response_time":123,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["java","java8","spring","spring-boot"],"created_at":"2024-10-05T19:41:16.027Z","updated_at":"2026-05-09T04:33:00.686Z","avatar_url":"https://github.com/denis256.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"Trade validation service\n========================\n\nService which checks trade details \n\nService is based on Gradle, Spring 4.3.3 and Spring Boot 1.4.1\n\nService built from modules which implement separated functionality.\n \n - trade-validator-model : model classes for trade, validation errors \n  \n - trade-validator-api : API interfaces to add new things into validation service\n \n - trade-validator-core : core services for trade validation\n  \n - trade-validator-app : REST interface for validating trades\n \n - trade-validators : implementation of trade validation business rules\n\n\nEach validation rule should implement `TradeValidator` interface and be a spring managed bean, during startup Spring will inject available validators into `ValidationCore`.\nREST API controllers calls `ValidationCore` for validate trodes and return results.\n\nValidators from `trade-validators` have pre-defined, hardcoded  settings, can load configurations from spring configurations and also expose JMX managed beans which allow settings change on runtime. \n\n\n\nAPI endpoints\n=============\n\n`/api/validate` - validate single trade, as result is returned trade and list of invalid fields\n\n`/api/validateBulk` - bulk validate of a trade list, as result is returned list of trades and each trade have list of errors\n\n`/api/shutdown` - shutdown endpoint, `GET` request to fetch status, `POST` to shutdown service. Shutdown can be canceled by sending `DELETE` on shutdown API.\nShutdown status is also available through default `/info` endpoint. When shutdown status is set, service no more accept trades for validation.\n\n`/metrics` - fetch  application metrics \n\n`/swagger-ui.html#/validation-controller` - swagger Rest API documentation\n\n\n\nExample API calls\n=================\n\n**Validate single trade**\n\nRequest\n\n`curl -v   -H \"Content-Type: application/json\"   -X POST --data \"@./raw_trades/single_trade.json\" localhost:8080/api/validate`\n\nResponse\n\n```\n* Hostname was NOT found in DNS cache\n*   Trying 127.0.0.1...\n* Connected to localhost (127.0.0.1) port 8080 (#0)\n\u003e POST /api/validate HTTP/1.1\n\u003e User-Agent: curl/7.35.0\n\u003e Host: localhost:8080\n\u003e Accept: */*\n\u003e Content-Type: application/json\n\u003e Content-Length: 232\n\u003e \n* upload completely sent off: 232 out of 232 bytes\n\u003c HTTP/1.1 200 \n\u003c X-Application-Context: application\n\u003c Content-Type: application/json;charset=UTF-8\n\u003c Transfer-Encoding: chunked\n\u003c Date: Sun, 09 Oct 2016 09:40:17 GMT\n\u003c \n* Connection #0 to host localhost left intact\n{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":\"2016-08-15\",\"customer\":\"PLUTO1\",\"ccyPair\":\"EURUSD\",\"type\":\"Spot\",\"style\":null,\"excerciseStartDate\":null,\"expiryDate\":null,\"premiumDate\":null,\"deliveryDate\":null,\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{\"valueDate\":[\"On spot trades valueDate should be +2 days from today date\"]},\"haveErrors\":true}\n```\n**Bulk trades validation**\n\nRequest \n\n`curl -v   -H \"Content-Type: application/json\"   -X POST --data \"@./raw_trades/bulk_trades.json\" localhost:8080/api/validateBulk`\n\nResponse\n\n```\ncurl -v   -H \"Content-Type: application/json\"   -X POST --data \"@./raw_trades/bulk_trades.json\" localhost:8080/api/validateBulk\n* Hostname was NOT found in DNS cache\n*   Trying 127.0.0.1...\n* Connected to localhost (127.0.0.1) port 8080 (#0)\n\u003e POST /api/validateBulk HTTP/1.1\n\u003e User-Agent: curl/7.35.0\n\u003e Host: localhost:8080\n\u003e Accept: */*\n\u003e Content-Type: application/json\n\u003e Content-Length: 5089\n\u003e Expect: 100-continue\n\u003e \n\u003c HTTP/1.1 100 Continue\n\u003c HTTP/1.1 200 \n\u003c X-Application-Context: application\n\u003c Content-Type: application/json;charset=UTF-8\n\u003c Transfer-Encoding: chunked\n\u003c Date: Sun, 09 Oct 2016 09:43:29 GMT\n\u003c \n[{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":\"2016-08-15\",\"customer\":\"PLUTO1\",\"ccyPair\":\"EURUSD\",\"type\":\"Spot\",\"style\":null,\"excerciseStartDate\":null,\"expiryDate\":null,\"premiumDate\":null,\"deliveryDate\":null,\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{\"valueDate\":[\"On spot trades valueDate should be +2 days from today date\"]},\"haveErrors\":true},{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":\"2016-08-22\",\"customer\":\"PLUTO1\",\"ccyPair\":\"EURUSD\",\"type\":\"Spot\",\"style\":null,\"excerciseStartDate\":null,\"expiryDate\":null,\"premiumDate\":null,\"deliveryDate\":null,\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{\"valueDate\":[\"On spot trades valueDate should be +2 days from today date\"]},\"haveErrors\":true},{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":\"2016-08-22\",\"customer\":\"PLUTO2\",\"ccyPair\":\"EURUSD\",\"type\":\"Forward\",\"style\":null,\"excerciseStartDate\":null,\"expiryDate\":null,\"premiumDate\":null,\"deliveryDate\":null,\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{\"valueDate\":[\"On forward trades valueDate should be more than 2 days\"]},\"haveErrors\":true},{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":\"2016-08-21\",\"customer\":\"PLUTO2\",\"ccyPair\":\"EURUSD\",\"type\":\"Forward\",\"style\":null,\"excerciseStartDate\":null,\"expiryDate\":null,\"premiumDate\":null,\"deliveryDate\":null,\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{\"valueDate\":[\"On forward trades valueDate should be more than 2 days\",\"valueDate is holiday date\"]},\"haveErrors\":true},{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":\"2016-08-08\",\"customer\":\"PLUTO2\",\"ccyPair\":\"EURUSD\",\"type\":\"Forward\",\"style\":null,\"excerciseStartDate\":null,\"expiryDate\":null,\"premiumDate\":null,\"deliveryDate\":null,\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{\"valueDate\":[\"On forward trades valueDate should be more than 2 days\",\"Value date cannot be before Trade date\"]},\"haveErrors\":true},{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":\"2016-08-08\",\"customer\":\"PLUT02\",\"ccyPair\":\"EURUSD\",\"type\":\"Forward\",\"style\":null,\"excerciseStartDate\":null,\"expiryDate\":null,\"premiumDate\":null,\"deliveryDate\":null,\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{\"valueDate\":[\"On forward trades valueDate should be more than 2 days\",\"Value date cannot be before Trade date\"],\"customer\":[\"Customer is not in approved list\"]},\"haveErrors\":true},{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":\"2016-08-22\",\"customer\":\"PLUTO3\",\"ccyPair\":\"EURUSD\",\"type\":\"Forward\",\"style\":null,\"excerciseStartDate\":null,\"expiryDate\":null,\"premiumDate\":null,\"deliveryDate\":null,\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{\"valueDate\":[\"On forward trades valueDate should be more than 2 days\"],\"customer\":[\"Customer is not in approved list\"]},\"haveErrors\":true},{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":null,\"customer\":\"PLUTO1\",\"ccyPair\":\"EURUSD\",\"type\":\"VanillaOption\",\"style\":\"EUROPEAN\",\"excerciseStartDate\":null,\"expiryDate\":\"2016-08-19\",\"premiumDate\":\"2016-08-12\",\"deliveryDate\":\"2016-08-22\",\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{\"valueDate\":[\"valueDate is missing\"]},\"haveErrors\":true},{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":null,\"customer\":\"PLUTO2\",\"ccyPair\":\"EURUSD\",\"type\":\"VanillaOption\",\"style\":\"EUROPEAN\",\"excerciseStartDate\":null,\"expiryDate\":\"2016-08-21\",\"premiumDate\":\"2016-08-12\",\"deliveryDate\":\"2016-08-22\",\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{\"valueDate\":[\"valueDate is missing\"]},\"haveErrors\":true},{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":null,\"customer\":\"PLUTO1\",\"ccyPair\":\"EURUSD\",\"type\":\"VanillaOption\",\"style\":\"EUROPEAN\",\"excerciseStartDate\":null,\"expiryDate\":\"2016-08-25\",\"premiumDate\":\"2016-08-12\",\"deliveryDate\":\"2016-08-22\",\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{\"expiryDate\":[\"expiry date should be before delivery date\"],\"valueDate\":[\"valueDate is missing\"]},\"haveErrors\":true},{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":null,\"customer\":\"PLUTO1\",\"ccyPair\":\"EURUSD\",\"type\":\"VanillaOption\",\"style\":\"AMERICAN\",\"excerciseStartDate\":\"2016-08-12\",\"expiryDate\":\"2016-08-19\",\"premiumDate\":\"2016-08-12\",\"deliveryDate\":\"2016-08-22\",\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{\"valueDate\":[\"valueDate is missing\"]},\"haveErrors\":true},{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":null,\"customer\":\"PLUTO2\",\"ccyPair\":\"EURUSD\",\"type\":\"VanillaOption\",\"style\":\"AMERICAN\",\"excerciseStartDate\":\"2016-08-12\",\"expiryDate\":\"2016-08-21\",\"premiumDate\":\"2016-08-12\",\"deliveryDate\":\"2016-08-22\",\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{\"valueDate\":[\"valueDate is missing\"]},\"haveErrors\":true},{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":null,\"customer\":\"PLUTO1\",\"ccyPair\":\"EURUSD\",\"type\":\"VanillaOption\",\"style\":\"AMERICAN\",\"excerciseStartDate\":\"2016-08-12\",\"expiryDate\":\"2016-08-25\",\"premiumDate\":\"2016-08-12\",\"deliveryDate\":\"2016-08-22\",\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{\"expiryDate\":[\"expiry date should be before delivery date\"],\"valueDate\":[\"valueDate is missing\"]},\"haveErrors\":true},{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":null,\"customer\":\"PLUTO1\",\"ccyPair\":\"EURUSD\",\"type\":\"VanillaOption\",\"style\":\"AMERICAN\",\"excerciseStartDate\":\"2016-08-10\",\"expiryDate\":\"2016-08-19\",\"premiumDate\":\"2016-08-12\",\"deliveryDate\":\"2016-08-22\",\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{* Connection #0 to host localhost left intact\n\"excerciseStartDate\":[\"excerciseStartDate should be after trade date\"],\"valueDate\":[\"valueDate is missing\"]},\"haveErrors\":true},{\"trade\":{\"tradeDate\":\"2016-08-11\",\"valueDate\":null,\"customer\":\"PLUTO3\",\"ccyPair\":\"EURUSD\",\"type\":\"VanillaOption\",\"style\":\"AMERICAN\",\"excerciseStartDate\":\"2016-08-10\",\"expiryDate\":\"2016-08-19\",\"premiumDate\":\"2016-08-12\",\"deliveryDate\":\"2016-08-22\",\"legalEntity\":\"CS Zurich\"},\"invalidFields\":{\"excerciseStartDate\":[\"excerciseStartDate should be after trade date\"],\"valueDate\":[\"valueDate is missing\"],\"customer\":[\"Customer is not in approved list\"]},\"haveErrors\":true}]\n```\n\n\n**Fetch shutdown status**\n\nRequest \n`curl http://localhost:8080/api/shutdown`\n\nResponse\n```\n* Hostname was NOT found in DNS cache\n*   Trying 127.0.0.1...\n* Connected to localhost (127.0.0.1) port 8080 (#0)\n\u003e GET /api/shutdown HTTP/1.1\n\u003e User-Agent: curl/7.35.0\n\u003e Host: localhost:8080\n\u003e Accept: */*\n\u003e \n\u003c HTTP/1.1 200 \n\u003c X-Application-Context: application\n\u003c Content-Type: application/json;charset=UTF-8\n\u003c Transfer-Encoding: chunked\n\u003c Date: Sun, 09 Oct 2016 09:45:08 GMT\n\u003c \n* Connection #0 to host localhost left intact\nfalse⏎                                            \n```\n\n**Set shutdown flag**\n \n Request\n `curl -v -X POST http://localhost:8080/api/shutdown`\n \n Response\n```\n* Hostname was NOT found in DNS cache\n*   Trying 127.0.0.1...\n* Connected to localhost (127.0.0.1) port 8080 (#0)\n\u003e POST /api/shutdown HTTP/1.1\n\u003e User-Agent: curl/7.35.0\n\u003e Host: localhost:8080\n\u003e Accept: */*\n\u003e \n\u003c HTTP/1.1 200 \n\u003c X-Application-Context: application\n\u003c Content-Type: application/json;charset=UTF-8\n\u003c Transfer-Encoding: chunked\n\u003c Date: Sun, 09 Oct 2016 09:46:29 GMT\n\u003c \n* Connection #0 to host localhost left intact\ntrue⏎ \n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdenis256%2Ftrade-validator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdenis256%2Ftrade-validator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdenis256%2Ftrade-validator/lists"}