poly-position-watcher 0.2.7__tar.gz → 0.2.9__tar.gz

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.
Files changed (25) hide show
  1. {poly_position_watcher-0.2.7/poly_position_watcher.egg-info → poly_position_watcher-0.2.9}/PKG-INFO +22 -4
  2. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/README.md +21 -3
  3. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher/_version.py +1 -1
  4. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher/api_worker.py +12 -0
  5. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher/common/enums.py +10 -0
  6. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher/position_service.py +44 -4
  7. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher/schema/position_model.py +9 -4
  8. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher/trade_calculator.py +21 -5
  9. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9/poly_position_watcher.egg-info}/PKG-INFO +22 -4
  10. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/pyproject.toml +1 -1
  11. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/setup.py +1 -1
  12. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/LICENSE +0 -0
  13. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/MANIFEST.in +0 -0
  14. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher/__init__.py +0 -0
  15. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher/common/__init__.py +0 -0
  16. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher/common/logger.py +0 -0
  17. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher/schema/__init__.py +0 -0
  18. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher/schema/base.py +0 -0
  19. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher/schema/common_model.py +0 -0
  20. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher/wss_worker.py +0 -0
  21. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher.egg-info/SOURCES.txt +0 -0
  22. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher.egg-info/dependency_links.txt +0 -0
  23. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher.egg-info/requires.txt +0 -0
  24. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/poly_position_watcher.egg-info/top_level.txt +0 -0
  25. {poly_position_watcher-0.2.7 → poly_position_watcher-0.2.9}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: poly-position-watcher
3
- Version: 0.2.7
3
+ Version: 0.2.9
4
4
  Summary: polymarket proxy wallet redeem
5
5
  Home-page: https://github.com/tosmart01/polymarket-position-watcher
6
6
  Author: pinbar
@@ -19,7 +19,11 @@ Dynamic: requires-python
19
19
 
20
20
  # poly-position-watcher
21
21
 
