tradingstore

package module
v0.14.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 21, 2026 License: AGPL-3.0 Imports: 16 Imported by: 0

README

Trading Store Open in Gitpod

Tests Status Go Report Card PkgGoDev

TradingStore is a Go package for storing and managing financial market data, including OHLCV (Open, High, Low, Close, Volume) price data and instrument definitions.

Features

  • Store price data with OHLCV format
  • Manage financial instrument definitions (symbols, exchanges, asset classes)
  • Query price and instrument data with flexible filters
  • Support for different asset classes (Currency, ETF, Index, REIT, Stock)
  • Supports multiple database storages (SQLite, MySQL, or PostgreSQL)
  • Dynamic price table naming with pattern price_{symbol}_{timeframe} or price_{symbol}_{exchange}_{timeframe}

Price Table Naming Convention

Price data is stored in tables following the pattern:

  • price_{lowercase(symbol)}_{lowercase(timeframe)} (default)
  • price_{lowercase(symbol)}_{lowercase(exchange)}_{lowercase(timeframe)} (when UseMultipleExchanges is enabled)

This approach allows for better data organization and improved query performance.

Queries

TradingStore provides powerful query interfaces for retrieving price and instrument data:

Price Queries
// Get all prices for AAPL in June 2023
prices, err := store.PriceList(ctx, "AAPL", "NASDAQ", TIMEFRAME_1_MINUTE,
    NewPriceQuery().
        SetTimeGte("2023-06-01T00:00:00Z").
        SetTimeLte("2023-06-30T23:59:59Z"))

// Count prices matching criteria
count, err := store.PriceCount(ctx, "AAPL", "NASDAQ", TIMEFRAME_1_MINUTE,
    NewPriceQuery())

// Check if specific price data exists
exists, err := store.PriceExists(ctx, "AAPL", "NASDAQ", TIMEFRAME_1_MINUTE,
    NewPriceQuery().SetTime("2023-06-01T16:00:00Z"))
Instrument Queries
// Get all stock instruments
instruments, err := store.InstrumentList(ctx, NewInstrumentQuery().
    SetAssetClass(ASSET_CLASS_STOCK))

// Find instruments with names containing "Apple"
instruments, err := store.InstrumentList(ctx, NewInstrumentQuery().
    SetSymbolLike("Apple"))

// Count instruments on NASDAQ
count, err := store.InstrumentCount(ctx, NewInstrumentQuery().
    SetExchange("NASDAQ"))

Usage Example

package main

import (
    "context"
    "database/sql"
    "fmt"
    "log"

    "github.com/dracory/tradingstore"
    _ "modernc.org/sqlite"
)

func main() {
    // Open a database connection
    db, err := sql.Open("sqlite", "trading.db")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // Create a new trading store
    store, err := tradingstore.NewStore(tradingstore.NewStoreOptions{
        PriceTableNamePrefix: "price_",
        InstrumentTableName:  "instruments",
        UseMultipleExchanges: false,
        DB:                  db,
        AutomigrateEnabled:  true,
    })
    if err != nil {
        log.Fatal(err)
    }

    ctx := context.Background()

    // Create a new instrument
    instrument := NewInstrument().
        SetName("Apple Inc.").
        SetSymbol("AAPL").
        SetExchange("NASDAQ").
        SetAssetClass("STOCK").
        SetDescription("Apple Inc.").
        SetTimeframes([]string{TIMEFRAME_1_MINUTE, TIMEFRAME_5_MINUTES, TIMEFRAME_1_HOUR, TIMEFRAME_1_DAY})

    if err := store.InstrumentCreate(ctx, instrument); err != nil {
        log.Fatal(err)
    }

    // Create pricing tables
    err := store.AutomigratePrices(ctx)

    if err != nil {
        log.Fatal(err)
    }

    // Create a price entry
    price := NewPrice().
        SetTime("2023-06-01T16:00:00Z").
        SetOpen("180.25").
        SetHigh("182.50").
        SetLow("179.80").
        SetClose("181.75").
        SetVolume("34250000")

    if err := store.PriceCreate(ctx, "AAPL", "NASDAQ", TIMEFRAME_1_MINUTE, price); err != nil {
        log.Fatal(err)
    }

    // Query prices
    prices, err := store.PriceList(ctx, "AAPL", "NASDAQ", TIMEFRAME_1_MINUTE, NewPriceQuery().
        SetTimeGte("2023-06-01T00:00:00Z").
        SetTimeLte("2023-06-30T23:59:59Z"))
    if err != nil {
        log.Fatal(err)
    }

    for _, p := range prices {
        fmt.Printf("AAPL on %s: Open=%s, Close=%s\n",
            p.Time(), p.Open(), p.Close())
    }
}

