Giter Site home page Giter Site logo

alpacahq / marketstore Goto Github PK

View Code? Open in Web Editor NEW
1.8K 105.0 222.0 7.18 MB

DataFrame Server for Financial Timeseries Data

License: Apache License 2.0

Makefile 0.78% Go 81.50% Shell 0.74% ANTLR 2.47% Java 7.79% Dockerfile 0.06% Python 6.57% Mustache 0.10%
marketstore golang financial-analysis pandas-dataframe trading database timeseries-database cryptocurrency gdax alpaca

marketstore's Introduction

MarketStore

CircleCI GoDoc chatroom icon codecov

Read this in 日本語(Japanese)

Introduction

MarketStore is a database server optimized for financial time-series data. You can think of it as an extensible DataFrame service that is accessible from anywhere in your system, at higher scalability.

It is designed from the ground up to address scalability issues around handling large amounts of financial market data used in algorithmic trading backtesting, charting, and analyzing price history with data spanning many years, and granularity down to tick-level for the all US equities or the exploding cryptocurrencies space. If you are struggling with managing lots of HDF5 files, this is perfect solution to your problem.

The batteries are included with the basic install - you can start pulling crypto price data from GDAX and writing it to the db with a simple plugin configuration.

MarketStore enables you to query DataFrame content over the network at as low latency as your local HDF5 files from disk, and appending new data to the end is two orders of magnitude faster than DataFrame would be. This is because the storage format is optimized for the type of data and use cases as well as for modern filesystem/hardware characteristics.

MarketStore is production ready! At Alpaca it has been used in production for years in serious business. If you encounter a bug or are interested in getting involved, please see the contribution section for more details.

Install

Docker

If you want to get started right away, you can bootstrap a marketstore db instance using our latest docker image. The image comes pre-loaded with the default mkts.yml file and declares the VOLUME /data, as its root directory. To run the container with the defaults:

docker run -i -p 5993:5993 alpacamarkets/marketstore:latest

If you want to run a custom mkts.yml you can create a new container and load your mkts.yml file into it:

docker create --name mktsdb -p 5993:5993 alpacamarkets/marketstore:latest
docker cp mkts.yml mktsdb:/etc/mkts.yml
docker start -i mktsdb

You can also bind mount the container to a local host config file: a custom mkts.yml:

docker run -v /full/path/to/mkts.yml:/etc/mkts.yml -i -p 5993:5993 alpacamarkets/marketstore:latest

This allows you to test out the image included plugins with ease if you prefer to skip the copying step suggested above.

By default the container will not persist any written data to your container's host storage. To accomplish this, bind the data directory to a local location:

docker run -v "/path/to/store/data:/data" -i -p 5993:5993 alpacamarkets/marketstore:latest

Once data is written to the server you should see a file tree layout like the following that will persist across container runs:

>>> tree /<path_to_data>/marketstore
/<path_to_data>/marketstore
├── category_name
├── WALFile.1590868038674814776.walfile
├── SYMBOL_1
├── SYMBOL_2
├── SYMBOL_3

If you have built the cmd package locally, you can open a session with your running docker instance using:

marketstore connect --url localhost:5993

Source

MarketStore is implemented in Go, so you can install it by go install.

go install github.com/alpacahq/marketstore/v4@latest
# export GOROOT=$HOME/go
# export PATH=$PATH:$GOROOT/bin
marketstore --version

You can build it from source easily too. You need Go 1.11+ as it uses go mod to manage dependencies.

go get -u github.com/alpacahq/marketstore

then compile and install the project binaries using

make install

Optionally, you can install the project's included plugins using

make plugins

Homebrew on macOS

You can also install marketstore using the Homebrew package manager for macOS.

$ brew tap zjhmale/marketstore
$ brew install --HEAD marketstore

To upgrade marketstore in the future, use upgrade instead of install.

Then you are equipped with marketstore service plist also

$ brew services start marketstore
$ brew services stop marketstore

Usage

You can list available commands by running

marketstore

or

$GOPATH/bin/marketstore

depending on your GOPATH.

You can create a new configuration file named mkts.yml, populated with defaults by running:

$GOPATH/bin/marketstore init

and then start the marketstore server with:

$GOPATH/bin/marketstore start

The output will look something like:

example@alpaca:~/go/bin/src/github.com/alpacahq/marketstore$ marketstore
I0619 16:29:30.102101    7835 log.go:14] Disabling "enable_last_known" feature until it is fixed...
I0619 16:29:30.102980    7835 log.go:14] Initializing MarketStore...
I0619 16:29:30.103092    7835 log.go:14] WAL Setup: initCatalog true, initWALCache true, backgroundSync true, WALBypass false:
I0619 16:29:30.103179    7835 log.go:14] Root Directory: /example/go/bin/src/github.com/alpacahq/marketstore/project/data/mktsdb
I0619 16:29:30.144461    7835 log.go:14] My WALFILE: WALFile.1529450970104303654.walfile
I0619 16:29:30.144486    7835 log.go:14] Found a WALFILE: WALFile.1529450306968096708.walfile, entering replay...
I0619 16:29:30.244778    7835 log.go:14] Beginning WAL Replay
I0619 16:29:30.244861    7835 log.go:14] Partial Read
I0619 16:29:30.244882    7835 log.go:14] Entering replay of TGData
I0619 16:29:30.244903    7835 log.go:14] Replay of WAL file /example/go/bin/src/github.com/alpacahq/marketstore/project/data/mktsdb/WALFile.1529450306968096708.walfile finished
I0619 16:29:30.289401    7835 log.go:14] Finished replay of TGData
I0619 16:29:30.340760    7835 log.go:14] Launching rpc data server...
I0619 16:29:30.340792    7835 log.go:14] Initializing websocket...
I0619 16:29:30.340814    7835 plugins.go:14] InitializeTriggers
I0619 16:29:30.340824    7835 plugins.go:42] InitializeBgWorkers

Configuration

In order to run MarketStore, a YAML config file is needed. A default file (mkts.yml) can be created using marketstore init. The path to this file is passed in to the start command with the --config flag, or by default it finds a file named mkts.yml in the directory it is running from.

Options

