opentick

package module
v0.0.0-...-20c71ce Latest Latest
Warning

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

Go to latest
Published: Oct 25, 2020 License: Apache-2.0 Imports: 25 Imported by: 0

README

OpenTick

OpenTrade Logo

OpenTick is a fast tick database for financial timeseries data, built on FoundationDB with simplified SQL layer.

Features:

  • Built-in price adjustment support

  • Nanosecond support

  • Python, C++ and Go SDK

  • Both sync and async query

  • Implicit SQL statement prepare

  • Permission Control, check Python API for related functions, turned off by default

  • Cache

Installation on Ubuntu

You need to use Go >=1.11 which has module support.

sudo apt install -y python
wget https://www.foundationdb.org/downloads/6.2.22/ubuntu/installers/foundationdb-server_6.2.22-1_amd64.deb
wget https://www.foundationdb.org/downloads/6.2.22/ubuntu/installers/foundationdb-clients_6.2.22-1_amd64.deb
sudo dpkg -i foundationdb-clients_6.2.22-1_amd64.deb foundationdb-server_6.2.22-1_amd64.deb
git clone https://github.com/opentradesolutions/opentick
make build
sudo apt install nodejs
sudo npm install -g pm2
pm2 start ./opentick

Note: FoundationDB runs in memory storage mode and only one process by default. You can change it to disk storage as belows:

user@host$ fdbcli
fdb> configure ssd

Fore more configuration on FoundationDB, please check FoundationDB Configuration

Usage

Python

pip install opentick

C++

Go

Performance

100k ohlcv bar inserted in 1 second.

user@host:~/opentick/bindings/go$ go run test.go
2018/11/27 21:27:23 4.500470184s 5.500314708s 0 100000 all insert futures get done
2018/11/27 21:27:25 861.306778ms 1.139363333s 0 10 all batch insert futures get done
2018/11/27 21:27:26 805.542584ms 100000 retrieved with ranges
2018/11/27 21:27:27 1.782497936s 100000 retrieved with async
2018/11/27 21:27:29 1.424262818s 100000 retrieved with one sync
user@host:~/opentick/bindings/python$ ./test.py
2018-11-27 21:29:10.168138 0:00:00.200577 0:00:06.724991 0 100000 all insert futures get done
2018-11-27 21:29:12.192570 0:00:00.176540 0:00:00.959563 0 10 all batch insert futures get done
2018-11-27 21:29:13.460025 0:00:01.267462 100000 retrieved with ranges
2018-11-27 21:29:15.077686 0:00:01.617666 100000 retrieved with async
2018-11-27 21:29:16.777043 0:00:01.699361 100000 retrieved with one sync
user@host:~/opentick/bindings/cpp$ make test
21:33:19.231156889: 4.22207s 4.84954s 0 100000 all insert futures get done
21:33:20.172744180: 0.447708s 0.934337s 0 10 all batch insert futures get done
21:33:21.677161076: 1.49497s 100000 retrieved with async

Sample Code (C++)

  • Create database and table
auto conn = Connection::Create("127.0.0.1", 1116);
conn->Start();
conn->Execute("create database if not exists test");
conn->Use("test");
conn->Execute(R"(
      create table if not exists test(sec int, interval int, tm timestamp,
      open double, high double, low double, close double, v double, vwap
      double, primary key(sec, interval, tm))
)");
  • Execute
// opentick prepares the sql statement automatically, no need to prepare explicitly
auto fut = conn->ExecuteAsync(
          "select * from test where sec=1 and interval=?", Args{1}));
auto res = fut->Get(); // blocked wait until execution done
// Get last 2 rows ordering by primary key
auto res = conn->Execute(
        "select tm from test where sec=1 and interval=? limit -2", Args{1});
  • Insert
static const std::string kInsert =
    "insert into test(sec, interval, tm, open, high, low, close, vol, vwap) "
    "values(?, ?, ?, ?, ?, ?, ?, ?, ?)";
std::vector<Future> futs;
for (auto i = 0; i < 1000; ++i) {
  futs.push_back(conn->ExecuteAsync(kInsert, Args{1, 1, system_clock::now(), 2.2, 2.4, 2.1, 2.3, 1000000, 2.25}));
}
// wait for all insertion done
for (auto fut : futs) fut->Get();
  • Batch Insert
