{"id":37216095,"url":"https://github.com/evsamsonov/trengin","last_synced_at":"2026-01-15T00:59:14.169Z","repository":{"id":40237218,"uuid":"380332336","full_name":"evsamsonov/trengin","owner":"evsamsonov","description":"A golang library to build an automated trading robot. It provides the ability to separate trading strategy logic and interaction with broker.","archived":false,"fork":false,"pushed_at":"2024-04-24T11:44:13.000Z","size":87,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-01-13T18:49:51.500Z","etag":null,"topics":["automated-trading","go","golang","golang-library","trading","trading-engine"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/evsamsonov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2021-06-25T19:08:20.000Z","updated_at":"2024-04-24T11:44:16.000Z","dependencies_parsed_at":"2024-01-23T11:28:14.342Z","dependency_job_id":"5c1bd121-784e-47d0-b9f6-d303aaf60d05","html_url":"https://github.com/evsamsonov/trengin","commit_stats":{"total_commits":52,"total_committers":1,"mean_commits":52.0,"dds":0.0,"last_synced_commit":"1f778791d417861c1d950be5f05f723a7a296484"},"previous_names":["evsamsonov/trading-engine"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/evsamsonov/trengin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evsamsonov%2Ftrengin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evsamsonov%2Ftrengin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evsamsonov%2Ftrengin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evsamsonov%2Ftrengin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/evsamsonov","download_url":"https://codeload.github.com/evsamsonov/trengin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evsamsonov%2Ftrengin/sbom","scorecard":{"id":387175,"data":{"date":"2025-08-11","repo":{"name":"github.com/evsamsonov/trengin","commit":"e50aea7a258738e235aafbe5a7af5828a73679e5"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:9: update your workflow using https://app.stepsecurity.io/secureworkflow/evsamsonov/trengin/lint.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/lint.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/evsamsonov/trengin/lint.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/evsamsonov/trengin/test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/evsamsonov/trengin/test.yml/master?enable=pin","Warn: downloadThenRun not pinned by hash: .github/workflows/test.yml:21","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   1 downloadThenRun dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/lint.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 11 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T16:55:30.814Z","repository_id":40237218,"created_at":"2025-08-18T16:55:30.814Z","updated_at":"2025-08-18T16:55:30.814Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28440995,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-15T00:55:22.719Z","status":"ssl_error","status_checked_at":"2026-01-15T00:55:20.945Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["automated-trading","go","golang","golang-library","trading","trading-engine"],"created_at":"2026-01-15T00:59:13.669Z","updated_at":"2026-01-15T00:59:14.160Z","avatar_url":"https://github.com/evsamsonov.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# trengin \n\n_**TR**ading **ENGIN**e_\n\n[![Lint Status](https://github.com/evsamsonov/trengin/actions/workflows/lint.yml/badge.svg)](https://github.com/evsamsonov/trengin/actions?workflow=golangci-lint)\n[![Test Status](https://github.com/evsamsonov/trengin/actions/workflows/test.yml/badge.svg)](https://github.com/evsamsonov/trengin/actions?workflow=test)\n[![Go Report Card](https://goreportcard.com/badge/github.com/evsamsonov/trengin)](https://goreportcard.com/report/github.com/evsamsonov/trengin)\n[![codecov](https://codecov.io/gh/evsamsonov/trengin/branch/master/graph/badge.svg?token=AC751PKE5Y)](https://codecov.io/gh/evsamsonov/trengin)\n\nA golang library to build an automated trading robot. It provides the ability to separate trading strategy logic and interaction with broker.\n\n\n## Contents \n\n- [Installing](#installing)\n- [How to use](#how-to-use)\n- [Main types](#main-types)\n- [How to implement Strategy](#how-to-implement-strategy)\n- [How to implement Broker](#how-to-implement-broker)\n- [Position](#position)\n- [Callbacks on events](#callbacks-on-events)\n- [Broker implementations](#broker-implementations)\n- [What's next?](#whats-next)\n\n## Installing\n\n```shell\ngo get github.com/evsamsonov/trengin/v2\n```\n\n## How to use\n\nImport the package.\n\n```go\nimport \"github.com/evsamsonov/trengin/v2\"\n```\n\nCreate an Engine instance passing implementations of Strategy and Broker and call Run.\n\n```go\ntradingEngine := trengin.New(strategy, broker)\ntradingEngine.Run(context.TODO())\n```\n\n## Main types\n\n| Name             | Description                                                                                |\n|------------------|--------------------------------------------------------------------------------------------|\n| `Engine`         | Trading engine                                                                             |\n| `Strategy`       | Interface of trading strategy                                                              |\n| `Broker`         | Interface of interaction with broker                                                       |\n| `Runner`         | Сan be implemented in the Broker to starts background tasks such as tracking open position |\n| `Actions`        | Channel for sending trading actions                                                        |\n| `Position`       | Trading position                                                                           |\n| `PositionClosed` | Channel for receiving a closed position                                                    |\n\n## How to implement Strategy\n\n```go\ntype Strategy interface {\n\tRun(ctx context.Context, actions Actions) error\n}\n```\n\nThe `Run` method should implement trading strategy logic. \nIt can contain analysis of current data, opening and closing positions, tracking current positions, modifying conditional orders.\nYou can send `OpenPositionAction`, `ClosePositionAction`, `ChangeConditionalOrderAction` in `actions` channel.\n\n### OpenPositionAction\n\nOpening a trading position.\n\nConstructor: `NewOpenPositionAction`\n\n| Arguments          | Description                            |\n|--------------------|----------------------------------------|\n| `figi`             | Financial Instrument Global Identifier |\n| `positionType`     | Position type (long or short)          |\n| `quantity`         | Quantity in lots                       |\n| `stopLossOffset`   | Stop loss offset from opening price    |\n| `takeProfitOffset` | Take profit offset from opening price  |\n\n### ChangeConditionalOrderAction\n\nChanging a condition order.\n\nConstructor: `NewChangeConditionalOrderAction`\n\n| Name         | Description                                   |\n|--------------|-----------------------------------------------|\n| `positionID` | Unique ID (UUID)                              |\n| `stopLoss`   | New stop loss value (if 0 then leave as is)   |\n| `takeProfit` | New take profit value (if 0 then leave as is) |\n\n### ClosePositionAction\n\nClosing a position.\n\nConstructor: `NewClosePositionAction`\n\n| Name         | Description       |\n|--------------|-------------------|\n| `positionID` | Unique ID  (UUID) |\n\nAn example of sending an action and receiving the result. \n\n```go\nsendActionOrDone := func(ctx context.Context, action interface{}) error {\n    select {\n    case \u003c-ctx.Done():\n    \treturn ctx.Err()\n    case s.actions \u003c- action:\n    }\n    return nil\n}\n\nvar stopLossIndent, takeProfitIndent float64 // Set your values\naction := trengin.NewOpenPositionAction(\"figi\", trengin.Long, 1, stopLossOffset, takeProfitOffset)\nif err = s.sendActionOrDone(ctx, action); err != nil {\n    // Handle error\n}\nresult, err := action.Result(ctx)\nif err != nil {\n    // Handle error\n}\n```\n\n## How to implement Broker\n\n```go\ntype Broker interface {\n\tOpenPosition(ctx context.Context, action OpenPositionAction) (Position, PositionClosed, error)\n\tClosePosition(ctx context.Context, action ClosePositionAction) (Position, error)\n\tChangeConditionalOrder(ctx context.Context, action ChangeConditionalOrderAction) (Position, error)\n}\n```\n\nThe `OpenPosition` method should open a new position, return the opened position and a `PositionClosed` channel.\nIt should implement tracking of the closure of the position by a conditional order.\nAfter sending the closed position to the `PositionClosed`, it should be closed.\n\nThe `ClosePosition` method should close the position. It should return the closed position.\n\nThe `ChangeConditionalOrder` method should modify the conditional orders. It should return the updated position.\n\nAlso, you can implement `Runner` interface in the Broker implementation to starts background tasks such as tracking open position.\n\n```go\ntype Runner interface {\n\tRun(ctx context.Context) error\n}\n```\n\n## Position\n\nThe Position describes a trading position. \nIt contains a unique ID (UUID), primary and extra data. \nIt can be in two states \u0026mdash; open or closed.\n\nThe `Extra` is additional data should only be used for local and should not be tied \nto the trading strategy logic and the Broker implementation.\n\nThe `Extra` is additional data should only be used for local or information purposes. It should not be tied\nto the trading strategy logic and the Broker implementation. \n\nUse `NewPosition` constructor to create Position.  \nThe position must be created and closed in the Broker implementation.\n\n**Fields**\n\n| Name         | Description                            |\n|--------------|----------------------------------------|\n| `ID`         | Unique identifier (UUID)               |\n| `FIGI`       | Financial Instrument Global Identifier |\n| `Quantity`   | Quantity in lots                       |\n| `Type`       | Type (long or short)                   |\n| `OpenTime`   | Opening time                           |\n| `OpenPrice`  | Opening price                          |\n| `CloseTime`  | Closing time                           |\n| `ClosePrice` | Closing price                          |\n| `StopLoss`   | Current stop loss                      |\n| `TakeProfit` | Current take profit                    |\n| `Commission` | Commission                             |\n\n**Methods**\n\n| Name             | Description                                                                                  |\n|------------------|----------------------------------------------------------------------------------------------|\n| `Close`          | Close position. If the position is already closed it will return an `ErrAlreadyClosed` error |\n| `Closed`         | Returns a channel that will be closed upon closing the position                              |\n| `IsClosed`       | Position is closed                                                                           |\n| `IsLong`         | Position type is long                                                                        |\n| `IsShort`        | Position type is short                                                                       |\n| `AddCommission`  | Position type is short                                                                       |\n| `Profit`         | Profit by closed position                                                                    |\n| `UnitProfit`     | Profit on a lot by closed position                                                           |\n| `UnitCommission` | Commission on a lot by closed position                                                       |\n| `ProfitByPrice`  | Profit by passing `price`                                                                    |\n| `Duration`       | Position duration from opening time to closing time                                          |\n| `Extra`          | Returns extra data by `key` or `nil` if not set                                              |\n| `SetExtra`       | Sets `val` for `key`                                                                         |\n| `RangeExtra`     | Executes passed function for each extra values                                               |\n\n## Callbacks on events\n\nTo perform additional actions (sending notifications, saving position in the database, etc.), \nthe trading engine provides methods to set callbacks. \nThe methods are not thread-safe and should be called before running the strategy.\n\n| Method                    | Description                                        |\n|---------------------------|----------------------------------------------------|\n| OnPositionOpened          | Sets callback on opening position                  |\n| OnConditionalOrderChanged | Sets callback on changing condition order position |\n| OnPositionClosed          | Sets callback on closing position                  |\n\n## Broker implementations\n\n| Name                                                                      | Description                                                     |\n|---------------------------------------------------------------------------|-----------------------------------------------------------------|\n| [evsamsonov/tinkoff-broker](https://github.com/evsamsonov/tinkoff-broker) | It uses [Tinkoff Invest API](https://tinkoff.github.io/investAPI/) |\n| [evsamsonov/finam-broker](https://github.com/evsamsonov/finam-broker) | It uses [Finam Trade API](https://finamweb.github.io/trade-api-docs/)  |\n\n## What's next?\n\n* Implement the initialization of the trading engine with open positions. \n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevsamsonov%2Ftrengin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fevsamsonov%2Ftrengin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevsamsonov%2Ftrengin/lists"}