Var Type Description
root_directory string Allows the user to specify the directory in which the MarketStore database resides
listen_port int Port that MarketStore will serve through for JSON-RPC API
grpc_listen_port int Port that MarketStore will serve through for GRPC API
timezone string System timezone by name of TZ database (e.g. America/New_York)
log_level string Allows the user to specify the log level (info
stop_grace_period int Sets the amount of time MarketStore will wait to shutdown after a SIGINT signal is received
wal_rotate_interval int Frequency (in minutes) at which the WAL file will be trimmed after being flushed to disk
stale_threshold int Threshold (in days) by which MarketStore will declare a symbol stale
disable_variable_compression bool disables the default compression of variable data
triggers slice List of trigger plugins
bgworkers slice List of background worker plugins

Default mkts.yml

root_directory: data
listen_port: 5993
grpc_listen_port: 5995
log_level: info
stop_grace_period: 0
wal_rotate_interval: 5
stale_threshold: 5

Clients

After starting up a MarketStore instance on your machine, you're all set to be able to read and write tick data.

Python

pymarketstore is the standard python client. Make sure that in another terminal, you have marketstore running

  • query data
import pymarketstore as pymkts
param = pymkts.Params('BTC', '1Min', 'OHLCV', limit=10)
cli = pymkts.Client()
reply = cli.query(param)
reply.first().df()

shows

Out[5]:
                               Open      High       Low     Close     Volume
Epoch
2018-01-17 17:19:00+00:00  10400.00  10400.25  10315.00  10337.25   7.772154
2018-01-17 17:20:00+00:00  10328.22  10359.00  10328.22  10337.00  14.206040
2018-01-17 17:21:00+00:00  10337.01  10337.01  10180.01  10192.15   7.906481
2018-01-17 17:22:00+00:00  10199.99  10200.00  10129.88  10160.08  28.119562
2018-01-17 17:23:00+00:00  10140.01  10161.00  10115.00  10115.01  11.283704
2018-01-17 17:24:00+00:00  10115.00  10194.99  10102.35  10194.99  10.617131
2018-01-17 17:25:00+00:00  10194.99  10240.00  10194.98  10220.00   8.586766
2018-01-17 17:26:00+00:00  10210.02  10210.02  10101.00  10138.00   6.616969
2018-01-17 17:27:00+00:00  10137.99  10138.00  10108.76  10124.94   9.962978
2018-01-17 17:28:00+00:00  10124.95  10142.39  10124.94  10142.39   2.262249
  • write data
import numpy as np
import pandas as pd
data = np.array([(pd.Timestamp('2017-01-01 00:00').value / 10**9, 10.0)], dtype=[('Epoch', 'i8'), ('Ask', 'f4')])
cli.write(data, 'TEST/1Min/Tick')
# Out[10]: {'responses': None}

cli.query(pymkts.Params('TEST', '1Min', 'Tick')).first().df()

shows

                            Ask
Epoch
2017-01-01 00:00:00+00:00  10.0
  • Variable length records

Marketstore is a database that achieves high performance by limiting the number of records in a timeframe to one. The supported timeframes are from 1D (1 day) to 1Sec (1 second), and basically, the longer the timeframe is, the faster you can read and write data.

However, it also supports data that does not arrive at a specific interval or more frequently than every second, such as board data and TICK data. Such kind of data is called variable-length records in marketstore.

You can use the variable-length records feature by specifying isvariablelength=True when you write with pymarketstore.

import numpy as np, pandas as pd, pymarketstore as pymkts

symbol, timeframe, attribute_group = "TEST", "1Sec", "Tick"
data_type = [('Epoch', 'i8'), ('Bid', 'f4'), ('Ask', 'f4'), ('Nanoseconds', 'i4')]
tbk = "{}/{}/{}".format(symbol, timeframe, attribute_group)
client = pymkts.Client()

# --- write variable-length records (=multiple records in a single timeframe (1Sec))
data = np.array([
    (pd.Timestamp('2021-01-01 00:00:00').value / 10 ** 9, 10.0, 20.0, 1000000),
    (pd.Timestamp('2021-01-01 00:00:00').value / 10 ** 9, 30.0, 40.0, 2000000),
    (pd.Timestamp('2021-01-01 00:00:00').value / 10 ** 9, 50.0, 60.0, 3000000),
], dtype=data_type)
client.write(data, tbk, isvariablelength=True)

# --- query variable-length records
params = pymkts.Params(symbol, timeframe, attribute_group)
print(client.query(params=params).first().df())

# --- tearDown
client.destroy(tbk)

shows

                            Bid Ask Nanoseconds
Epoch                                             
2021-01-01 00:00:00+00:00 10.0 20.0 1000000
2021-01-01 00:00:00+00:00 30.0 40.0 2000000
2021-01-01 00:00:00+00:00 50.0 60.0 3000000

Because the data type of Epoch column is always set as 'i8'(=int64) and it's not sufficient for describing a date with sub-second accuracy, the sub-second information is stored in another column (=Nanoseconds column, the data type is 'i4') in marketstore.

Command-line

Connect to a marketstore instance with

// For a local db-
marketstore connect --dir <path>
// For a server-
marketstore connect --url <address>

and run commands through the sql session.

Plugins

Go plugin architecture works best with Go1.10+ on linux. For more on plugins, see the plugins package Some featured plugins are covered here -

Streaming

You can receive realtime bars updates through the WebSocket streaming feature. The db server accepts a WebSocket connection on /ws, and we have built a plugin that pushes the data. Take a look at the package for more details.

GDAX Data Feeder

The batteries are included, so you can start pulling crypto price data from GDAX right after you install MarketStore. Then you can query DataFrame content over the network at as low latency as your local HDF5 files from disk, and appending new data to the end is two orders of magnitude faster than DataFrame would be. This is because the storage format is optimized for the type of data and use cases as well as for modern filesystem/hardware characteristics.

You can start pulling data from GDAX if you configure the data poller. For more information, see the package

On-Disk Aggregation

This plugin allows you to only worry about writing tick/minute level data. This plugin handles time-based aggregation on disk. For more, see the package

Replication

You can replicate data from a master marketstore instance to other marketstore instances. In mkts.yml config file, please set the config as the following:

  • master instance
replication:
  # when enabled=true, this instance works as master instance and accept connections from replicas
  enabled: true
  # when tls_enabled=true, transport security between master and replica is enabled.
  # tls_enabled: true # both master and replica should have tls_enabled=true to enable TLS
  # public/private key pair from a pair of files. The files must contain PEM encoded data.
  # The cert file may contain intermediate certificates following the leaf certificate to form a certificate chain.
  # cert_file: "/Users/dakimura/projects/misks/tmpcert/server.crt" # both master and replica should have this config to enable TLS
  # key_file: "/Users/dakimura/projects/misks/tmpcert/server.key"
  # port to be used for the replication protocol
  listen_port: 5996
  • replica instance(s)
replication:
  # when master_host is set, this instance works as a replica instance
  master_host: "127.0.0.1:5995"
  # when tls_enabled=true on master server, GRPC communication between master and replica is encrypted by SSL.
  # tls_enabled: true
  # cert_file: "/Users/dakimura/projects/misks/tmpcert/server.crt" # both master and replica should have this config to enable TLS

limitations

  • Currently, the replication connection is initialized only at a startup of a marketstore replica instance. Please be sure to start the master instance first when you want to replicate data.

  • Currently, only write API is supported. delete API result won't be reflected to replica instances.

  • When replication is enabled on a replica instance, the instance is set to read-only mode and write API call(s) to the instance will fail.

Development

If you are interested in improving MarketStore, you are more than welcome! Just file issues or requests in GitHub or contact [email protected]. Before opening a PR please be sure tests pass-

make unittest

Plugins Development

We know the needs and requirements in this space are diverse. MarketStore provides strong core functionality with flexible plug-in architecture. If you want to build your own, look around plugins

marketstore's People

Contributors

ackleymi avatar bdowling avatar briancappello avatar dakimura avatar darkbladecr avatar dependabot[bot] avatar ericcrosson avatar ethanchewy avatar goodboy avatar itsankoff avatar jaredmcqueen avatar julio-santiesteban avatar juneezee avatar kalmant avatar keisuke-umezawa avatar kulcsarb avatar leki75 avatar lszamosi avatar notargets avatar rocketbitz avatar tibkiss avatar umitanuki avatar utekaravinash avatar wanderer163 avatar xgdgsc avatar zjhmale avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

marketstore's Issues

SetRange should take epoch

The system design assumption is that everything in the server should be under UTC unless otherwise required. SetRange() is an internal API and should take epoch instead of time.Time which could be incorrectly timezoned.

Video

Is it possible to get a video walk through on setting this up?
Been trying for a few days with no prevail.

Question about candler plugin

Hi. Looking at the Candler plugin I'm not sure about something: If the Candler plugin transforms data into "OHLCV" format, this means the rest of the data saved in marketstore is not OHLCV?

I have several questions about the design of a web application using marketstore as a source for chart data:

  • How do I query for history OHLCV data? Does marketstore use (Postgre)SQL?
  • Is there an example of how to set up a client for the websocket?
  • How do you handle indicators? They have one to many (bollllinger band has 3, for example) values per market per period per timestamp. Can marketstore save/serve these as well?
    • Should indicators be stored in a database beforehand or calculated on request? Some indicators might show inaccurate results if only considering the UI Chart data, without a "warmup" period.
    • Some indicators are coming from different docker containers, for example TensorFlow, these also require an array of close prices as input.

I hope this platform will thrive in the futre, it is very interesting to me. Very nice work :-)

