@catalyst-team/poly-sdk 0.2.0 → 0.2.1
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.
- package/LICENSE +1 -1
- package/README.en.md +8 -44
- package/README.md +5 -3
- package/README.zh-CN.md +502 -0
- package/dist/__tests__/clob-api.test.d.ts +5 -0
- package/dist/__tests__/clob-api.test.d.ts.map +1 -0
- package/dist/__tests__/clob-api.test.js +240 -0
- package/dist/__tests__/clob-api.test.js.map +1 -0
- package/dist/__tests__/integration/bridge-client.integration.test.d.ts +11 -0
- package/dist/__tests__/integration/bridge-client.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/bridge-client.integration.test.js +260 -0
- package/dist/__tests__/integration/bridge-client.integration.test.js.map +1 -0
- package/dist/__tests__/integration/clob-api.integration.test.d.ts +13 -0
- package/dist/__tests__/integration/clob-api.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/clob-api.integration.test.js +170 -0
- package/dist/__tests__/integration/clob-api.integration.test.js.map +1 -0
- package/dist/__tests__/integration/ctf-client.integration.test.d.ts +17 -0
- package/dist/__tests__/integration/ctf-client.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/ctf-client.integration.test.js +234 -0
- package/dist/__tests__/integration/ctf-client.integration.test.js.map +1 -0
- package/dist/__tests__/integration/data-api.integration.test.d.ts +9 -0
- package/dist/__tests__/integration/data-api.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/data-api.integration.test.js +161 -0
- package/dist/__tests__/integration/data-api.integration.test.js.map +1 -0
- package/dist/__tests__/integration/gamma-api.integration.test.d.ts +9 -0
- package/dist/__tests__/integration/gamma-api.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/gamma-api.integration.test.js +170 -0
- package/dist/__tests__/integration/gamma-api.integration.test.js.map +1 -0
- package/dist/__tests__/test-utils.d.ts +92 -0
- package/dist/__tests__/test-utils.d.ts.map +1 -0
- package/dist/__tests__/test-utils.js +143 -0
- package/dist/__tests__/test-utils.js.map +1 -0
- package/dist/clients/bridge-client.d.ts +388 -0
- package/dist/clients/bridge-client.d.ts.map +1 -0
- package/dist/clients/bridge-client.js +587 -0
- package/dist/clients/bridge-client.js.map +1 -0
- package/dist/clients/clob-api.d.ts +318 -0
- package/dist/clients/clob-api.d.ts.map +1 -0
- package/dist/clients/clob-api.js +388 -0
- package/dist/clients/clob-api.js.map +1 -0
- package/dist/clients/ctf-client.d.ts +473 -0
- package/dist/clients/ctf-client.d.ts.map +1 -0
- package/dist/clients/ctf-client.js +915 -0
- package/dist/clients/ctf-client.js.map +1 -0
- package/dist/clients/data-api.d.ts +134 -0
- package/dist/clients/data-api.d.ts.map +1 -0
- package/dist/clients/data-api.js +265 -0
- package/dist/clients/data-api.js.map +1 -0
- package/dist/clients/gamma-api.d.ts +401 -0
- package/dist/clients/gamma-api.d.ts.map +1 -0
- package/dist/clients/gamma-api.js +352 -0
- package/dist/clients/gamma-api.js.map +1 -0
- package/dist/clients/trading-client.d.ts +252 -0
- package/dist/clients/trading-client.d.ts.map +1 -0
- package/dist/clients/trading-client.js +543 -0
- package/dist/clients/trading-client.js.map +1 -0
- package/dist/clients/websocket-manager.d.ts +100 -0
- package/dist/clients/websocket-manager.d.ts.map +1 -0
- package/dist/clients/websocket-manager.js +193 -0
- package/dist/clients/websocket-manager.js.map +1 -0
- package/dist/core/cache-adapter-bridge.d.ts +36 -0
- package/dist/core/cache-adapter-bridge.d.ts.map +1 -0
- package/dist/core/cache-adapter-bridge.js +81 -0
- package/dist/core/cache-adapter-bridge.js.map +1 -0
- package/dist/core/cache.d.ts +40 -0
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +71 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/errors.d.ts +38 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +84 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/rate-limiter.d.ts +31 -0
- package/dist/core/rate-limiter.d.ts.map +1 -0
- package/dist/core/rate-limiter.js +70 -0
- package/dist/core/rate-limiter.js.map +1 -0
- package/{src/core/types.ts → dist/core/types.d.ts} +169 -215
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +19 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/unified-cache.d.ts +63 -0
- package/dist/core/unified-cache.d.ts.map +1 -0
- package/dist/core/unified-cache.js +114 -0
- package/dist/core/unified-cache.js.map +1 -0
- package/dist/index.d.ts +93 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +255 -0
- package/dist/index.js.map +1 -0
- package/dist/services/arbitrage-service.d.ts +408 -0
- package/dist/services/arbitrage-service.d.ts.map +1 -0
- package/dist/services/arbitrage-service.js +1422 -0
- package/dist/services/arbitrage-service.js.map +1 -0
- package/dist/services/authorization-service.d.ts +97 -0
- package/dist/services/authorization-service.d.ts.map +1 -0
- package/dist/services/authorization-service.js +279 -0
- package/dist/services/authorization-service.js.map +1 -0
- package/dist/services/market-service.d.ts +108 -0
- package/dist/services/market-service.d.ts.map +1 -0
- package/dist/services/market-service.js +458 -0
- package/dist/services/market-service.js.map +1 -0
- package/dist/services/realtime-service.d.ts +82 -0
- package/dist/services/realtime-service.d.ts.map +1 -0
- package/dist/services/realtime-service.js +150 -0
- package/dist/services/realtime-service.js.map +1 -0
- package/dist/services/swap-service.d.ts +217 -0
- package/dist/services/swap-service.d.ts.map +1 -0
- package/dist/services/swap-service.js +695 -0
- package/dist/services/swap-service.js.map +1 -0
- package/dist/services/wallet-service.d.ts +94 -0
- package/dist/services/wallet-service.d.ts.map +1 -0
- package/dist/services/wallet-service.js +173 -0
- package/dist/services/wallet-service.js.map +1 -0
- package/dist/utils/price-utils.d.ts +153 -0
- package/dist/utils/price-utils.d.ts.map +1 -0
- package/dist/utils/price-utils.js +236 -0
- package/dist/utils/price-utils.js.map +1 -0
- package/package.json +7 -2
- package/docs/00-design.md +0 -760
- package/docs/02-API.md +0 -1148
- package/docs/arb/test-plan.md +0 -387
- package/docs/arb/test-results.md +0 -336
- package/docs/arbitrage.md +0 -754
- package/docs/reports/smart-money-analysis-2025-12-23-cn.md +0 -840
- package/examples/01-basic-usage.ts +0 -68
- package/examples/02-smart-money.ts +0 -95
- package/examples/03-market-analysis.ts +0 -108
- package/examples/04-kline-aggregation.ts +0 -158
- package/examples/05-follow-wallet-strategy.ts +0 -156
- package/examples/06-services-demo.ts +0 -124
- package/examples/07-realtime-websocket.ts +0 -117
- package/examples/08-trading-orders.ts +0 -278
- package/examples/09-rewards-tracking.ts +0 -187
- package/examples/10-ctf-operations.ts +0 -336
- package/examples/11-live-arbitrage-scan.ts +0 -221
- package/examples/12-trending-arb-monitor.ts +0 -406
- package/examples/13-arbitrage-service.ts +0 -211
- package/examples/README.md +0 -179
- package/scripts/README.md +0 -163
- package/scripts/approvals/approve-erc1155.ts +0 -129
- package/scripts/approvals/approve-neg-risk-erc1155.ts +0 -149
- package/scripts/approvals/approve-neg-risk.ts +0 -102
- package/scripts/approvals/check-all-allowances.ts +0 -150
- package/scripts/approvals/check-allowance.ts +0 -129
- package/scripts/approvals/check-ctf-approval.ts +0 -158
- package/scripts/arb/faze-bo3-arb.ts +0 -385
- package/scripts/arb/settle-position.ts +0 -190
- package/scripts/arb/token-rebalancer.ts +0 -420
- package/scripts/arb-tests/01-unit-tests.ts +0 -495
- package/scripts/arb-tests/02-integration-tests.ts +0 -412
- package/scripts/arb-tests/03-e2e-tests.ts +0 -503
- package/scripts/arb-tests/README.md +0 -109
- package/scripts/datas/001-report.md +0 -486
- package/scripts/datas/clone-modal-screenshot.png +0 -0
- package/scripts/deposit/deposit-native-usdc.ts +0 -179
- package/scripts/deposit/deposit-usdc.ts +0 -155
- package/scripts/deposit/swap-usdc-to-usdce.ts +0 -375
- package/scripts/research/research-markets.ts +0 -166
- package/scripts/trading/check-orders.ts +0 -50
- package/scripts/trading/sell-nvidia-positions.ts +0 -206
- package/scripts/trading/test-order.ts +0 -172
- package/scripts/verify/test-approve-trading.ts +0 -98
- package/scripts/verify/test-provider-fix.ts +0 -43
- package/scripts/verify/test-search-mcp.ts +0 -113
- package/scripts/verify/verify-all-apis.ts +0 -160
- package/scripts/wallet/check-wallet-balances.ts +0 -75
- package/scripts/wallet/test-wallet-operations.ts +0 -191
- package/scripts/wallet/verify-wallet-tools.ts +0 -124
- package/src/__tests__/clob-api.test.ts +0 -301
- package/src/__tests__/integration/bridge-client.integration.test.ts +0 -314
- package/src/__tests__/integration/clob-api.integration.test.ts +0 -218
- package/src/__tests__/integration/ctf-client.integration.test.ts +0 -331
- package/src/__tests__/integration/data-api.integration.test.ts +0 -194
- package/src/__tests__/integration/gamma-api.integration.test.ts +0 -206
- package/src/__tests__/test-utils.ts +0 -170
- package/src/clients/bridge-client.ts +0 -841
- package/src/clients/clob-api.ts +0 -629
- package/src/clients/ctf-client.ts +0 -1216
- package/src/clients/data-api.ts +0 -469
- package/src/clients/gamma-api.ts +0 -597
- package/src/clients/trading-client.ts +0 -749
- package/src/clients/websocket-manager.ts +0 -267
- package/src/core/cache-adapter-bridge.ts +0 -94
- package/src/core/cache.ts +0 -85
- package/src/core/errors.ts +0 -117
- package/src/core/rate-limiter.ts +0 -74
- package/src/core/unified-cache.ts +0 -153
- package/src/index.ts +0 -461
- package/src/services/arbitrage-service.ts +0 -1807
- package/src/services/authorization-service.ts +0 -357
- package/src/services/market-service.ts +0 -544
- package/src/services/realtime-service.ts +0 -196
- package/src/services/swap-service.ts +0 -896
- package/src/services/wallet-service.ts +0 -259
- package/src/utils/price-utils.ts +0 -307
- package/tsconfig.json +0 -8
- package/vitest.config.ts +0 -19
- package/vitest.integration.config.ts +0 -18
|
@@ -1,495 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit Tests for Arbitrage Price Utilities
|
|
3
|
-
*
|
|
4
|
-
* Tests getEffectivePrices() and checkArbitrage() functions
|
|
5
|
-
* with various price scenarios and edge cases.
|
|
6
|
-
*
|
|
7
|
-
* Run: npx tsx scripts/arb-tests/01-unit-tests.ts
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { getEffectivePrices, checkArbitrage } from '../../src/utils/price-utils.js';
|
|
11
|
-
|
|
12
|
-
// ===== Test Framework =====
|
|
13
|
-
|
|
14
|
-
interface TestCase {
|
|
15
|
-
name: string;
|
|
16
|
-
input: {
|
|
17
|
-
yesAsk: number;
|
|
18
|
-
yesBid: number;
|
|
19
|
-
noAsk: number;
|
|
20
|
-
noBid: number;
|
|
21
|
-
};
|
|
22
|
-
expected: {
|
|
23
|
-
effectiveBuyYes?: number;
|
|
24
|
-
effectiveBuyNo?: number;
|
|
25
|
-
effectiveSellYes?: number;
|
|
26
|
-
effectiveSellNo?: number;
|
|
27
|
-
arbType?: 'long' | 'short' | null;
|
|
28
|
-
arbProfit?: number;
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
class TestRunner {
|
|
33
|
-
private passed = 0;
|
|
34
|
-
private failed = 0;
|
|
35
|
-
private failedTests: string[] = [];
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Run a test case for getEffectivePrices()
|
|
39
|
-
*/
|
|
40
|
-
testGetEffectivePrices(testCase: TestCase): void {
|
|
41
|
-
console.log(`\n📝 ${testCase.name}`);
|
|
42
|
-
console.log(` Input: YES(ask=${testCase.input.yesAsk}, bid=${testCase.input.yesBid}), NO(ask=${testCase.input.noAsk}, bid=${testCase.input.noBid})`);
|
|
43
|
-
|
|
44
|
-
const result = getEffectivePrices(
|
|
45
|
-
testCase.input.yesAsk,
|
|
46
|
-
testCase.input.yesBid,
|
|
47
|
-
testCase.input.noAsk,
|
|
48
|
-
testCase.input.noBid
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
console.log(` Result:`, result);
|
|
52
|
-
console.log(` Expected:`, testCase.expected);
|
|
53
|
-
|
|
54
|
-
// Check each expected field
|
|
55
|
-
const checks = [
|
|
56
|
-
{ field: 'effectiveBuyYes', actual: result.effectiveBuyYes, expected: testCase.expected.effectiveBuyYes },
|
|
57
|
-
{ field: 'effectiveBuyNo', actual: result.effectiveBuyNo, expected: testCase.expected.effectiveBuyNo },
|
|
58
|
-
{ field: 'effectiveSellYes', actual: result.effectiveSellYes, expected: testCase.expected.effectiveSellYes },
|
|
59
|
-
{ field: 'effectiveSellNo', actual: result.effectiveSellNo, expected: testCase.expected.effectiveSellNo },
|
|
60
|
-
];
|
|
61
|
-
|
|
62
|
-
let testPassed = true;
|
|
63
|
-
for (const check of checks) {
|
|
64
|
-
if (check.expected !== undefined) {
|
|
65
|
-
const match = Math.abs(check.actual - check.expected) < 0.0001;
|
|
66
|
-
if (!match) {
|
|
67
|
-
console.log(` ❌ ${check.field}: expected ${check.expected}, got ${check.actual}`);
|
|
68
|
-
testPassed = false;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (testPassed) {
|
|
74
|
-
console.log(` ✅ PASS`);
|
|
75
|
-
this.passed++;
|
|
76
|
-
} else {
|
|
77
|
-
console.log(` ❌ FAIL`);
|
|
78
|
-
this.failed++;
|
|
79
|
-
this.failedTests.push(testCase.name);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Run a test case for checkArbitrage()
|
|
85
|
-
*/
|
|
86
|
-
testCheckArbitrage(testCase: TestCase): void {
|
|
87
|
-
console.log(`\n📝 ${testCase.name}`);
|
|
88
|
-
console.log(` Input: YES(ask=${testCase.input.yesAsk}, bid=${testCase.input.yesBid}), NO(ask=${testCase.input.noAsk}, bid=${testCase.input.noBid})`);
|
|
89
|
-
|
|
90
|
-
const result = checkArbitrage(
|
|
91
|
-
testCase.input.yesAsk,
|
|
92
|
-
testCase.input.noAsk,
|
|
93
|
-
testCase.input.yesBid,
|
|
94
|
-
testCase.input.noBid
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
console.log(` Result:`, result ? `${result.type} arb, profit=${result.profit.toFixed(4)}` : 'No arbitrage');
|
|
98
|
-
console.log(` Expected:`, testCase.expected.arbType ? `${testCase.expected.arbType} arb, profit=${testCase.expected.arbProfit?.toFixed(4)}` : 'No arbitrage');
|
|
99
|
-
|
|
100
|
-
let testPassed = true;
|
|
101
|
-
|
|
102
|
-
// Check arbitrage type
|
|
103
|
-
if (testCase.expected.arbType === null) {
|
|
104
|
-
if (result !== null) {
|
|
105
|
-
console.log(` ❌ arbType: expected null, got ${result.type}`);
|
|
106
|
-
testPassed = false;
|
|
107
|
-
}
|
|
108
|
-
} else {
|
|
109
|
-
if (result === null) {
|
|
110
|
-
console.log(` ❌ arbType: expected ${testCase.expected.arbType}, got null`);
|
|
111
|
-
testPassed = false;
|
|
112
|
-
} else if (result.type !== testCase.expected.arbType) {
|
|
113
|
-
console.log(` ❌ arbType: expected ${testCase.expected.arbType}, got ${result.type}`);
|
|
114
|
-
testPassed = false;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Check profit
|
|
119
|
-
if (testCase.expected.arbProfit !== undefined && result !== null) {
|
|
120
|
-
const profitMatch = Math.abs(result.profit - testCase.expected.arbProfit) < 0.0001;
|
|
121
|
-
if (!profitMatch) {
|
|
122
|
-
console.log(` ❌ profit: expected ${testCase.expected.arbProfit}, got ${result.profit}`);
|
|
123
|
-
testPassed = false;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (testPassed) {
|
|
128
|
-
console.log(` ✅ PASS`);
|
|
129
|
-
this.passed++;
|
|
130
|
-
} else {
|
|
131
|
-
console.log(` ❌ FAIL`);
|
|
132
|
-
this.failed++;
|
|
133
|
-
this.failedTests.push(testCase.name);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Print summary
|
|
139
|
-
*/
|
|
140
|
-
printSummary(): void {
|
|
141
|
-
console.log('\n' + '='.repeat(60));
|
|
142
|
-
console.log('TEST SUMMARY');
|
|
143
|
-
console.log('='.repeat(60));
|
|
144
|
-
console.log(`Total: ${this.passed + this.failed}`);
|
|
145
|
-
console.log(`✅ Passed: ${this.passed}`);
|
|
146
|
-
console.log(`❌ Failed: ${this.failed}`);
|
|
147
|
-
|
|
148
|
-
if (this.failedTests.length > 0) {
|
|
149
|
-
console.log('\nFailed Tests:');
|
|
150
|
-
for (const name of this.failedTests) {
|
|
151
|
-
console.log(` - ${name}`);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
console.log('\n' + (this.failed === 0 ? '🎉 All tests passed!' : '❌ Some tests failed'));
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// ===== Test Cases =====
|
|
160
|
-
|
|
161
|
-
function main() {
|
|
162
|
-
console.log('Arbitrage Price Utilities - Unit Tests');
|
|
163
|
-
console.log('=' .repeat(60));
|
|
164
|
-
|
|
165
|
-
const runner = new TestRunner();
|
|
166
|
-
|
|
167
|
-
// ===== getEffectivePrices() Tests =====
|
|
168
|
-
console.log('\n' + '#'.repeat(60));
|
|
169
|
-
console.log('# getEffectivePrices() Tests');
|
|
170
|
-
console.log('#'.repeat(60));
|
|
171
|
-
|
|
172
|
-
// Test 1: Normal market - no arbitrage
|
|
173
|
-
runner.testGetEffectivePrices({
|
|
174
|
-
name: 'Normal market - no arbitrage',
|
|
175
|
-
input: { yesAsk: 0.52, yesBid: 0.50, noAsk: 0.50, noBid: 0.48 },
|
|
176
|
-
expected: {
|
|
177
|
-
effectiveBuyYes: 0.52, // min(0.52, 1-0.48=0.52) = 0.52
|
|
178
|
-
effectiveBuyNo: 0.50, // min(0.50, 1-0.50=0.50) = 0.50
|
|
179
|
-
effectiveSellYes: 0.50, // max(0.50, 1-0.50=0.50) = 0.50
|
|
180
|
-
effectiveSellNo: 0.48, // max(0.48, 1-0.52=0.48) = 0.48
|
|
181
|
-
},
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
// Test 2: Long arbitrage opportunity
|
|
185
|
-
runner.testGetEffectivePrices({
|
|
186
|
-
name: 'Long arbitrage opportunity',
|
|
187
|
-
input: { yesAsk: 0.48, yesBid: 0.46, noAsk: 0.50, noBid: 0.48 },
|
|
188
|
-
expected: {
|
|
189
|
-
effectiveBuyYes: 0.48, // min(0.48, 1-0.48=0.52) = 0.48
|
|
190
|
-
effectiveBuyNo: 0.50, // min(0.50, 1-0.46=0.54) = 0.50
|
|
191
|
-
effectiveSellYes: 0.50, // max(0.46, 1-0.50=0.50) = 0.50
|
|
192
|
-
effectiveSellNo: 0.52, // max(0.48, 1-0.48=0.52) = 0.52 (corrected)
|
|
193
|
-
},
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
// Test 3: Short arbitrage opportunity
|
|
197
|
-
runner.testGetEffectivePrices({
|
|
198
|
-
name: 'Short arbitrage opportunity',
|
|
199
|
-
input: { yesAsk: 0.48, yesBid: 0.46, noAsk: 0.56, noBid: 0.54 },
|
|
200
|
-
expected: {
|
|
201
|
-
effectiveBuyYes: 0.46, // min(0.48, 1-0.54=0.46) = 0.46
|
|
202
|
-
effectiveBuyNo: 0.54, // min(0.56, 1-0.46=0.54) = 0.54
|
|
203
|
-
effectiveSellYes: 0.46, // max(0.46, 1-0.56=0.44) = 0.46
|
|
204
|
-
effectiveSellNo: 0.54, // max(0.54, 1-0.48=0.52) = 0.54
|
|
205
|
-
},
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
// Test 4: Mirror relationship - buy YES vs sell NO
|
|
209
|
-
runner.testGetEffectivePrices({
|
|
210
|
-
name: 'Mirror relationship validation',
|
|
211
|
-
input: { yesAsk: 0.60, yesBid: 0.58, noAsk: 0.42, noBid: 0.40 },
|
|
212
|
-
expected: {
|
|
213
|
-
effectiveBuyYes: 0.60, // min(0.60, 1-0.40=0.60) = 0.60
|
|
214
|
-
effectiveBuyNo: 0.42, // min(0.42, 1-0.58=0.42) = 0.42
|
|
215
|
-
effectiveSellYes: 0.58, // max(0.58, 1-0.42=0.58) = 0.58
|
|
216
|
-
effectiveSellNo: 0.40, // max(0.40, 1-0.60=0.40) = 0.40
|
|
217
|
-
},
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
// Test 5: Edge case - prices at 0.001
|
|
221
|
-
runner.testGetEffectivePrices({
|
|
222
|
-
name: 'Edge case - very low prices',
|
|
223
|
-
input: { yesAsk: 0.02, yesBid: 0.01, noAsk: 0.99, noBid: 0.98 },
|
|
224
|
-
expected: {
|
|
225
|
-
effectiveBuyYes: 0.02, // min(0.02, 1-0.98=0.02) = 0.02
|
|
226
|
-
effectiveBuyNo: 0.99, // min(0.99, 1-0.01=0.99) = 0.99
|
|
227
|
-
effectiveSellYes: 0.01, // max(0.01, 1-0.99=0.01) = 0.01
|
|
228
|
-
effectiveSellNo: 0.98, // max(0.98, 1-0.02=0.98) = 0.98
|
|
229
|
-
},
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
// Test 6: Edge case - prices at 0.999
|
|
233
|
-
runner.testGetEffectivePrices({
|
|
234
|
-
name: 'Edge case - very high prices',
|
|
235
|
-
input: { yesAsk: 0.99, yesBid: 0.98, noAsk: 0.02, noBid: 0.01 },
|
|
236
|
-
expected: {
|
|
237
|
-
effectiveBuyYes: 0.99, // min(0.99, 1-0.01=0.99) = 0.99
|
|
238
|
-
effectiveBuyNo: 0.02, // min(0.02, 1-0.98=0.02) = 0.02
|
|
239
|
-
effectiveSellYes: 0.98, // max(0.98, 1-0.02=0.98) = 0.98
|
|
240
|
-
effectiveSellNo: 0.01, // max(0.01, 1-0.99=0.01) = 0.01
|
|
241
|
-
},
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
// Test 7: Edge case - 50/50 market
|
|
245
|
-
runner.testGetEffectivePrices({
|
|
246
|
-
name: 'Edge case - 50/50 market',
|
|
247
|
-
input: { yesAsk: 0.51, yesBid: 0.49, noAsk: 0.51, noBid: 0.49 },
|
|
248
|
-
expected: {
|
|
249
|
-
effectiveBuyYes: 0.51, // min(0.51, 1-0.49=0.51) = 0.51
|
|
250
|
-
effectiveBuyNo: 0.51, // min(0.51, 1-0.49=0.51) = 0.51
|
|
251
|
-
effectiveSellYes: 0.49, // max(0.49, 1-0.51=0.49) = 0.49
|
|
252
|
-
effectiveSellNo: 0.49, // max(0.49, 1-0.51=0.49) = 0.49
|
|
253
|
-
},
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
// ===== checkArbitrage() Tests =====
|
|
257
|
-
console.log('\n' + '#'.repeat(60));
|
|
258
|
-
console.log('# checkArbitrage() Tests');
|
|
259
|
-
console.log('#'.repeat(60));
|
|
260
|
-
|
|
261
|
-
// Test 8: Long arbitrage - clear opportunity
|
|
262
|
-
runner.testCheckArbitrage({
|
|
263
|
-
name: 'Long arbitrage - clear opportunity',
|
|
264
|
-
input: { yesAsk: 0.45, yesBid: 0.43, noAsk: 0.52, noBid: 0.50 },
|
|
265
|
-
expected: {
|
|
266
|
-
arbType: 'long',
|
|
267
|
-
arbProfit: 0.03, // 1 - (0.45 + 0.52) = 0.03
|
|
268
|
-
},
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
// Test 9: Long arbitrage - small opportunity
|
|
272
|
-
runner.testCheckArbitrage({
|
|
273
|
-
name: 'Long arbitrage - small opportunity',
|
|
274
|
-
input: { yesAsk: 0.49, yesBid: 0.47, noAsk: 0.50, noBid: 0.48 },
|
|
275
|
-
expected: {
|
|
276
|
-
arbType: 'long',
|
|
277
|
-
arbProfit: 0.01, // 1 - (0.49 + 0.50) = 0.01
|
|
278
|
-
},
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
// Test 10: Short arbitrage - clear opportunity
|
|
282
|
-
// Note: With these prices, both long AND short arb exist
|
|
283
|
-
// effectiveBuyYes = min(0.48, 1-0.50) = 0.48
|
|
284
|
-
// effectiveBuyNo = min(0.52, 1-0.55) = 0.45
|
|
285
|
-
// longCost = 0.48 + 0.45 = 0.93, longProfit = 0.07
|
|
286
|
-
// Since long arb is checked first and exists, it returns long
|
|
287
|
-
runner.testCheckArbitrage({
|
|
288
|
-
name: 'Short arbitrage - clear opportunity (actually returns long due to priority)',
|
|
289
|
-
input: { yesAsk: 0.48, yesBid: 0.55, noAsk: 0.52, noBid: 0.50 },
|
|
290
|
-
expected: {
|
|
291
|
-
arbType: 'long',
|
|
292
|
-
arbProfit: 0.07, // 1 - (0.48 + 0.45) = 0.07
|
|
293
|
-
},
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
// Test 11: Short arbitrage - small opportunity
|
|
297
|
-
// Note: With these prices, both long AND short arb exist
|
|
298
|
-
// effectiveBuyYes = min(0.49, 1-0.50) = 0.49
|
|
299
|
-
// effectiveBuyNo = min(0.50, 1-0.51) = 0.49
|
|
300
|
-
// longCost = 0.49 + 0.49 = 0.98, longProfit = 0.02
|
|
301
|
-
// Since long arb is checked first and exists, it returns long
|
|
302
|
-
runner.testCheckArbitrage({
|
|
303
|
-
name: 'Short arbitrage - small opportunity (actually returns long due to priority)',
|
|
304
|
-
input: { yesAsk: 0.49, yesBid: 0.51, noAsk: 0.50, noBid: 0.50 },
|
|
305
|
-
expected: {
|
|
306
|
-
arbType: 'long',
|
|
307
|
-
arbProfit: 0.02, // 1 - (0.49 + 0.49) = 0.02
|
|
308
|
-
},
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
// Test 12: No arbitrage - balanced market
|
|
312
|
-
runner.testCheckArbitrage({
|
|
313
|
-
name: 'No arbitrage - balanced market',
|
|
314
|
-
input: { yesAsk: 0.52, yesBid: 0.50, noAsk: 0.50, noBid: 0.48 },
|
|
315
|
-
expected: {
|
|
316
|
-
arbType: null,
|
|
317
|
-
},
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
// Test 13: No arbitrage - tight spread
|
|
321
|
-
runner.testCheckArbitrage({
|
|
322
|
-
name: 'No arbitrage - tight spread',
|
|
323
|
-
input: { yesAsk: 0.501, yesBid: 0.499, noAsk: 0.501, noBid: 0.499 },
|
|
324
|
-
expected: {
|
|
325
|
-
arbType: null,
|
|
326
|
-
},
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
// Test 14: Edge case - extreme long arbitrage
|
|
330
|
-
runner.testCheckArbitrage({
|
|
331
|
-
name: 'Edge case - extreme long arbitrage',
|
|
332
|
-
input: { yesAsk: 0.30, yesBid: 0.28, noAsk: 0.40, noBid: 0.38 },
|
|
333
|
-
expected: {
|
|
334
|
-
arbType: 'long',
|
|
335
|
-
arbProfit: 0.30, // 1 - (0.30 + 0.40) = 0.30
|
|
336
|
-
},
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
// Test 15: Edge case - extreme short arbitrage
|
|
340
|
-
// Note: With these prices, both long AND short arb exist
|
|
341
|
-
// effectiveBuyYes = min(0.40, 1-0.60) = 0.40
|
|
342
|
-
// effectiveBuyNo = min(0.50, 1-0.65) = 0.35
|
|
343
|
-
// longCost = 0.40 + 0.35 = 0.75, longProfit = 0.25
|
|
344
|
-
// Since long arb is checked first and exists, it returns long
|
|
345
|
-
runner.testCheckArbitrage({
|
|
346
|
-
name: 'Edge case - extreme short arbitrage (actually returns long due to priority)',
|
|
347
|
-
input: { yesAsk: 0.40, yesBid: 0.65, noAsk: 0.50, noBid: 0.60 },
|
|
348
|
-
expected: {
|
|
349
|
-
arbType: 'long',
|
|
350
|
-
arbProfit: 0.25, // 1 - (0.40 + 0.35) = 0.25
|
|
351
|
-
},
|
|
352
|
-
});
|
|
353
|
-
|
|
354
|
-
// Test 16: Edge case - prices near 0
|
|
355
|
-
runner.testCheckArbitrage({
|
|
356
|
-
name: 'Edge case - prices near 0',
|
|
357
|
-
input: { yesAsk: 0.02, yesBid: 0.01, noAsk: 0.03, noBid: 0.02 },
|
|
358
|
-
expected: {
|
|
359
|
-
arbType: 'long',
|
|
360
|
-
arbProfit: 0.95, // 1 - (0.02 + 0.03) = 0.95
|
|
361
|
-
},
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
// Test 17: Edge case - prices near 1
|
|
365
|
-
runner.testCheckArbitrage({
|
|
366
|
-
name: 'Edge case - prices near 1',
|
|
367
|
-
input: { yesAsk: 0.97, yesBid: 0.96, noAsk: 0.04, noBid: 0.03 },
|
|
368
|
-
expected: {
|
|
369
|
-
arbType: null, // 0.97 + 0.04 = 1.01 (no long arb), 0.96 + 0.03 = 0.99 (no short arb)
|
|
370
|
-
},
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
// Test 18: Boundary - exactly at break-even (long)
|
|
374
|
-
runner.testCheckArbitrage({
|
|
375
|
-
name: 'Boundary - exactly at break-even (long)',
|
|
376
|
-
input: { yesAsk: 0.50, yesBid: 0.48, noAsk: 0.50, noBid: 0.48 },
|
|
377
|
-
expected: {
|
|
378
|
-
arbType: null, // 0.50 + 0.50 = 1.00 (no profit)
|
|
379
|
-
},
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
// Test 19: Boundary - exactly at break-even (short)
|
|
383
|
-
runner.testCheckArbitrage({
|
|
384
|
-
name: 'Boundary - exactly at break-even (short)',
|
|
385
|
-
input: { yesAsk: 0.50, yesBid: 0.50, noAsk: 0.50, noBid: 0.50 },
|
|
386
|
-
expected: {
|
|
387
|
-
arbType: null, // 0.50 + 0.50 = 1.00 (no profit)
|
|
388
|
-
},
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
// Test 20: Mirror relationship - long arb through mirrored orders
|
|
392
|
-
runner.testCheckArbitrage({
|
|
393
|
-
name: 'Mirror relationship - long arb through NO bid',
|
|
394
|
-
input: { yesAsk: 0.52, yesBid: 0.50, noAsk: 0.50, noBid: 0.50 },
|
|
395
|
-
expected: {
|
|
396
|
-
arbType: null, // effectiveBuyYes = min(0.52, 1-0.50) = 0.50, effectiveBuyNo = 0.50, total = 1.00
|
|
397
|
-
},
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
// Test 21: Mirror relationship - short arb through mirrored orders
|
|
401
|
-
// Note: With these prices, both long AND short arb exist
|
|
402
|
-
// effectiveBuyYes = min(0.48, 1-0.44) = 0.48
|
|
403
|
-
// effectiveBuyNo = min(0.46, 1-0.52) = 0.46
|
|
404
|
-
// longCost = 0.48 + 0.46 = 0.94, longProfit = 0.06
|
|
405
|
-
// Since long arb is checked first and exists, it returns long
|
|
406
|
-
runner.testCheckArbitrage({
|
|
407
|
-
name: 'Mirror relationship - short arb through NO ask (actually returns long)',
|
|
408
|
-
input: { yesAsk: 0.48, yesBid: 0.52, noAsk: 0.46, noBid: 0.44 },
|
|
409
|
-
expected: {
|
|
410
|
-
arbType: 'long',
|
|
411
|
-
arbProfit: 0.06, // 1 - (0.48 + 0.46) = 0.06
|
|
412
|
-
},
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
// Test 22: Wide spread - no arbitrage
|
|
416
|
-
runner.testCheckArbitrage({
|
|
417
|
-
name: 'Wide spread - no arbitrage',
|
|
418
|
-
input: { yesAsk: 0.60, yesBid: 0.40, noAsk: 0.60, noBid: 0.40 },
|
|
419
|
-
expected: {
|
|
420
|
-
arbType: null, // 0.60 + 0.60 = 1.20 (no long arb), 0.40 + 0.40 = 0.80 (no short arb)
|
|
421
|
-
},
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
// Test 23: Asymmetric market - long arb
|
|
425
|
-
runner.testCheckArbitrage({
|
|
426
|
-
name: 'Asymmetric market - long arb',
|
|
427
|
-
input: { yesAsk: 0.35, yesBid: 0.33, noAsk: 0.60, noBid: 0.58 },
|
|
428
|
-
expected: {
|
|
429
|
-
arbType: 'long',
|
|
430
|
-
arbProfit: 0.05, // 1 - (0.35 + 0.60) = 0.05
|
|
431
|
-
},
|
|
432
|
-
});
|
|
433
|
-
|
|
434
|
-
// Test 24: Asymmetric market - short arb
|
|
435
|
-
// Note: With these prices, both long AND short arb exist
|
|
436
|
-
// effectiveBuyYes = min(0.30, 1-0.38) = 0.30
|
|
437
|
-
// effectiveBuyNo = min(0.40, 1-0.65) = 0.35
|
|
438
|
-
// longCost = 0.30 + 0.35 = 0.65, longProfit = 0.35
|
|
439
|
-
// Since long arb is checked first and exists, it returns long
|
|
440
|
-
runner.testCheckArbitrage({
|
|
441
|
-
name: 'Asymmetric market - short arb (actually returns long due to priority)',
|
|
442
|
-
input: { yesAsk: 0.30, yesBid: 0.65, noAsk: 0.40, noBid: 0.38 },
|
|
443
|
-
expected: {
|
|
444
|
-
arbType: 'long',
|
|
445
|
-
arbProfit: 0.35, // 1 - (0.30 + 0.35) = 0.35
|
|
446
|
-
},
|
|
447
|
-
});
|
|
448
|
-
|
|
449
|
-
// Test 25: Real-world example - FaZe BO3 scenario
|
|
450
|
-
runner.testCheckArbitrage({
|
|
451
|
-
name: 'Real-world - FaZe BO3 scenario',
|
|
452
|
-
input: { yesAsk: 0.49, yesBid: 0.47, noAsk: 0.52, noBid: 0.50 },
|
|
453
|
-
expected: {
|
|
454
|
-
arbType: null, // 0.49 + 0.52 = 1.01 (no long arb), 0.47 + 0.50 = 0.97 (no short arb)
|
|
455
|
-
},
|
|
456
|
-
});
|
|
457
|
-
|
|
458
|
-
// Test 26: Pure short arbitrage - no long arb exists
|
|
459
|
-
// This also has both arbs due to the mirroring property - long is checked first
|
|
460
|
-
runner.testCheckArbitrage({
|
|
461
|
-
name: 'Pure short arbitrage - no long arb exists (actually returns long)',
|
|
462
|
-
input: { yesAsk: 0.49, yesBid: 0.52, noAsk: 0.49, noBid: 0.52 },
|
|
463
|
-
expected: {
|
|
464
|
-
arbType: 'long',
|
|
465
|
-
// effectiveBuyYes = min(0.49, 1-0.52) = 0.48
|
|
466
|
-
// effectiveBuyNo = min(0.49, 1-0.52) = 0.48
|
|
467
|
-
// longCost = 0.48 + 0.48 = 0.96, longProfit = 0.04
|
|
468
|
-
// Since long arb is checked first and exists, it returns long
|
|
469
|
-
arbProfit: 0.04,
|
|
470
|
-
},
|
|
471
|
-
});
|
|
472
|
-
|
|
473
|
-
// Test 27: Another pure short arbitrage scenario
|
|
474
|
-
// This one also has both arbs due to mirroring - long is checked first
|
|
475
|
-
runner.testCheckArbitrage({
|
|
476
|
-
name: 'Pure short arbitrage - small profit (actually returns long)',
|
|
477
|
-
input: { yesAsk: 0.48, yesBid: 0.505, noAsk: 0.48, noBid: 0.505 },
|
|
478
|
-
expected: {
|
|
479
|
-
arbType: 'long',
|
|
480
|
-
// effectiveBuyYes = min(0.48, 1-0.505) = 0.48
|
|
481
|
-
// effectiveBuyNo = min(0.48, 1-0.505) = 0.48
|
|
482
|
-
// longCost = 0.48 + 0.48 = 0.96, longProfit = 0.04
|
|
483
|
-
// Since long arb is checked first and exists, it returns long
|
|
484
|
-
arbProfit: 0.04,
|
|
485
|
-
},
|
|
486
|
-
});
|
|
487
|
-
|
|
488
|
-
// Print summary
|
|
489
|
-
runner.printSummary();
|
|
490
|
-
|
|
491
|
-
// Exit with appropriate code
|
|
492
|
-
process.exit(runner['failed'] > 0 ? 1 : 0);
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
main();
|