@@ -207,9 +207,11 @@ def final_probability(self) -> float:
207207 """
208208 return self .probability_history ()[1 ][- 1 ]
209209
210- def probability_at_time (self , timestamp : float ) -> float :
210+ def probability_at_time (self , timestamp : float , smooth : bool = False ) -> float :
211211 """Return the probability at a given time, where time is represented as ms since origin.
212212
213+ If smooth is true, then it will give you the weighted mean of the two nearest probabilities.
214+
213215 Originally from manifoldpy/api.py, with permission, under the MIT License, under which this project is also
214216 licensed.
215217 """
@@ -222,22 +224,53 @@ def probability_at_time(self, timestamp: float) -> float:
222224 start_guess = 0
223225 end_guess = len (times )
224226 idx = end_guess // 2
225- while not (times [idx - 1 ] <= timestamp < times [idx ]):
226- if times [idx ] >= timestamp :
227- start_guess = (start_guess + idx ) // 2
228- else :
229- end_guess = (end_guess + idx ) // 2
230- new_idx = (start_guess + end_guess ) // 2
231- if new_idx == idx :
232- raise RuntimeError ("Loop would have repeated" )
233- idx = new_idx
234- return probs [idx ]
227+ try :
228+ while not (times [idx - 1 ] <= timestamp < times [idx ]):
229+ if times [idx ] >= timestamp :
230+ start_guess = (start_guess + idx ) // 2
231+ else :
232+ end_guess = (end_guess + idx ) // 2
233+ new_idx = (start_guess + end_guess ) // 2
234+ if new_idx == idx :
235+ raise RuntimeError ("Loop would have repeated" )
236+ idx = new_idx
237+ except IndexError :
238+ # this means that we fell off the edge of the probability map, so just return the nearest one
239+ if idx <= 0 :
240+ return probs [0 ]
241+ return probs [- 1 ]
242+ if smooth :
243+ weight_1 = 1 / abs (timestamp - times [idx - 1 ])
244+ weight_2 = 1 / abs (timestamp - times [idx ])
245+ total_weight = weight_1 + weight_2
246+ return (probs [idx - 1 ] * weight_1 + probs [idx ] * weight_2 ) / total_weight
247+ return probs [idx - 1 ]
235248
236249 # end section from manifoldpy
250+ def value_at_time (self , timestamp : float , smooth : bool = False ) -> float :
251+ """Get the value at a given time.
252+
253+ Note: if this is a binary market, this is the same thing as probability_at_time()
254+ """
255+ if self .outcomeType == "BINARY" :
256+ return self .probability_at_time (timestamp , smooth )
257+ assert self .min is not None
258+ assert self .max is not None
259+ return prob_to_number_cpmm1 (
260+ self .probability_at_time (timestamp , smooth ),
261+ self .min ,
262+ self .max ,
263+ bool (self .isLogScale )
264+ )
265+
237266 def probability_at_datetime (self , dt : datetime ) -> float :
238267 """Translate your datetime into one that is Manifold-compatible."""
239268 return self .probability_at_time (dt .timestamp () * 1000 )
240269
270+ def value_at_datetime (self , dt : datetime ) -> float :
271+ """Translate your datetime into one that is Manifold-compatible."""
272+ return self .value_at_time (dt .timestamp () * 1000 )
273+
241274
242275@dataclass
243276class Group (DictDeserializable ):
0 commit comments