If lucky, I can throw away a big pile of unfinished work that tries to accomplish some of the same goals for my app :-)

gr,

Industrial / Tom Wieland

improve aggtrigger performance

Currently, when the number of symbols is large, the aggtrigger uses a very large amount of resources. It should be optimized.

optimize serialization for writes

Currently the Serialize routine in the io package is quite inefficient, and being called far too frequently. This should be optimized to make writes faster.

Adding additional timeframe buckets, is a bit of a process.

I was fooled by the config into thinking I could just enter another entry in the list, but realized this does not actually handle the mappings from these tags.

To solve, I added an entry to Timeframes, and rebuilt my docker image

I thought I was going to need to resend my data into the 1Min bucket for the ondiskagg to populate the new timeslot, but somehow it already did this? Not certain how exactly this magic happens, but that was surprising. ;)

Just posting this idea out here, as it feels like this could be easier, e.g. TimeframeStrings can already be parsed, why not let the buckets be a bit more dynamic?

--- a/utils/timeframe.go
+++ b/utils/timeframe.go
@@ -26,6 +26,7 @@ var timeframeDefs = []Timeframe{
 var Timeframes = []*Timeframe{
        {"1Min", time.Minute},
        {"5Min", 5 * time.Minute},
+       {"10Min", 10 * time.Minute},
        {"15Min", 15 * time.Minute},
        {"1H", time.Hour},
        {"4H", 4 * time.Hour},

mkts/examples failed to parse Epoch

Reading control file ticks-example.yaml with size 223 bytes
Read next 1000 lines from CSV file...Error parsing Epoch column(s) from input data file: parsing time "1.05185" as "20060102 15:04:05": cannot parse "185" as "2006"
Error building time columns from csv data
No new data written

bash runtest.sh in cmd/tools/mkts/examples failed.

binance feeder broken for specific symbols

I0624 23:28:22.273633   21515 binancefeeder.go:198] Requesting ETHBTC 2018-06-20 00:00:00 +0000 UTC - 2018-06-20 05:00:00 +0000 UTC
E0624 23:28:22.494356   21515 binancefeeder.go:203] Response error: <APIError> code=-1121, msg=Invalid symbol.

I keep receiving the API error code =-1121
when trying any of the symbol pairs available from the API

Data not available

Hi. I am running marketstore with docker and sometimes there is no data available for my charts.

Marketstore will download everything from the start again.

I would like to request the feature that all queries ran against marketstore get satisfied first.

If MarketStore is downloading stuff on minute scale and my query is requesting all of 2018 on day scale .. I want these data to be imported first, then the query to hang until its completed and to return the data on day scale for the request.

This way I can continue developing instead of having to wait until all data is imported on minute scale before being able to develop again ..

Can I access marketstore from JavaScript?

Hi. I'm building a charting application. Right now I'm using PostgreSQL but I'd love to replace that part with Marketstore.

I'm not using Python in my stack, and I'm using Node.js to write several services. I'm using GraphQL (which supports "Live Queries" in the form of Subscriptions) to connect the browser and API.

How do I query marketstore for history data and live updates without using python?

Decimal type support

I want to put decimal column into marketstore to store crypto order books. Floating point types won't work because of the precision issues.

For the time being we could work around with variable-length record with string type column, but definitely it'll be great if we support decimal type column natively with potentially arithmetic operations.

one marketstore, several feeders

hi is it possible,

to populate 1 market store, with say data for for

USDT/BTC from binance

and

USDT/BTC from gdax

and query these separately?

By utilizing the feeder plugins?

Or do you have to run several market store instances?

thanks

Support <start-end> + n candles query

Pretty often, the client wants to say "I want candles between and with additional 100 candles before ". Today, the client makes one extra request to know where is the -100 position, then query the entire range, as a work around.

OHLCV bar for 2018-01-01 Cannot be Inserted

import numpy
import pandas

SHAPE = [
    ('Epoch',  'i8'),
    ('Open',   'i8'),
    ('High',   'i8'),
    ('Low',    'i8'),
    ('Close',  'i8'),
    ('Volume', 'i8')
]

ms = Client(endpoint='http://mds:5993/rpc')

def write(bar):
    ms.write(numpy.array(bar, dtype=SHAPE), 'TESTSYM/1D/OHLCV')

