forked from WW-shan/poly_strategy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_paper.py
More file actions
136 lines (117 loc) · 5.15 KB
/
test_paper.py
File metadata and controls
136 lines (117 loc) · 5.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import unittest
from poly_strategy.models import BinaryMarketSnapshot, Leg, Opportunity, OrderBook
from poly_strategy.orderbook import Level
from poly_strategy.paper import select_paper_trades
from poly_strategy.scanner import find_yes_no_bundle_arbs
class PaperTests(unittest.TestCase):
def test_select_paper_trades_reserves_overlapping_liquidity(self):
shared_leg = Leg("polymarket", "a", "NO", "buy", 0.30, 100, "a-no")
better = Opportunity(
kind="mutually_exclusive",
quantity=100,
cost_per_share=0.80,
net_edge_per_share=0.20,
legs=[shared_leg, Leg("polymarket", "b", "NO", "buy", 0.50, 100, "b-no")],
ts="2026-05-09T00:00:00Z",
)
worse = Opportunity(
kind="mutually_exclusive",
quantity=100,
cost_per_share=0.95,
net_edge_per_share=0.05,
legs=[shared_leg, Leg("polymarket", "c", "NO", "buy", 0.65, 100, "c-no")],
ts="2026-05-09T00:00:00Z",
)
selection = select_paper_trades([worse, better])
self.assertEqual(len(selection.trades), 1)
self.assertEqual(selection.trades[0].opportunity, better)
self.assertEqual(len(selection.rejections), 1)
self.assertEqual(selection.rejections[0].reason, "overlapping_liquidity_reserved")
def test_select_paper_trades_caps_by_bankroll_and_per_trade_cap(self):
opportunity = Opportunity(
kind="yes_no_bundle",
quantity=100,
cost_per_share=0.80,
net_edge_per_share=0.10,
legs=[
Leg("polymarket", "a", "YES", "buy", 0.40, 100, "a-yes"),
Leg("polymarket", "a", "NO", "buy", 0.40, 100, "a-no"),
],
)
selection = select_paper_trades([opportunity], max_capital_per_trade=20, bankroll=12)
self.assertEqual(len(selection.trades), 1)
self.assertAlmostEqual(selection.trades[0].quantity, 15)
self.assertAlmostEqual(selection.trades[0].capital_used, 12)
self.assertAlmostEqual(selection.trades[0].edge, 1.5)
def test_select_paper_trades_reprices_reduced_quantity_from_orderbook_levels(self):
snapshot = BinaryMarketSnapshot(
market_id="sample",
venue="polymarket",
yes=OrderBook(asks=[Level(0.40, 5), Level(0.70, 100)], bids=[]),
no=OrderBook(asks=[Level(0.40, 5), Level(0.70, 100)], bids=[]),
fee_rate=0.0,
)
opportunity = find_yes_no_bundle_arbs(snapshot, min_net_edge=0.0)[0]
selection = select_paper_trades([opportunity], max_capital_per_trade=4)
self.assertEqual(len(selection.trades), 1)
trade = selection.trades[0]
self.assertAlmostEqual(trade.quantity, 5)
self.assertAlmostEqual(trade.capital_used, 4)
self.assertAlmostEqual(trade.edge, 1)
self.assertAlmostEqual(trade.opportunity.cost_per_share, 0.80)
self.assertAlmostEqual(trade.opportunity.net_edge_per_share, 0.20)
self.assertEqual([leg.worst_price for leg in trade.opportunity.legs], [0.40, 0.40])
def test_select_paper_trades_reprices_kalshi_fee_by_venue(self):
opportunity = Opportunity(
kind="cross_venue_same_binary",
quantity=100,
cost_per_share=0.980773,
net_edge_per_share=0.019227,
legs=[
Leg(
"polymarket",
"pm",
"YES",
"buy",
0.16,
100,
"pm-yes",
levels=[Level(0.16, 100)],
),
Leg(
"kalshi",
"kx",
"NO",
"buy",
0.81,
100,
"kx-no",
fee_rate=0.07,
levels=[Level(0.81, 100)],
),
],
)
selection = select_paper_trades([opportunity], max_capital_per_trade=10)
self.assertEqual(len(selection.trades), 1)
trade = selection.trades[0]
expected_cost_per_share = 0.16 + 0.81 + (0.07 * 0.81 * 0.19)
self.assertAlmostEqual(trade.opportunity.cost_per_share, expected_cost_per_share)
self.assertAlmostEqual(trade.quantity, 10 / expected_cost_per_share)
self.assertAlmostEqual(trade.edge, trade.quantity * (1.0 - expected_cost_per_share))
def test_select_paper_trades_rejects_below_min_roi_after_repricing(self):
opportunity = Opportunity(
kind="yes_no_bundle",
quantity=100,
cost_per_share=0.98,
net_edge_per_share=0.02,
legs=[
Leg("polymarket", "a", "YES", "buy", 0.45, 100, "a-yes"),
Leg("polymarket", "a", "NO", "buy", 0.53, 100, "a-no"),
],
)
selection = select_paper_trades([opportunity], min_roi=0.05)
self.assertEqual(selection.trades, [])
self.assertEqual(len(selection.rejections), 1)
self.assertEqual(selection.rejections[0].reason, "below_min_roi")
if __name__ == "__main__":
unittest.main()