https://github.com/evsamsonov/trengin
A golang library to build an automated trading robot. It provides the ability to separate trading strategy logic and interaction with broker.
https://github.com/evsamsonov/trengin
automated-trading go golang golang-library trading trading-engine
Last synced: 5 months ago
JSON representation
A golang library to build an automated trading robot. It provides the ability to separate trading strategy logic and interaction with broker.
- Host: GitHub
- URL: https://github.com/evsamsonov/trengin
- Owner: evsamsonov
- License: mit
- Created: 2021-06-25T19:08:20.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2024-04-24T11:44:13.000Z (about 2 years ago)
- Last Synced: 2026-01-13T18:49:51.500Z (5 months ago)
- Topics: automated-trading, go, golang, golang-library, trading, trading-engine
- Language: Go
- Homepage:
- Size: 85 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# trengin
_**TR**ading **ENGIN**e_
[](https://github.com/evsamsonov/trengin/actions?workflow=golangci-lint)
[](https://github.com/evsamsonov/trengin/actions?workflow=test)
[](https://goreportcard.com/report/github.com/evsamsonov/trengin)
[](https://codecov.io/gh/evsamsonov/trengin)
A golang library to build an automated trading robot. It provides the ability to separate trading strategy logic and interaction with broker.
## Contents
- [Installing](#installing)
- [How to use](#how-to-use)
- [Main types](#main-types)
- [How to implement Strategy](#how-to-implement-strategy)
- [How to implement Broker](#how-to-implement-broker)
- [Position](#position)
- [Callbacks on events](#callbacks-on-events)
- [Broker implementations](#broker-implementations)
- [What's next?](#whats-next)
## Installing
```shell
go get github.com/evsamsonov/trengin/v2
```
## How to use
Import the package.
```go
import "github.com/evsamsonov/trengin/v2"
```
Create an Engine instance passing implementations of Strategy and Broker and call Run.
```go
tradingEngine := trengin.New(strategy, broker)
tradingEngine.Run(context.TODO())
```
## Main types
| Name | Description |
|------------------|--------------------------------------------------------------------------------------------|
| `Engine` | Trading engine |
| `Strategy` | Interface of trading strategy |
| `Broker` | Interface of interaction with broker |
| `Runner` | Сan be implemented in the Broker to starts background tasks such as tracking open position |
| `Actions` | Channel for sending trading actions |
| `Position` | Trading position |
| `PositionClosed` | Channel for receiving a closed position |
## How to implement Strategy
```go
type Strategy interface {
Run(ctx context.Context, actions Actions) error
}
```
The `Run` method should implement trading strategy logic.
It can contain analysis of current data, opening and closing positions, tracking current positions, modifying conditional orders.
You can send `OpenPositionAction`, `ClosePositionAction`, `ChangeConditionalOrderAction` in `actions` channel.
### OpenPositionAction
Opening a trading position.
Constructor: `NewOpenPositionAction`
| Arguments | Description |
|--------------------|----------------------------------------|
| `figi` | Financial Instrument Global Identifier |
| `positionType` | Position type (long or short) |
| `quantity` | Quantity in lots |
| `stopLossOffset` | Stop loss offset from opening price |
| `takeProfitOffset` | Take profit offset from opening price |
### ChangeConditionalOrderAction
Changing a condition order.
Constructor: `NewChangeConditionalOrderAction`
| Name | Description |
|--------------|-----------------------------------------------|
| `positionID` | Unique ID (UUID) |
| `stopLoss` | New stop loss value (if 0 then leave as is) |
| `takeProfit` | New take profit value (if 0 then leave as is) |
### ClosePositionAction
Closing a position.
Constructor: `NewClosePositionAction`
| Name | Description |
|--------------|-------------------|
| `positionID` | Unique ID (UUID) |
An example of sending an action and receiving the result.
```go
sendActionOrDone := func(ctx context.Context, action interface{}) error {
select {
case <-ctx.Done():
return ctx.Err()
case s.actions <- action:
}
return nil
}
var stopLossIndent, takeProfitIndent float64 // Set your values
action := trengin.NewOpenPositionAction("figi", trengin.Long, 1, stopLossOffset, takeProfitOffset)
if err = s.sendActionOrDone(ctx, action); err != nil {
// Handle error
}
result, err := action.Result(ctx)
if err != nil {
// Handle error
}
```
## How to implement Broker
```go
type Broker interface {
OpenPosition(ctx context.Context, action OpenPositionAction) (Position, PositionClosed, error)
ClosePosition(ctx context.Context, action ClosePositionAction) (Position, error)
ChangeConditionalOrder(ctx context.Context, action ChangeConditionalOrderAction) (Position, error)
}
```
The `OpenPosition` method should open a new position, return the opened position and a `PositionClosed` channel.
It should implement tracking of the closure of the position by a conditional order.
After sending the closed position to the `PositionClosed`, it should be closed.
The `ClosePosition` method should close the position. It should return the closed position.
The `ChangeConditionalOrder` method should modify the conditional orders. It should return the updated position.
Also, you can implement `Runner` interface in the Broker implementation to starts background tasks such as tracking open position.
```go
type Runner interface {
Run(ctx context.Context) error
}
```
## Position
The Position describes a trading position.
It contains a unique ID (UUID), primary and extra data.
It can be in two states — open or closed.
The `Extra` is additional data should only be used for local and should not be tied
to the trading strategy logic and the Broker implementation.
The `Extra` is additional data should only be used for local or information purposes. It should not be tied
to the trading strategy logic and the Broker implementation.
Use `NewPosition` constructor to create Position.
The position must be created and closed in the Broker implementation.
**Fields**
| Name | Description |
|--------------|----------------------------------------|
| `ID` | Unique identifier (UUID) |
| `FIGI` | Financial Instrument Global Identifier |
| `Quantity` | Quantity in lots |
| `Type` | Type (long or short) |
| `OpenTime` | Opening time |
| `OpenPrice` | Opening price |
| `CloseTime` | Closing time |
| `ClosePrice` | Closing price |
| `StopLoss` | Current stop loss |
| `TakeProfit` | Current take profit |
| `Commission` | Commission |
**Methods**
| Name | Description |
|------------------|----------------------------------------------------------------------------------------------|
| `Close` | Close position. If the position is already closed it will return an `ErrAlreadyClosed` error |
| `Closed` | Returns a channel that will be closed upon closing the position |
| `IsClosed` | Position is closed |
| `IsLong` | Position type is long |
| `IsShort` | Position type is short |
| `AddCommission` | Position type is short |
| `Profit` | Profit by closed position |
| `UnitProfit` | Profit on a lot by closed position |
| `UnitCommission` | Commission on a lot by closed position |
| `ProfitByPrice` | Profit by passing `price` |
| `Duration` | Position duration from opening time to closing time |
| `Extra` | Returns extra data by `key` or `nil` if not set |
| `SetExtra` | Sets `val` for `key` |
| `RangeExtra` | Executes passed function for each extra values |
## Callbacks on events
To perform additional actions (sending notifications, saving position in the database, etc.),
the trading engine provides methods to set callbacks.
The methods are not thread-safe and should be called before running the strategy.
| Method | Description |
|---------------------------|----------------------------------------------------|
| OnPositionOpened | Sets callback on opening position |
| OnConditionalOrderChanged | Sets callback on changing condition order position |
| OnPositionClosed | Sets callback on closing position |
## Broker implementations
| Name | Description |
|---------------------------------------------------------------------------|-----------------------------------------------------------------|
| [evsamsonov/tinkoff-broker](https://github.com/evsamsonov/tinkoff-broker) | It uses [Tinkoff Invest API](https://tinkoff.github.io/investAPI/) |
| [evsamsonov/finam-broker](https://github.com/evsamsonov/finam-broker) | It uses [Finam Trade API](https://finamweb.github.io/trade-api-docs/) |
## What's next?
* Implement the initialization of the trading engine with open positions.