pmxt 1.5.7__py3-none-any.whl → 1.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pmxt/__init__.py +19 -1
- pmxt/_server/server/bundled.js +281 -20
- pmxt/client.py +222 -2
- pmxt/models.py +68 -0
- pmxt/server_manager.py +18 -1
- {pmxt-1.5.7.dist-info → pmxt-1.6.0.dist-info}/METADATA +1 -1
- {pmxt-1.5.7.dist-info → pmxt-1.6.0.dist-info}/RECORD +14 -14
- pmxt_internal/__init__.py +1 -1
- pmxt_internal/api_client.py +1 -1
- pmxt_internal/configuration.py +1 -1
- pmxt_internal/models/market_outcome.py +4 -2
- pmxt_internal/models/unified_market.py +4 -2
- {pmxt-1.5.7.dist-info → pmxt-1.6.0.dist-info}/WHEEL +0 -0
- {pmxt-1.5.7.dist-info → pmxt-1.6.0.dist-info}/top_level.txt +0 -0
pmxt/__init__.py
CHANGED
|
@@ -33,7 +33,23 @@ from .models import (
|
|
|
33
33
|
CreateOrderParams,
|
|
34
34
|
)
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
|
|
37
|
+
# Global server management functions
|
|
38
|
+
_default_manager = ServerManager()
|
|
39
|
+
|
|
40
|
+
def stop_server():
|
|
41
|
+
"""
|
|
42
|
+
Stop the background PMXT sidecar server.
|
|
43
|
+
"""
|
|
44
|
+
_default_manager.stop()
|
|
45
|
+
|
|
46
|
+
def restart_server():
|
|
47
|
+
"""
|
|
48
|
+
Restart the background PMXT sidecar server.
|
|
49
|
+
"""
|
|
50
|
+
_default_manager.restart()
|
|
51
|
+
|
|
52
|
+
__version__ = "1.6.0"
|
|
37
53
|
__all__ = [
|
|
38
54
|
# Exchanges
|
|
39
55
|
"Polymarket",
|
|
@@ -42,6 +58,8 @@ __all__ = [
|
|
|
42
58
|
"Exchange",
|
|
43
59
|
# Server Management
|
|
44
60
|
"ServerManager",
|
|
61
|
+
"stop_server",
|
|
62
|
+
"restart_server",
|
|
45
63
|
# Data Models
|
|
46
64
|
"UnifiedMarket",
|
|
47
65
|
"MarketOutcome",
|
pmxt/_server/server/bundled.js
CHANGED
|
@@ -24494,6 +24494,227 @@ var require_BaseExchange = __commonJS({
|
|
|
24494
24494
|
return (0, math_1.getExecutionPriceDetailed)(orderBook, side, amount);
|
|
24495
24495
|
}
|
|
24496
24496
|
// ----------------------------------------------------------------------------
|
|
24497
|
+
// Filtering Methods
|
|
24498
|
+
// ----------------------------------------------------------------------------
|
|
24499
|
+
/**
|
|
24500
|
+
* Filter markets based on criteria or custom function.
|
|
24501
|
+
*
|
|
24502
|
+
* @param markets - Array of markets to filter
|
|
24503
|
+
* @param criteria - Filter criteria object, string (simple text search), or predicate function
|
|
24504
|
+
* @returns Filtered array of markets
|
|
24505
|
+
*
|
|
24506
|
+
* @example Simple text search
|
|
24507
|
+
* api.filterMarkets(markets, 'Trump')
|
|
24508
|
+
*
|
|
24509
|
+
* @example Advanced filtering
|
|
24510
|
+
* api.filterMarkets(markets, {
|
|
24511
|
+
* text: 'Trump',
|
|
24512
|
+
* searchIn: ['title', 'tags'],
|
|
24513
|
+
* volume24h: { min: 10000 },
|
|
24514
|
+
* category: 'Politics',
|
|
24515
|
+
* price: { outcome: 'yes', max: 0.5 }
|
|
24516
|
+
* })
|
|
24517
|
+
*
|
|
24518
|
+
* @example Custom predicate
|
|
24519
|
+
* api.filterMarkets(markets, m => m.liquidity > 5000 && m.yes?.price < 0.3)
|
|
24520
|
+
*/
|
|
24521
|
+
filterMarkets(markets, criteria) {
|
|
24522
|
+
if (typeof criteria === "function") {
|
|
24523
|
+
return markets.filter(criteria);
|
|
24524
|
+
}
|
|
24525
|
+
if (typeof criteria === "string") {
|
|
24526
|
+
const lowerQuery = criteria.toLowerCase();
|
|
24527
|
+
return markets.filter((m) => m.title.toLowerCase().includes(lowerQuery));
|
|
24528
|
+
}
|
|
24529
|
+
return markets.filter((market) => {
|
|
24530
|
+
if (criteria.text) {
|
|
24531
|
+
const lowerQuery = criteria.text.toLowerCase();
|
|
24532
|
+
const searchIn = criteria.searchIn || ["title"];
|
|
24533
|
+
let textMatch = false;
|
|
24534
|
+
for (const field of searchIn) {
|
|
24535
|
+
if (field === "title" && market.title?.toLowerCase().includes(lowerQuery)) {
|
|
24536
|
+
textMatch = true;
|
|
24537
|
+
break;
|
|
24538
|
+
}
|
|
24539
|
+
if (field === "description" && market.description?.toLowerCase().includes(lowerQuery)) {
|
|
24540
|
+
textMatch = true;
|
|
24541
|
+
break;
|
|
24542
|
+
}
|
|
24543
|
+
if (field === "category" && market.category?.toLowerCase().includes(lowerQuery)) {
|
|
24544
|
+
textMatch = true;
|
|
24545
|
+
break;
|
|
24546
|
+
}
|
|
24547
|
+
if (field === "tags" && market.tags?.some((tag) => tag.toLowerCase().includes(lowerQuery))) {
|
|
24548
|
+
textMatch = true;
|
|
24549
|
+
break;
|
|
24550
|
+
}
|
|
24551
|
+
if (field === "outcomes" && market.outcomes?.some((o) => o.label.toLowerCase().includes(lowerQuery))) {
|
|
24552
|
+
textMatch = true;
|
|
24553
|
+
break;
|
|
24554
|
+
}
|
|
24555
|
+
}
|
|
24556
|
+
if (!textMatch)
|
|
24557
|
+
return false;
|
|
24558
|
+
}
|
|
24559
|
+
if (criteria.category && market.category !== criteria.category) {
|
|
24560
|
+
return false;
|
|
24561
|
+
}
|
|
24562
|
+
if (criteria.tags && criteria.tags.length > 0) {
|
|
24563
|
+
const hasMatchingTag = criteria.tags.some((tag) => market.tags?.some((marketTag) => marketTag.toLowerCase() === tag.toLowerCase()));
|
|
24564
|
+
if (!hasMatchingTag)
|
|
24565
|
+
return false;
|
|
24566
|
+
}
|
|
24567
|
+
if (criteria.volume24h) {
|
|
24568
|
+
if (criteria.volume24h.min !== void 0 && market.volume24h < criteria.volume24h.min) {
|
|
24569
|
+
return false;
|
|
24570
|
+
}
|
|
24571
|
+
if (criteria.volume24h.max !== void 0 && market.volume24h > criteria.volume24h.max) {
|
|
24572
|
+
return false;
|
|
24573
|
+
}
|
|
24574
|
+
}
|
|
24575
|
+
if (criteria.volume) {
|
|
24576
|
+
if (criteria.volume.min !== void 0 && (market.volume || 0) < criteria.volume.min) {
|
|
24577
|
+
return false;
|
|
24578
|
+
}
|
|
24579
|
+
if (criteria.volume.max !== void 0 && (market.volume || 0) > criteria.volume.max) {
|
|
24580
|
+
return false;
|
|
24581
|
+
}
|
|
24582
|
+
}
|
|
24583
|
+
if (criteria.liquidity) {
|
|
24584
|
+
if (criteria.liquidity.min !== void 0 && market.liquidity < criteria.liquidity.min) {
|
|
24585
|
+
return false;
|
|
24586
|
+
}
|
|
24587
|
+
if (criteria.liquidity.max !== void 0 && market.liquidity > criteria.liquidity.max) {
|
|
24588
|
+
return false;
|
|
24589
|
+
}
|
|
24590
|
+
}
|
|
24591
|
+
if (criteria.openInterest) {
|
|
24592
|
+
if (criteria.openInterest.min !== void 0 && (market.openInterest || 0) < criteria.openInterest.min) {
|
|
24593
|
+
return false;
|
|
24594
|
+
}
|
|
24595
|
+
if (criteria.openInterest.max !== void 0 && (market.openInterest || 0) > criteria.openInterest.max) {
|
|
24596
|
+
return false;
|
|
24597
|
+
}
|
|
24598
|
+
}
|
|
24599
|
+
if (criteria.resolutionDate) {
|
|
24600
|
+
const resDate = market.resolutionDate;
|
|
24601
|
+
if (criteria.resolutionDate.before && resDate >= criteria.resolutionDate.before) {
|
|
24602
|
+
return false;
|
|
24603
|
+
}
|
|
24604
|
+
if (criteria.resolutionDate.after && resDate <= criteria.resolutionDate.after) {
|
|
24605
|
+
return false;
|
|
24606
|
+
}
|
|
24607
|
+
}
|
|
24608
|
+
if (criteria.price) {
|
|
24609
|
+
const outcome = market[criteria.price.outcome];
|
|
24610
|
+
if (!outcome)
|
|
24611
|
+
return false;
|
|
24612
|
+
if (criteria.price.min !== void 0 && outcome.price < criteria.price.min) {
|
|
24613
|
+
return false;
|
|
24614
|
+
}
|
|
24615
|
+
if (criteria.price.max !== void 0 && outcome.price > criteria.price.max) {
|
|
24616
|
+
return false;
|
|
24617
|
+
}
|
|
24618
|
+
}
|
|
24619
|
+
if (criteria.priceChange24h) {
|
|
24620
|
+
const outcome = market[criteria.priceChange24h.outcome];
|
|
24621
|
+
if (!outcome || outcome.priceChange24h === void 0)
|
|
24622
|
+
return false;
|
|
24623
|
+
if (criteria.priceChange24h.min !== void 0 && outcome.priceChange24h < criteria.priceChange24h.min) {
|
|
24624
|
+
return false;
|
|
24625
|
+
}
|
|
24626
|
+
if (criteria.priceChange24h.max !== void 0 && outcome.priceChange24h > criteria.priceChange24h.max) {
|
|
24627
|
+
return false;
|
|
24628
|
+
}
|
|
24629
|
+
}
|
|
24630
|
+
return true;
|
|
24631
|
+
});
|
|
24632
|
+
}
|
|
24633
|
+
/**
|
|
24634
|
+
* Filter events based on criteria or custom function.
|
|
24635
|
+
*
|
|
24636
|
+
* @param events - Array of events to filter
|
|
24637
|
+
* @param criteria - Filter criteria object, string (simple text search), or predicate function
|
|
24638
|
+
* @returns Filtered array of events
|
|
24639
|
+
*
|
|
24640
|
+
* @example Simple text search
|
|
24641
|
+
* api.filterEvents(events, 'Trump')
|
|
24642
|
+
*
|
|
24643
|
+
* @example Advanced filtering
|
|
24644
|
+
* api.filterEvents(events, {
|
|
24645
|
+
* text: 'Election',
|
|
24646
|
+
* searchIn: ['title', 'tags'],
|
|
24647
|
+
* category: 'Politics',
|
|
24648
|
+
* marketCount: { min: 5 }
|
|
24649
|
+
* })
|
|
24650
|
+
*
|
|
24651
|
+
* @example Custom predicate
|
|
24652
|
+
* api.filterEvents(events, e => e.markets.length > 10)
|
|
24653
|
+
*/
|
|
24654
|
+
filterEvents(events, criteria) {
|
|
24655
|
+
if (typeof criteria === "function") {
|
|
24656
|
+
return events.filter(criteria);
|
|
24657
|
+
}
|
|
24658
|
+
if (typeof criteria === "string") {
|
|
24659
|
+
const lowerQuery = criteria.toLowerCase();
|
|
24660
|
+
return events.filter((e) => e.title.toLowerCase().includes(lowerQuery));
|
|
24661
|
+
}
|
|
24662
|
+
return events.filter((event) => {
|
|
24663
|
+
if (criteria.text) {
|
|
24664
|
+
const lowerQuery = criteria.text.toLowerCase();
|
|
24665
|
+
const searchIn = criteria.searchIn || ["title"];
|
|
24666
|
+
let textMatch = false;
|
|
24667
|
+
for (const field of searchIn) {
|
|
24668
|
+
if (field === "title" && event.title?.toLowerCase().includes(lowerQuery)) {
|
|
24669
|
+
textMatch = true;
|
|
24670
|
+
break;
|
|
24671
|
+
}
|
|
24672
|
+
if (field === "description" && event.description?.toLowerCase().includes(lowerQuery)) {
|
|
24673
|
+
textMatch = true;
|
|
24674
|
+
break;
|
|
24675
|
+
}
|
|
24676
|
+
if (field === "category" && event.category?.toLowerCase().includes(lowerQuery)) {
|
|
24677
|
+
textMatch = true;
|
|
24678
|
+
break;
|
|
24679
|
+
}
|
|
24680
|
+
if (field === "tags" && event.tags?.some((tag) => tag.toLowerCase().includes(lowerQuery))) {
|
|
24681
|
+
textMatch = true;
|
|
24682
|
+
break;
|
|
24683
|
+
}
|
|
24684
|
+
}
|
|
24685
|
+
if (!textMatch)
|
|
24686
|
+
return false;
|
|
24687
|
+
}
|
|
24688
|
+
if (criteria.category && event.category !== criteria.category) {
|
|
24689
|
+
return false;
|
|
24690
|
+
}
|
|
24691
|
+
if (criteria.tags && criteria.tags.length > 0) {
|
|
24692
|
+
const hasMatchingTag = criteria.tags.some((tag) => event.tags?.some((eventTag) => eventTag.toLowerCase() === tag.toLowerCase()));
|
|
24693
|
+
if (!hasMatchingTag)
|
|
24694
|
+
return false;
|
|
24695
|
+
}
|
|
24696
|
+
if (criteria.marketCount) {
|
|
24697
|
+
const count = event.markets.length;
|
|
24698
|
+
if (criteria.marketCount.min !== void 0 && count < criteria.marketCount.min) {
|
|
24699
|
+
return false;
|
|
24700
|
+
}
|
|
24701
|
+
if (criteria.marketCount.max !== void 0 && count > criteria.marketCount.max) {
|
|
24702
|
+
return false;
|
|
24703
|
+
}
|
|
24704
|
+
}
|
|
24705
|
+
if (criteria.totalVolume) {
|
|
24706
|
+
const totalVolume = event.markets.reduce((sum, m) => sum + m.volume24h, 0);
|
|
24707
|
+
if (criteria.totalVolume.min !== void 0 && totalVolume < criteria.totalVolume.min) {
|
|
24708
|
+
return false;
|
|
24709
|
+
}
|
|
24710
|
+
if (criteria.totalVolume.max !== void 0 && totalVolume > criteria.totalVolume.max) {
|
|
24711
|
+
return false;
|
|
24712
|
+
}
|
|
24713
|
+
}
|
|
24714
|
+
return true;
|
|
24715
|
+
});
|
|
24716
|
+
}
|
|
24717
|
+
// ----------------------------------------------------------------------------
|
|
24497
24718
|
// WebSocket Streaming Methods
|
|
24498
24719
|
// ----------------------------------------------------------------------------
|
|
24499
24720
|
/**
|
|
@@ -38170,9 +38391,11 @@ var require_utils4 = __commonJS({
|
|
|
38170
38391
|
if (index === 0 || label.toLowerCase() === "yes" || candidateName && label === candidateName) {
|
|
38171
38392
|
priceChange = Number(market.oneDayPriceChange || 0);
|
|
38172
38393
|
}
|
|
38394
|
+
const outcomeIdValue = clobTokenIds[index] || String(index);
|
|
38173
38395
|
outcomes.push({
|
|
38174
|
-
id:
|
|
38396
|
+
id: outcomeIdValue,
|
|
38175
38397
|
// Use CLOB Token ID as the primary ID
|
|
38398
|
+
outcomeId: outcomeIdValue,
|
|
38176
38399
|
label: outcomeLabel,
|
|
38177
38400
|
price: parseFloat(rawPrice) || 0,
|
|
38178
38401
|
priceChange24h: priceChange,
|
|
@@ -38185,6 +38408,7 @@ var require_utils4 = __commonJS({
|
|
|
38185
38408
|
}
|
|
38186
38409
|
const um = {
|
|
38187
38410
|
id: market.id,
|
|
38411
|
+
marketId: market.id,
|
|
38188
38412
|
title: market.question ? `${event.title} - ${market.question}` : event.title,
|
|
38189
38413
|
description: market.description || event.description,
|
|
38190
38414
|
outcomes,
|
|
@@ -38421,6 +38645,26 @@ var require_getMarketsBySlug = __commonJS({
|
|
|
38421
38645
|
}
|
|
38422
38646
|
});
|
|
38423
38647
|
|
|
38648
|
+
// dist/utils/validation.js
|
|
38649
|
+
var require_validation = __commonJS({
|
|
38650
|
+
"dist/utils/validation.js"(exports2) {
|
|
38651
|
+
"use strict";
|
|
38652
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
38653
|
+
exports2.validateOutcomeId = validateOutcomeId;
|
|
38654
|
+
exports2.validateIdFormat = validateIdFormat;
|
|
38655
|
+
function validateOutcomeId(id, context) {
|
|
38656
|
+
if (id.length < 10 && /^\d+$/.test(id)) {
|
|
38657
|
+
throw new Error(`Invalid ID for ${context}: "${id}". This appears to be a market ID (deprecated: market.id, use: market.marketId). Please use outcome ID (preferred: outcome.outcomeId, deprecated: outcome.id).`);
|
|
38658
|
+
}
|
|
38659
|
+
}
|
|
38660
|
+
function validateIdFormat(id, context) {
|
|
38661
|
+
if (!id || id.trim().length === 0) {
|
|
38662
|
+
throw new Error(`Invalid ID for ${context}: ID cannot be empty`);
|
|
38663
|
+
}
|
|
38664
|
+
}
|
|
38665
|
+
}
|
|
38666
|
+
});
|
|
38667
|
+
|
|
38424
38668
|
// dist/exchanges/polymarket/fetchOHLCV.js
|
|
38425
38669
|
var require_fetchOHLCV = __commonJS({
|
|
38426
38670
|
"dist/exchanges/polymarket/fetchOHLCV.js"(exports2) {
|
|
@@ -38432,10 +38676,10 @@ var require_fetchOHLCV = __commonJS({
|
|
|
38432
38676
|
exports2.fetchOHLCV = fetchOHLCV;
|
|
38433
38677
|
var axios_1 = __importDefault(require_axios());
|
|
38434
38678
|
var utils_1 = require_utils4();
|
|
38679
|
+
var validation_1 = require_validation();
|
|
38435
38680
|
async function fetchOHLCV(id, params) {
|
|
38436
|
-
|
|
38437
|
-
|
|
38438
|
-
}
|
|
38681
|
+
(0, validation_1.validateIdFormat)(id, "OHLCV");
|
|
38682
|
+
(0, validation_1.validateOutcomeId)(id, "OHLCV");
|
|
38439
38683
|
try {
|
|
38440
38684
|
const fidelity = (0, utils_1.mapIntervalToFidelity)(params.resolution);
|
|
38441
38685
|
const nowTs = Math.floor(Date.now() / 1e3);
|
|
@@ -38519,7 +38763,10 @@ var require_fetchOrderBook = __commonJS({
|
|
|
38519
38763
|
exports2.fetchOrderBook = fetchOrderBook;
|
|
38520
38764
|
var axios_1 = __importDefault(require_axios());
|
|
38521
38765
|
var utils_1 = require_utils4();
|
|
38766
|
+
var validation_1 = require_validation();
|
|
38522
38767
|
async function fetchOrderBook(id) {
|
|
38768
|
+
(0, validation_1.validateIdFormat)(id, "OrderBook");
|
|
38769
|
+
(0, validation_1.validateOutcomeId)(id, "OrderBook");
|
|
38523
38770
|
try {
|
|
38524
38771
|
const response = await axios_1.default.get(`${utils_1.CLOB_API_URL}/book`, {
|
|
38525
38772
|
params: { token_id: id }
|
|
@@ -38557,10 +38804,10 @@ var require_fetchTrades = __commonJS({
|
|
|
38557
38804
|
exports2.fetchTrades = fetchTrades;
|
|
38558
38805
|
var axios_1 = __importDefault(require_axios());
|
|
38559
38806
|
var utils_1 = require_utils4();
|
|
38807
|
+
var validation_1 = require_validation();
|
|
38560
38808
|
async function fetchTrades(id, params) {
|
|
38561
|
-
|
|
38562
|
-
|
|
38563
|
-
}
|
|
38809
|
+
(0, validation_1.validateIdFormat)(id, "Trades");
|
|
38810
|
+
(0, validation_1.validateOutcomeId)(id, "Trades");
|
|
38564
38811
|
try {
|
|
38565
38812
|
const queryParams = {
|
|
38566
38813
|
asset_id: id
|
|
@@ -76055,7 +76302,7 @@ var require_permessage_deflate = __commonJS({
|
|
|
76055
76302
|
});
|
|
76056
76303
|
|
|
76057
76304
|
// ../node_modules/ws/lib/validation.js
|
|
76058
|
-
var
|
|
76305
|
+
var require_validation2 = __commonJS({
|
|
76059
76306
|
"../node_modules/ws/lib/validation.js"(exports2, module2) {
|
|
76060
76307
|
"use strict";
|
|
76061
76308
|
var { isUtf8 } = require("buffer");
|
|
@@ -76268,7 +76515,7 @@ var require_receiver = __commonJS({
|
|
|
76268
76515
|
kWebSocket
|
|
76269
76516
|
} = require_constants();
|
|
76270
76517
|
var { concat: concat2, toArrayBuffer, unmask } = require_buffer_util();
|
|
76271
|
-
var { isValidStatusCode, isValidUTF8 } =
|
|
76518
|
+
var { isValidStatusCode, isValidUTF8 } = require_validation2();
|
|
76272
76519
|
var FastBuffer = Buffer[Symbol.species];
|
|
76273
76520
|
var GET_INFO = 0;
|
|
76274
76521
|
var GET_PAYLOAD_LENGTH_16 = 1;
|
|
@@ -76855,7 +77102,7 @@ var require_sender = __commonJS({
|
|
|
76855
77102
|
var { randomFillSync } = require("crypto");
|
|
76856
77103
|
var PerMessageDeflate = require_permessage_deflate();
|
|
76857
77104
|
var { EMPTY_BUFFER, kWebSocket, NOOP } = require_constants();
|
|
76858
|
-
var { isBlob: isBlob2, isValidStatusCode } =
|
|
77105
|
+
var { isBlob: isBlob2, isValidStatusCode } = require_validation2();
|
|
76859
77106
|
var { mask: applyMask, toBuffer } = require_buffer_util();
|
|
76860
77107
|
var kByteLength = Symbol("kByteLength");
|
|
76861
77108
|
var maskBuffer = Buffer.alloc(4);
|
|
@@ -77568,7 +77815,7 @@ var require_event_target = __commonJS({
|
|
|
77568
77815
|
var require_extension = __commonJS({
|
|
77569
77816
|
"../node_modules/ws/lib/extension.js"(exports2, module2) {
|
|
77570
77817
|
"use strict";
|
|
77571
|
-
var { tokenChars } =
|
|
77818
|
+
var { tokenChars } = require_validation2();
|
|
77572
77819
|
function push(dest, name, elem) {
|
|
77573
77820
|
if (dest[name] === void 0) dest[name] = [elem];
|
|
77574
77821
|
else dest[name].push(elem);
|
|
@@ -77732,7 +77979,7 @@ var require_websocket = __commonJS({
|
|
|
77732
77979
|
var PerMessageDeflate = require_permessage_deflate();
|
|
77733
77980
|
var Receiver = require_receiver();
|
|
77734
77981
|
var Sender = require_sender();
|
|
77735
|
-
var { isBlob: isBlob2 } =
|
|
77982
|
+
var { isBlob: isBlob2 } = require_validation2();
|
|
77736
77983
|
var {
|
|
77737
77984
|
BINARY_TYPES,
|
|
77738
77985
|
EMPTY_BUFFER,
|
|
@@ -78701,7 +78948,7 @@ var require_stream = __commonJS({
|
|
|
78701
78948
|
var require_subprotocol = __commonJS({
|
|
78702
78949
|
"../node_modules/ws/lib/subprotocol.js"(exports2, module2) {
|
|
78703
78950
|
"use strict";
|
|
78704
|
-
var { tokenChars } =
|
|
78951
|
+
var { tokenChars } = require_validation2();
|
|
78705
78952
|
function parse(header) {
|
|
78706
78953
|
const protocols = /* @__PURE__ */ new Set();
|
|
78707
78954
|
let start = -1;
|
|
@@ -83892,7 +84139,7 @@ var require_permessage_deflate2 = __commonJS({
|
|
|
83892
84139
|
});
|
|
83893
84140
|
|
|
83894
84141
|
// ../node_modules/@nevuamarkets/poly-websockets/node_modules/ws/lib/validation.js
|
|
83895
|
-
var
|
|
84142
|
+
var require_validation3 = __commonJS({
|
|
83896
84143
|
"../node_modules/@nevuamarkets/poly-websockets/node_modules/ws/lib/validation.js"(exports2, module2) {
|
|
83897
84144
|
"use strict";
|
|
83898
84145
|
var { isUtf8 } = require("buffer");
|
|
@@ -84105,7 +84352,7 @@ var require_receiver2 = __commonJS({
|
|
|
84105
84352
|
kWebSocket
|
|
84106
84353
|
} = require_constants2();
|
|
84107
84354
|
var { concat: concat2, toArrayBuffer, unmask } = require_buffer_util2();
|
|
84108
|
-
var { isValidStatusCode, isValidUTF8 } =
|
|
84355
|
+
var { isValidStatusCode, isValidUTF8 } = require_validation3();
|
|
84109
84356
|
var FastBuffer = Buffer[Symbol.species];
|
|
84110
84357
|
var GET_INFO = 0;
|
|
84111
84358
|
var GET_PAYLOAD_LENGTH_16 = 1;
|
|
@@ -84692,7 +84939,7 @@ var require_sender2 = __commonJS({
|
|
|
84692
84939
|
var { randomFillSync } = require("crypto");
|
|
84693
84940
|
var PerMessageDeflate = require_permessage_deflate2();
|
|
84694
84941
|
var { EMPTY_BUFFER, kWebSocket, NOOP } = require_constants2();
|
|
84695
|
-
var { isBlob: isBlob2, isValidStatusCode } =
|
|
84942
|
+
var { isBlob: isBlob2, isValidStatusCode } = require_validation3();
|
|
84696
84943
|
var { mask: applyMask, toBuffer } = require_buffer_util2();
|
|
84697
84944
|
var kByteLength = Symbol("kByteLength");
|
|
84698
84945
|
var maskBuffer = Buffer.alloc(4);
|
|
@@ -85405,7 +85652,7 @@ var require_event_target2 = __commonJS({
|
|
|
85405
85652
|
var require_extension2 = __commonJS({
|
|
85406
85653
|
"../node_modules/@nevuamarkets/poly-websockets/node_modules/ws/lib/extension.js"(exports2, module2) {
|
|
85407
85654
|
"use strict";
|
|
85408
|
-
var { tokenChars } =
|
|
85655
|
+
var { tokenChars } = require_validation3();
|
|
85409
85656
|
function push(dest, name, elem) {
|
|
85410
85657
|
if (dest[name] === void 0) dest[name] = [elem];
|
|
85411
85658
|
else dest[name].push(elem);
|
|
@@ -85569,7 +85816,7 @@ var require_websocket2 = __commonJS({
|
|
|
85569
85816
|
var PerMessageDeflate = require_permessage_deflate2();
|
|
85570
85817
|
var Receiver = require_receiver2();
|
|
85571
85818
|
var Sender = require_sender2();
|
|
85572
|
-
var { isBlob: isBlob2 } =
|
|
85819
|
+
var { isBlob: isBlob2 } = require_validation3();
|
|
85573
85820
|
var {
|
|
85574
85821
|
BINARY_TYPES,
|
|
85575
85822
|
CLOSE_TIMEOUT,
|
|
@@ -86542,7 +86789,7 @@ var require_stream2 = __commonJS({
|
|
|
86542
86789
|
var require_subprotocol2 = __commonJS({
|
|
86543
86790
|
"../node_modules/@nevuamarkets/poly-websockets/node_modules/ws/lib/subprotocol.js"(exports2, module2) {
|
|
86544
86791
|
"use strict";
|
|
86545
|
-
var { tokenChars } =
|
|
86792
|
+
var { tokenChars } = require_validation3();
|
|
86546
86793
|
function parse(header) {
|
|
86547
86794
|
const protocols = /* @__PURE__ */ new Set();
|
|
86548
86795
|
let start = -1;
|
|
@@ -105192,8 +105439,10 @@ var require_utils10 = __commonJS({
|
|
|
105192
105439
|
const tokenEntries = Object.entries(market.tokens);
|
|
105193
105440
|
tokenEntries.forEach(([label, tokenId], index) => {
|
|
105194
105441
|
const outcomePrice = market.prices[index] || 0;
|
|
105442
|
+
const outcomeIdValue = tokenId;
|
|
105195
105443
|
outcomes.push({
|
|
105196
|
-
id:
|
|
105444
|
+
id: outcomeIdValue,
|
|
105445
|
+
outcomeId: outcomeIdValue,
|
|
105197
105446
|
label: label.charAt(0).toUpperCase() + label.slice(1),
|
|
105198
105447
|
// Capitalize 'yes'/'no'
|
|
105199
105448
|
price: outcomePrice,
|
|
@@ -105207,6 +105456,7 @@ var require_utils10 = __commonJS({
|
|
|
105207
105456
|
}
|
|
105208
105457
|
const um = {
|
|
105209
105458
|
id: market.slug,
|
|
105459
|
+
marketId: market.slug,
|
|
105210
105460
|
title: market.title || market.question,
|
|
105211
105461
|
description: market.description,
|
|
105212
105462
|
outcomes,
|
|
@@ -105415,7 +105665,9 @@ var require_fetchOHLCV2 = __commonJS({
|
|
|
105415
105665
|
exports2.fetchOHLCV = fetchOHLCV;
|
|
105416
105666
|
var axios_1 = __importDefault(require_axios());
|
|
105417
105667
|
var utils_1 = require_utils10();
|
|
105668
|
+
var validation_1 = require_validation();
|
|
105418
105669
|
async function fetchOHLCV(id, params) {
|
|
105670
|
+
(0, validation_1.validateIdFormat)(id, "OHLCV");
|
|
105419
105671
|
try {
|
|
105420
105672
|
const fidelity = (0, utils_1.mapIntervalToFidelity)(params.resolution);
|
|
105421
105673
|
const url2 = `${utils_1.LIMITLESS_API_URL}/markets/${id}/historical-price`;
|
|
@@ -105466,7 +105718,9 @@ var require_fetchOrderBook2 = __commonJS({
|
|
|
105466
105718
|
exports2.fetchOrderBook = fetchOrderBook;
|
|
105467
105719
|
var axios_1 = __importDefault(require_axios());
|
|
105468
105720
|
var utils_1 = require_utils10();
|
|
105721
|
+
var validation_1 = require_validation();
|
|
105469
105722
|
async function fetchOrderBook(id) {
|
|
105723
|
+
(0, validation_1.validateIdFormat)(id, "OrderBook");
|
|
105470
105724
|
try {
|
|
105471
105725
|
const url2 = `${utils_1.LIMITLESS_API_URL}/markets/${id}/orderbook`;
|
|
105472
105726
|
const response = await axios_1.default.get(url2);
|
|
@@ -106092,6 +106346,7 @@ var require_utils11 = __commonJS({
|
|
|
106092
106346
|
{
|
|
106093
106347
|
id: market.ticker,
|
|
106094
106348
|
// The actual market ticker (primary tradeable)
|
|
106349
|
+
outcomeId: market.ticker,
|
|
106095
106350
|
label: candidateName || "Yes",
|
|
106096
106351
|
price,
|
|
106097
106352
|
priceChange24h: priceChange
|
|
@@ -106099,6 +106354,7 @@ var require_utils11 = __commonJS({
|
|
|
106099
106354
|
{
|
|
106100
106355
|
id: `${market.ticker}-NO`,
|
|
106101
106356
|
// Virtual ID for the No outcome
|
|
106357
|
+
outcomeId: `${market.ticker}-NO`,
|
|
106102
106358
|
label: candidateName ? `Not ${candidateName}` : "No",
|
|
106103
106359
|
price: 1 - price,
|
|
106104
106360
|
priceChange24h: -priceChange
|
|
@@ -106118,6 +106374,7 @@ var require_utils11 = __commonJS({
|
|
|
106118
106374
|
}
|
|
106119
106375
|
const um = {
|
|
106120
106376
|
id: market.ticker,
|
|
106377
|
+
marketId: market.ticker,
|
|
106121
106378
|
title: event.title,
|
|
106122
106379
|
description: market.rules_primary || market.rules_secondary || "",
|
|
106123
106380
|
outcomes,
|
|
@@ -106446,7 +106703,9 @@ var require_fetchOHLCV3 = __commonJS({
|
|
|
106446
106703
|
exports2.fetchOHLCV = fetchOHLCV;
|
|
106447
106704
|
var axios_1 = __importDefault(require_axios());
|
|
106448
106705
|
var utils_1 = require_utils11();
|
|
106706
|
+
var validation_1 = require_validation();
|
|
106449
106707
|
async function fetchOHLCV(id, params) {
|
|
106708
|
+
(0, validation_1.validateIdFormat)(id, "OHLCV");
|
|
106450
106709
|
try {
|
|
106451
106710
|
const cleanedId = id.replace(/-NO$/, "");
|
|
106452
106711
|
const normalizedId = cleanedId.toUpperCase();
|
|
@@ -106532,7 +106791,9 @@ var require_fetchOrderBook3 = __commonJS({
|
|
|
106532
106791
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
106533
106792
|
exports2.fetchOrderBook = fetchOrderBook;
|
|
106534
106793
|
var axios_1 = __importDefault(require_axios());
|
|
106794
|
+
var validation_1 = require_validation();
|
|
106535
106795
|
async function fetchOrderBook(id) {
|
|
106796
|
+
(0, validation_1.validateIdFormat)(id, "OrderBook");
|
|
106536
106797
|
try {
|
|
106537
106798
|
const isNoOutcome = id.endsWith("-NO");
|
|
106538
106799
|
const ticker = id.replace(/-NO$/, "");
|
pmxt/client.py
CHANGED
|
@@ -7,7 +7,7 @@ OpenAPI client, matching the JavaScript API exactly.
|
|
|
7
7
|
|
|
8
8
|
import os
|
|
9
9
|
import sys
|
|
10
|
-
from typing import List, Optional, Dict, Any, Literal
|
|
10
|
+
from typing import List, Optional, Dict, Any, Literal, Union
|
|
11
11
|
from datetime import datetime
|
|
12
12
|
from abc import ABC, abstractmethod
|
|
13
13
|
import json
|
|
@@ -37,6 +37,10 @@ from .models import (
|
|
|
37
37
|
HistoryFilterParams,
|
|
38
38
|
CreateOrderParams,
|
|
39
39
|
ExecutionPriceResult,
|
|
40
|
+
MarketFilterCriteria,
|
|
41
|
+
MarketFilterFunction,
|
|
42
|
+
EventFilterCriteria,
|
|
43
|
+
EventFilterFunction,
|
|
40
44
|
)
|
|
41
45
|
from .server_manager import ServerManager
|
|
42
46
|
|
|
@@ -432,7 +436,223 @@ class Exchange(ABC):
|
|
|
432
436
|
return [_convert_market(m) for m in data]
|
|
433
437
|
except ApiException as e:
|
|
434
438
|
raise Exception(f"Failed to get markets by slug: {e}")
|
|
435
|
-
|
|
439
|
+
|
|
440
|
+
# ----------------------------------------------------------------------------
|
|
441
|
+
# Filtering Methods
|
|
442
|
+
# ----------------------------------------------------------------------------
|
|
443
|
+
|
|
444
|
+
def filter_markets(
|
|
445
|
+
self,
|
|
446
|
+
markets: List[UnifiedMarket],
|
|
447
|
+
criteria: Union[str, MarketFilterCriteria, MarketFilterFunction]
|
|
448
|
+
) -> List[UnifiedMarket]:
|
|
449
|
+
"""
|
|
450
|
+
Filter markets based on criteria or custom function.
|
|
451
|
+
|
|
452
|
+
Args:
|
|
453
|
+
markets: List of markets to filter
|
|
454
|
+
criteria: Filter criteria object, string (simple text search), or predicate function
|
|
455
|
+
|
|
456
|
+
Returns:
|
|
457
|
+
Filtered list of markets
|
|
458
|
+
|
|
459
|
+
Example:
|
|
460
|
+
>>> api.filter_markets(markets, "Trump")
|
|
461
|
+
>>> api.filter_markets(markets, {"volume_24h": {"min": 1000}})
|
|
462
|
+
>>> api.filter_markets(markets, lambda m: m.yes and m.yes.price > 0.5)
|
|
463
|
+
"""
|
|
464
|
+
# Handle predicate function
|
|
465
|
+
if callable(criteria):
|
|
466
|
+
return list(filter(criteria, markets))
|
|
467
|
+
|
|
468
|
+
# Handle simple string search
|
|
469
|
+
if isinstance(criteria, str):
|
|
470
|
+
lower_query = criteria.lower()
|
|
471
|
+
return [m for m in markets if m.title and lower_query in m.title.lower()]
|
|
472
|
+
|
|
473
|
+
# Handle criteria object
|
|
474
|
+
params: MarketFilterCriteria = criteria # type: ignore
|
|
475
|
+
results = []
|
|
476
|
+
|
|
477
|
+
for market in markets:
|
|
478
|
+
# Text search
|
|
479
|
+
if "text" in params:
|
|
480
|
+
lower_query = params["text"].lower()
|
|
481
|
+
search_in = params.get("search_in", ["title"])
|
|
482
|
+
match = False
|
|
483
|
+
|
|
484
|
+
if "title" in search_in and market.title and lower_query in market.title.lower():
|
|
485
|
+
match = True
|
|
486
|
+
elif "description" in search_in and market.description and lower_query in market.description.lower():
|
|
487
|
+
match = True
|
|
488
|
+
elif "category" in search_in and market.category and lower_query in market.category.lower():
|
|
489
|
+
match = True
|
|
490
|
+
elif "tags" in search_in and market.tags and any(lower_query in t.lower() for t in market.tags):
|
|
491
|
+
match = True
|
|
492
|
+
elif "outcomes" in search_in and market.outcomes and any(lower_query in o.label.lower() for o in market.outcomes):
|
|
493
|
+
match = True
|
|
494
|
+
|
|
495
|
+
if not match:
|
|
496
|
+
continue
|
|
497
|
+
|
|
498
|
+
# Category filter
|
|
499
|
+
if "category" in params:
|
|
500
|
+
if market.category != params["category"]:
|
|
501
|
+
continue
|
|
502
|
+
|
|
503
|
+
# Tags filter (match ANY)
|
|
504
|
+
if "tags" in params and params["tags"]:
|
|
505
|
+
if not market.tags:
|
|
506
|
+
continue
|
|
507
|
+
query_tags = [t.lower() for t in params["tags"]]
|
|
508
|
+
market_tags = [t.lower() for t in market.tags]
|
|
509
|
+
if not any(t in market_tags for t in query_tags):
|
|
510
|
+
continue
|
|
511
|
+
|
|
512
|
+
# Volume 24h
|
|
513
|
+
if "volume_24h" in params:
|
|
514
|
+
f = params["volume_24h"]
|
|
515
|
+
val = market.volume_24h
|
|
516
|
+
if "min" in f and val < f["min"]: continue
|
|
517
|
+
if "max" in f and val > f["max"]: continue
|
|
518
|
+
|
|
519
|
+
# Volume
|
|
520
|
+
if "volume" in params:
|
|
521
|
+
f = params["volume"]
|
|
522
|
+
val = market.volume or 0
|
|
523
|
+
if "min" in f and val < f["min"]: continue
|
|
524
|
+
if "max" in f and val > f["max"]: continue
|
|
525
|
+
|
|
526
|
+
# Liquidity
|
|
527
|
+
if "liquidity" in params:
|
|
528
|
+
f = params["liquidity"]
|
|
529
|
+
val = market.liquidity
|
|
530
|
+
if "min" in f and val < f["min"]: continue
|
|
531
|
+
if "max" in f and val > f["max"]: continue
|
|
532
|
+
|
|
533
|
+
# Open Interest
|
|
534
|
+
if "open_interest" in params:
|
|
535
|
+
f = params["open_interest"]
|
|
536
|
+
val = market.open_interest or 0
|
|
537
|
+
if "min" in f and val < f["min"]: continue
|
|
538
|
+
if "max" in f and val > f["max"]: continue
|
|
539
|
+
|
|
540
|
+
# Resolution Date
|
|
541
|
+
if "resolution_date" in params:
|
|
542
|
+
f = params["resolution_date"]
|
|
543
|
+
val = market.resolution_date
|
|
544
|
+
|
|
545
|
+
if not val:
|
|
546
|
+
continue
|
|
547
|
+
|
|
548
|
+
# Ensure val is timezone-aware if the filter dates are, or naive if filter dates are.
|
|
549
|
+
# Assuming standard library comparison works (or both are TZ aware/naive).
|
|
550
|
+
if "before" in f and val >= f["before"]: continue
|
|
551
|
+
if "after" in f and val <= f["after"]: continue
|
|
552
|
+
|
|
553
|
+
# Price filter
|
|
554
|
+
if "price" in params:
|
|
555
|
+
f = params["price"]
|
|
556
|
+
outcome_key = f.get("outcome")
|
|
557
|
+
if outcome_key:
|
|
558
|
+
outcome = getattr(market, outcome_key, None)
|
|
559
|
+
if not outcome: continue
|
|
560
|
+
if "min" in f and outcome.price < f["min"]: continue
|
|
561
|
+
if "max" in f and outcome.price > f["max"]: continue
|
|
562
|
+
|
|
563
|
+
# Price Change 24h
|
|
564
|
+
if "price_change_24h" in params:
|
|
565
|
+
f = params["price_change_24h"]
|
|
566
|
+
outcome_key = f.get("outcome")
|
|
567
|
+
if outcome_key:
|
|
568
|
+
outcome = getattr(market, outcome_key, None)
|
|
569
|
+
if not outcome or outcome.price_change_24h is None: continue
|
|
570
|
+
if "min" in f and outcome.price_change_24h < f["min"]: continue
|
|
571
|
+
if "max" in f and outcome.price_change_24h > f["max"]: continue
|
|
572
|
+
|
|
573
|
+
results.append(market)
|
|
574
|
+
|
|
575
|
+
return results
|
|
576
|
+
|
|
577
|
+
def filter_events(
|
|
578
|
+
self,
|
|
579
|
+
events: List[UnifiedEvent],
|
|
580
|
+
criteria: Union[str, EventFilterCriteria, EventFilterFunction]
|
|
581
|
+
) -> List[UnifiedEvent]:
|
|
582
|
+
"""
|
|
583
|
+
Filter events based on criteria or custom function.
|
|
584
|
+
|
|
585
|
+
Args:
|
|
586
|
+
events: List of events to filter
|
|
587
|
+
criteria: Filter criteria object, string, or function
|
|
588
|
+
|
|
589
|
+
Returns:
|
|
590
|
+
Filtered list of events
|
|
591
|
+
"""
|
|
592
|
+
# Handle predicate function
|
|
593
|
+
if callable(criteria):
|
|
594
|
+
return list(filter(criteria, events))
|
|
595
|
+
|
|
596
|
+
# Handle simple string search
|
|
597
|
+
if isinstance(criteria, str):
|
|
598
|
+
lower_query = criteria.lower()
|
|
599
|
+
return [e for e in events if e.title and lower_query in e.title.lower()]
|
|
600
|
+
|
|
601
|
+
# Handle criteria object
|
|
602
|
+
params: EventFilterCriteria = criteria # type: ignore
|
|
603
|
+
results = []
|
|
604
|
+
|
|
605
|
+
for event in events:
|
|
606
|
+
# Text search
|
|
607
|
+
if "text" in params:
|
|
608
|
+
lower_query = params["text"].lower()
|
|
609
|
+
search_in = params.get("search_in", ["title"])
|
|
610
|
+
match = False
|
|
611
|
+
|
|
612
|
+
if "title" in search_in and event.title and lower_query in event.title.lower():
|
|
613
|
+
match = True
|
|
614
|
+
elif "description" in search_in and event.description and lower_query in event.description.lower():
|
|
615
|
+
match = True
|
|
616
|
+
elif "category" in search_in and event.category and lower_query in event.category.lower():
|
|
617
|
+
match = True
|
|
618
|
+
elif "tags" in search_in and event.tags and any(lower_query in t.lower() for t in event.tags):
|
|
619
|
+
match = True
|
|
620
|
+
|
|
621
|
+
if not match:
|
|
622
|
+
continue
|
|
623
|
+
|
|
624
|
+
# Category
|
|
625
|
+
if "category" in params:
|
|
626
|
+
if event.category != params["category"]:
|
|
627
|
+
continue
|
|
628
|
+
|
|
629
|
+
# Tags
|
|
630
|
+
if "tags" in params and params["tags"]:
|
|
631
|
+
if not event.tags:
|
|
632
|
+
continue
|
|
633
|
+
query_tags = [t.lower() for t in params["tags"]]
|
|
634
|
+
event_tags = [t.lower() for t in event.tags]
|
|
635
|
+
if not any(t in event_tags for t in query_tags):
|
|
636
|
+
continue
|
|
637
|
+
|
|
638
|
+
# Market Count
|
|
639
|
+
if "market_count" in params:
|
|
640
|
+
f = params["market_count"]
|
|
641
|
+
count = len(event.markets)
|
|
642
|
+
if "min" in f and count < f["min"]: continue
|
|
643
|
+
if "max" in f and count > f["max"]: continue
|
|
644
|
+
|
|
645
|
+
# Total Volume
|
|
646
|
+
if "total_volume" in params:
|
|
647
|
+
f = params["total_volume"]
|
|
648
|
+
total_vol = sum(m.volume_24h for m in event.markets)
|
|
649
|
+
if "min" in f and total_vol < f["min"]: continue
|
|
650
|
+
if "max" in f and total_vol > f["max"]: continue
|
|
651
|
+
|
|
652
|
+
results.append(event)
|
|
653
|
+
|
|
654
|
+
return results
|
|
655
|
+
|
|
436
656
|
def fetch_ohlcv(
|
|
437
657
|
self,
|
|
438
658
|
outcome_id: str,
|
pmxt/models.py
CHANGED
|
@@ -15,6 +15,7 @@ SortOption = Literal["volume", "liquidity", "newest"]
|
|
|
15
15
|
SearchIn = Literal["title", "description", "both"]
|
|
16
16
|
OrderSide = Literal["buy", "sell"]
|
|
17
17
|
OrderType = Literal["market", "limit"]
|
|
18
|
+
OutcomeType = Literal["yes", "no", "up", "down"]
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
@dataclass
|
|
@@ -398,3 +399,70 @@ class CreateOrderParams:
|
|
|
398
399
|
|
|
399
400
|
fee: Optional[int] = None
|
|
400
401
|
"""Optional fee rate (e.g., 1000 for 0.1%)"""
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
# ----------------------------------------------------------------------------
|
|
405
|
+
# Filtering Types
|
|
406
|
+
# ----------------------------------------------------------------------------
|
|
407
|
+
|
|
408
|
+
from typing import TypedDict, Callable, Union
|
|
409
|
+
|
|
410
|
+
class MinMax(TypedDict, total=False):
|
|
411
|
+
"""Range filter."""
|
|
412
|
+
min: float
|
|
413
|
+
max: float
|
|
414
|
+
|
|
415
|
+
class DateRange(TypedDict, total=False):
|
|
416
|
+
"""Date range filter."""
|
|
417
|
+
before: datetime
|
|
418
|
+
after: datetime
|
|
419
|
+
|
|
420
|
+
class PriceFilter(TypedDict, total=False):
|
|
421
|
+
"""Price filter."""
|
|
422
|
+
outcome: OutcomeType
|
|
423
|
+
min: float
|
|
424
|
+
max: float
|
|
425
|
+
|
|
426
|
+
class MarketFilterCriteria(TypedDict, total=False):
|
|
427
|
+
"""Criteria for filtering markets locally."""
|
|
428
|
+
|
|
429
|
+
# Text search
|
|
430
|
+
text: str
|
|
431
|
+
search_in: List[Literal["title", "description", "category", "tags", "outcomes"]]
|
|
432
|
+
|
|
433
|
+
# Numeric range filters
|
|
434
|
+
volume_24h: MinMax
|
|
435
|
+
volume: MinMax
|
|
436
|
+
liquidity: MinMax
|
|
437
|
+
open_interest: MinMax
|
|
438
|
+
|
|
439
|
+
# Date filters
|
|
440
|
+
resolution_date: DateRange
|
|
441
|
+
|
|
442
|
+
# Category/tag filters
|
|
443
|
+
category: str
|
|
444
|
+
tags: List[str]
|
|
445
|
+
|
|
446
|
+
# Price filters
|
|
447
|
+
price: PriceFilter
|
|
448
|
+
price_change_24h: PriceFilter
|
|
449
|
+
|
|
450
|
+
MarketFilterFunction = Callable[[UnifiedMarket], bool]
|
|
451
|
+
|
|
452
|
+
class EventFilterCriteria(TypedDict, total=False):
|
|
453
|
+
"""Criteria for filtering events locally."""
|
|
454
|
+
|
|
455
|
+
# Text search
|
|
456
|
+
text: str
|
|
457
|
+
search_in: List[Literal["title", "description", "category", "tags"]]
|
|
458
|
+
|
|
459
|
+
# Category/tag filters
|
|
460
|
+
category: str
|
|
461
|
+
tags: List[str]
|
|
462
|
+
|
|
463
|
+
# Market metrics
|
|
464
|
+
market_count: MinMax
|
|
465
|
+
total_volume: MinMax
|
|
466
|
+
|
|
467
|
+
EventFilterFunction = Callable[[UnifiedEvent], bool]
|
|
468
|
+
|
pmxt/server_manager.py
CHANGED
|
@@ -130,8 +130,25 @@ class ServerManager:
|
|
|
130
130
|
|
|
131
131
|
return False
|
|
132
132
|
|
|
133
|
+
def stop(self) -> None:
|
|
134
|
+
"""
|
|
135
|
+
Stop the currently running server.
|
|
136
|
+
|
|
137
|
+
This reads the lock file to find the process ID and sends a SIGTERM.
|
|
138
|
+
"""
|
|
139
|
+
self._kill_old_server()
|
|
140
|
+
|
|
141
|
+
def restart(self) -> None:
|
|
142
|
+
"""
|
|
143
|
+
Restart the server.
|
|
144
|
+
|
|
145
|
+
Stops the current server if running, and starts a fresh one.
|
|
146
|
+
"""
|
|
147
|
+
self.stop()
|
|
148
|
+
self.ensure_server_running()
|
|
149
|
+
|
|
133
150
|
def _kill_old_server(self) -> None:
|
|
134
|
-
"""Kill the currently running server."""
|
|
151
|
+
"""Kill the currently running server (Internal)."""
|
|
135
152
|
server_info = self.get_server_info()
|
|
136
153
|
if server_info and 'pid' in server_info:
|
|
137
154
|
import signal
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
pmxt/__init__.py,sha256=
|
|
2
|
-
pmxt/client.py,sha256=
|
|
3
|
-
pmxt/models.py,sha256=
|
|
4
|
-
pmxt/server_manager.py,sha256=
|
|
1
|
+
pmxt/__init__.py,sha256=kbtmNd7bfDO-SNmmsJ0D11RuTWmX1gYBrJiVyTTRdgo,1520
|
|
2
|
+
pmxt/client.py,sha256=lpDT0zDw1OXal_hbjcV69DidlgyyzKMmPMqvm4waNGg,43488
|
|
3
|
+
pmxt/models.py,sha256=LYfbd_SEtvqI9gYnVz6wAqlijJkSODrodE7v0owbyok,10291
|
|
4
|
+
pmxt/server_manager.py,sha256=kkbvQOgCBBDUbe0X4KGLZsWpuHxz3Yvb9ECDhjQxMOE,12050
|
|
5
5
|
pmxt/_server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
pmxt/_server/bin/pmxt-ensure-server,sha256=kXIond0UbxS52FAVQD7kHmSBaL_s6cbIyapLRr4KZJw,4544
|
|
7
7
|
pmxt/_server/bin/pmxt-ensure-server.js,sha256=kXIond0UbxS52FAVQD7kHmSBaL_s6cbIyapLRr4KZJw,4544
|
|
8
|
-
pmxt/_server/server/bundled.js,sha256=
|
|
9
|
-
pmxt_internal/__init__.py,sha256=
|
|
10
|
-
pmxt_internal/api_client.py,sha256=
|
|
8
|
+
pmxt/_server/server/bundled.js,sha256=ZfMpYAXX5UZECbkYlvCB5mGPvhorSrkw-h4m0ZeRdEk,4251928
|
|
9
|
+
pmxt_internal/__init__.py,sha256=CEpTnAT2C0rjNGAaRZbClTn4UvDWuHTe3AeC5n7AuBE,7756
|
|
10
|
+
pmxt_internal/api_client.py,sha256=nNG9x5sU703c-iI5McO1R21TNLikw9sHxn5osmiSmkk,27889
|
|
11
11
|
pmxt_internal/api_response.py,sha256=eMxw1mpmJcoGZ3gs9z6jM4oYoZ10Gjk333s9sKxGv7s,652
|
|
12
|
-
pmxt_internal/configuration.py,sha256=
|
|
12
|
+
pmxt_internal/configuration.py,sha256=QzLqWzVIo7r9XwfJKlfaHgWg7cbgNmERylbCO6Ja4b8,18320
|
|
13
13
|
pmxt_internal/exceptions.py,sha256=txF8A7vlan57JS69kFPs-IZF-Qhp7IZobBTJVa4fOaM,6644
|
|
14
14
|
pmxt_internal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
pmxt_internal/rest.py,sha256=FMj4yaV6XLr842u_ScWHSzQsTFdk0jaUeuWLJoRbogQ,9760
|
|
@@ -50,7 +50,7 @@ pmxt_internal/models/get_markets_by_slug_request.py,sha256=PtjXAw6hixHuYzCvSGH1a
|
|
|
50
50
|
pmxt_internal/models/health_check200_response.py,sha256=yR_OkIlTPztO0zFmpyWllSwyaEbI48RpumfmVVCJAyc,2758
|
|
51
51
|
pmxt_internal/models/history_filter_params.py,sha256=0i9oQLwJsRWRyzPZuW467y_0ccKpc2_I6T2lgZCkHd4,3239
|
|
52
52
|
pmxt_internal/models/market_filter_params.py,sha256=Jun3HbQP05HEXlht1bYCrqrlgbO0QjP6vCOKCHkZn-E,3638
|
|
53
|
-
pmxt_internal/models/market_outcome.py,sha256=
|
|
53
|
+
pmxt_internal/models/market_outcome.py,sha256=W8-34Q-DQR-pVmpuAROSusu8BxwGfeUporTxh8BhKsQ,3532
|
|
54
54
|
pmxt_internal/models/order.py,sha256=WniZ6JgnnhPBPyZje1wzgmsz4OjyOCIl5a-ksQFmUNM,4768
|
|
55
55
|
pmxt_internal/models/order_book.py,sha256=FZQ5g81szBtpCun3vFFTDZb_xZkwUMVyEIF1ZZPzqhI,3615
|
|
56
56
|
pmxt_internal/models/order_level.py,sha256=dMeuXlhBqe1kA-R1ysFjt77qJxx6ukrZHwO1y3hZ6EM,2735
|
|
@@ -62,11 +62,11 @@ pmxt_internal/models/search_markets_request.py,sha256=BARoy2GXgV7RQNIGck6UaOyQqf
|
|
|
62
62
|
pmxt_internal/models/search_markets_request_args_inner.py,sha256=PkusFd_OxhUsItsBpluPJA11zg0sXXjbOK-lPmemvLs,5561
|
|
63
63
|
pmxt_internal/models/trade.py,sha256=U6Fc18rbwILs9FmX8CSDYYL8dF6763l8QzeMQNRxQdo,3328
|
|
64
64
|
pmxt_internal/models/unified_event.py,sha256=zJVokyA3_Ny9cFxI_kZaJShB_V-KMqr5rY-i6oMDXCU,3896
|
|
65
|
-
pmxt_internal/models/unified_market.py,sha256=
|
|
65
|
+
pmxt_internal/models/unified_market.py,sha256=0y917aPCUNtlToDhfJWwVh3lGT-1VRFh_pDF9f3C9b8,5919
|
|
66
66
|
pmxt_internal/models/watch_order_book_request.py,sha256=kavGUI-SLz2-Kam_jcJ_h0GDe0-9UkxqCmVsAi6Uios,3726
|
|
67
67
|
pmxt_internal/models/watch_order_book_request_args_inner.py,sha256=ZHrjmFDGxRG5MXbuz4mUp9KFfo3XS7zuXWTyMNgi4xI,5464
|
|
68
68
|
pmxt_internal/models/watch_trades_request.py,sha256=brrg8JbEe-aeg7mIe_Y2HzRPogp-IfRhkXChrxzqoLU,3722
|
|
69
|
-
pmxt-1.
|
|
70
|
-
pmxt-1.
|
|
71
|
-
pmxt-1.
|
|
72
|
-
pmxt-1.
|
|
69
|
+
pmxt-1.6.0.dist-info/METADATA,sha256=aglrK1EbEVfA2fdanlMDKDCmRdHd8ONF8mcUOuvf9h8,6449
|
|
70
|
+
pmxt-1.6.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
71
|
+
pmxt-1.6.0.dist-info/top_level.txt,sha256=J_jrcouJ-x-5lpcXMxeW0GOSi1HsBVR5_PdSfvigVrw,19
|
|
72
|
+
pmxt-1.6.0.dist-info/RECORD,,
|
pmxt_internal/__init__.py
CHANGED
pmxt_internal/api_client.py
CHANGED
|
@@ -91,7 +91,7 @@ class ApiClient:
|
|
|
91
91
|
self.default_headers[header_name] = header_value
|
|
92
92
|
self.cookie = cookie
|
|
93
93
|
# Set default User-Agent.
|
|
94
|
-
self.user_agent = 'OpenAPI-Generator/1.
|
|
94
|
+
self.user_agent = 'OpenAPI-Generator/1.6.0/python'
|
|
95
95
|
self.client_side_validation = configuration.client_side_validation
|
|
96
96
|
|
|
97
97
|
def __enter__(self):
|
pmxt_internal/configuration.py
CHANGED
|
@@ -506,7 +506,7 @@ class Configuration:
|
|
|
506
506
|
"OS: {env}\n"\
|
|
507
507
|
"Python Version: {pyversion}\n"\
|
|
508
508
|
"Version of the API: 0.4.4\n"\
|
|
509
|
-
"SDK Package Version: 1.
|
|
509
|
+
"SDK Package Version: 1.6.0".\
|
|
510
510
|
format(env=sys.platform, pyversion=sys.version)
|
|
511
511
|
|
|
512
512
|
def get_host_settings(self) -> List[HostSetting]:
|
|
@@ -26,12 +26,13 @@ class MarketOutcome(BaseModel):
|
|
|
26
26
|
"""
|
|
27
27
|
MarketOutcome
|
|
28
28
|
""" # noqa: E501
|
|
29
|
-
id: Optional[StrictStr] = None
|
|
29
|
+
id: Optional[StrictStr] = Field(default=None, description="DEPRECATED: Use outcomeId instead. Will be removed in v2.0")
|
|
30
|
+
outcome_id: Optional[StrictStr] = Field(default=None, description="Outcome ID for trading operations (CLOB Token ID for Polymarket, Market Ticker for Kalshi)", alias="outcomeId")
|
|
30
31
|
label: Optional[StrictStr] = None
|
|
31
32
|
price: Optional[Union[StrictFloat, StrictInt]] = None
|
|
32
33
|
price_change24h: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, alias="priceChange24h")
|
|
33
34
|
metadata: Optional[Dict[str, Any]] = Field(default=None, description="Exchange-specific metadata (e.g., clobTokenId for Polymarket)")
|
|
34
|
-
__properties: ClassVar[List[str]] = ["id", "label", "price", "priceChange24h", "metadata"]
|
|
35
|
+
__properties: ClassVar[List[str]] = ["id", "outcomeId", "label", "price", "priceChange24h", "metadata"]
|
|
35
36
|
|
|
36
37
|
model_config = ConfigDict(
|
|
37
38
|
populate_by_name=True,
|
|
@@ -85,6 +86,7 @@ class MarketOutcome(BaseModel):
|
|
|
85
86
|
|
|
86
87
|
_obj = cls.model_validate({
|
|
87
88
|
"id": obj.get("id"),
|
|
89
|
+
"outcomeId": obj.get("outcomeId"),
|
|
88
90
|
"label": obj.get("label"),
|
|
89
91
|
"price": obj.get("price"),
|
|
90
92
|
"priceChange24h": obj.get("priceChange24h"),
|
|
@@ -28,7 +28,8 @@ class UnifiedMarket(BaseModel):
|
|
|
28
28
|
"""
|
|
29
29
|
UnifiedMarket
|
|
30
30
|
""" # noqa: E501
|
|
31
|
-
id: Optional[StrictStr] = None
|
|
31
|
+
id: Optional[StrictStr] = Field(default=None, description="DEPRECATED: Use marketId instead. Will be removed in v2.0")
|
|
32
|
+
market_id: Optional[StrictStr] = Field(default=None, description="The unique identifier for this market", alias="marketId")
|
|
32
33
|
title: Optional[StrictStr] = None
|
|
33
34
|
description: Optional[StrictStr] = None
|
|
34
35
|
outcomes: Optional[List[MarketOutcome]] = None
|
|
@@ -45,7 +46,7 @@ class UnifiedMarket(BaseModel):
|
|
|
45
46
|
no: Optional[MarketOutcome] = None
|
|
46
47
|
up: Optional[MarketOutcome] = None
|
|
47
48
|
down: Optional[MarketOutcome] = None
|
|
48
|
-
__properties: ClassVar[List[str]] = ["id", "title", "description", "outcomes", "resolutionDate", "volume24h", "volume", "liquidity", "openInterest", "url", "image", "category", "tags", "yes", "no", "up", "down"]
|
|
49
|
+
__properties: ClassVar[List[str]] = ["id", "marketId", "title", "description", "outcomes", "resolutionDate", "volume24h", "volume", "liquidity", "openInterest", "url", "image", "category", "tags", "yes", "no", "up", "down"]
|
|
49
50
|
|
|
50
51
|
model_config = ConfigDict(
|
|
51
52
|
populate_by_name=True,
|
|
@@ -118,6 +119,7 @@ class UnifiedMarket(BaseModel):
|
|
|
118
119
|
|
|
119
120
|
_obj = cls.model_validate({
|
|
120
121
|
"id": obj.get("id"),
|
|
122
|
+
"marketId": obj.get("marketId"),
|
|
121
123
|
"title": obj.get("title"),
|
|
122
124
|
"description": obj.get("description"),
|
|
123
125
|
"outcomes": [MarketOutcome.from_dict(_item) for _item in obj["outcomes"]] if obj.get("outcomes") is not None else None,
|
|
File without changes
|
|
File without changes
|