22
- English README (default). For Chinese: [README.zh.md](README.zh.md)
22
+ ![PyPI](https://img.shields.io/pypi/v/poly-web3)
23
+ ![Python](https://img.shields.io/pypi/pyversions/poly-web3)
24
+ ![License](https://img.shields.io/github/license/tosmart01/poly-web3)
25
+
26
+ [English](README.md) | [中文](README.zh.md)
23
27
 
24
28
  ## Overview
25
29
 
@@ -28,6 +32,9 @@ English README (default). For Chinese: [README.zh.md](README.zh.md)
28
32
  - WSS real-time tracking for `TRADE` and `ORDER` (positions + orders)
29
33
  - HTTP polling fallback for reliability
30
34
  - Optional fee calculation (toggle + custom formula)
35
+ - Position fields for fill checks:
36
+ `size` (post-fee net size), `original_size` (pre-fee net size), `sellable_size` (on-chain confirmed size), `fee_amount` (accumulated fee amount)
37
+ - Failed trades are detected and returned on positions (`has_failed`, `failed_trades`)
31
38
 
32
39
  **Note: WSS disconnects are auto-detected and reconnected.**
33
40
 
@@ -65,6 +72,10 @@ with PositionWatcherService(
65
72
  order: OrderMessage = service.get_order("<order_id>")
66
73
  print(position)
67
74
  print(order)
75
+ if position:
76
+ print("size(post-fee):", position.size)
77
+ print("size(pre-fee):", position.original_size)
78
+ print("fee_amount:", position.fee_amount)
68
79
  service.show_positions(limit=10)
69
80
  service.show_orders(limit=10)
70
81
 
@@ -107,17 +118,22 @@ OrderMessage(
107
118
  UserPosition(
108
119
  price: 0.0,
109
120
  size: 0.0,
121
+ original_size: 0.0,
110
122
  volume: 0.0,
123
+ fee_amount: 0.0,
124
+ sellable_size: 0.0,
111
125
  token_id: '',
112
126
  last_update: 0.0,
113
127
  market_id: None,
114
128
  outcome: None,
115
- created_at: None
129
+ created_at: None,
130
+ has_failed: False,
131
+ failed_trades: []
116
132
  )
117
133
  ```
118
134
 
119
135
 
120
- **Full example (`examples/http_bootstrap_example.py`)**
136
+ **Full example (`examples/example.py`)**
121
137
 
122
138
  ## Pretty printing
123
139
 
@@ -136,6 +152,8 @@ Some Polymarket markets enable taker fee / maker rebate. This library **fully su
136
152
  - Enable with `enable_fee_calc=True` to apply fees using `feeRateBps` from trades/orders
137
153
  - Customize with `fee_calc_fn` if you need a different formula
138
154
  - Disable (default) if you prefer pre-fee positions
155
+ - Returned position fields:
156
+ `size` = post-fee net size, `original_size` = pre-fee net size, `fee_amount` = accumulated fee amount
139
157
 
140
158
  Default fee formula (when `fee_calc_fn` is not provided):
141
159
  `fee = 0.25 * (p * (1 - p)) ** 2 * (fee_rate_bps / 1000)`, and `new_size = (1 - fee) * size`.
@@ -1,6 +1,10 @@
1
1
  # poly-position-watcher
2
2
 
3
- English README (default). For Chinese: [README.zh.md](README.zh.md)
3
+ ![PyPI](https://img.shields.io/pypi/v/poly-web3)
4
+ ![Python](https://img.shields.io/pypi/pyversions/poly-web3)
5
+ ![License](https://img.shields.io/github/license/tosmart01/poly-web3)
6
+
7
+ [English](README.md) | [中文](README.zh.md)
4
8
 
5
9
  ## Overview
6
10
 
@@ -9,6 +13,9 @@ English README (default). For Chinese: [README.zh.md](README.zh.md)
9
13
  - WSS real-time tracking for `TRADE` and `ORDER` (positions + orders)
10
14
  - HTTP polling fallback for reliability
11
15
  - Optional fee calculation (toggle + custom formula)
16
+ - Position fields for fill checks:
17
+ `size` (post-fee net size), `original_size` (pre-fee net size), `sellable_size` (on-chain confirmed size), `fee_amount` (accumulated fee amount)
18
+ - Failed trades are detected and returned on positions (`has_failed`, `failed_trades`)
12
19
 
13
20
  **Note: WSS disconnects are auto-detected and reconnected.**
14
21
 
@@ -46,6 +53,10 @@ with PositionWatcherService(
46
53
  order: OrderMessage = service.get_order("<order_id>")
47
54
  print(position)
48
55
  print(order)
56
+ if position:
57
+ print("size(post-fee):", position.size)
58
+ print("size(pre-fee):", position.original_size)
59
+ print("fee_amount:", position.fee_amount)
49
60
  service.show_positions(limit=10)
50
61
  service.show_orders(limit=10)
51
62
 
@@ -88,17 +99,22 @@ OrderMessage(
88
99
  UserPosition(
89
100
  price: 0.0,
90
101
  size: 0.0,
102
+ original_size: 0.0,
91
103
  volume: 0.0,
104
+ fee_amount: 0.0,
105
+ sellable_size: 0.0,
92
106
  token_id: '',
93
107
  last_update: 0.0,
94
108
  market_id: None,
95
109
  outcome: None,
96
- created_at: None
110
+ created_at: None,
111
+ has_failed: False,
112
+ failed_trades: []
97
113
  )
98
114
  ```
99
115
 
100
116
 
101
- **Full example (`examples/http_bootstrap_example.py`)**
117
+ **Full example (`examples/example.py`)**
102
118
 
103
119
  ## Pretty printing
104
120
 
@@ -117,6 +133,8 @@ Some Polymarket markets enable taker fee / maker rebate. This library **fully su
117
133
  - Enable with `enable_fee_calc=True` to apply fees using `feeRateBps` from trades/orders
118
134
  - Customize with `fee_calc_fn` if you need a different formula
119
135
  - Disable (default) if you prefer pre-fee positions
136
+ - Returned position fields:
137
+ `size` = post-fee net size, `original_size` = pre-fee net size, `fee_amount` = accumulated fee amount
120
138
 
121
139
  Default fee formula (when `fee_calc_fn` is not provided):
122
140
  `fee = 0.25 * (p * (1 - p)) ** 2 * (fee_rate_bps / 1000)`, and `new_size = (1 - fee) * size`.
@@ -1,3 +1,3 @@
1
1
  __all__ = ["__version__"]
2
2
 
3
- __version__ = "0.2.6"
3
+ __version__ = "0.2.9"
@@ -262,6 +262,18 @@ class HttpFallbackManager:
262
262
  if order_ids:
263
263
  self.orders.update(order_ids)
264
264
  logger.info(f"Added HTTP monitoring: {len(market_ids or [])} markets, {len(order_ids or [])} orders")
265
+
266
+ def set_markets(self, market_ids: list[str] | None = None):
267
+ """Replace monitored markets with the provided list."""
268
+ with self._lock:
269
+ self.markets = set(market_ids or [])
270
+ logger.info(f"Set HTTP monitoring markets: {len(self.markets)} total")
271
+
272
+ def set_orders(self, order_ids: list[str] | None = None):
273
+ """Replace monitored orders with the provided list."""
274
+ with self._lock:
275
+ self.orders = set(order_ids or [])
276
+ logger.info(f"Set HTTP monitoring orders: {len(self.orders)} total")
265
277
 
266
278
  def remove(self, market_ids: list[str] = None, order_ids: list[str] = None):
267
279
  """Remove markets/orders from monitoring."""
@@ -18,3 +18,13 @@ class MarketEvent(str, Enum):
18
18
  PRICE_CHANGE = "price_change"
19
19
  TICK_SIZE_CHANGE = "tick_size_change"
20
20
  BOOK = "book"
21
+
22
+
23
+ class TradeStatus(str, Enum):
24
+ """Trade status values from Polymarket."""
25
+
26
+ MATCHED = "MATCHED"
27
+ MINED = "MINED"
28
+ CONFIRMED = "CONFIRMED"
29
+ RETRYING = "RETRYING"
30
+ FAILED = "FAILED"
@@ -12,7 +12,7 @@ from queue import Queue, Empty
12
12
  from collections import defaultdict
13
13
  from typing import Callable, Dict, List
14
14
 
15
- from poly_position_watcher.common.enums import Side
15
+ from poly_position_watcher.common.enums import Side, TradeStatus
16
16
  from poly_position_watcher.common.logger import logger
17
17
  from poly_position_watcher.api_worker import APIWorker, HttpFallbackManager
18
18
 
@@ -27,7 +27,7 @@ from rich.console import Console
27
27
  from rich.table import Table
28
28
  from poly_position_watcher.wss_worker import PolymarketUserWS
29
29
 
30
- FILLED_TRADE = "FAILED"
30
+ FAILED_TRADE = TradeStatus.FAILED
31
31
 
32
32
 
33
33
  class PositionStore:
@@ -139,8 +139,14 @@ class PositionStore:
139
139
  def build_position(
140
140
  self, trades: list[TradeMessage], token_id, outcome: str
141
141
  ) -> UserPosition | None:
142
- filled_trades = [i for i in trades if i.status == FILLED_TRADE]
143
- success_trades = [i for i in trades if i.status != FILLED_TRADE]
142
+ def _status_is(trade: TradeMessage, status: TradeStatus) -> bool:
143
+ return trade.status == status or trade.status == status.value
144
+
145
+ filled_trades = [i for i in trades if _status_is(i, FAILED_TRADE)]
146
+ success_trades = [i for i in trades if not _status_is(i, FAILED_TRADE)]
147
+ confirmed_trades = [
148
+ i for i in success_trades if _status_is(i, TradeStatus.CONFIRMED)
149
+ ]
144
150
  has_failed = bool(len(filled_trades))
145
151
  if has_failed:
146
152
  filled_size = sum([i.size for i in filled_trades])
@@ -152,10 +158,22 @@ class PositionStore:
152
158
  enable_fee_calc=self.enable_fee_calc,
153
159
  fee_calc_fn=self.fee_calc_fn,
154
160
  )
161
+ sellable_size = 0.0
162
+ if confirmed_trades:
163
+ confirmed_result = calculate_position_from_trades(
164
+ confirmed_trades,
165
+ user_address=self.user_address,
166
+ enable_fee_calc=self.enable_fee_calc,
167
+ fee_calc_fn=self.fee_calc_fn,
168
+ )
169
+ sellable_size = confirmed_result.size
155
170
  current = UserPosition(
156
171
  price=position_result.avg_price,
157
172
  size=position_result.size,
173
+ original_size=position_result.original_size,
158
174
  volume=position_result.amount,
175
+ fee_amount=position_result.fee_amount,
176
+ sellable_size=sellable_size,
159
177
  token_id=token_id,
160
178
  last_update=position_result.last_update,
161
179
  market_id=trades[0].market,
@@ -591,6 +609,28 @@ class PositionWatcherService:
591
609
 
592
610
  self._http_fallback.remove(market_ids=market_ids, order_ids=order_ids)
593
611
 
612
+ def set_market_http_listen(self, market_ids: list[str] = None):
613
+ """
614
+ Replace HTTP fallback market monitoring list.
615
+
616
+ :param market_ids: List of market (condition) IDs to monitor
617
+ """
618
+ if not self.enable_http_fallback or not self._http_fallback:
619
+ return
620
+
621
+ self._http_fallback.set_markets(market_ids=market_ids)
622
+
623
+ def set_order_http_listen(self, order_ids: list[str] = None):
624
+ """
625
+ Replace HTTP fallback order monitoring list.
626
+
627
+ :param order_ids: List of order IDs to monitor
628
+ """
629
+ if not self.enable_http_fallback or not self._http_fallback:
630
+ return
631
+
632
+ self._http_fallback.set_orders(order_ids=order_ids)
633
+
594
634
  def clear_http(self):
595
635
  """Clear all HTTP fallback monitoring (threads keep running)."""
596
636
  if not self.enable_http_fallback or not self._http_fallback:
@@ -9,7 +9,7 @@ from typing import List, Optional, Literal
9
9
 
10
10
  from pydantic import BaseModel, Field, field_validator, model_validator
11
11
 
12
- from poly_position_watcher.common.enums import Side
12
+ from poly_position_watcher.common.enums import Side, TradeStatus
13
13
  from poly_position_watcher.schema.base import PrettyPrintBaseModel
14
14
 
15
15
 
@@ -52,7 +52,7 @@ class TradeMessage(BaseModel):
52
52
  price: float
53
53
  side: Side
54
54
  size: float
55
- status: str
55
+ status: TradeStatus | str
56
56
  taker_order_id: str
57
57
  timestamp: int | None = None
58
58
  match_time: int | None = None
@@ -122,7 +122,10 @@ class OrderMessage(PrettyPrintBaseModel):
122
122
  class UserPosition(PrettyPrintBaseModel):
123
123
  price: float
124
124
  size: float
125
+ original_size: float = 0.0
125
126
  volume: float
127
+ fee_amount: float = 0.0
128
+ sellable_size: float = 0.0
126
129
  token_id: Optional[str] = None
127
130
  last_update: float
128
131
  market_id: Optional[str] = None
@@ -133,8 +136,8 @@ class UserPosition(PrettyPrintBaseModel):
133
136
  failed_trades: list[TradeMessage] = Field(default_factory=list)
134
137
 
135
138
  @property
136
- def failed_size(self) -> float | None:
137
- return sum([i.size for i in self.failed_trades])
139
+ def failed_size(self) -> float:
140
+ return sum(i.size for i in self.failed_trades)
138
141
 
139
142
 
140
143
  class PositionDetails(BaseModel):
@@ -149,9 +152,11 @@ class PositionResult(PrettyPrintBaseModel):
149
152
  """仓位计算结果"""
150
153
 
151
154
  size: float
155
+ original_size: float = 0.0
152
156
  avg_price: float
153
157
  realized_pnl: float
154
158
  amount: float
159
+ fee_amount: float = 0.0
155
160
  position_value: Optional[float] = None
156
161
  unrealized_pnl: Optional[float] = None
157
162
  total_pnl: Optional[float] = None
@@ -39,18 +39,23 @@ def calculate_position_from_trades(
39
39
 
40
40
  buy_events = []
41
41
  sell_events = []
42
+ total_original_size = 0.0
42
43
 
43
44
  def apply_fee(
44
45
  size: float, price: float, fee_rate_bps: float, trader_side: str | None
45
- ) -> float:
46
+ ) -> tuple[float, float]:
46
47
  if (
47
48
  not enable_fee_calc
48
49
  or fee_rate_bps <= 0
49
50
  or trader_side != "TAKER"
50
51
  ):
51
- return size
52
+ return size, 0.0
52
53
  calc = fee_calc_fn or _default_fee_calc
53
- return calc(size, price, fee_rate_bps)
54
+ size_after_fee = calc(size, price, fee_rate_bps)
55
+ fee_amount = (size - size_after_fee) * price
56
+ return size_after_fee, fee_amount
57
+
58
+ total_fee_amount = 0.0
54
59
 
55
60
  # --- 1. 解析所有交易 ---
56
61
  for trade in trades:
@@ -61,24 +66,30 @@ def calculate_position_from_trades(
61
66
  if order.maker_address.upper() != user_address.upper():
62
67
  continue
63
68
  is_maker_order = True
64
- size = apply_fee(
69
+ size, fee_amount = apply_fee(
65
70
  order.size, order.price, order.fee_rate_bps, trade.trader_side
66
71
  )
72
+ total_fee_amount += fee_amount
67
73
 
68
74
  if order.side == Side.BUY:
69
75
  buy_events.append((size, order.price, trade.match_time))
76
+ total_original_size += order.size
70
77
  else:
71
78
  sell_events.append((-size, order.price, trade.match_time))
79
+ total_original_size -= order.size
72
80
 
73
81
  # taker 部分
74
82
  if not is_maker_order and trade.maker_address.upper() == user_address.upper():
75
- size = apply_fee(
83
+ size, fee_amount = apply_fee(
76
84
  trade.size, trade.price, trade.fee_rate_bps, trade.trader_side
77
85
  )
86
+ total_fee_amount += fee_amount
78
87
  if trade.side == Side.BUY:
79
88
  buy_events.append((size, trade.price, trade.match_time))
89
+ total_original_size += trade.size
80
90
  else:
81
91
  sell_events.append((-size, trade.price, trade.match_time))
92
+ total_original_size -= trade.size
82
93
 
83
94
  # --- 2. 时间排序 ---
84
95
  all_events = sorted(buy_events + sell_events, key=lambda x: x[2])
@@ -118,20 +129,25 @@ def calculate_position_from_trades(
118
129
 
119
130
  # --- 4. 计算最终持仓 ---
120
131
  total_size = clean(sum(q[0] for q in buy_queue))
132
+ original_size = clean(total_original_size)
121
133
  cost_basis = clean(sum(clean(q[0]) * q[1] for q in buy_queue))
122
134
 
123
135
  # 若因误差产生 0.0000003 的 ghost position → 完全清掉
124
136
  if abs(total_size) < EPS:
125
137
  total_size = 0.0
126
138
  cost_basis = 0.0
139
+ if abs(original_size) < EPS:
140
+ original_size = 0.0
127
141
 
128
142
  avg_price = cost_basis / total_size if total_size != 0 else 0.0
129
143
 
130
144
  return PositionResult(
131
145
  size=total_size,
146
+ original_size=original_size,
132
147
  avg_price=avg_price,
133
148
  realized_pnl=realized_pnl,
134
149
  amount=cost_basis,
150
+ fee_amount=total_fee_amount,
135
151
  is_long=total_size > 0,
136
152
  is_short=total_size < 0,
137
153
  details=PositionDetails(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: poly-position-watcher
3
- Version: 0.2.7
3
+ Version: 0.2.9
4
4
  Summary: polymarket proxy wallet redeem
5
5
  Home-page: https://github.com/tosmart01/polymarket-position-watcher
6
6
  Author: pinbar
@@ -19,7 +19,11 @@ Dynamic: requires-python
19
19
 
20
20
  # poly-position-watcher
21
21
 
22
- English README (default). For Chinese: [README.zh.md](README.zh.md)
22
+ ![PyPI](https://img.shields.io/pypi/v/poly-web3)
23
+ ![Python](https://img.shields.io/pypi/pyversions/poly-web3)
24
+ ![License](https://img.shields.io/github/license/tosmart01/poly-web3)
25
+
26
+ [English](README.md) | [中文](README.zh.md)
23
27
 
24
28
  ## Overview
25
29
 
@@ -28,6 +32,9 @@ English README (default). For Chinese: [README.zh.md](README.zh.md)
28
32
  - WSS real-time tracking for `TRADE` and `ORDER` (positions + orders)
29
33
  - HTTP polling fallback for reliability
30
34
  - Optional fee calculation (toggle + custom formula)
35
+ - Position fields for fill checks:
36
+ `size` (post-fee net size), `original_size` (pre-fee net size), `sellable_size` (on-chain confirmed size), `fee_amount` (accumulated fee amount)
37
+ - Failed trades are detected and returned on positions (`has_failed`, `failed_trades`)
31
38
 
32
39
  **Note: WSS disconnects are auto-detected and reconnected.**
33
40
 
@@ -65,6 +72,10 @@ with PositionWatcherService(
65
72
  order: OrderMessage = service.get_order("<order_id>")
66
73
  print(position)
67
74
  print(order)
75
+ if position:
76
+ print("size(post-fee):", position.size)
77
+ print("size(pre-fee):", position.original_size)
78
+ print("fee_amount:", position.fee_amount)
68
79
  service.show_positions(limit=10)
69
80
  service.show_orders(limit=10)
70
81
 
@@ -107,17 +118,22 @@ OrderMessage(
107
118
  UserPosition(
108
119
  price: 0.0,
109
120
  size: 0.0,
121
+ original_size: 0.0,
110
122
  volume: 0.0,
123
+ fee_amount: 0.0,
124
+ sellable_size: 0.0,
111
125
  token_id: '',
112
126
  last_update: 0.0,
113
127
  market_id: None,
114
128
  outcome: None,
115
- created_at: None
129
+ created_at: None,
130
+ has_failed: False,
131
+ failed_trades: []
116
132
  )
117
133
  ```
118
134
 
119
135
 
120
- **Full example (`examples/http_bootstrap_example.py`)**
136
+ **Full example (`examples/example.py`)**
121
137
 
122
138
  ## Pretty printing
123
139
 
@@ -136,6 +152,8 @@ Some Polymarket markets enable taker fee / maker rebate. This library **fully su
136
152
  - Enable with `enable_fee_calc=True` to apply fees using `feeRateBps` from trades/orders
137
153
  - Customize with `fee_calc_fn` if you need a different formula
138
154
  - Disable (default) if you prefer pre-fee positions
155
+ - Returned position fields:
156
+ `size` = post-fee net size, `original_size` = pre-fee net size, `fee_amount` = accumulated fee amount
139
157
 
140
158
  Default fee formula (when `fee_calc_fn` is not provided):
141
159
  `fee = 0.25 * (p * (1 - p)) ** 2 * (fee_rate_bps / 1000)`, and `new_size = (1 - fee) * size`.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "poly-position-watcher"
3
- version = "0.2.7"
3
+ version = "0.2.9"
4
4
  description = "polymarket proxy wallet redeem"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -24,7 +24,7 @@ for cache_dir in HERE.rglob("__pycache__"):
24
24
 
25
25
  setup(
26
26
  name=PROJECT.get("name", "poly-position-watcher"),
27
- version=PROJECT.get("version", "0.2.7"),
27
+ version=PROJECT.get("version", "0.2.9"),
28
28
  description=PROJECT.get("description", ""),
29
29
  long_description=README_PATH.read_text(encoding="utf-8") if README_PATH.exists() else "",
30
30
  long_description_content_type="text/markdown",