Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New demo market #2128

Merged
merged 12 commits into from
Mar 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmake/re2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ if(WIN32)
# ************************************
# TKP NOTE: THIS SECTION IS CUSTOM
# ************************************
elseif(APPLE)
elseif(APPLE OR (${CMAKE_SYSTEM_NAME} MATCHES "Emscripten"))
add_definitions(-DTARGET_OS_OSX=1)
# assume built-in pthreads on MacOS
set(CMAKE_THREAD_LIBS_INIT "-lpthread")
Expand Down
8 changes: 8 additions & 0 deletions cpp/perspective/src/cpp/aggspec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ t_aggspec::agg_str() const {
case AGGTYPE_LAST_VALUE: {
return "last_value";
}
case AGGTYPE_MAX: {
return "max";
}
case AGGTYPE_MIN: {
return "min";
}
case AGGTYPE_HIGH_WATER_MARK: {
return "high_water_mark";
}
Expand Down Expand Up @@ -320,6 +326,8 @@ t_aggspec::get_output_specs(const t_schema& schema) const {
case AGGTYPE_LAST_MINUS_FIRST:
case AGGTYPE_OR:
case AGGTYPE_LAST_VALUE:
case AGGTYPE_MAX:
case AGGTYPE_MIN:
case AGGTYPE_HIGH_WATER_MARK:
case AGGTYPE_LOW_WATER_MARK:
case AGGTYPE_HIGH_MINUS_LOW:
Expand Down
4 changes: 4 additions & 0 deletions cpp/perspective/src/cpp/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,10 @@ str_to_aggtype(const std::string& str) {
return t_aggtype::AGGTYPE_OR;
} else if (str == "last" || str == "last_value") {
return t_aggtype::AGGTYPE_LAST_VALUE;
} else if (str == "max") {
return t_aggtype::AGGTYPE_MAX;
} else if (str == "min") {
return t_aggtype::AGGTYPE_MIN;
} else if (str == "high" || str == "high_water_mark") {
return t_aggtype::AGGTYPE_HIGH_WATER_MARK;
} else if (str == "low" || str == "low_water_mark") {
Expand Down
2 changes: 2 additions & 0 deletions cpp/perspective/src/cpp/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ t_config::setup(const std::vector<std::string>& detail_columns,
case AGGTYPE_JOIN:
case AGGTYPE_DOMINANT:
case AGGTYPE_PY_AGG:
case AGGTYPE_MIN:
case AGGTYPE_MAX:
case AGGTYPE_SUM_NOT_NULL:
case AGGTYPE_SUM_ABS:
case AGGTYPE_ABS_SUM:
Expand Down
2 changes: 2 additions & 0 deletions cpp/perspective/src/cpp/extract_aggregate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ extract_aggregate(const t_aggspec& aggspec, const t_column* aggcol,
case AGGTYPE_LAST_BY_INDEX:
case AGGTYPE_LAST_VALUE:
case AGGTYPE_LAST_MINUS_FIRST:
case AGGTYPE_MAX:
case AGGTYPE_MIN:
case AGGTYPE_HIGH_WATER_MARK:
case AGGTYPE_LOW_WATER_MARK:
case AGGTYPE_HIGH_MINUS_LOW:
Expand Down
28 changes: 28 additions & 0 deletions cpp/perspective/src/cpp/sparse_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1298,6 +1298,34 @@ t_stree::update_agg_table(t_uindex nidx, t_agg_update_info& info,
dst->set_scalar(dst_ridx, mknone());
}
} break;
case AGGTYPE_MAX: {
t_tscalar src_scalar = src->get_scalar(src_ridx);
t_tscalar dst_scalar = dst->get_scalar(dst_ridx);
old_value.set(dst_scalar);
// new_value.set(std::max(dst_scalar, src_scalar));
// if (is_expr || old_value.is_nan() || new_value.is_nan() || new_value > old_value) {
auto pkeys = get_pkeys(nidx);
std::vector<double> values;
read_column_from_gstate(gstate, expression_master_table,
spec.get_dependencies()[0].name(), pkeys, values, true);
new_value.set(*std::max_element(values.begin(), values.end()));
// }
dst->set_scalar(dst_ridx, new_value);
} break;
case AGGTYPE_MIN: {
t_tscalar src_scalar = src->get_scalar(src_ridx);
t_tscalar dst_scalar = dst->get_scalar(dst_ridx);
old_value.set(dst_scalar);
// new_value.set(std::max(dst_scalar, src_scalar));
// if (is_expr || old_value.is_nan() || new_value.is_nan() || new_value < old_value) {
auto pkeys = get_pkeys(nidx);
std::vector<double> values;
read_column_from_gstate(gstate, expression_master_table,
spec.get_dependencies()[0].name(), pkeys, values, true);
new_value.set(*std::min_element(values.begin(), values.end()));
// }
dst->set_scalar(dst_ridx, new_value);
} break;
case AGGTYPE_HIGH_WATER_MARK: {
t_tscalar src_scalar = src->get_scalar(src_ridx);
t_tscalar dst_scalar = dst->get_scalar(dst_ridx);
Expand Down
2 changes: 2 additions & 0 deletions cpp/perspective/src/include/perspective/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ enum t_aggtype {
AGGTYPE_LAST_VALUE,
AGGTYPE_HIGH_WATER_MARK,
AGGTYPE_LOW_WATER_MARK,
AGGTYPE_MAX,
AGGTYPE_MIN,
AGGTYPE_HIGH_MINUS_LOW,
AGGTYPE_UDF_COMBINER,
AGGTYPE_UDF_REDUCER,
Expand Down
55 changes: 55 additions & 0 deletions examples/blocks/src/market/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@

A simple market simulation implemented in Perspective, designed to be simple
rather than accurate. The simulation proceeds in steps:

1) Insert a batch of random orders in a range around the market's bid/ask
spread. For each side of the order book, we can calculate the best open price
by querying the orders `Table` using the `"max"` or `"min"` aggregates
(respectively).

```json
{
columns: ["price"],
group_by: ["security"],
aggregates: { price: "max" },
filter: [
["side", "==", "buy"],
["status", "==", "open"],
],
}
```

1) Clear any matched orders in the `Table`. To match orders, we fetch all open
orders on both sides which are outside of the best price, then update an
_equal_ number of both `"buy"` and `"sell"` side orders to `"closed"`. The
`sort` field guarantees that orders are closed in best, then oldest, order.

```json
{
columns: ["id"],
filter: [
["side", "==", "buy"],
["status", "==", "open"],
["price", ">", price],
],
sort: [
["price", "desc"],
["timestamp", "asc"],
],
}
```

3) Expire any elapsed orders which are still `"open"` by fetching orders older
than the expiration ID and update thair status' to `"expired"`.

```json
{
columns: ["id"],
filter: [
["status", "==", "open"],
["id", "<", 12345],
],
}
```

4) Sleep for a bit and repeat (1).
76 changes: 76 additions & 0 deletions examples/blocks/src/market/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
body {
background: #242526;
color: white;
font-family: "Roboto Mono";
touch-action: none;
}

* {
box-sizing: border-box;
}

#app {
display: flex;
flex-direction: column;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}

#header {
display: flex;
flex-wrap: wrap;
align-items: center;
}