def time(s):
    v = pandas.Timestamp(s).value / 10**9
    print(s, v)
    return v

write([(time('2018-01-01'), 1, 1, 1, 1, 100)])
#write([(time('2018-01-02'), 2, 2, 2, 2, 200)])
#write([(time('2018-01-03'), 3, 3, 3, 3, 300)])
#write([(time('2018-01-03'), 4, 4, 4, 4, 400)])

r = ms.query(Params('TESTSYM','1D','OHLCV'))
print(r.first().df())

Output:
2018-01-01 1514764800.0
Empty DataFrame
Columns: [Open, High, Low, Close, Volume]
Index: []

It seems that an OHLCV bar for 2018-01-01 cannot be inserted.

Or perhaps there is something I've done wrong.

Additionally, if I uncomment the three writes I get the following:
Open High Low Close Volume
Epoch
2018-01-02 00:00:00+00:00 2 2 2 2 200
2018-01-03 00:00:00+00:00 4 4 4 4 400

I had expected three records, bars for -01, -02, and -03

I'm using image alpacamarkets/marketstore:v2.3.7

Hitoshi Harada, [Aug 7, 2018 at 9:00:23 AM]:
There is not such feature to ignore input record

Your second output also doesn’t make sense

Year bound can be an issue since filed are partitioned by year

But the only issue I found was the record fell into the previous year but never saw record gone

Please report the detail in github issue

Optimize scan code by cgo

This is the profiling result around reader.Read with 8K symbols, 15Min, last 100 records, after some optimization with readhint, as of today.

2.03s of 2.19s total (92.69%)
Dropped 30 nodes (cum <= 0.01s)
      flat  flat%   sum%        cum   cum%
     0.86s 39.27% 39.27%      0.87s 39.73%  syscall.Syscall
     0.30s 13.70% 52.97%      1.10s 50.23%  marketstore/executor.packingReader
     0.21s  9.59% 62.56%      0.21s  9.59%  runtime.memclrNoHeapPointers
     0.10s  4.57% 67.12%      0.10s  4.57%  syscall.Syscall6
     0.07s  3.20% 70.32%      0.07s  3.20%  runtime.memmove
     0.06s  2.74% 73.06%      0.06s  2.74%  runtime.cgocall
     0.04s  1.83% 74.89%      0.21s  9.59%  marketstore/udf.PatternDataFromRowSeries
     0.04s  1.83% 76.71%      0.04s  1.83%  runtime.lock
     0.03s  1.37% 78.08%      0.03s  1.37%  path/filepath.Clean
     0.03s  1.37% 79.45%      0.03s  1.37%  runtime.aeshashbody
     0.03s  1.37% 80.82%      0.03s  1.37%  runtime.unlock
     0.03s  1.37% 82.19%      0.05s  2.28%  strings.Map
     0.02s  0.91% 83.11%      0.04s  1.83%  marketstore/planner.(*ParseResult).GetRowLen
     0.02s  0.91% 84.02%      0.03s  1.37%  runtime.(*mheap).allocSpanLocked
     0.02s  0.91% 84.93%      0.02s  0.91%  runtime.futex
     0.02s  0.91% 85.84%      0.02s  0.91%  runtime.heapBitsSetType
     0.02s  0.91% 86.76%      0.09s  4.11%  runtime.mapassign
     0.02s  0.91% 87.67%      0.02s  0.91%  runtime.usleep
     0.01s  0.46% 88.13%      1.74s 79.45%  marketstore/executor.(*reader).Read
     0.01s  0.46% 88.58%      1.44s 65.75%  marketstore/executor.readBackward
     0.01s  0.46% 89.04%      0.07s  3.20%  marketstore/planner.NamesMatch
     0.01s  0.46% 89.50%      0.17s  7.76%  marketstore/utils/io.getFloat32Column
     0.01s  0.46% 89.95%      0.76s 34.70%  os.(*File).read
     0.01s  0.46% 90.41%      0.13s  5.94%  os.OpenFile
     0.01s  0.46% 90.87%      0.04s  1.83%  path/filepath.Rel
     0.01s  0.46% 91.32%      0.33s 15.07%  runtime.(*mcache).nextFree
     0.01s  0.46% 91.78%      0.26s 11.87%  runtime.(*mcentral).cacheSpan
     0.01s  0.46% 92.24%      0.05s  2.28%  runtime.(*mheap).alloc_m
     0.01s  0.46% 92.69%      0.02s  0.91%  runtime.addfinalizer
         0     0% 92.69%      0.06s  2.74%  marketstore/catalog.FullPathToItemKey

The scanning code may be faster if it was C.

The sleep time is broken in gdaxfetcher

I0601 22:33:23.004369       1 gdaxfeeder.go:181] BTC: 300 rates between 2017-05-08 07:00:00 +0000 UTC - 2017-05-09 07:55:00 +0000 UTC
I0601 22:33:23.014670       1 gdaxfeeder.go:194] next expected(2017-05-09 08:05:00 +0000 UTC) - now(2018-06-01 22:33:23.0146394 +0000 UTC m=+4.115405301) = -9326h28m23.0146394s

tested

_, err := nc.Subscribe("AM.*", handler)

had to change this to AM.AAPL to get the code to work properly. I think the load is to big otherwise, what is the specs of your system? running AM.* crushed me and generated 2GB worth of data in 30minutes.

after changing it worked fine, streaming worked fine and i crashed the system and restored it a few minutes later and it pulled the missing data fine.

mkts load panics when csv files is not exists

Opening USDJPY-hoge.csv as - unable to open file: invalid argument
Beginning parse...
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x581302]

goroutine 1 [running]:
github.com/alpacahq/marketstore/utils/io.(*TimeBucketKey).GetItemKey(0x0, 0x13, 0x0)
        /home/fooo/golang/src/github.com/alpacahq/marketstore/utils/io/keytypes.go:58 +0x22
github.com/alpacahq/marketstore/utils/io.(*TimeBucketKey).GetPathToYearFiles(0x0, 0xc42007c1e0, 0x29, 0x1, 0x13)
        /home/fooo/golang/src/github.com/alpacahq/marketstore/utils/io/keytypes.go:132 +0x2f
github.com/alpacahq/marketstore/catalog.(*Directory).GetLatestTimeBucketInfoFromKey(0xc4200a51f0, 0x0, 0x1, 0x13, 0x0)
        /home/fooo/golang/src/github.com/alpacahq/marketstore/catalog/catalog.go:209 +0x46
main.processLoad(0xc420020460, 0x4a)
        /home/fooo/golang/src/github.com/alpacahq/marketstore/cmd/tools/mkts/main.go:320 +0x180
main.main()
        /home/fooo/golang/src/github.com/alpacahq/marketstore/cmd/tools/mkts/main.go:128 +0x607

