Using a time period in IF statements - python

So I have a variable x that is being updated to a new value through a websocket within a while loop.
I have an IF statement where
if x >= 150 :
#execute orders here
Now the problem I have is sometimes the x value will spike above 150 for a fraction of a second, perhaps not even 0.01 seconds in which case I do not want to the orders to execute, and disregard this.
I was thinking of solving this by executing if x >= 150 and remains so for 0.1 seconds.
But I am not sure how to execute this. Perhaps I could create a time variable y, when x first goes above 150 and than measure the time difference against the datetime.now. The problem with that is the variable y will keeping changing to the current time as x will be constantly getting updated by the websocket connection.
Any ideas how to do this? Please keep in mind that execution speed is critical to this code making me any money, and also it is a websocket so that x value will be getting updated constantly.

This is the code I made to solve this problem.
from datetime import datetime
from datetime import timedelta
x=100 # trigger value
y = datetime.now()
while True :
try:
if x > 150 :
z= datetime.now()
if z-y >= timedelta(seconds=5) : # time here represents how long it needs to stay past trigger point
#execute code here
print(y)
y = datetime.now()
except Exception as e: print( "this is the error1:" +str(e))
I was also doing this within an asynchronous loop. In that case a better solution can be found here:
How can I periodically execute a function with asyncio?

Related

Summing Results from a function running every 30 seconds

I've made a simple trading strategy, which executes every 30 seconds. I've defined the strategy in a function:
def strategy():
# strategy
time.sleep(30)
print(f'The Result from the Trade is: {result}')
Then I run it through a while loop:
while True:
strategy()
It's definitely not the best implementation, but it works for only testing a strategy. It shows me the result from each trade. However, I want to let it run through the whole day and accumulate and store the result from each trade in a variable, so I have the final result from all the trades from the whole day.
I've been looking at how to make this happen, but I can't find anything for the structure I have. Can someone help, please?
If you want to sum up the value returned you can do the following
strategy_output = 0
while True:
strategy_output =+ strategy()
If you want to save all the values till the last loop you can mantain the value in a dictionary corresponding to execution time
from datetime import datetime
strategy_output_dict = {}
while True:
now = datetime.now()
current_time = now.strftime("%H:%M:%S")
strategy_output = strategy()
strategy_output_dict[current_time] = strategy_output

Functions that stop after x time Python

I am working at a Python project, and I reached a point where I need a function to stop and return after a x time, that is passed as a parameter. A simple example:
def timedfunc(time_to_stop):
result = None
while (time_has_not_passed):
do()
return result
I explain:
When time has passed, timedfunc stops and interrupts everything in it, and jumps right to return result. So, what I need is a way to make this function work as long as possible (time_to_stop), and then to return the result variable, which is as accurate as possible (More time, more calculations, more accuracy). Of course, when time is out, also do() stops. To better understand, I say that the function is continuosly changing the value of result, and once the time has passed it returns the current value. (do() stands for all the calculations that change result)
I just made a simple example to better explain what I want:
def multiply(time):
result = 10
while time_has_not_passed:
temporary = result*10 #Actually much more time-consuming, also like 3 minutes.
temporary /= 11
result = temporary
return result
This explains what kind of calculations do() makes, and I need as many *10/11 as python can do in, for example, 0.5 sec.
I know that this pretty complicated, but any help would be great.
import time
start_time = time.time()
program()
if (time.time()-start_time)>0.5: #you can change 0.5 to any other value you want
exit()
It is something like this. you can put this if statement right inside your program function too.
maybe you can use:
time.sleep(x)
do()
# OR
now = time()
cooldown = x
if now + cooldown < time():
do()
if you want it to do something for a while
now = time()
needed_time = x
while now + needed_time > time():
do()

Make a loop last once second using datetime?