Architecture

The TradingStore library is organized into three main components:

Store Component
classDiagram
    class StoreInterface {
        <<interface>>
        +AutoMigrateInstruments(ctx) error
        +AutoMigratePrices(ctx) error
        +DB() *sql.DB
        +EnableDebug(debug bool)
        +InstrumentCount(ctx, options) (int64, error)
        +InstrumentCreate(ctx, instrument) error
        +InstrumentDelete(ctx, instrument) error
        +InstrumentDeleteByID(ctx, id string) error
        +InstrumentExists(ctx, options) (bool, error)
        +InstrumentFindByID(ctx, id string) (InstrumentInterface, error)
        +InstrumentList(ctx, options) ([]InstrumentInterface, error)
        +InstrumentSoftDelete(ctx, instrument) error
        +InstrumentSoftDeleteByID(ctx, id string) error
        +InstrumentUpdate(ctx, instrument) error
        +PriceCount(ctx, symbol, exchange, timeframe, options) (int64, error)
        +PriceCreate(ctx, symbol, exchange, timeframe, price) error
        +PriceDelete(ctx, symbol, exchange, timeframe, price) error
        +PriceDeleteByID(ctx, symbol, exchange, timeframe, id string) error
        +PriceExists(ctx, symbol, exchange, timeframe, options) (bool, error)
        +PriceFindByID(ctx, symbol, exchange, timeframe, id string) (PriceInterface, error)
        +PriceList(ctx, symbol, exchange, timeframe, options) ([]PriceInterface, error)
        +PriceUpdate(ctx, symbol, exchange, timeframe, price) error
    }

    class Store {
        -priceTableNamePrefix string
        -instrumentTableName string
        -useMultipleExchanges bool
        -db *sql.DB
        -dbDriverName string
        -automigrateEnabled bool
        -debugEnabled bool
        -sqlLogger *slog.Logger
        +AutoMigrateInstruments(ctx) error
        +AutoMigratePrices(ctx) error
        +DB() *sql.DB
        +EnableDebug(debug bool)
        +PriceTableName(symbol, exchange, timeframe) string
    }

    StoreInterface <|.. Store
Price Component
classDiagram
    class PriceInterface {
        <<interface>>
        +Data() map[string]string
        +DataChanged() map[string]string
        +MarkAsNotDirty()
        +ID() string
        +SetID(id string) PriceInterface
        +Close() string
        +CloseFloat() float64
        +SetClose(close string) PriceInterface
        +High() string
        +HighFloat() float64
        +SetHigh(high string) PriceInterface
        +Low() string
        +LowFloat() float64
        +SetLow(low string) PriceInterface
        +Open() string
        +OpenFloat() float64
        +SetOpen(open string) PriceInterface
        +Time() string
        +TimeCarbon() *carbon.Carbon
        +SetTime(time string) PriceInterface
        +Volume() string
        +VolumeFloat() float64
        +SetVolume(volume string) PriceInterface
    }

    class Price {
        +dataobject.DataObject
    }

    class PriceQueryInterface {
        <<interface>>
        +Validate() error
        +Columns() []string
        +SetColumns(columns []string) PriceQueryInterface
        +HasCountOnly() bool
        +IsCountOnly() bool
        +SetCountOnly(countOnly bool) PriceQueryInterface
        +HasTime() bool
        +Time() string
        +SetTime(createdAt string) PriceQueryInterface
        +HasTimeGte() bool
        +TimeGte() string
        +SetTimeGte(createdAtGte string) PriceQueryInterface
        +HasTimeLte() bool
        +TimeLte() string
        +SetTimeLte(createdAtLte string) PriceQueryInterface
        +HasID() bool
        +ID() string
        +SetID(id string) PriceQueryInterface
        +HasIDIn() bool
        +IDIn() []string
        +SetIDIn(idIn []string) PriceQueryInterface
        +HasLimit() bool
        +Limit() int
        +SetLimit(limit int) PriceQueryInterface
        +HasOffset() bool
        +Offset() int
        +SetOffset(offset int) PriceQueryInterface
        +HasOrderBy() bool
        +OrderBy() string
        +SetOrderBy(orderBy string) PriceQueryInterface
        +HasSortDirection() bool
        +SortDirection() string
        +SetSortDirection(sortDirection string) PriceQueryInterface
    }

    PriceInterface <|.. Price
