Skip to content

Commit 5ed1574

Browse files
support for separate product/reference data accounts from price accounts, including support for alternate symbol indentifiers
1 parent cf6e30c commit 5ed1574

35 files changed

+2518
-1126
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread")
2222
# pyth client API library
2323
#
2424
set( PC_SRC
25+
pc/attr_id.cpp;
2526
pc/capture.cpp;
2627
pc/key_pair.cpp;
2728
pc/key_store.cpp;
@@ -38,6 +39,7 @@ set( PC_SRC
3839
)
3940

4041
set( PC_HDR
42+
pc/attr_id.hpp;
4143
pc/capture.hpp;
4244
pc/dbl_list.hpp;
4345
pc/error.hpp;

dashboard/dashboard.js

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ class Prices
55
this.req = [];
66
this.sub = [];
77
this.reuse = [];
8-
this.symbols = {};
98
this.fact = [ 0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8 ];
109
}
1110
send( msg, callback ) {
@@ -33,24 +32,30 @@ class Prices
3332
cell.textContent = txt;
3433
cell.style.color = color;
3534
}
36-
on_price( sym, msg ) {
35+
on_price( pxa, msg ) {
3736
let tab = document.getElementById( "prices" );
38-
let row = tab.rows[sym.idx];
37+
let row = tab.rows[pxa.idx];
3938
let res = msg.params.result;
4039
let col = 0;
41-
let expo = -sym.price_exponent;
40+
let expo = -pxa.price_exponent;
4241
let px = res.price * this.fact[expo];
4342
let conf = res.conf * this.fact[expo];
4443
let color = 'cornsilk';
4544
if ( res.status == 'unknown' ) {
4645
color = '#c0392b';
4746
}
4847
row.cells[col++].style.color = color;
48+
row.cells[col++].style.color = color;
49+
row.cells[col++].style.color = color;
50+
row.cells[col++].style.color = color;
4951
this.draw_cell( row.cells[col++], px.toFixed(expo), color );
5052
this.draw_cell( row.cells[col++], conf.toFixed(expo), color );
5153
this.draw_cell( row.cells[col++], res.status, color );
5254
this.draw_cell( row.cells[col++], res.valid_slot, color );
5355
this.draw_cell( row.cells[col++], res.pub_slot, color );
56+
row.cells[col++].style.color = color;
57+
row.cells[col++].style.color = color;
58+
row.cells[col++].style.color = color;
5459
}
5560
get_price( sym, msg ) {
5661
let sub_id = msg.result.subscription;
@@ -59,30 +64,41 @@ class Prices
5964
}
6065
this.sub[sub_id] = this.on_price.bind( this, sym );
6166
}
62-
get_symbols( res ) {
63-
this.symbols = [];
67+
get_title( att, title ) {
68+
let td = document.createElement( 'TD' )
69+
td.textContent = att[title]
70+
td.style['text-align'] = 'left';
71+
return td;
72+
}
73+
get_product_list( res ) {
6474
let tab = document.getElementById( "prices" );
6575
for( let i = 0; i != res.result.length; ++i ) {
6676
let sym = res.result[i];
67-
let row = tab.insertRow(-1);
68-
let sym_td = document.createElement( 'TD' )
69-
sym_td.textContent = sym['symbol']
70-
sym_td.style['text-align'] = 'left';
71-
row.appendChild( sym_td );
72-
row.appendChild( document.createElement( 'TD' ) );
73-
row.appendChild( document.createElement( 'TD' ) );
74-
row.appendChild( document.createElement( 'TD' ) );
75-
row.appendChild( document.createElement( 'TD' ) );
76-
row.appendChild( document.createElement( 'TD' ) );
77-
let msg = {
78-
'method' : 'subscribe_price',
79-
'params' : {
80-
'symbol' : sym['symbol'],
81-
'price_type' : sym['price_type']
82-
}
83-
};
84-
sym.idx = i+1;
85-
this.send( msg, this.get_price.bind( this, sym ) );
77+
let att = sym['attr_dict']
78+
for( let j=0; j != sym.price.length; ++j ) {
79+
let pxa = sym.price[j];
80+
let row = tab.insertRow(-1);
81+
row.appendChild( this.get_title( att, 'asset_type') );
82+
row.appendChild( this.get_title( att, 'country') );
83+
row.appendChild( this.get_title( att, 'symbol') );
84+
row.appendChild( this.get_title( pxa, 'price_type') );
85+
row.appendChild( document.createElement( 'TD' ) );
86+
row.appendChild( document.createElement( 'TD' ) );
87+
row.appendChild( document.createElement( 'TD' ) );
88+
row.appendChild( document.createElement( 'TD' ) );
89+
row.appendChild( document.createElement( 'TD' ) );
90+
row.appendChild( this.get_title( att, 'tenor') );
91+
row.appendChild( this.get_title( att, 'quote_currency') );
92+
row.appendChild( this.get_title( att, 'description') );
93+
let msg = {
94+
'method' : 'subscribe_price',
95+
'params' : {
96+
'account' : pxa['account']
97+
}
98+
};
99+
pxa.idx = i+1;
100+
this.send( msg, this.get_price.bind( this, pxa ) );
101+
}
86102
}
87103
}
88104
}
@@ -95,8 +111,8 @@ window.onload = function() {
95111
ws.onopen = function(e) {
96112
let n = document.getElementById('notify');
97113
n.textContent = 'connected';
98-
px.send( { 'method': 'get_symbol_list' },
99-
px.get_symbols.bind( px ) );
114+
px.send( { 'method': 'get_product_list' },
115+
px.get_product_list.bind( px ) );
100116
};
101117
ws.onclose = function(e) {
102118
let n = document.getElementById('notify');

dashboard/index.html

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,20 @@ <h2>pyth dashboard
1010
<P>
1111
<div id="prices_div">
1212
<table id="prices">
13-
<tr><th width=150px>symbol</th>
13+
<tr>
14+
<th>atype</th>
15+
<th>cnt</th>
16+
<th width=100px>symbol</th>
17+
<th>ptype</th>
1418
<th width=100px>price</th>
1519
<th width=100px>conf</th>
16-
<th width=100px>status</th>
17-
<th width=100px>valid_slot</th>
18-
<th width=100px>pub_slot</th>
20+
<th width=80>status</th>
21+
<th>valid_slot</th>
22+
<th>pub_slot</th>
23+
<th>tenor</th>
24+
<th>curr</th>
25+
<th>description</th>
26+
</tr>
1927
</table>
2028
</div>
2129
<div id="notify"></div>

doc/websocket_api.md

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,89 @@
11
# pyth-client websocket API
22
The pythd daemon supports a websocket interface based on the jsoni-rpc 2.0 standard. Methods include:
33

4-
- [get_symbol_list](#get_symbol_list)
4+
- [get_product_list](#get_product_list)
55
- [update_price](#update_price)
66
- [subscribe_price](#subscribe_price)
77
- [subscribe_price_sched](#subscribe_price_sched)
88

99
Batch requests are processed in the order the requests appear within the batch.
1010

11-
## get_symbol_list
11+
## get_product_list
1212

1313
Get list of available symbols and associated meta data.
1414

1515
Request looks like:
1616
```
1717
{
1818
"jsonrpc": "2.0",
19-
"method": "get_symbol_list",
19+
"method": "get_product_list",
2020
"id" : 1
2121
}
2222
```
2323

24-
A successful response looks like:
24+
A successful response looks something like:
2525
```
2626
{
27-
"jsonrpc": "2.0",
28-
"result" : [
27+
"jsonrpc": "2.0",
28+
"result": [
29+
{
30+
"account": "9F6eBgAfktth93C9zmtKDXFXNjZkq6JwJR56VPKqWmJm",
31+
"attr_dict": {
32+
"symbol": "SYMBOL1/USD",
33+
"asset_type": "Equity",
34+
"country": "USA",
35+
"description": "pyth example product #1",
36+
"quote_currency": "USD",
37+
"tenor": "Spot",
38+
"cms_symbol": "SYMBOL1",
39+
"cqs_symbol": "SYMBOL1",
40+
"nasdaq_symbol": "SYMBOL1"
41+
},
42+
"price": [
2943
{
30-
"symbol" : "US.EQ.SYMBOL1",
31-
"price_exponent" : -4,
32-
"price_type" : "price"
33-
},
44+
"account": "CrZCEEt3awgkGLnVbsv45Pp4aLhr7fZfZr3ubzrbNXaq",
45+
"price_exponent": -4,
46+
"price_type": "price"
47+
}
48+
]
49+
},
50+
{
51+
"account": "HCFaDYyz1ajS57HfCaaqzA1cZSaa2oEccQejbHaaofd4",
52+
"attr_dict": {
53+
"symbol": "SYMBOL2/USD",
54+
"asset_type": "Equity",
55+
"country": "USA",
56+
"description": "pyth example product #2",
57+
"quote_currency": "USD",
58+
"tenor": "Spot",
59+
"cms_symbol": "SYMBOL2",
60+
"cqs_symbol": "SYMBOL2",
61+
"nasdaq_symbol": "SYMBOL2"
62+
},
63+
"price": [
3464
{
35-
"symbol" : "US.EQ.SYMBOL2",
36-
"price_exponent" : -6,
37-
"price_type" : "price"
65+
"account": "7FUsKvvtN5rB1fgYFWZLo5DLcqHTTeu63bUPThYT6MiS",
66+
"price_exponent": -4,
67+
"price_type": "price"
3868
}
39-
],
40-
"id" : 1
69+
]
70+
}
71+
],
72+
"id": null
4173
}
42-
4374
```
4475

4576
## update_price
4677

4778
Update component price of some symbol using the publishing key of the pythd daemon.
4879

49-
Request looks like:
80+
Request includes the pricing account from the get_product_list output and looks something like:
5081
```
5182
{
5283
"jsonrpc": "2.0",
5384
"method": "update_price",
5485
"params" : {
55-
"symbol": "US.EQ.SYMBOL1",
56-
"price_type": "price",
86+
"account": "CrZCEEt3awgkGLnVbsv45Pp4aLhr7fZfZr3ubzrbNXaq",
5787
"price" : 42002,
5888
"conf" : 3,
5989
"status": "trading"
@@ -84,8 +114,7 @@ Request looks like:
84114
"jsonrpc": "2.0",
85115
"method": "subscribe_price",
86116
"params" : {
87-
"symbol" : "US.EQ.SYMBOL1",
88-
"price_type" : "price"
117+
"account": "CrZCEEt3awgkGLnVbsv45Pp4aLhr7fZfZr3ubzrbNXaq",
89118
},
90119
"id" : 1
91120
}
@@ -138,8 +167,7 @@ Request looks like:
138167
"jsonrpc": "2.0",
139168
"method": "subscribe_price_sched",
140169
"params" : {
141-
"symbol" : "US.EQ.SYMBOL1",
142-
"price_type" : "price"
170+
"account": "CrZCEEt3awgkGLnVbsv45Pp4aLhr7fZfZr3ubzrbNXaq",
143171
},
144172
"id" : 1
145173
}

0 commit comments

Comments
 (0)