Bright minds of Stackoverflow, I have a quest for you.
Currently I am running a loop in which calculations and data aquisition happen. These get more and more complicated over time. I want each run of the loop to last exactly one second. Due to the growing time of the calculations a simple "sleep(1)" at the end does not really help.
while True:
#here calculations happen that take more and more time
print 'some of the data'
sleep(1)
I was hoping to use datetime to calculate the seconds/milliseconds before these calculations and after to enter the difference into the sleep command. But i can't quite get my head around it. Can anyone help me out?
a=datetime.now()
#calculations
b=datetime.now()
calctime=(b-a).total_seconds()
sleep(1-calctime)
Try this:
from datetime import datetime
import time
def test():
a = datetime.now()
# calculations
b = datetime.now()
calctime = (b - a).total_seconds()
print("one")
time.sleep((1 - calctime) if (1-calctime)>0.0 else 0) #if your calculation already took 1 or more than 1 second then then make the waiting time 0
print("two")
test()
a=datetime.now()
#calculations
b=datetime.now()
calctime=b-a
ms = calctime.microseconds
if calctime.seconds == 0:
sleep(1-ms/1000000)
Additional info here: Python speed testing - Time Difference - milliseconds

Python: How to compare two hours

I need to call a function, exactly 08:00, 18:00, 22:00 hours. I've created a example to test the comparison between hours. When the current time reaches one of those horary. Put in inside a While loop thinking this example would work as a stopwatch, but I think I'm wrong. How is the best way to compare those values?
currentH= dt.datetime.now().strftime("%H:%M:%S")
h = "16:15:10"
while True:
if(currentH==h):
print 'Ok'
print 'The current Hour is: '+h
import datetime as dt
import time
currentH= dt.datetime.now().replace(microsecond=0).time()
hrs = ['00:02', '12:00']
for i in range(len(hrs)):
h = [int(x) for x in hrs[i].split(':')]
h = dt.datetime.now().replace(hour=h[0], minute=h[1], second=0,microsecond=0).time()
hrs[i] = h
while True:
currentH = dt.datetime.now().replace(microsecond=0).time()
print(currentH)
if currentH in hrs:
print('Time is now',currentH)
time.sleep(1)
The biggest problem with your code is that you never call now() again inside the loop, so you're just spinning forever comparing the initial time to 16:15:10.
While we're at it: Why convert the time to a string for comparison instead of just comparing times?
But there are bigger problems with this design that can't be fixed as easily.
What happens if you check the time at 16:15, then go to sleep, then wake up at 16:25? Then now() never returns 16:15:10.
Also, do you really want to burn 100% CPU for 10 hours?
A better solution is to write a sleep_until function:
def sleep_until(target):
left = target - dt.datetime.now()
if left > dt.timedelta(seconds=0):
time.sleep(left.total_seconds())
(If you're using Python 2.7 or 3.4, it's a bit more complicated, because sleep will wake up early if there's a signal. But to handle that case, you just need to add a while True: loop around the whole thing.)
Now, the only tricky bit is working out the first time you need to sleep until, which isn't all that tricky:
waits = itertools.cycle(dt.timedelta(hours=wait) for wait in (10, 4, 10))
now = dt.datetime.now()
start = dt.datetime.combine(dt.date.today(), dt.time(hour=8))
for wait in waits:
start += wait
if start > now:
break
And now, we just loop over the waits forever, sleeping until each next time:
for wait in waits:
sleep_until(start)
print('Time to make the donuts')
start += wait
Or, of course, you could just grab one of the many scheduling libraries off PyPI.
Or just use your platform's cron/launchd/Scheduled Tasks API to run your script.

Time.sleep inaccurate for Python counter?

I'd like to create a revenue counter for the sales team at work and would love to use Python. E.g. Joe Bloggs shifts his target from 22.1 to 23.1 (difference of 1.0.) I'd like the counter to tick evenly from 22.1 to 23.1 over an hour.
I've created this script, which works fine for counting a minute (runs 2 seconds over the minute); however, when it's supposed to run for an hour, it runs for 47 minutes.
Question: Does anyone know why it runs faster when I set it to an hour? Is sleep.time inaccurate?
import time
def rev_counter(time_length):
time_start = (time.strftime("%H:%M:%S"))
prev_pp = 22.1
new_pp = 23.1
difference = new_pp - prev_pp
iter_difference = (difference / 100000.) # Divide by 100,000 to show 10 decimal places
time_difference = ((time_length / difference) / 100000.)
i = prev_pp
while i < new_pp:
print("%.10f" % i)
i = i + iter_difference
time.sleep(time_difference)
time_end = (time.strftime("%H:%M:%S"))
print "Time started at", time_start
print "Time ended at", time_end
rev_counter(60) # 60 seconds. Returns 62 seconds
rev_counter(600) # 10 minutes. Returns 10 minutes, 20 secs
rev_counter(3600) # 1 hour. Returns 47 minutes
Please note this quote from the Python documentation for time.sleep()
The actual suspension time may be less than that requested because any
caught signal will terminate the sleep() following execution of that
signal's catching routine. Also, the suspension time may be longer
than requested by an arbitrary amount because of the scheduling of
other activity in the system.
As a suggestion, if faced with this problem, I would use a variable to track the time that the interval starts. When sleep wakes up, check to see if the expected time has elapsed. If not, restart a sleep for the difference, etc.
First of all, your loop doesn't only contain sleep statements -- the things you do between calling time.sleep take time, too, so if you do 10 repetions, you'll spent only 10% of the time doing these compared to when you have 100 iterations through your loop.
Is sleep.time inaccurate?
Yes. Or well. Quite.
I come from a real-time signal processing background. PC clocks are only somewhat accurate, and the time you spend in your OS, your standard libraries, your scripting language run time and your scripting logic between the point in time when a piece of hardware notifies you that your time has elapsed and the point in time your software notices is significant.
I just noticed time.sleep taking way too long (5-30000 times longer for input values between .0001 to 1 second), and searching for an answer, found this thread. I ran some tests and it is consistently doing this (see code and results below). The weird thing is, I restarted, then it was back to normal, working very accurately. When code started to hang it was time.sleep taking 10000 times too long?!
So a restart is a temporary solution, but not sure what the cause is/ permanent solution is.
import numpy as np
import time
def test_sleep(N,w):
data = []
for i in xrange(N):
t0 = time.time()
time.sleep(w)
t1 = time.time()
data.append(t1-t0)
print "ave = %s, min = %s, max = %s" %(np.average(data), np.min(data), np.max(data))
return data
data1 = test_sleep(20,.0001)
Out: ave = 2.95489487648, min = 1.11787080765, max = 3.23506307602
print data1
Out: [3.1929759979248047,
3.121081829071045,
3.1982388496398926,
3.1221959590911865,
3.098078966140747,
3.131525993347168,
3.12644100189209,
3.1535091400146484,
3.2167508602142334,
3.1277999877929688,
3.1103289127349854,
3.125699996948242,
3.1129801273345947,
3.1223208904266357,
3.1313750743865967,
3.1280829906463623,
1.117870807647705,
1.3357980251312256,
3.235063076019287,
3.189779043197632]
data2 = test_sleep(20, 1)
Out: ave = 9.44276217222, min = 1.00008392334, max = 10.9998381138
print data2
Out: [10.999573945999146,
10.999622106552124,
3.8115758895874023,
1.0000839233398438,
3.3502109050750732,
10.999613046646118,
10.99983811378479,
10.999617099761963,
10.999662160873413,
10.999619960784912,
10.999650955200195,
10.99962306022644,
10.999721050262451,
10.999620914459229,
10.999532222747803,
10.99965500831604,
10.999596118927002,
10.999563932418823,
10.999600887298584,
4.6992621421813965]

Categories