Instrument Component
classDiagram
    class InstrumentInterface {
        <<interface>>
        +Data() map[string]string
        +DataChanged() map[string]string
        +MarkAsNotDirty()
        +AssetClass() string
        +SetAssetClass(assetClass string) InstrumentInterface
        +Exchange() string
        +SetExchange(exchange string) InstrumentInterface
        +Description() string
        +SetDescription(description string) InstrumentInterface
        +ID() string
        +SetID(id string) InstrumentInterface
        +Name() string
        +SetName(name string) InstrumentInterface
        +Status() string
        +SetStatus(status string) InstrumentInterface
        +Symbol() string
        +SetSymbol(symbol string) InstrumentInterface
        +Timeframes() []string
        +SetTimeframes(timeframes []string) InstrumentInterface
        +Meta(key string) (string, error)
        +SetMeta(key string, value string) error
        +DeleteMeta(key string) error
        +Metas() (map[string]string, error)
        +SetMetas(metas map[string]string) error
        +Memo() string
        +SetMemo(memo string) InstrumentInterface
        +CreatedAt() string
        +CreatedAtCarbon() *carbon.Carbon
        +SetCreatedAt(createdAt string) InstrumentInterface
        +UpdatedAt() string
        +UpdatedAtCarbon() *carbon.Carbon
        +SetUpdatedAt(updatedAt string) InstrumentInterface
        +SoftDeletedAt() string
        +SoftDeletedAtCarbon() *carbon.Carbon
        +SetSoftDeletedAt(softDeletedAt string) InstrumentInterface
    }

    class Instrument {
        +dataobject.DataObject
    }

    class InstrumentQueryInterface {
        <<interface>>
        +SetID(id string) InstrumentQueryInterface
        +HasID() bool
        +ID() string
        +SetIDIn(idIn []string) InstrumentQueryInterface
        +HasIDIn() bool
        +IDIn() []string
        +SetSymbol(symbol string) InstrumentQueryInterface
        +HasSymbol() bool
        +Symbol() string
        +SetSymbolLike(symbolLike string) InstrumentQueryInterface
        +HasSymbolLike() bool
        +SymbolLike() string
        +SetAssetClass(assetClass string) InstrumentQueryInterface
        +HasAssetClass() bool
        +AssetClass() string
        +SetExchange(exchange string) InstrumentQueryInterface
        +HasExchange() bool
        +Exchange() string
        +SetLimit(limit int) InstrumentQueryInterface
        +HasLimit() bool
        +Limit() int
        +SetOffset(offset int) InstrumentQueryInterface
        +HasOffset() bool
        +Offset() int
        +SetOrderBy(orderBy string) InstrumentQueryInterface
        +HasOrderBy() bool
        +OrderBy() string
        +SetSortDirection(sortDirection string) InstrumentQueryInterface
        +HasSortDirection() bool
        +SortDirection() string
        +SetCountOnly(countOnly bool) InstrumentQueryInterface
        +HasCountOnly() bool
        +IsCountOnly() bool
        +Columns() []string
        +SetColumns(columns []string) InstrumentQueryInterface
    }

    InstrumentInterface <|.. Instrument

License

This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). You can find a copy of the license at https://www.gnu.org/licenses/agpl-3.0.en.html

For commercial use, please use my contact page to obtain a commercial license.

Documentation

Index

Constants

View Source
const ASSET_CLASS_BOND = "BOND"