#header a {
display: inline-flex;
}

perspective-viewer {
border-top: 1px solid #666;
flex: 1 1 auto;
}

label {
height: 32px;
font-size: 12px;
padding: 6px 0px;
margin-right: 4px;
margin-left: 14px;
margin-top: 8px;
margin-bottom: 8px;
border: 1px solid transparent;
}

img {
vertical-align: middle;
margin-left: 14px;
}

select, button {
font-family: "Roboto Mono";
font-size: 12px;
appearance: none;
background-color: transparent;
border: 1px solid #666;
border-radius: 2px;
padding: 6px 10px;
color: #f4f5f6;
cursor: pointer;
margin-right: 4px;
margin-left: 4px;
outline: none;
user-select: none;
height: 32px;
margin-top: 8px;
margin-bottom: 8px;
}

select:hover, button:hover {
color: #242526;
background-color: #f4f5f6;
border-color: #f4f5f6;
}
72 changes: 72 additions & 0 deletions examples/blocks/src/market/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html>
<head>
<meta
name="viewport"
content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<link
rel="preload"
href="/node_modules/@finos/perspective-viewer/dist/cdn/perspective_bg.wasm"
as="fetch"
type="application/wasm"
crossorigin="anonymous"
/>
<link
rel="preload"
href="/node_modules/@finos/perspective/dist/cdn/perspective.js"
as="script"
type="application/javascript"
crossorigin="anonymous"
/>
<link
rel="preload"
href="/node_modules/@finos/perspective/dist/cdn/perspective.cpp.wasm"
as="fetch"
type="application/wasm"
crossorigin="anonymous"
/>
<link
rel="preload"
href="/node_modules/@finos/perspective/dist/cdn/perspective.worker.js"
as="fetch"
type="application/javascript"
crossorigin="anonymous"
/>
<script
type="module"
src="/node_modules/@finos/perspective-viewer/dist/cdn/perspective-viewer.js"
></script>
<script
type="module"
src="/node_modules/@finos/perspective-viewer-datagrid/dist/cdn/perspective-viewer-datagrid.js"
></script>
<script
type="module"
src="/node_modules/@finos/perspective-viewer-d3fc/dist/cdn/perspective-viewer-d3fc.js"
></script>
<script type="module" src="market.js"></script>
<link rel="stylesheet" href="index.css" />
<link
rel="stylesheet"
crossorigin="anonymous"
href="/node_modules/@finos/perspective-viewer/dist/css/themes.css"
/>
</head>
<body>
<div id="app">
<div id="header">
<a href="https://perspective.finos.org">
<img
height="12"
src="https://raw.githubusercontent.com/finos/perspective/master/docs/static/svg/perspective-logo-dark.svg"
/>
</a>
<label>Market Simulation Demo</label>
<select></select>
<button>Reset</button>
</div>
<perspective-viewer theme="Pro Dark"></perspective-viewer>
</div>
</body>
</html>
Loading