@@ -6,129 +6,109 @@ use serde::{Deserialize, Serialize};
66// DATA STRUCTURES
77// ============================================================================
88
9+ #[ derive( Serialize , Deserialize ) ]
10+ struct PolyMarketEvent {
11+ closed : bool ,
12+ markets : Vec < PolyMarketMarket > ,
13+ }
14+
915#[ derive( Serialize , Deserialize ) ]
1016struct PolyMarketMarket {
1117 #[ serde( rename = "outcomePrices" ) ]
1218 outcome_prices : String , // PolyMarket returns this as a JSON string, not an array
13- volume : String ,
1419}
1520
16- #[ derive( Serialize , Deserialize ) ]
17- struct KalshiMarket {
18- yes_bid_dollars : String ,
19- volume : u64 ,
20- }
2121
2222#[ derive( Serialize , Deserialize ) ]
23- struct KalshiMarketResponse {
24- market : KalshiMarket ,
23+ struct Response {
24+ prices : Vec < f64 > ,
25+ market_status : String ,
2526}
2627
2728// ============================================================================
28- // EXECUTION PHASE - FETCHES LIVE DATA FROM KALSHI & POLYMARKET - TAKES VOLUME WEIGHTED PRICE
29+ // EXECUTION PHASE - FETCHES LIVE DATA FROM POLYMARKET ONLY
2930// ============================================================================
3031
3132/**
3233 * Executes the data request phase within the SEDA network.
33- * This phase fetches price data from both Kalshi and PolyMarket for the same market,
34- * then calculates a volume-weighted average price between the two platforms.
35- * Currently works with binary prediction markets and focuses on the "yes" outcome price.
36- * Returns the volume-weighted average price as the final result .
34+ * This phase fetches event data from PolyMarket for a specific event.
35+ * Takes a single input: event_id
36+ * Loops through all markets in the event and extracts the first outcome price from each market .
37+ * Returns a JSON response with a vector of first outcome prices and whether the event is closed .
3738 */
3839pub fn execution_phase ( ) -> Result < ( ) > {
3940 // Retrieve the input parameters for the data request (DR).
40- // Expected to be a market identifier that works for both Kalshi and PolyMarket APIs.
41+ // Expected to be a single event_id
4142 let dr_inputs_raw = String :: from_utf8 ( Process :: get_inputs ( ) ) ?;
42- let dr_inputs_trimmed = dr_inputs_raw. trim ( ) ;
43-
44- let market_tickers: Vec < & str > = dr_inputs_trimmed. split ( ',' ) . collect ( ) ;
43+ let event_id = dr_inputs_raw. trim ( ) ;
4544
46- log ! ( "Fetching market data from Kalshi and PolyMarket for market : {} and {} " , market_tickers [ 0 ] , market_tickers [ 1 ] ) ;
45+ log ! ( "Fetching event data from PolyMarket for event : {}" , event_id ) ;
4746
48- // Step 1: Fetch Kalshi market data (yes bid price and volume)
49- let kalshi_market_response = http_fetch (
50- format ! ( "https://api.elections.kalshi. com/trade-api/v2/markets/ {}" , market_tickers [ 0 ] ) ,
47+ // Fetch PolyMarket event data
48+ let polymarket_event_response = http_fetch (
49+ format ! ( "https://gamma- api.polymarket. com/events/ {}" , event_id ) ,
5150 None ,
5251 ) ;
5352
54-
55- // Check if the market request was successful
56- if !kalshi_market_response. is_ok ( ) {
53+ // Check if the event request was successful
54+ if !polymarket_event_response. is_ok ( ) {
5755 elog ! (
58- "market HTTP Response was rejected: {} - {}" ,
59- kalshi_market_response . status,
60- String :: from_utf8( kalshi_market_response . bytes) ?
56+ "PolyMarket HTTP Response was rejected: {} - {}" ,
57+ polymarket_event_response . status,
58+ String :: from_utf8( polymarket_event_response . bytes) ?
6159 ) ;
62- Process :: error ( "Error while fetching market information" . as_bytes ( ) ) ;
60+ Process :: error ( "Error while fetching PolyMarket event information" . as_bytes ( ) ) ;
6361 return Ok ( ( ) ) ;
6462 }
6563
64+ // Parse event information
65+ let poly_market_event_data = serde_json:: from_slice :: < PolyMarketEvent > ( & polymarket_event_response. bytes ) ?;
6666
67- // Parse market informationmarket_response
68- let kalshi_market_data = serde_json:: from_slice :: < KalshiMarketResponse > ( & kalshi_market_response. bytes ) ?;
69- log ! (
70- "Fetched Kalshi Price (YES BID): {} cents with volume {}" ,
71- kalshi_market_data. market. yes_bid_dollars,
72- kalshi_market_data. market. volume
73- ) ;
74-
75- let kalshi_yes_bid_dollars = kalshi_market_data. market . yes_bid_dollars . parse :: < f64 > ( ) ?;
76-
77-
78- // Step 2: Fetch PolyMarket market data (yes outcome price and volume)
79- let polymarket_market_response = http_fetch (
80- format ! ( "https://gamma-api.polymarket.com/markets/{}" , market_tickers[ 1 ] ) ,
81- None ,
82- ) ;
83-
84-
85- // Check if the market request was successful
86- if !polymarket_market_response. is_ok ( ) {
87- elog ! (
88- "market HTTP Response was rejected: {} - {}" ,
89- polymarket_market_response. status,
90- String :: from_utf8( polymarket_market_response. bytes) ?
91- ) ;
92- Process :: error ( "Error while fetching market information" . as_bytes ( ) ) ;
67+ // Validate that the event has at least one market
68+ if poly_market_event_data. markets . is_empty ( ) {
69+ elog ! ( "Event has no markets available" ) ;
70+ Process :: error ( "Error: Event has no markets" . as_bytes ( ) ) ;
9371 return Ok ( ( ) ) ;
9472 }
9573
96- // Parse market informationmarket_response
97- let poly_market_market_data = serde_json:: from_slice :: < PolyMarketMarket > ( & polymarket_market_response. bytes ) ?;
98- let outcome_prices_array: Vec < String > = serde_json:: from_str ( & poly_market_market_data. outcome_prices ) ?;
99- let polymarket_yes_price = outcome_prices_array[ 0 ] . parse :: < f64 > ( ) ?; // 0 = yes price
100-
101- log ! (
102- "Fetched Price (YES PRICE): {} cents with volume {}" ,
103- polymarket_yes_price,
104- poly_market_market_data. volume
105- ) ;
106-
107-
108- let poly_market_volume = poly_market_market_data. volume . parse :: < f64 > ( ) ?;
109-
110- // Step 3: Calculate volume-weighted average price between Kalshi and PolyMarket
111- let total_volume = kalshi_market_data. market . volume as f64 + poly_market_volume;
74+ // Loop through all markets and extract the first outcome price from each
75+ let mut yes_prices: Vec < f64 > = Vec :: new ( ) ;
11276
113- if total_volume == 0.0 {
114- elog ! ( "Total volume is zero, cannot calculate volume weighted average price" ) ;
115- Process :: error ( "Error: Total volume is zero" . as_bytes ( ) ) ;
116- return Ok ( ( ) ) ;
77+ for ( i, market) in poly_market_event_data. markets . iter ( ) . enumerate ( ) {
78+ // Parse the outcome_prices JSON string into a vector
79+ let outcome_prices_array: Vec < String > = serde_json:: from_str ( & market. outcome_prices ) ?;
80+
81+ if outcome_prices_array. is_empty ( ) {
82+ elog ! ( "Market {} has no outcome prices" , i) ;
83+ continue ;
84+ }
85+
86+ // Get the first outcome price and parse it as f64
87+ let yes_price = outcome_prices_array[ 0 ] . parse :: < f64 > ( ) . map_err ( |e| {
88+ elog ! ( "Failed to parse first outcome price for market {}: {}" , i, e) ;
89+ anyhow:: anyhow!( "Invalid price format" )
90+ } ) ?;
91+
92+ yes_prices. push ( yes_price) ;
93+ log ! ( "Market {}: First outcome price = {}" , i, yes_price) ;
11794 }
11895
119- // Calculate weighted prices: price × volume for each platform
120- let kalshi_weighted_price = kalshi_yes_bid_dollars * ( kalshi_market_data. market . volume as f64 ) ;
121- let polymarket_weighted_price = polymarket_yes_price * poly_market_volume;
122-
123- // Final volume-weighted average: (sum of weighted prices) / (total volume)
124- let volume_weighted_average_price = ( kalshi_weighted_price + polymarket_weighted_price) / total_volume;
125-
12696 log ! (
127- "Volume Weighted Average Price: {:.8} cents " ,
128- volume_weighted_average_price
97+ "Collected {} first outcome prices from all markets " ,
98+ yes_prices . len ( )
12999 ) ;
130100
131- // Return the volume-weighted average price as the execution result
132- Process :: success ( volume_weighted_average_price. to_string ( ) . as_bytes ( ) ) ;
101+ let market_status = if poly_market_event_data. closed {
102+ "closed" . to_string ( )
103+ } else {
104+ "open" . to_string ( )
105+ } ;
106+
107+
108+ // Return the PolyMarket first outcome prices and event status as JSON
109+ Process :: success ( & serde_json:: to_vec ( & Response {
110+ prices : yes_prices,
111+ market_status : market_status,
112+ } ) ?) ;
133113 Ok ( ( ) )
134114}
0 commit comments