@@ -33,6 +33,9 @@ export class LimitlessExchange extends PredictionMarketExchange {
3333 // New signature: LimitlessExchangeOptions
3434 credentials = options . credentials ;
3535 wsConfig = options . websocket ;
36+ } else if ( options && 'privateKey' in options ) {
37+ // Support direct privateKey for easier initialization
38+ credentials = options as ExchangeCredentials ;
3639 } else {
3740 // Old signature: ExchangeCredentials directly
3841 credentials = options as ExchangeCredentials | undefined ;
@@ -111,6 +114,21 @@ export class LimitlessExchange extends PredictionMarketExchange {
111114 // For market orders, use max slippage: 0.99 for BUY (willing to pay up to 99%), 0.01 for SELL (willing to accept down to 1%)
112115 const price = params . price || ( side === Side . BUY ? 0.99 : 0.01 ) ;
113116
117+ // Auto-detect tick size if not provided
118+ let tickSize : string ;
119+ if ( params . tickSize ) {
120+ tickSize = params . tickSize . toString ( ) ;
121+ } else {
122+ // Fetch the order book to infer tick size from price levels
123+ try {
124+ const orderBook = await this . fetchOrderBook ( params . outcomeId ) ;
125+ tickSize = this . inferTickSize ( orderBook ) ;
126+ } catch ( error ) {
127+ // Fallback to 0.001 if order book fetch fails
128+ tickSize = "0.001" ;
129+ }
130+ }
131+
114132 try {
115133 // We use createAndPostOrder which handles signing and posting
116134 const response = await client . createAndPostOrder ( {
@@ -120,7 +138,7 @@ export class LimitlessExchange extends PredictionMarketExchange {
120138 size : params . amount ,
121139 feeRateBps : 0 ,
122140 } , {
123- tickSize : "0.01"
141+ tickSize : tickSize as any
124142 } ) ;
125143
126144 if ( ! response || ! response . success ) {
@@ -145,6 +163,41 @@ export class LimitlessExchange extends PredictionMarketExchange {
145163 }
146164 }
147165
166+ /**
167+ * Infer the tick size from order book price levels.
168+ * Analyzes the decimal precision of existing orders to determine the market's tick size.
169+ */
170+ private inferTickSize ( orderBook : OrderBook ) : string {
171+ const allPrices = [
172+ ...orderBook . bids . map ( b => b . price ) ,
173+ ...orderBook . asks . map ( a => a . price )
174+ ] ;
175+
176+ if ( allPrices . length === 0 ) {
177+ return "0.001" ; // Default fallback
178+ }
179+
180+ // Find the smallest non-zero decimal increment
181+ let minIncrement = 1 ;
182+ for ( const price of allPrices ) {
183+ const priceStr = price . toString ( ) ;
184+ const decimalPart = priceStr . split ( '.' ) [ 1 ] ;
185+ if ( decimalPart ) {
186+ const decimals = decimalPart . length ;
187+ const increment = Math . pow ( 10 , - decimals ) ;
188+ if ( increment < minIncrement ) {
189+ minIncrement = increment ;
190+ }
191+ }
192+ }
193+
194+ // Map to valid tick sizes: 0.1, 0.01, 0.001, 0.0001
195+ if ( minIncrement >= 0.1 ) return "0.1" ;
196+ if ( minIncrement >= 0.01 ) return "0.01" ;
197+ if ( minIncrement >= 0.001 ) return "0.001" ;
198+ return "0.0001" ;
199+ }
200+
148201 async cancelOrder ( orderId : string ) : Promise < Order > {
149202 const auth = this . ensureAuth ( ) ;
150203 const client = await auth . getClobClient ( ) ;
@@ -216,7 +269,7 @@ export class LimitlessExchange extends PredictionMarketExchange {
216269 timestamp : o . created_at * 1000
217270 } ) ) ;
218271 } catch ( error : any ) {
219- console . error ( 'Error fetching Limitless open orders:' , error ) ;
272+ console . error ( 'Error fetching Limitless open orders:' , error . message ) ;
220273 return [ ] ;
221274 }
222275 }
0 commit comments