Asset Class (from https://en.wikipedia.org/wiki/Asset_classes)

View Source
const ASSET_CLASS_COMMODITY = "COMMODITY" // Commodities, such as gold, oil, and agricultural products
View Source
const ASSET_CLASS_CRYPTO = "CRYPTO" // Cryptocurrency
View Source
const ASSET_CLASS_CURRENCY = "CURRENCY" // Currencies
View Source
const ASSET_CLASS_DERIVATIVE = "DERIVATIVE" // Derivatives
View Source
const ASSET_CLASS_ETF = "ETF" // Exchange Traded Funds
View Source
const ASSET_CLASS_FOREX = "FOREX" // Foreign Exchange
View Source
const ASSET_CLASS_FUTURE = "FUTURE" // Futures
View Source
const ASSET_CLASS_INDEX = "INDEX" // Index
View Source
const ASSET_CLASS_OPTION = "OPTION" // Options
View Source
const ASSET_CLASS_REIT = "REIT" // Real Estate Investment Trust
View Source
const ASSET_CLASS_STOCK = "STOCK" // Stocks
View Source
const ASSET_CLASS_UNKNOWN = "UNKNOWN" // Unknown
View Source
const COLUMN_ASSET_CLASS = "asset_class"

Column names

View Source
const COLUMN_CLOSE = "close"
View Source
const COLUMN_CREATED_AT = "created_at"
View Source
const COLUMN_DESCRIPTION = "description"
View Source
const COLUMN_EXCHANGE = "exchange"
View Source
const COLUMN_HIGH = "high"
View Source
const COLUMN_ID = "id"
View Source
const COLUMN_LOW = "low"
View Source
const COLUMN_MEMO = "memo"
View Source
const COLUMN_METAS = "metas"
View Source
const COLUMN_NAME = "name"
View Source
const COLUMN_OPEN = "open"
View Source
const COLUMN_SOFT_DELETED_AT = "soft_deleted_at"
View Source
const COLUMN_STATUS = "status"
View Source
const COLUMN_SYMBOL = "symbol"
View Source
const COLUMN_TIME = "time"
View Source
const COLUMN_TIMEFRAMES = "timeframes"
View Source
const COLUMN_UPDATED_AT = "updated_at"
View Source
const COLUMN_VOLUME = "volume"
View Source
const INSTRUMENT_STATUS_ACTIVE = "active"
View Source
const INSTRUMENT_STATUS_DISABLED = "disabled"
View Source
const INSTRUMENT_STATUS_DRAFT = "draft"

Instrument Status

View Source
const INSTRUMENT_STATUS_INACTIVE = "inactive"
View Source
const MAX_DATETIME = "9999-12-31 23:59:59"

MAX_DATETIME is a far-future datetime used as the default soft-delete sentinel.

View Source
const NIL_FLOAT = -0.0000000001

Nil float

View Source
const TIMEFRAME_15_MINUTES = "15min"
View Source
const TIMEFRAME_1_DAY = "1day"
View Source
const TIMEFRAME_1_HOUR = "1hour"
View Source
const TIMEFRAME_1_MINUTE = "1min"

Timeframe

View Source
const TIMEFRAME_1_MONTH = "1month"
View Source
const TIMEFRAME_1_WEEK = "1week"
View Source
const TIMEFRAME_1_YEAR = "1year"
View Source
const TIMEFRAME_30_MINUTES = "30min"
View Source
const TIMEFRAME_4_HOURS = "4hour"
View Source
const TIMEFRAME_5_MINUTES = "5min"

Variables

This section is empty.

Functions

This section is empty.

Types

type InstrumentInterface

type InstrumentInterface interface {
	// setters and getters
	AssetClass() string
	SetAssetClass(assetClass string) InstrumentInterface

	Exchange() string
	SetExchange(exchange string) InstrumentInterface

	Description() string
	SetDescription(description string) InstrumentInterface

	ID() string
	SetID(id string) InstrumentInterface

	Meta(key string) (string, error)
	SetMeta(key string, value string) error
	DeleteMeta(key string) error

	Metas() (map[string]string, error)
	SetMetas(metas map[string]string) error

	Memo() string
	SetMemo(memo string) InstrumentInterface

	Name() string
	SetName(name string) InstrumentInterface

	Status() string
	SetStatus(status string) InstrumentInterface

	Symbol() string
	SetSymbol(symbol string) InstrumentInterface

	Timeframes() []string
	SetTimeframes(timeframes []string) InstrumentInterface

	CreatedAt() string
	CreatedAtCarbon() *carbon.Carbon
	SetCreatedAt(createdAt string) InstrumentInterface

	UpdatedAt() string
	UpdatedAtCarbon() *carbon.Carbon
	SetUpdatedAt(updatedAt string) InstrumentInterface

	SoftDeletedAt() string
	SoftDeletedAtCarbon() *carbon.Carbon
	SetSoftDeletedAt(softDeletedAt string) InstrumentInterface

	IsSoftDeleted() bool
}

InstrumentInterface defines the interface for a financial instrument.

func NewInstrument

func NewInstrument() InstrumentInterface

NewInstrument creates a new instrument with default values.

func NewInstrumentFromExistingData

func NewInstrumentFromExistingData(data map[string]string) InstrumentInterface

NewInstrumentFromExistingData hydrates an instrument from a raw column map.

type InstrumentQueryInterface

type InstrumentQueryInterface interface {
	Validate() error

	SetAssetClass(assetClass string) InstrumentQueryInterface
	IsAssetClassSet() bool
	AssetClass() string

	IsExchangeSet() bool
	Exchange() string
	SetExchange(exchange string) InstrumentQueryInterface

	IsColumnsSet() bool
	Columns() []string
	SetColumns(columns []string) InstrumentQueryInterface

	SetCountOnly(countOnly bool) InstrumentQueryInterface
	IsCountOnly() bool

	SetID(id string) InstrumentQueryInterface
	IsIDSet() bool
	ID() string

	SetIDIn(ids []string) InstrumentQueryInterface
	IsIDInSet() bool
	IDIn() []string

	IsLimitSet() bool
	Limit() int
	SetLimit(limit int) InstrumentQueryInterface

	IsOffsetSet() bool
	Offset() int
	SetOffset(offset int) InstrumentQueryInterface

	IsOrderBySet() bool
	OrderBy() string
	SetOrderBy(orderBy string) InstrumentQueryInterface

	IsOrderDirectionSet() bool
	OrderDirection() string
	SetOrderDirection(orderDirection string) InstrumentQueryInterface

	SetStatus(status string) InstrumentQueryInterface
	IsStatusSet() bool
	Status() string

	IsSymbolSet() bool
	Symbol() string
	SetSymbol(symbol string) InstrumentQueryInterface

	IsSymbolLikeSet() bool
	SymbolLike() string
	SetSymbolLike(symbolLike string) InstrumentQueryInterface

	IsSoftDeletedIncluded() bool
	SoftDeletedIncluded() bool
	SetSoftDeletedIncluded(softDeletedIncluded bool) InstrumentQueryInterface
}

InstrumentQueryInterface defines the interface for instrument query options.

func InstrumentQuery

func InstrumentQuery() InstrumentQueryInterface

InstrumentQuery is a shortcut to create a new instrument query

func NewInstrumentQuery

func NewInstrumentQuery() InstrumentQueryInterface

NewInstrumentQuery creates a new instrument query

type NewStoreOptions

type NewStoreOptions struct {
	PriceTableNamePrefix string
	InstrumentTableName  string
	UseMultipleExchanges bool
	DB                   *sql.DB
	AutomigrateEnabled   bool
	DebugEnabled         bool
}

NewStoreOptions define the options for creating a new tradingstore

type PriceInterface

type PriceInterface interface {
	ID() string
	SetID(id string) PriceInterface

	Close() string
	CloseFloat() float64
	SetClose(close string) PriceInterface

	High() string
	HighFloat() float64
	SetHigh(high string) PriceInterface

	Low() string
	LowFloat() float64
	SetLow(low string) PriceInterface

	Open() string
	OpenFloat() float64
	SetOpen(open string) PriceInterface

	Time() string
	TimeCarbon() *carbon.Carbon
	SetTime(time string) PriceInterface

	Volume() string
	VolumeFloat() float64
	SetVolume(volume string) PriceInterface
}

PriceInterface defines the interface for an OHLCV price record.

func NewPrice

func NewPrice() PriceInterface

NewPrice creates a new price with default values.

func NewPriceFromExistingData

func NewPriceFromExistingData(data map[string]string) PriceInterface

NewPriceFromExistingData hydrates a price from a raw column map.

type PriceQueryInterface

type PriceQueryInterface interface {
	Validate() error

	IsColumnsSet() bool
	Columns() []string
	SetColumns(columns []string) PriceQueryInterface

	IsCountOnlySet() bool
	IsCountOnly() bool
	SetCountOnly(countOnly bool) PriceQueryInterface

	IsTimeSet() bool
	Time() string
	SetTime(createdAt string) PriceQueryInterface

	IsTimeGteSet() bool
	TimeGte() string
	SetTimeGte(createdAtGte string) PriceQueryInterface

	IsTimeLteSet() bool
	TimeLte() string
	SetTimeLte(createdAtLte string) PriceQueryInterface

	IsIDSet() bool
	ID() string
	SetID(id string) PriceQueryInterface

	IsIDInSet() bool
	IDIn() []string
	SetIDIn(idIn []string) PriceQueryInterface

	IsLimitSet() bool
	Limit() int
	SetLimit(limit int) PriceQueryInterface

	IsOffsetSet() bool
	Offset() int
	SetOffset(offset int) PriceQueryInterface

	IsOrderBySet() bool
	OrderBy() string
	SetOrderBy(orderBy string) PriceQueryInterface

	IsOrderDirectionSet() bool
	OrderDirection() string
	SetOrderDirection(orderDirection string) PriceQueryInterface
}

PriceQueryInterface defines the interface for price query options.

func NewPriceQuery

func NewPriceQuery() PriceQueryInterface

NewPriceQuery creates a new price query

func PriceQuery

func PriceQuery() PriceQueryInterface

PriceQuery is a shortcut for NewPriceQuery

type StoreInterface

type StoreInterface interface {
	MigrateDown(ctx context.Context, tx ...*sql.Tx) error
	MigrateUp(ctx context.Context, tx ...*sql.Tx) error
	DB() *sql.DB
	EnableDebug(bool)

	InstrumentCount(ctx context.Context, options InstrumentQueryInterface) (int64, error)
	InstrumentCreate(ctx context.Context, instrument InstrumentInterface) error
	InstrumentDelete(ctx context.Context, instrument InstrumentInterface) error
	InstrumentDeleteByID(ctx context.Context, id string) error
	InstrumentExists(ctx context.Context, options InstrumentQueryInterface) (bool, error)
	InstrumentFindByID(ctx context.Context, id string) (InstrumentInterface, error)
	InstrumentList(ctx context.Context, options InstrumentQueryInterface) ([]InstrumentInterface, error)
	InstrumentSoftDelete(ctx context.Context, instrument InstrumentInterface) error
	InstrumentSoftDeleteByID(ctx context.Context, id string) error
	InstrumentUpdate(ctx context.Context, instrument InstrumentInterface) error

	PriceCount(ctx context.Context, symbol string, exchange string, timeframe string, options PriceQueryInterface) (int64, error)
	PriceCreate(ctx context.Context, symbol string, exchange string, timeframe string, price PriceInterface) error
	PriceDelete(ctx context.Context, symbol string, exchange string, timeframe string, price PriceInterface) error
	PriceDeleteByID(ctx context.Context, symbol string, exchange string, timeframe string, priceID string) error
	PriceExists(ctx context.Context, symbol string, exchange string, timeframe string, options PriceQueryInterface) (bool, error)
	PriceFindByID(ctx context.Context, symbol string, exchange string, timeframe string, priceID string) (PriceInterface, error)
	PriceList(ctx context.Context, symbol string, exchange string, timeframe string, options PriceQueryInterface) ([]PriceInterface, error)
	PriceUpdate(ctx context.Context, symbol string, exchange string, timeframe string, price PriceInterface) error
}

StoreInterface defines the interface for a store

func NewStore

func NewStore(opts NewStoreOptions) (StoreInterface, error)

NewStore creates a new trading store

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL