Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoSign in
Socket

order-book

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

order-book - pypi Package Compare versions

Comparing version
0.3.2
to
0.4.0
+4
-0
CHANGES.md
## Changelog
### 0.4.0 (2021-09-16)
* Feature: changes to code and setup.py to enable compiling on windows
* Feature: add from_type/to_type kwargs to the to_dict methods, allowing for type conversion when creating the dictionary
### 0.3.2 (2021-09-04)

@@ -4,0 +8,0 @@ * Bugfix: depth was incorrectly ignored when converting sorteddict to python dict

Metadata-Version: 2.1
Name: order-book
Version: 0.3.2
Version: 0.4.0
Summary: A fast orderbook implementation, in C, for Python

@@ -130,2 +130,6 @@ Home-page: https://github.com/bmoscon/orderbook

### 0.4.0 (2021-09-16)
* Feature: changes to code and setup.py to enable compiling on windows
* Feature: add from_type/to_type kwargs to the to_dict methods, allowing for type conversion when creating the dictionary
### 0.3.2 (2021-09-04)

@@ -132,0 +136,0 @@ * Bugfix: depth was incorrectly ignored when converting sorteddict to python dict

+36
-36

@@ -110,11 +110,11 @@ /*

/* Orderbook methods */
PyObject* Orderbook_todict(const Orderbook *self, PyObject *Py_UNUSED(ignored))
PyObject* Orderbook_todict(const Orderbook *self, PyObject *unused, PyObject *kwargs)
{
PyObject *ret = PyDict_New();
if (__builtin_expect(!ret, 0)) {
if (EXPECT(!ret, 0)) {
return NULL;
}
PyObject *bids = SortedDict_todict(self->bids, NULL);
if (__builtin_expect(!bids, 0)) {
PyObject *bids = SortedDict_todict(self->bids, unused, kwargs);
if (EXPECT(!bids, 0)) {
Py_DECREF(ret);

@@ -124,4 +124,4 @@ return NULL;

PyObject *asks = SortedDict_todict(self->asks, NULL);
if (__builtin_expect(!asks, 0)) {
PyObject *asks = SortedDict_todict(self->asks, unused, kwargs);
if (EXPECT(!asks, 0)) {
Py_DECREF(bids);

@@ -132,3 +132,3 @@ Py_DECREF(ret);

if (__builtin_expect(PyDict_SetItemString(ret, "bid", bids) < 0, 0)) {
if (EXPECT(PyDict_SetItemString(ret, "bid", bids) < 0, 0)) {
Py_DECREF(asks);

@@ -140,3 +140,3 @@ Py_DECREF(bids);

if (__builtin_expect(PyDict_SetItemString(ret, "ask", asks) < 0, 0)) {
if (EXPECT(PyDict_SetItemString(ret, "ask", asks) < 0, 0)) {
Py_DECREF(asks);

@@ -156,3 +156,3 @@ Py_DECREF(bids);

{
if (__builtin_expect(self->checksum == INVALID_CHECKSUM_FORMAT, 0)) {
if (EXPECT(self->checksum == INVALID_CHECKSUM_FORMAT, 0)) {
PyErr_SetString(PyExc_ValueError, "no checksum format specified");

@@ -162,7 +162,7 @@ return NULL;

if (__builtin_expect(update_keys(self->bids), 0)) {
if (EXPECT(update_keys(self->bids), 0)) {
return NULL;
}
if (__builtin_expect(update_keys(self->asks), 0)) {
if (EXPECT(update_keys(self->asks), 0)) {
return NULL;

@@ -186,3 +186,3 @@ }

{
if (__builtin_expect(!PyUnicode_Check(key), 0)) {
if (EXPECT(!PyUnicode_Check(key), 0)) {
PyErr_SetString(PyExc_ValueError, "key must one of bid/ask");

@@ -193,3 +193,3 @@ return NULL;

PyObject *str = PyUnicode_AsEncodedString(key, "UTF-8", "strict");
if (__builtin_expect(!str, 0)) {
if (EXPECT(!str, 0)) {
return NULL;

@@ -217,3 +217,3 @@ }

{
if (__builtin_expect(!PyUnicode_Check(key), 0)) {
if (EXPECT(!PyUnicode_Check(key), 0)) {
PyErr_SetString(PyExc_ValueError, "key must one of bid/ask");

@@ -224,3 +224,3 @@ return -1;

PyObject *str = PyUnicode_AsEncodedString(key, "UTF-8", "strict");
if (__builtin_expect(!str, 0)) {
if (EXPECT(!str, 0)) {
return -1;

@@ -232,3 +232,3 @@ }

if (__builtin_expect(key_int == INVALID_SIDE, 0)) {
if (EXPECT(key_int == INVALID_SIDE, 0)) {
PyErr_SetString(PyExc_ValueError, "key must one of bid/ask");

@@ -238,3 +238,3 @@ return -1;

if (__builtin_expect(!value, 0)) {
if (EXPECT(!value, 0)) {
PyErr_SetString(PyExc_ValueError, "cannot delete");

@@ -244,3 +244,3 @@ return -1;

if (__builtin_expect(!PyDict_Check(value), 0)) {
if (EXPECT(!PyDict_Check(value), 0)) {
PyErr_SetString(PyExc_ValueError, "value must be a dict");

@@ -251,3 +251,3 @@ return -1;

PyObject *copy = PyDict_Copy(value);
if (__builtin_expect(!copy, 0)) {
if (EXPECT(!copy, 0)) {
return -1;

@@ -308,3 +308,3 @@ }

PyObject *repr = PyObject_Str(pydata);
if (__builtin_expect(!repr, 0)) {
if (EXPECT(!repr, 0)) {
return -1;

@@ -315,3 +315,3 @@ }

Py_DECREF(repr);
if (__builtin_expect(!str, 0)) {
if (EXPECT(!str, 0)) {
return -1;

@@ -321,3 +321,3 @@ }

const char *string = PyBytes_AS_STRING(str);
if (__builtin_expect(!string, 0)) {
if (EXPECT(!string, 0)) {
Py_DECREF(str);

@@ -354,7 +354,7 @@ return -1;

if (__builtin_expect(kraken_string_builder(price, data, pos), 0)) {
if (EXPECT(kraken_string_builder(price, data, pos), 0)) {
return -1;
}
if (__builtin_expect(kraken_string_builder(size, data, pos), 0)) {
if (EXPECT(kraken_string_builder(size, data, pos), 0)) {
return -1;

@@ -370,3 +370,3 @@ }

{
if (__builtin_expect(ob->max_depth && ob->max_depth < 10, 0)) {
if (EXPECT(ob->max_depth && ob->max_depth < 10, 0)) {
PyErr_SetString(PyExc_ValueError, "Max depth is less than minimum number of levels for Kraken checksum");

@@ -379,3 +379,3 @@ return NULL;

if (__builtin_expect(bids_size < 10 || asks_size < 10, 0)) {
if (EXPECT(bids_size < 10 || asks_size < 10, 0)) {
PyErr_SetString(PyExc_ValueError, "Depth is less than minimum number of levels for Kraken checksum");

@@ -386,7 +386,7 @@ return NULL;

int pos = 0;
if (__builtin_expect(kraken_populate_side(ob->asks, ob->checksum_buffer, &pos), 0)) {
if (EXPECT(kraken_populate_side(ob->asks, ob->checksum_buffer, &pos), 0)) {
return NULL;
}
if (__builtin_expect(kraken_populate_side(ob->bids, ob->checksum_buffer, &pos), 0)) {
if (EXPECT(kraken_populate_side(ob->bids, ob->checksum_buffer, &pos), 0)) {
return NULL;

@@ -403,3 +403,3 @@ }

PyObject *repr = PyObject_Str(pydata);
if (__builtin_expect(!repr, 0)) {
if (EXPECT(!repr, 0)) {
return -1;

@@ -410,3 +410,3 @@ }

Py_DECREF(repr);
if (__builtin_expect(!str, 0)) {
if (EXPECT(!str, 0)) {
return -1;

@@ -416,3 +416,3 @@ }

const char *string = PyBytes_AS_STRING(str);
if (__builtin_expect(!string, 0)) {
if (EXPECT(!string, 0)) {
Py_DECREF(str);

@@ -434,3 +434,3 @@ return -1;

{
if (__builtin_expect(ob->max_depth && ob->max_depth < depth, 0)) {
if (EXPECT(ob->max_depth && ob->max_depth < depth, 0)) {
PyErr_SetString(PyExc_ValueError, "Max depth is less than minimum number of levels for checksum");

@@ -451,7 +451,7 @@ return NULL;

if (__builtin_expect(ftx_string_builder(price, ob->checksum_buffer, &pos), 0)) {
if (EXPECT(ftx_string_builder(price, ob->checksum_buffer, &pos), 0)) {
return NULL;
}
if (__builtin_expect(ftx_string_builder(size, ob->checksum_buffer, &pos), 0)) {
if (EXPECT(ftx_string_builder(size, ob->checksum_buffer, &pos), 0)) {
return NULL;

@@ -465,7 +465,7 @@ }

if (__builtin_expect(ftx_string_builder(price, ob->checksum_buffer, &pos), 0)) {
if (EXPECT(ftx_string_builder(price, ob->checksum_buffer, &pos), 0)) {
return NULL;
}
if (__builtin_expect(ftx_string_builder(size, ob->checksum_buffer, &pos), 0)) {
if (EXPECT(ftx_string_builder(size, ob->checksum_buffer, &pos), 0)) {
return NULL;

@@ -472,0 +472,0 @@ }

@@ -44,3 +44,3 @@ /*

PyObject* Orderbook_todict(const Orderbook *self, PyObject *Py_UNUSED(ignored));
PyObject* Orderbook_todict(const Orderbook *self, PyObject *unused, PyObject *kwargs);
PyObject* Orderbook_checksum(const Orderbook *self, PyObject *Py_UNUSED(ignored));

@@ -62,3 +62,3 @@

{"ask", T_OBJECT_EX, offsetof(Orderbook, asks), 0, "asks"},
{"max_depth", T_INT, offsetof(Orderbook, max_depth), READONLY, "Maximum book depth"},
{"max_depth", T_INT, offsetof(Orderbook, max_depth), READONLY, "maximum book depth"},
{NULL}

@@ -70,4 +70,4 @@ };

static PyMethodDef Orderbook_methods[] = {
{"to_dict", (PyCFunction) Orderbook_todict, METH_NOARGS, "Return a python dictionary with bids and asks"},
{"checksum", (PyCFunction) Orderbook_checksum, METH_NOARGS, "Calculate checksum using top N levels"},
{"to_dict", (PyCFunction) Orderbook_todict, METH_VARARGS | METH_KEYWORDS, "return a python dictionary with bids and asks"},
{"checksum", (PyCFunction) Orderbook_checksum, METH_NOARGS, "calculate checksum using top N levels"},
{NULL}

@@ -74,0 +74,0 @@ };

@@ -45,2 +45,3 @@ /*

}
return (PyObject *) self;

@@ -164,7 +165,7 @@ }

if (__builtin_expect(!keys, 0)) {
if (EXPECT(!keys, 0)) {
return 1;
}
if (__builtin_expect(PyList_Sort(keys) < 0, 0)) {
if (EXPECT(PyList_Sort(keys) < 0, 0)) {
Py_DECREF(keys);

@@ -175,3 +176,3 @@ return 1;

if (self->ordering == DESCENDING) {
if (__builtin_expect(PyList_Reverse(keys) < 0, 0)) {
if (EXPECT(PyList_Reverse(keys) < 0, 0)) {
Py_DECREF(keys);

@@ -184,3 +185,3 @@ return 1;

Py_DECREF(keys);
if (__builtin_expect(!ret, 0)) {
if (EXPECT(!ret, 0)) {
return 1;

@@ -202,3 +203,3 @@ }

{
if (__builtin_expect(update_keys(self), 0)) {
if (EXPECT(update_keys(self), 0)) {
return NULL;

@@ -222,7 +223,7 @@ }

long i = PyLong_AsLong(index);
if (__builtin_expect(PyErr_Occurred() != NULL, 0)) {
if (EXPECT(PyErr_Occurred() != NULL, 0)) {
return NULL;
}
if (__builtin_expect(update_keys(self), 0)) {
if (EXPECT(update_keys(self), 0)) {
return NULL;

@@ -233,3 +234,3 @@ }

PyObject *key = PySequence_GetItem(self->keys, i);
if (__builtin_expect(!key, 0)) {
if (EXPECT(!key, 0)) {
return NULL;

@@ -240,3 +241,3 @@ }

PyObject *value = PyDict_GetItem(self->data, key);
if (__builtin_expect(!value, 0)) {
if (EXPECT(!value, 0)) {
Py_DECREF(key);

@@ -247,3 +248,3 @@ return value;

PyObject *ret = PyTuple_New(2);
if (__builtin_expect(!ret, 0)) {
if (EXPECT(!ret, 0)) {
Py_DECREF(key);

@@ -261,10 +262,19 @@ return NULL;

PyObject* SortedDict_todict(SortedDict *self, PyObject *Py_UNUSED(ignored))
PyObject* SortedDict_todict(SortedDict *self, PyObject *unused, PyObject *kwargs)
{
static char *kwlist[] = {"from_type", "to_type", NULL};
PyObject *from = NULL;
PyObject *to = NULL;
if (!PyArg_ParseTupleAndKeywords(unused, kwargs, "|$OO", kwlist, &from, &to)) {
return NULL;
}
PyObject *ret = PyDict_New();
if (__builtin_expect(!ret, 0)) {
if (EXPECT(!ret, 0)) {
return NULL;
}
if (__builtin_expect(update_keys(self), 0)) {
if (EXPECT(update_keys(self), 0)) {
Py_DECREF(ret);
return NULL;

@@ -278,6 +288,60 @@ }

bool free_key, free_value;
for(int i = 0; i < len; ++i) {
free_key = false;
free_value = false;
PyObject *key = PyTuple_GET_ITEM(self->keys, i);
PyObject *value = PyDict_GetItem(self->data, key);
if (to) {
if (!from || (from && (PyObject_IsInstance(key, from)))) {
PyObject *args = PyTuple_Pack(1, key);
if (EXPECT(!args, 0)) {
Py_DECREF(ret);
return NULL;
}
key = PyObject_CallObject(to, args);
Py_DECREF(args);
if (EXPECT(!key, 0)) {
Py_DECREF(ret);
return NULL;
}
free_key = true;
}
if (!from || (from && (PyObject_IsInstance(value, from)))) {
PyObject *args = PyTuple_Pack(1, value);
if (EXPECT(!args, 0)) {
Py_DECREF(ret);
if (free_key) {
Py_DECREF(key);
}
return NULL;
}
value = PyObject_CallObject(to, args);
Py_DECREF(args);
if (EXPECT(!value, 0)) {
Py_DECREF(ret);
if (free_key) {
Py_DECREF(key);
}
return NULL;
}
free_value = true;
}
}
PyDict_SetItem(ret, key, value);
if (free_key) {
Py_DECREF(key);
}
if (free_value) {
Py_DECREF(value);
}
}

@@ -292,3 +356,3 @@

if (self->depth) {
if (__builtin_expect(update_keys(self), 0)) {
if (EXPECT(update_keys(self), 0)) {
return NULL;

@@ -298,3 +362,3 @@ }

PyObject *delete = PySequence_GetSlice(self->keys, self->depth, PyDict_Size(self->data));
if (__builtin_expect(!delete, 0)) {
if (EXPECT(!delete, 0)) {
return NULL;

@@ -304,3 +368,3 @@ }

int len = PySequence_Length(delete);
if (__builtin_expect(len == -1, 0)) {
if (EXPECT(len == -1, 0)) {
Py_DECREF(delete);

@@ -311,3 +375,3 @@ return NULL;

for (int i = 0; i < len; ++i) {
if (__builtin_expect(PyDict_DelItem(self->data, PySequence_Fast_GET_ITEM(delete, i)) == -1, 0)) {
if (EXPECT(PyDict_DelItem(self->data, PySequence_Fast_GET_ITEM(delete, i)) == -1, 0)) {
Py_DECREF(delete);

@@ -323,3 +387,3 @@ return NULL;

if (__builtin_expect(update_keys(self), 0)) {
if (EXPECT(update_keys(self), 0)) {
return NULL;

@@ -352,3 +416,3 @@ }

if (__builtin_expect(!PyErr_Occurred(), 0)) {
if (EXPECT(!PyErr_Occurred(), 0)) {
PyErr_SetString(PyExc_KeyError, "key does not exist");

@@ -367,5 +431,5 @@ }

if (__builtin_expect(ret == -1, 0)) {
if (EXPECT(ret == -1, 0)) {
return ret;
} else if (__builtin_expect(self->truncate && !SortedDict_truncate(self, NULL), 0)) {
} else if (EXPECT(self->truncate && !SortedDict_truncate(self, NULL), 0)) {
return -1;

@@ -393,3 +457,3 @@ }

if (__builtin_expect(update_keys(self), 0)) {
if (EXPECT(update_keys(self), 0)) {
return NULL;

@@ -399,3 +463,3 @@ }

Py_ssize_t size = PySequence_Fast_GET_SIZE(self->keys);
if (__builtin_expect(size == 0, 0)){
if (EXPECT(size == 0, 0)){
return NULL;

@@ -402,0 +466,0 @@ }

@@ -44,3 +44,3 @@ /*

PyObject* SortedDict_index(SortedDict *self, PyObject *index);
PyObject* SortedDict_todict(SortedDict *self, PyObject *Py_UNUSED(ignored));
PyObject* SortedDict_todict(SortedDict *self, PyObject *unused, PyObject *kwargs);
PyObject* SortedDict_truncate(SortedDict *self, PyObject *Py_UNUSED(ignored));

@@ -69,5 +69,5 @@

{"keys", (PyCFunction) SortedDict_keys, METH_NOARGS, "return a list of keys in the sorted dictionary"},
{"index", (PyCFunction) SortedDict_index, METH_O, "Return a key, value tuple at index N"},
{"truncate", (PyCFunction) SortedDict_truncate, METH_NOARGS, "Truncate to length max_depth"},
{"to_dict", (PyCFunction) SortedDict_todict, METH_NOARGS, "return a python dictionary, sorted by keys"},
{"index", (PyCFunction) SortedDict_index, METH_O, "return a key, value tuple at index N"},
{"truncate", (PyCFunction) SortedDict_truncate, METH_NOARGS, "truncate to length max_depth"},
{"to_dict", (PyCFunction) SortedDict_todict, METH_VARARGS | METH_KEYWORDS, "return a python dictionary, sorted by keys"},
{NULL}

@@ -74,0 +74,0 @@ };

@@ -10,2 +10,8 @@ /*

#if defined(_WIN32)
#define EXPECT(EXPR, VAL) (EXPR)
#else
#define EXPECT(EXPR, VAL) __builtin_expect((EXPR), (VAL))
#endif
enum side_e {

@@ -12,0 +18,0 @@ BID,

Metadata-Version: 2.1
Name: order_book
Version: 0.3.2
Version: 0.4.0
Summary: A fast orderbook implementation, in C, for Python

@@ -130,2 +130,6 @@ Home-page: https://github.com/bmoscon/orderbook

### 0.4.0 (2021-09-16)
* Feature: changes to code and setup.py to enable compiling on windows
* Feature: add from_type/to_type kwargs to the to_dict methods, allowing for type conversion when creating the dictionary
### 0.3.2 (2021-09-04)

@@ -132,0 +136,0 @@ * Bugfix: depth was incorrectly ignored when converting sorteddict to python dict

@@ -8,2 +8,3 @@ '''

import glob
import os
from os import path

@@ -16,3 +17,4 @@ from setuptools import setup, Extension, find_packages

sources = glob.glob('orderbook/*.c')
orderbook = Extension('order_book', sources=sources, extra_compile_args=["-O3"])
optimize_arg = "/O2" if os.name == "nt" else "-O3"
orderbook = Extension('order_book', sources=sources, extra_compile_args=[optimize_arg])

@@ -38,3 +40,3 @@

name='order_book',
version='0.3.2',
version='0.4.0',
author="Bryant Moscon",

@@ -41,0 +43,0 @@ author_email="bmoscon@gmail.com",