https://github.com/alpacahq/marketstore/blob/master/cmd/tools/mkts/main.go#L315

Could you add err to parseLoadArgs return value or nil check ?

Unable to compile plugins

I'm having a few problems compiling the plugins.

  1. Easy to solve, but the compiler needed to be set to c99. export CC=c99 fixed that.
  2. A little more obscure, a regression that prevents ondiskagg from compiling. This is a bug from go introduced last December. This can be worked around by using go 1.9.1. This seems to come from a c99 vs a gnu99 issue.
  3. Still having an issue with
gcc_linux_amd64.c: In function ‘_cgo_sys_thread_start’:
gcc_linux_amd64.c:62:2: error: unknown type name ‘sigset_t’

Not sure what this one is.

The system is on Redhat x86_64 GNU/Linux. If there's a recommended system architecture, please let me know. I'll be using the Docker image in the mean time.

ondiskagg doesn't handle integer types

I attempted to load some OHLCV data where the volume column was an integer type. ondiskagg doesn't know how to handle this, which resulted in the following error:

created by github.com/alpacahq/marketstore/executor.run
        /go/src/github.com/alpacahq/marketstore/executor/written.go:57 +0x154
E0629 03:09:28.348744       1 accum.go:197] no compatible function
E0629 03:09:28.348910       1 written.go:67] recovering from runtime error: invalid memory address or nil pointer dereference
goroutine 181 [running]:
runtime/debug.Stack(0xc421415658, 0xdde200, 0x1656c10)

fwiw, it might be helpful additionally if the 'no compatible function' message included the type.

Unable to make plugins

I have managed to build this from source and spin this up on my ubuntu server without any real issues. I am looking to create some new plugins so that I can support candlestick data from other exchanges. However I am getting an error when trying to build.

go version go1.10.3 darwin/amd64
go env:

GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/stefan/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/pl/q2xfv4ss4ndgdwhwqpkp6d440000gn/T/go-build652065154=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"

Then when I run
$ make all plugins

/Applications/Xcode.app/Contents/Developer/usr/bin/make -C contrib/ondiskagg
go build -o /bin/ondiskagg.so -buildmode=plugin .
go build github.com/marketstore/contrib/ondiskagg: open /bin/ondiskagg.so: operation not permitted
make[1]: *** [all] Error 1
make: *** [plugins] Error 2

I keep getting an error with operation not permitted. I have also tried with root access. Does anyone have any ideas as to why this is happening?

client.write() does not work with python 2.7

When I try the example in the README, it fails with a corrupted time index:

import numpy as np
import pandas as pd
import pymarketstore as pymkts

data = np.array([(pd.Timestamp('2017-01-01 00:00').value / 10**9, 10.0)], dtype=[('Epoch', 'i8'), ('Ask', 'f4')])

cli = pymkts.Client()

cli.write(data, 'TEST/1Min/Tick')

d2 = cli.query(pymkts.Params('TEST', '1Min', 'Tick')).first().df()
print d2

I get the following output:

# python tests/basic_driver.py 
Empty DataFrame
Columns: [Ask]
Index: []

I believe the problem is in the handling of the numpy data in the driver as compared with the handling in the API code in the marketstore server. To fix this, we should:

  • develop and document the binary data interchange format
  • implement a basic sanity test of the index values used in the data package - perhaps send the beginning and ending values of time index in the intended write data in the data package
  • implement a system level test in CircleCI that verifies this driver's correct operation with the latest marketstore codebase

Binance plugin searching beyond current time

The Binance plugin currently will grab data from your query_start date, but then will overshoot the current time and then continue indefinitely, for example:

Jun 27 19:51:14 ip-172-31-1-100 marketstore[11903]: I0627 19:51:14.679280   11903 binancefeeder.go:241] Requesting BTC 2018-07-05 05:31:00 +0000 UTC - 2018-07-05 10:31:00 +0000 UTC
Jun 27 19:51:14 ip-172-31-1-100 marketstore[11903]: I0627 19:51:14.956699   11903 binancefeeder.go:251] len(rates) == 0
Jun 27 19:51:14 ip-172-31-1-100 marketstore[11903]: I0627 19:51:14.957102   11903 binancefeeder.go:241] Requesting ETH 2018-07-05 05:31:00 +0000 UTC - 2018-07-05 10:31:00 +0000 UTC
Jun 27 19:51:15 ip-172-31-1-100 marketstore[11903]: I0627 19:51:15.208399   11903 binancefeeder.go:251] len(rates) == 0
Jun 27 19:51:15 ip-172-31-1-100 marketstore[11903]: I0627 19:51:15.208787   11903 binancefeeder.go:241] Requesting LTC 2018-07-05 05:31:00 +0000 UTC - 2018-07-05 10:31:00 +0000 UTC
Jun 27 19:51:15 ip-172-31-1-100 marketstore[11903]: I0627 19:51:15.968124   11903 binancefeeder.go:251] len(rates) == 0

Does not raise informative error when queried symbol does not exist

If it is easy to do, we could raise an informative error when a symbol is queried but does not exist. It can be done on the client side, in pymarkestore but it is not straightforward unfortunately, so if there is a an easy way to do it on the go side, it should be preferrable.

Push capability

As a client user of MarketStore server, I want to get notified about the changes especially new candle update and completion. Since time-aggregate is in plugin side, this should be done similar way, yet there is need for the server core to support websocket interface and message routing to facilitate plugin's push.

Panic on catalog initilization

I ran the latest code on my mac with gdax fetcher and right after startup panic'ed.

runtime: bad pointer in frame runtime.mapassign_faststr at 0xc42008b440: 0x30
fatal error: invalid pointer found on stack

runtime stack:
runtime.throw(0x821ca81, 0x1e)
	/Users/hitoshi/local/go/src/runtime/panic.go:616 +0x81 fp=0x70000ae26708 sp=0x70000ae266e8 pc=0x7e750d1
runtime.adjustpointers(0xc42008b438, 0x70000ae26800, 0x70000ae26bc0, 0x8292dc0, 0x83ce4c0)
	/Users/hitoshi/local/go/src/runtime/stack.go:592 +0x23e fp=0x70000ae26778 sp=0x70000ae26708 pc=0x7e8abfe
runtime.adjustframe(0x70000ae26ad0, 0x70000ae26bc0, 0x83ce4c0)
	/Users/hitoshi/local/go/src/runtime/stack.go:663 +0x325 fp=0x70000ae26830 sp=0x70000ae26778 pc=0x7e8af45
