pmxt 1.5.6__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 +289 -24
- pmxt/client.py +224 -2
- pmxt/models.py +71 -0
- pmxt/server_manager.py +18 -1
- {pmxt-1.5.6.dist-info → pmxt-1.6.0.dist-info}/METADATA +1 -1
- {pmxt-1.5.6.dist-info → pmxt-1.6.0.dist-info}/RECORD +15 -15
- pmxt_internal/__init__.py +1 -1
- pmxt_internal/api_client.py +1 -1
- pmxt_internal/configuration.py +1 -1
- pmxt_internal/models/create_order_params.py +4 -2
- pmxt_internal/models/market_outcome.py +4 -2
- pmxt_internal/models/unified_market.py +4 -2
- {pmxt-1.5.6.dist-info → pmxt-1.6.0.dist-info}/WHEEL +0 -0
- {pmxt-1.5.6.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;
|
|
@@ -104956,13 +105203,16 @@ var require_polymarket = __commonJS({
|
|
|
104956
105203
|
}
|
|
104957
105204
|
}
|
|
104958
105205
|
try {
|
|
104959
|
-
const
|
|
105206
|
+
const orderArgs = {
|
|
104960
105207
|
tokenID: params.outcomeId,
|
|
104961
105208
|
price,
|
|
104962
105209
|
side,
|
|
104963
|
-
size: params.amount
|
|
104964
|
-
|
|
104965
|
-
|
|
105210
|
+
size: params.amount
|
|
105211
|
+
};
|
|
105212
|
+
if (params.fee !== void 0 && params.fee !== null) {
|
|
105213
|
+
orderArgs.feeRateBps = params.fee;
|
|
105214
|
+
}
|
|
105215
|
+
const response = await client.createAndPostOrder(orderArgs, {
|
|
104966
105216
|
tickSize
|
|
104967
105217
|
});
|
|
104968
105218
|
if (!response || !response.success) {
|
|
@@ -104979,6 +105229,7 @@ var require_polymarket = __commonJS({
|
|
|
104979
105229
|
status: "open",
|
|
104980
105230
|
filled: 0,
|
|
104981
105231
|
remaining: params.amount,
|
|
105232
|
+
fee: params.fee,
|
|
104982
105233
|
timestamp: Date.now()
|
|
104983
105234
|
};
|
|
104984
105235
|
} catch (error) {
|
|
@@ -105188,8 +105439,10 @@ var require_utils10 = __commonJS({
|
|
|
105188
105439
|
const tokenEntries = Object.entries(market.tokens);
|
|
105189
105440
|
tokenEntries.forEach(([label, tokenId], index) => {
|
|
105190
105441
|
const outcomePrice = market.prices[index] || 0;
|
|
105442
|
+
const outcomeIdValue = tokenId;
|
|
105191
105443
|
outcomes.push({
|
|
105192
|
-
id:
|
|
105444
|
+
id: outcomeIdValue,
|
|
105445
|
+
outcomeId: outcomeIdValue,
|
|
105193
105446
|
label: label.charAt(0).toUpperCase() + label.slice(1),
|
|
105194
105447
|
// Capitalize 'yes'/'no'
|
|
105195
105448
|
price: outcomePrice,
|
|
@@ -105203,6 +105456,7 @@ var require_utils10 = __commonJS({
|
|
|
105203
105456
|
}
|
|
105204
105457
|
const um = {
|
|
105205
105458
|
id: market.slug,
|
|
105459
|
+
marketId: market.slug,
|
|
105206
105460
|
title: market.title || market.question,
|
|
105207
105461
|
description: market.description,
|
|
105208
105462
|
outcomes,
|
|
@@ -105411,7 +105665,9 @@ var require_fetchOHLCV2 = __commonJS({
|
|
|
105411
105665
|
exports2.fetchOHLCV = fetchOHLCV;
|
|
105412
105666
|
var axios_1 = __importDefault(require_axios());
|
|
105413
105667
|
var utils_1 = require_utils10();
|
|
105668
|
+
var validation_1 = require_validation();
|
|
105414
105669
|
async function fetchOHLCV(id, params) {
|
|
105670
|
+
(0, validation_1.validateIdFormat)(id, "OHLCV");
|
|
105415
105671
|
try {
|
|
105416
105672
|
const fidelity = (0, utils_1.mapIntervalToFidelity)(params.resolution);
|
|
105417
105673
|
const url2 = `${utils_1.LIMITLESS_API_URL}/markets/${id}/historical-price`;
|
|
@@ -105462,7 +105718,9 @@ var require_fetchOrderBook2 = __commonJS({
|
|
|
105462
105718
|
exports2.fetchOrderBook = fetchOrderBook;
|
|
105463
105719
|
var axios_1 = __importDefault(require_axios());
|
|
105464
105720
|
var utils_1 = require_utils10();
|
|
105721
|
+
var validation_1 = require_validation();
|
|
105465
105722
|
async function fetchOrderBook(id) {
|
|
105723
|
+
(0, validation_1.validateIdFormat)(id, "OrderBook");
|
|
105466
105724
|
try {
|
|
105467
105725
|
const url2 = `${utils_1.LIMITLESS_API_URL}/markets/${id}/orderbook`;
|
|
105468
105726
|
const response = await axios_1.default.get(url2);
|
|
@@ -106088,6 +106346,7 @@ var require_utils11 = __commonJS({
|
|
|
106088
106346
|
{
|
|
106089
106347
|
id: market.ticker,
|
|
106090
106348
|
// The actual market ticker (primary tradeable)
|
|
106349
|
+
outcomeId: market.ticker,
|
|
106091
106350
|
label: candidateName || "Yes",
|
|
106092
106351
|
price,
|
|
106093
106352
|
priceChange24h: priceChange
|
|
@@ -106095,6 +106354,7 @@ var require_utils11 = __commonJS({
|
|
|
106095
106354
|
{
|
|
106096
106355
|
id: `${market.ticker}-NO`,
|
|
106097
106356
|
// Virtual ID for the No outcome
|
|
106357
|
+
outcomeId: `${market.ticker}-NO`,
|
|
106098
106358
|
label: candidateName ? `Not ${candidateName}` : "No",
|
|
106099
106359
|
price: 1 - price,
|
|
106100
106360
|
priceChange24h: -priceChange
|
|
@@ -106114,6 +106374,7 @@ var require_utils11 = __commonJS({
|
|
|
106114
106374
|
}
|
|
106115
106375
|
const um = {
|
|
106116
106376
|
id: market.ticker,
|
|
106377
|
+
marketId: market.ticker,
|
|
106117
106378
|
title: event.title,
|
|
106118
106379
|
description: market.rules_primary || market.rules_secondary || "",
|
|
106119
106380
|
outcomes,
|
|
@@ -106442,7 +106703,9 @@ var require_fetchOHLCV3 = __commonJS({
|
|
|
106442
106703
|
exports2.fetchOHLCV = fetchOHLCV;
|
|
106443
106704
|
var axios_1 = __importDefault(require_axios());
|
|
106444
106705
|
var utils_1 = require_utils11();
|
|
106706
|
+
var validation_1 = require_validation();
|
|
106445
106707
|
async function fetchOHLCV(id, params) {
|
|
106708
|
+
(0, validation_1.validateIdFormat)(id, "OHLCV");
|
|
106446
106709
|
try {
|
|
106447
106710
|
const cleanedId = id.replace(/-NO$/, "");
|
|
106448
106711
|
const normalizedId = cleanedId.toUpperCase();
|
|
@@ -106528,7 +106791,9 @@ var require_fetchOrderBook3 = __commonJS({
|
|
|
106528
106791
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
106529
106792
|
exports2.fetchOrderBook = fetchOrderBook;
|
|
106530
106793
|
var axios_1 = __importDefault(require_axios());
|
|
106794
|
+
var validation_1 = require_validation();
|
|
106531
106795
|
async function fetchOrderBook(id) {
|
|
106796
|
+
(0, validation_1.validateIdFormat)(id, "OrderBook");
|
|
106532
106797
|
try {
|
|
106533
106798
|
const isNoOutcome = id.endsWith("-NO");
|
|
106534
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,
|
|
@@ -678,6 +898,8 @@ class Exchange(ABC):
|
|
|
678
898
|
}
|
|
679
899
|
if params.price is not None:
|
|
680
900
|
params_dict["price"] = params.price
|
|
901
|
+
if params.fee is not None:
|
|
902
|
+
params_dict["fee"] = params.fee
|
|
681
903
|
|
|
682
904
|
request_body_dict = {"args": [params_dict]}
|
|
683
905
|
|
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
|
|
@@ -395,3 +396,73 @@ class CreateOrderParams:
|
|
|
395
396
|
|
|
396
397
|
price: Optional[float] = None
|
|
397
398
|
"""Limit price (required for limit orders, 0.0-1.0)"""
|
|
399
|
+
|
|
400
|
+
fee: Optional[int] = None
|
|
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
|
|
@@ -21,7 +21,7 @@ pmxt_internal/models/base_request.py,sha256=ZNipF7ycXFkQJ6j3QmB1TzA0UO3fB54AMPlA
|
|
|
21
21
|
pmxt_internal/models/base_response.py,sha256=g-NG4Swxl3cg4-YOCPl65dUeHzOnA9S7ubTj8HOYZs0,2975
|
|
22
22
|
pmxt_internal/models/cancel_order_request.py,sha256=Q_tKEneDlyD9ZsqCifr4No9coPmzUWAiSnJFH2BhL5k,3153
|
|
23
23
|
pmxt_internal/models/create_order200_response.py,sha256=f4urlJUUhTCOON-alIg9Ac_q3ymHqHyP_BNtDB0pyh4,3345
|
|
24
|
-
pmxt_internal/models/create_order_params.py,sha256=
|
|
24
|
+
pmxt_internal/models/create_order_params.py,sha256=VxrjO1OFh6bxPlQTtfJA_B79A6edOPgZ44j4HGBPdCk,3736
|
|
25
25
|
pmxt_internal/models/create_order_request.py,sha256=prj6TnIFbhB8eDq-6e-MK2DtfDzAB6P-SoEEEST0cP8,3616
|
|
26
26
|
pmxt_internal/models/error_detail.py,sha256=590jlnQmIgqcjUQ5ef07_nWMn7fnyjuAvkUjmSoAkMs,2605
|
|
27
27
|
pmxt_internal/models/error_response.py,sha256=c5DgOpTGqx9Qoz7hYKhRPAM3UfoX4GBWkyhfxerMXEI,2979
|
|
@@ -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]:
|
|
@@ -32,7 +32,8 @@ class CreateOrderParams(BaseModel):
|
|
|
32
32
|
type: StrictStr
|
|
33
33
|
amount: Union[StrictFloat, StrictInt]
|
|
34
34
|
price: Optional[Union[StrictFloat, StrictInt]] = None
|
|
35
|
-
|
|
35
|
+
fee: Optional[Union[StrictFloat, StrictInt]] = None
|
|
36
|
+
__properties: ClassVar[List[str]] = ["marketId", "outcomeId", "side", "type", "amount", "price", "fee"]
|
|
36
37
|
|
|
37
38
|
@field_validator('side')
|
|
38
39
|
def side_validate_enum(cls, value):
|
|
@@ -104,7 +105,8 @@ class CreateOrderParams(BaseModel):
|
|
|
104
105
|
"side": obj.get("side"),
|
|
105
106
|
"type": obj.get("type"),
|
|
106
107
|
"amount": obj.get("amount"),
|
|
107
|
-
"price": obj.get("price")
|
|
108
|
+
"price": obj.get("price"),
|
|
109
|
+
"fee": obj.get("fee")
|
|
108
110
|
})
|
|
109
111
|
return _obj
|
|
110
112
|
|
|
@@ -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
|