Argss argss;
for (auto i = 0; i < 1000; ++i) {
  argss.push_back(Args{1, i, system_clock::now(), 2.2, 2.4, 2.1, 2.3, 1000000, 2.25});
}
conn->BatchInsert(kInsert, argss);
  • Price Adjustments
auto res = conn->Execute(
        "select tm, adj(open), adj(high), adj(low), adj(close), adj(vol) from test where sec=1 and interval=? limit -2", Args{1});

For more details, please checkout adj_test.go

Documentation

Index

Constants

This section is empty.

Variables

View Source
var FdbVersion = 520
View Source
var TableSchemaMap = sync.Map{}

Functions

func AlterTable

func AlterTable(db fdb.Transactor, dbName string, ast *AstAlterTable, user ...*User) (err error)

func BatchInsert

func BatchInsert(db fdb.Transactor, stmt *insertStmt, argsArray [][]interface{}) (err error)

func CreateAdj

func CreateAdj(db fdb.Transactor, dbName string) (err error)

func CreateDatabase

func CreateDatabase(db fdb.Transactor, dbName string) (err error)

func CreateTable

func CreateTable(db fdb.Transactor, dbName string, ast *AstCreateTable) (err error)

func DropDatabase

func DropDatabase(db fdb.Transactor, dbName string) (err error)

func DropTable

func DropTable(db fdb.Transactor, dbName string, tblName string) (err error)

func Execute

func Execute(db fdb.Transactor, dbName string, sql string, args []interface{}, user ...*User) (res [][]interface{}, err error)

func ExecuteStmt

func ExecuteStmt(db fdb.Transactor, stmt interface{}, args []interface{}) (res [][]interface{}, err error)

func HasDatabase

func HasDatabase(db fdb.Transactor, dbName string) (bool, error)

func HasTable

func HasTable(db fdb.Transactor, dbName string, tblName string) (bool, error)

func ListDatabases

func ListDatabases(db fdb.Transactor) (dbNames []string, err error)

func ListTables

func ListTables(db fdb.Transactor, dbName string) (tables []string, err error)

func LoadUsers

func LoadUsers(db fdb.Transactor) (err error)

func RenameTable

func RenameTable(db fdb.Transactor, tbl *TableSchema, colOldNewName []string, newTableName *string) (err error)

func Resolve

func Resolve(db fdb.Transactor, dbName string, ast *Ast, user ...*User) (stmt interface{}, err error)

func StartServer

func StartServer(addr string, fdbClusterFile string, numDatabaseConn, maxConcurrency, timeout int, cacheExpiration float64, permission bool) error

Types

type Ast

type Ast struct {
	Select     *AstSelect     `"SELECT" @@`
	Insert     *AstInsert     `| "INSERT" @@`
	Create     *AstCreate     `| "CREATE" @@`
	Drop       *AstDrop       `| "DROP" @@`
	Delete     *AstDelete     `| "DELETE" @@`
	AlterTable *AstAlterTable `| "ALTER" "TABLE" @@`
}

func Parse

func Parse(sql string) (*Ast, error)

type AstAlterTable

type AstAlterTable struct {
	Table          *AstTableName      `@@`
	AlterTableType *AstAlterTableType `@@`
}

type AstAlterTableType

type AstAlterTableType struct {
	Rename *AstRename `"RENAME" @@`
}

type AstBoolean

type AstBoolean bool

func (*AstBoolean) Capture

func (self *AstBoolean) Capture(values []string) error

type AstCondition

type AstCondition struct {
	LHS      *string   `@Ident`
	Operator *string   `@("<=" | ">=" | "=" | "<" | ">")`
	RHS      *AstValue `@@`
}

type AstCreate

type AstCreate struct {
	Table    *AstCreateTable    `"TABLE" @@`
	Database *AstCreateDatabase `| "DATABASE" @@`
}

type AstCreateDatabase

type AstCreateDatabase struct {
	IfNotExists *string `[@("IF" "NOT" "EXISTS")]`
	Name        *string `@Ident`
}

type AstCreateTable

type AstCreateTable struct {
	IfNotExists *string       `[@("IF" "NOT" "EXISTS")]`
	Name        *AstTableName `@@`
	Cols        []AstTypeDef  `"(" @@ {"," @@} ")"`
}

type AstDelete