runtime.gentraceback(0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0xc420aa8780, 0x0, 0x0, 0x7fffffff, 0x822add8, 0x70000ae26bc0, 0x0, ...)
	/Users/hitoshi/local/go/src/runtime/traceback.go:310 +0x12d3 fp=0x70000ae26b38 sp=0x70000ae26830 pc=0x7e94093
runtime.copystack(0xc420aa8780, 0x2000, 0x70000ae26d01)
	/Users/hitoshi/local/go/src/runtime/stack.go:891 +0x26e fp=0x70000ae26cf0 sp=0x70000ae26b38 pc=0x7e8ba2e
runtime.newstack()
	/Users/hitoshi/local/go/src/runtime/stack.go:1063 +0x310 fp=0x70000ae26e80 sp=0x70000ae26cf0 pc=0x7e8be40
runtime.morestack()
	/Users/hitoshi/local/go/src/runtime/asm_amd64.s:480 +0x89 fp=0x70000ae26e88 sp=0x70000ae26e80 pc=0x7e9a1a9

goroutine 66 [copystack]:
runtime.(*mcache).nextFree(0x50746c8, 0x16, 0x0, 0x0, 0x0)
	/Users/hitoshi/local/go/src/runtime/malloc.go:545 +0x254 fp=0xc42008b318 sp=0xc42008b310 pc=0x7e5bef4
runtime.mallocgc(0xa0, 0x4634100, 0x1, 0xc420077470)
	/Users/hitoshi/local/go/src/runtime/malloc.go:710 +0x7e5 fp=0xc42008b3b8 sp=0xc42008b318 pc=0x7e5c6e5
runtime.newobject(0x4634100, 0xe0209b03)
	/Users/hitoshi/local/go/src/runtime/malloc.go:839 +0x38 fp=0xc42008b3e8 sp=0xc42008b3b8 pc=0x7e5ca98
runtime.mapassign_faststr(0x45f0e00, 0xc42026ce40, 0x0, 0x0, 0xc420077498)
	/Users/hitoshi/local/go/src/runtime/hashmap_fast.go:712 +0x383 fp=0xc42008b458 sp=0xc42008b3e8 pc=0x7e57f03
github.com/alpacahq/marketstore/catalog.(*Directory).gatherCategoriesUpdateCache.func1(0xc4202c6000, 0x45f0e00, 0xc42026ce40)
	/Users/hitoshi/alpaca/go/src/github.com/alpacahq/marketstore/catalog/catalog.go:458 +0x58 fp=0xc42008b490 sp=0xc42008b458 pc=0x7fb1c68
github.com/alpacahq/marketstore/catalog.(*Directory).recurse(0xc4202c6000, 0x45f0e00, 0xc42026ce40, 0x822a8d8)
	/Users/hitoshi/alpaca/go/src/github.com/alpacahq/marketstore/catalog/catalog.go:543 +0xa2 fp=0xc42008b520 sp=0xc42008b490 pc=0x7fb06a2
github.com/alpacahq/marketstore/catalog.(*Directory).gatherCategoriesUpdateCache(0xc4202c6000, 0x10)
	/Users/hitoshi/alpaca/go/src/github.com/alpacahq/marketstore/catalog/catalog.go:461 +0x5a fp=0xc42008b558 sp=0xc42008b520 pc=0x7faff9a
github.com/alpacahq/marketstore/catalog.(*Directory).GatherCategoriesFromCache(0xc4202c6000, 0x10)
	/Users/hitoshi/alpaca/go/src/github.com/alpacahq/marketstore/catalog/catalog.go:384 +0x6b fp=0xc42008b580 sp=0xc42008b558 pc=0x7fafc1b
github.com/alpacahq/marketstore/planner.(*query).Parse(0xc421370000, 0xc42024d2a8, 0x7fffffffffffffff, 0x4cb6be0)
	/Users/hitoshi/alpaca/go/src/github.com/alpacahq/marketstore/planner/planner.go:236 +0x47 fp=0xc42008b718 sp=0xc42008b580 pc=0x7fb49c7
github.com/alpacahq/marketstore/contrib/gdaxfeeder.findLastTimestamp(0x82140a9, 0x3, 0xc420250050, 0x0, 0x0, 0xc420250050)
	/Users/hitoshi/alpaca/go/src/github.com/alpacahq/marketstore/contrib/gdaxfeeder/gdaxfeeder.go:99 +0x214 fp=0xc42008b7b8 sp=0xc42008b718 pc=0x813f744
github.com/alpacahq/marketstore/contrib/gdaxfeeder.(*GdaxFetcher).Run(0xc4202d4480)
	/Users/hitoshi/alpaca/go/src/github.com/alpacahq/marketstore/contrib/gdaxfeeder/gdaxfeeder.go:122 +0x2ce fp=0xc42008bfd8 sp=0xc42008b7b8 pc=0x813fb6e
runtime.goexit()
	/Users/hitoshi/local/go/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc42008bfe0 sp=0xc42008bfd8 pc=0x4059a81
created by main.RunBgWorkers
	/Users/hitoshi/alpaca/go/src/github.com/alpacahq/marketstore/cmd/marketstore/plugins.go:52 +0x1ef

The relevant code is here.

func (d *Directory) gatherCategoriesUpdateCache() map[string]int8 {
	// Must be thread-safe for WRITE access
	// Note that this should be called whenever catalog structure is modified to update the cache
	catListFunc := func(d *Directory, i_list interface{}) {
		list := i_list.(map[string]int8)
		list[d.category] = 0
	}
	newCatList := make(map[string]int8, 0)
	d.recurse(newCatList, catListFunc)
	d.Lock()
	d.catList = newCatList
	d.Unlock()
	return newCatList
}

It looks to me d.recurse should also be protected by the write lock, since d.category may be changed by someone else.

unittest fails

Hi, my unittest with go 1.10 on ubuntu fails. Any idea what I am doing wrong?

go fmt ./...
go vet ./...
#github.com/alpacahq/marketstore/contrib/slait
contrib/slait/slait.go:169:2: start declared but not used
vet: typecheck failures
Makefile:28: recipe for target 'unittest' failed
make: *** [unittest] Error 2

aggregator issue

In the below observation for 1Min data starting from 9:25 to 9:30 -- I'm not able to see volume getting added as expected. and it is even the same case with other OHLC values.
can you please help my understanding here

019-01-01 09:25:00+05:30 | 201.10 | 201.30 | 201.25 | 201.15 | 11702.0
200.90 | 201.20 | 201.15 | 200.95 | 36896.0
200.90 | 201.45 | 201.00 | 201.40 | 28820.0
201.25 | 201.75 | 201.30 | 201.70 | 17048.0
201.60 | 201.70 | 201.70 | 201.65 | 8968.0
201.25 | 201.65 | 201.65 | 201.45 | 26458.0

2019-01-01 09:25:00+05:30 | 201.10 | 201.75 | 201.00 | 201.65 | 103434.0
201.25 | 201.65 | 201.35 | 201.50 | 81657.0

Super dumb questions

Probably I'm missing something, because all the documentation available (README) gives me no clue about what to do when one has successfully started the marketstore server.

How do I learn about key concepts?
How do I create a measurement and write data to it?
What about indexing?
Is the python client the only choice? This article mentions HTTP-based API. Does it exist, and if it does, how to use it?

I'm sorry for asking such (probably) silly questions, but I am much confused, and I hope you can point me in the right direction.

Backfilling Trades

When I run:
backfiller -trades -from "2018-01-01" -to "2018-01-16" -dir /mnt/e/marketstore/data -apiKey ...

The following error occurs either on the symbol "A" or "AA":

panic: runtime error: makeslice: len out of range

goroutine 115 [running]:
github.com/alpacahq/marketstore/executor.WriteBufferToFileIndirect(0xc001874010, 0xc002da7831, 0x58, 0xcf, 0xc00000000c, 0x0, 0x0)
        /home/thesm/go/src/github.com/alpacahq/marketstore/executor/writer.go:199 +0x6c1
github.com/alpacahq/marketstore/executor.(*WALFileType).writePrimary(0xc00006bc00, 0xc001ae575f, 0x16, 0xc001b58000, 0x1315, 0x1400, 0xc00000001, 0x0, 0x0)
        /home/thesm/go/src/github.com/alpacahq/marketstore/executor/wal.go:337 +0x25b
github.com/alpacahq/marketstore/executor.(*WALFileType).flushToWAL(0xc00006bc00, 0xc00000d980, 0x0, 0x0)
        /home/thesm/go/src/github.com/alpacahq/marketstore/executor/wal.go:300 +0xd3b
github.com/alpacahq/marketstore/executor.(*WALFileType).RequestFlush(0xc00006bc00)
        /home/thesm/go/src/github.com/alpacahq/marketstore/executor/wal.go:863 +0xe4
github.com/alpacahq/marketstore/executor.WriteCSM(0xc00009dd40, 0xc001b06f01, 0x2d, 0xc00009dd70)
        /home/thesm/go/src/github.com/alpacahq/marketstore/executor/writer.go:335 +0x87a
github.com/alpacahq/marketstore/contrib/polygon/backfill.Trades(0xc0019e8790, 0x2, 0x0, 0xed1ef3780, 0x0, 0x0, 0xed1ef3780, 0x0, 0x0, 0xc000124180)
        /home/thesm/go/src/github.com/alpacahq/marketstore/contrib/polygon/backfill/backfill.go:121 +0x628
main.main.func4(0xc0016d5a40, 0xc001350000, 0xc000058000, 0x0, 0xed1ef3780, 0x0)
        /home/thesm/go/src/github.com/alpacahq/marketstore/contrib/polygon/backfill/backfiller/backfiller.go:159 +0xf8
created by main.main
        /home/thesm/go/src/github.com/alpacahq/marketstore/contrib/polygon/backfill/backfiller/backfiller.go:156 +0x6ae

It seems that WriteBufferToFileIndirect is trying to make a slice of size currentRecInfo.Len=5911047525390422 (after having a few hundred legitimate writes) when I printed it. Changing backfill.go:121 to have executor.WriteCSM(csm, false) instead of executor.WriteCSM(csm, true) fixes the issue, but I'm not sure of the deeper implications.

What is causing the writes to act strange, and is this the right fix?

EDIT: I found out that we are trying to write variable-length data instead of fixed-length data when we write trade-level ticks. This makes sense according to the design.

RemoveTimeBucket access to delete errant data loads

There does not appear to be a way to access RemoveTImeBucket in the RPC API, which is probably good from a security standpoint. Perhaps there should be a CLI way to access it?

Based on the simple file system layout I assumed I could remove the files and restart the service.

Support <start-end> + n candles query

It is often the client wants to say "I want candles between and with additional 100 candles before ". Today, the client makes one extra request to know where is the - 100 position, then query the entire range, as a work around.

Unable to replay WALFile.1544424147732049389.walfile\nsnappy: corrupt input

I had upgrade the code to newest version(v3.2.0) and found I can run the marketstore by cmd
marketstore start -c mkd.yml anymore.

The output like below:

{"level":"info","timestamp":"2018-12-09T23:04:43.671-0800","msg":"Running single threaded"}
{"level":"info","timestamp":"2018-12-09T23:04:43.729-0800","msg":"using mkd.yml for configuration"}
{"level":"info","timestamp":"2018-12-09T23:04:43.729-0800","msg":"Disabling \"enable_last_known\" feature until it is fixed..."}
{"level":"info","timestamp":"2018-12-09T23:04:43.730-0800","msg":"initializing marketstore..."}
{"level":"info","timestamp":"2018-12-09T23:04:43.730-0800","msg":"WAL Setup: initCatalog true, initWALCache true, backgroundSync true, WALBypass false: \n"}
{"level":"info","timestamp":"2018-12-09T23:04:43.730-0800","msg":"Root Directory: data"}
{"level":"info","timestamp":"2018-12-09T23:04:50.059-0800","msg":"My WALFILE: WALFile.1544425488825330509.walfile"}
{"level":"info","timestamp":"2018-12-09T23:04:50.059-0800","msg":"Found a WALFILE: WALFile.1544424147732049389.walfile, entering replay..."}
{"level":"info","timestamp":"2018-12-09T23:04:50.589-0800","msg":"Beginning WAL Replay"}
{"level":"info","timestamp":"2018-12-09T23:04:50.589-0800","msg":"Partial Read"}
{"level":"info","timestamp":"2018-12-09T23:04:50.589-0800","msg":"Entering replay of TGData"}
{"level":"info","timestamp":"2018-12-09T23:04:50.589-0800","msg":"Replaying TGID: 1544424167321434338, data length is: 3038 bytes"}
{"level":"fatal","timestamp":"2018-12-09T23:04:50.758-0800","msg":"Unable to replay WALFile.1544424147732049389.walfile\nsnappy: corrupt input"}

Looks the new WAL function break the old WAL. Anyone can help?

Keep data on restart

Hi. I am using Marketstore with Docker so I am restarting the service a lot. Right now, when the server restarts it imports from the start again.

If there's a cache directory, why isn't it used when it restarts? Am I doing something wrong?

undefined: syscall.Sync

I'm new to building open source code so I apologies for the dumb question.

I have Windows 7, GCC 5.1.0 and GO 1.11.5 and when I execute
go get -u github.com/alpacahq/marketstore
I get the following error;