type AstDelete struct {
	Table *AstTableName  `"FROM" @@`
	Where *AstExpression `["WHERE" @@]`
}

type AstDrop

type AstDrop struct {
	Table    *AstTableName `"TABLE" @@`
	Database *string       `| "DATABASE" @Ident`
}

type AstExpression

type AstExpression struct {
	And []AstCondition `@@ {"AND" @@}`
}

type AstInsert

type AstInsert struct {
	Table  *AstTableName `"INTO" @@`
	Cols   []string      `["(" @Ident {"," @Ident} ")"]`
	Values []AstValue    `"VALUES" "(" @@ {"," @@} ")"`
}

type AstNumber

type AstNumber struct {
	Float *float64
	Int   *int64
}

func (*AstNumber) Capture

func (self *AstNumber) Capture(values []string) error

type AstRename

type AstRename struct {
	ColOldNewName []string `"COLUMN" @Ident "TO" @Ident`
	NewTableName  *string  `| "TO" @Ident`
}

type AstSelect

type AstSelect struct {
	Selected *AstSelectExpression `@@`
	Table    *AstTableName        `"FROM" @@`
	Where    *AstExpression       `["WHERE" @@]`
	Limit    *int64               `["LIMIT" @Number]`
}

type AstSelectCol

type AstSelectCol struct {
	Name *string        `@Ident`
	Func *AstSelectFunc `| @@`
}

type AstSelectExpression

type AstSelectExpression struct {
	All  *string        `@"*"`
	Cols []AstSelectCol `| @@ {"," @@}`
}

type AstSelectFunc

type AstSelectFunc struct {
	Name   *string    `@Func "("`
	Col    *string    `@Ident`
	Params []AstValue `{"," @@} ")"`
}

type AstTableName

type AstTableName struct {
	A *string `@Ident`
	B *string `["." @Ident]`
}

func (*AstTableName) DatabaseName

func (self *AstTableName) DatabaseName() string

func (*AstTableName) TableName

func (self *AstTableName) TableName() string

type AstTypeDef

type AstTypeDef struct {
	Key  []string `"PRIMARY" "KEY" "(" @Ident {"," @Ident} ")"`
	Name *string  `| @Ident`
	Type *string  `@{"BIGINT" | "TINYINT" | "SMALLINT" | "INT"  | "DOUBLE" | "FLOAT" | "TIMESTAMP" | "BOOLEAN" | "TEXT"}`
}

type AstValue

type AstValue struct {
	Number      *AstNumber  `@Number`
	String      *string     `| @String`
	Placeholder *string     `| @"?"`
	Boolean     *AstBoolean `| @("TRUE" | "FALSE")`
}

func (*AstValue) Value

func (self *AstValue) Value() interface{}

type DataType

type DataType uint32
const (
	TinyInt DataType = iota
	SmallInt
	Int
	BigInt
	Double
	Float
	Timestamp
	Boolean
	Text
)

func (*DataType) Name

func (self *DataType) Name() string

type PermType

type PermType int
const (
	NoPerm PermType = iota
	ReadablePerm
	WritablePerm
)

func GetPerm

func GetPerm(dbName string, tblName string, users ...*User) PermType

type TableColDef

type TableColDef struct {
	Name   string
	Type   DataType
	IsKey  bool
	PosCol uint32
	Pos    uint32 // position in Key or Values
}

func NewTableColDef

func NewTableColDef(name string, t DataType) (tbl *TableColDef)

type TableSchema

type TableSchema struct {
	DbName  string
	TblName string
	Cols    []*TableColDef
	Keys    []*TableColDef
	Values  []*TableColDef
	NameMap map[string]*TableColDef
	Dir     directory.DirectorySubspace
}

func GetTableSchema

func GetTableSchema(db fdb.Transactor, dbName string, tblName string) (tbl *TableSchema, err error)

func NewTableSchema

func NewTableSchema(cols []*TableColDef, keys []int) (tbl TableSchema)

type User

type User struct {
	// contains filtered or unexported fields
}

func (*User) CheckPassword

func (user *User) CheckPassword(password string) bool

func (*User) Perm2Str

func (user *User) Perm2Str() (res string)

func (User) UpdatePasswd

func (user User) UpdatePasswd(db fdb.Transactor, newpasswd string) error

Directories

Path Synopsis
bindings
go

Jump to

Keyboard shortcuts

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