github.com/alpacahq/marketstore/utils/io
src\github.com\alpacahq\marketstore\utils\io\misc.go:13:2: undefined: syscall.Sync

What have a missed or done wrong please?

Implement cobra cli

The db will be a lot easier to use and understand with a structured cli framework - https://github.com/spf13/cobra is the best there is. We can use it to organize and explain every component and service. Also provides some really intuitive defaults and parsing capabilities right out of the box.

Is MarketStore a good fit for this use case?

I am still in the documentation phase but I am trying to understand if MarketStore would be a good fit to load and store a high volume of trade data, for example all the FIXML message, etc?

marketstore getting crashed

Hello Team,

Greatly impressed by the application, I'm trying to use it to store Indian Stock exchange data. Total symbols being saved are 1500+; and i'm saving 1 Min data, expecting ondiskagg.so to get be 5Min, 15Min and 1D data to get accumulated.

I wrote a bgworker module, taking gdaxfeeder as example; data is getting saved nicely by parsing csv files; but I get to see application is getting crashed because of ondiskagg plugin.

Initially I observed errors related file handles and sometimes it is due to lack of memory; but the result is same failing to get the data aggregated properly.

can you please help.

Thanks,
-Vikas.

Overhaul SQL engine

The support of SQL syntax is very limited and not well tested. First of all, we should define the feature set clearly and document it. Second, I want to support basic arithmetic functionality. Third, I want time-based aggregate on the fly from query with something like SELECT first(open) from TSLA/1Min/OHLCV GROUP BY time(5Min)

how to run docker image? thx!

Hi total noob here, spent an hour trying to figure out how to run this database.

I tried go, but could not build because of this error:

$ make configure
dep ensure
Solving failure: unable to deduce repository and source type for "code.cloudfoundry.org/bytefmt": unable to read metadata: go-import metadata not found
Makefile:17: recipe for target 'configure' failed
make: *** [configure] Error 1

I tried docker too:

$ docker run alpacamarkets/marketstore:v2.1.1
chown: /project: No such file or directory
go fmt ./...
go vet ./...
go test ./...
ok  	github.com/alpacahq/marketstore/SQLParser	3.473s
?   	github.com/alpacahq/marketstore/SQLParser/parser	[no test files]
ok  	github.com/alpacahq/marketstore/catalog	0.087s
?   	github.com/alpacahq/marketstore/cmd/marketstore	[no test files]
?   	github.com/alpacahq/marketstore/cmd/tools/integritycheck	[no test files]
?   	github.com/alpacahq/marketstore/cmd/tools/mkts	[no test files]
?   	github.com/alpacahq/marketstore/cmd/tools/mkts/csvreader	[no test files]
?   	github.com/alpacahq/marketstore/cmd/tools/walDebugger	[no test files]
?   	github.com/alpacahq/marketstore/contrib/candler	[no test files]
ok  	github.com/alpacahq/marketstore/contrib/candler/candlecandler	0.697s
ok  	github.com/alpacahq/marketstore/contrib/candler/tickcandler	0.095s
ok  	github.com/alpacahq/marketstore/contrib/gdaxfeeder	0.011s
?   	github.com/alpacahq/marketstore/contrib/ondiskagg	[no test files]
ok  	github.com/alpacahq/marketstore/contrib/ondiskagg/aggtrigger	0.100s
ok  	github.com/alpacahq/marketstore/contrib/ondiskagg/calendar	0.040s
ok  	github.com/alpacahq/marketstore/contrib/slait	0.045s
ok  	github.com/alpacahq/marketstore/executor	5.266s
ok  	github.com/alpacahq/marketstore/executor/buffile	0.027s
?   	github.com/alpacahq/marketstore/executor/readhint	[no test files]
ok  	github.com/alpacahq/marketstore/frontend	2.122s
?   	github.com/alpacahq/marketstore/frontend/client	[no test files]
ok  	github.com/alpacahq/marketstore/planner	0.070s
ok  	github.com/alpacahq/marketstore/plugins	1.575s
?   	github.com/alpacahq/marketstore/plugins/bgworker	[no test files]
ok  	github.com/alpacahq/marketstore/plugins/trigger	0.045s
?   	github.com/alpacahq/marketstore/uda	[no test files]
?   	github.com/alpacahq/marketstore/uda/avg	[no test files]
?   	github.com/alpacahq/marketstore/uda/count	[no test files]
?   	github.com/alpacahq/marketstore/uda/max	[no test files]
?   	github.com/alpacahq/marketstore/uda/min	[no test files]
ok  	github.com/alpacahq/marketstore/utils	0.072s
ok  	github.com/alpacahq/marketstore/utils/functions	0.059s
ok  	github.com/alpacahq/marketstore/utils/io	0.008s
?   	github.com/alpacahq/marketstore/utils/log	[no test files]
ok  	github.com/alpacahq/marketstore/utils/rpc/msgpack2	0.005s
?   	github.com/alpacahq/marketstore/utils/stats	[no test files]
?   	github.com/alpacahq/marketstore/utils/test	[no test files]

Is there documentation on how to run?
Thanks for your time!
I really want to try this database out, but so far it's so difficult to setup. (Mainly because I'm a noob at docker and go...)

Partial candle query in history

If you are querying latest 1D candles aggregated from 1Min, you will be able to get partially aggregated candle only for the last one. We should be able to query partial 1D candle even for history, just by saying end_dt='2017-07-20 10:00' to get the 1D candle grouping 1Min candle up to the end.

Questions and Thoughts about TimeBucketKey

Hi,

I've been trying to understand the mechanics of the TimeBucketKey concept how that overlaps/relates to using the custom SQL. Was curious about the intended capabilities for it going forward.

If I'm understanding the code correctly, it appears to me that the category keys of the time buckets are tied to the directory structure MarketStore uses on-disk. By extension, it seems to assume there are exactly 3 category keys? Perhaps I'm just misreading.

I raise this, because such limitations would appear to complicate adding support for multiple data vendors for the same symbol/timeframe? (eg #111)

One thought I had to get around this would be to put a database "in front", so for example, if I request the IEX:TSLA symbol, then it does a lookup to determine the unique key used on-disk, and the directory structure could remain 3-levels deep without breaking existing stores.

(I'm using : which seems to me like the most logic choice, although I realize it's currently taken as a delimeter. I'm not sure if there's any flexibility in changing the existing spec.)

The second question revolves around supporting multiple attribute groups for the same query. Just thinking out loud here, but for example, if I wanted to request TSLA/1D/OHLCV,MACD(12,26,9) and have it come back as a single dataframe, is that a desired feature for the future? [the TA could be done on-demand or read from disk]. Something like this could also be done on the client (python) side, if that seems more appropriate.

Would love to hear your guys thoughts! Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.