Python Schedule module works only the first time - python

I'm currently working as an quant intern in a financial company. What I'm trying to do is to let the system update today's stock market data into .csv every day at 16:30.
I searched online and found the Schedule module, seems quite easy so I implemented it. On the first day(Monday), it did a good job and updated accordingly. However, today I check the server yesterday's (Tuesday) date was not updated and error was reported.
how I wrote my code is as follows:
def job():
stockss = list(all_instruments(type='CS').order_book_id.values)
for stock in stockss:
d = datetime.datetime.today().strftime('%Y-%m-%d')
a = rq.get_price(stock,str(d),str(d))
df = pd.DataFrame(a)
with open(str(stock)+'.csv','a') as f:
df.to_csv(f, header = False)
schedule.every().monday.at("16:30").do(job)
schedule.every().tuesday.at("16:30").do(job)
schedule.every().wednesday.at("16:30").do(job)
schedule.every().thursday.at("16:30").do(job)
schedule.every().friday.at("16:30").do(job)
while True:
schedule.run_pending()
time.sleep(1)
thank you!

You can use another more powerful module apscheduler, here is an example:
# ... your import
from apscheduler.schedulers.blocking import BlockingScheduler
def job():
stockss = list(all_instruments(type='CS').order_book_id.values)
for stock in stockss:
d = datetime.datetime.today().strftime('%Y-%m-%d')
a = rq.get_price(stock,str(d),str(d))
df = pd.DataFrame(a)
with open(str(stock)+'.csv','a') as f:
df.to_csv(f, header = False)
if __name__ == '__main__':
scheduler = BlockingScheduler()
scheduler.add_job(job, 'cron', day_of_week="mon-fri", hour="16", minute="30") # run on Monday to Friday at 16:30
print('Press Ctrl+C to exit')
try:
scheduler.start()
except (KeyboardInterrupt, SystemExit):
pass
Here is the related docs:
https://apscheduler.readthedocs.io/en/latest/modules/triggers/cron.html#module-apscheduler.triggers.cron
https://apscheduler.readthedocs.io/en/latest/index.html

Related

Run a program on a specific time using python

I want to run a batch file(say wanted to run calculator) on a specific date and time using python (but don't use the default scheduler).
My program:
a = "C:\Windows\system32\calc.exe"
mybat = open(r"D:\Cyber_security\Python\cal.bat", "w+")
mybat.write(a)
mybat.close()
import datetime
start = datetime.datetime.now()
end = datetime.datetime(2022, 7, 12, 17, 29, 10)
while(True):
if(end - start == 0):
import subprocess
subprocess.call([r"D:\Cyber_security\Python\cal.bat"])
when I run it it doesn't show error but the batch file is not running at specific time. where is the wrong?
Ever tried schedule package?
import schedule
import time
def job():
print("I'm working...")
schedule.every(10).seconds.do(job)
schedule.every(10).minutes.do(job)
schedule.every().hour.do(job)
schedule.every().day.at("10:30").do(job)
schedule.every(5).to(10).minutes.do(job)
schedule.every().monday.do(job)
schedule.every().wednesday.at("13:15").do(job)
schedule.every().minute.at(":17").do(job)
while True:
schedule.run_pending()
time.sleep(1)
What about Rocketry?
from rocketry import Rocketry
app = Rocketry()
#app.task('every 1 hour')
def do_hourly():
...
#app.task('daily between 10:00 and 14:00 & time of week on Monday')
def do_once_a_day_on_monday():
...
#app.task("after task 'do_hourly'")
def do_after_another():
...
if __name__ == "__main__":
app.run()
It also has parametrization, parallelization and Pythonic conditions if you dislike the string-based condition language.
Documentation: https://rocketry.readthedocs.io/
Source code: https://github.com/Miksus/rocketry
I already found my answer.
a = "C:\Windows\system32\calc.exe"
mybat = open(r"D:\Cyber_security\Python\cal.bat", "w+")
mybat.write(a)
mybat.close()
import sched
from datetime import datetime
import time
def action():
import subprocess
subprocess.call([r"D:\Cyber_security\Python\cal.bat"])
s = sched.scheduler(time.time, time.sleep)
e_x = s.enterabs(time.strptime('Tue Jul 12 19:57:17 2022'), 0, action)
s.run()

Run Function at Given DateTime [duplicate]

How can I run a function in Python, at a given time?
For example:
run_it_at(func, '2012-07-17 15:50:00')
and it will run the function func at 2012-07-17 15:50:00.
I tried the sched.scheduler, but it didn't start my function.
import time as time_module
scheduler = sched.scheduler(time_module.time, time_module.sleep)
t = time_module.strptime('2012-07-17 15:50:00', '%Y-%m-%d %H:%M:%S')
t = time_module.mktime(t)
scheduler_e = scheduler.enterabs(t, 1, self.update, ())
What can I do?
Reading the docs from http://docs.python.org/py3k/library/sched.html:
Going from that we need to work out a delay (in seconds)...
from datetime import datetime
now = datetime.now()
Then use datetime.strptime to parse '2012-07-17 15:50:00' (I'll leave the format string to you)
# I'm just creating a datetime in 3 hours... (you'd use output from above)
from datetime import timedelta
run_at = now + timedelta(hours=3)
delay = (run_at - now).total_seconds()
You can then use delay to pass into a threading.Timer instance, eg:
threading.Timer(delay, self.update).start()
Take a look at the Advanced Python Scheduler, APScheduler: http://packages.python.org/APScheduler/index.html
They have an example for just this usecase:
http://packages.python.org/APScheduler/dateschedule.html
from datetime import date
from apscheduler.scheduler import Scheduler
# Start the scheduler
sched = Scheduler()
sched.start()
# Define the function that is to be executed
def my_job(text):
print text
# The job will be executed on November 6th, 2009
exec_date = date(2009, 11, 6)
# Store the job in a variable in case we want to cancel it
job = sched.add_date_job(my_job, exec_date, ['text'])
Might be worth installing this library: https://pypi.python.org/pypi/schedule, basically helps do everything you just described. Here's an example:
import schedule
import time
def job():
print("I'm working...")
schedule.every(10).minutes.do(job)
schedule.every().hour.do(job)
schedule.every().day.at("10:30").do(job)
schedule.every().monday.do(job)
schedule.every().wednesday.at("13:15").do(job)
while True:
schedule.run_pending()
time.sleep(1)
Here's an update to stephenbez' answer for version 3.5 of APScheduler using Python 2.7:
import os, time
from apscheduler.schedulers.background import BackgroundScheduler
from datetime import datetime, timedelta
def tick(text):
print(text + '! The time is: %s' % datetime.now())
scheduler = BackgroundScheduler()
dd = datetime.now() + timedelta(seconds=3)
scheduler.add_job(tick, 'date',run_date=dd, args=['TICK'])
dd = datetime.now() + timedelta(seconds=6)
scheduler.add_job(tick, 'date',run_date=dd, kwargs={'text':'TOCK'})
scheduler.start()
print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))
try:
# This is here to simulate application activity (which keeps the main thread alive).
while True:
time.sleep(2)
except (KeyboardInterrupt, SystemExit):
# Not strictly necessary if daemonic mode is enabled but should be done if possible
scheduler.shutdown()
I've confirmed the code in the opening post works, just lacking scheduler.run(). Tested and it runs the scheduled event. So that is another valid answer.
>>> import sched
>>> import time as time_module
>>> def myfunc(): print("Working")
...
>>> scheduler = sched.scheduler(time_module.time, time_module.sleep)
>>> t = time_module.strptime('2020-01-11 13:36:00', '%Y-%m-%d %H:%M:%S')
>>> t = time_module.mktime(t)
>>> scheduler_e = scheduler.enterabs(t, 1, myfunc, ())
>>> scheduler.run()
Working
>>>
I ran into the same issue: I could not get absolute time events registered with sched.enterabs to be recognized by sched.run. sched.enter worked for me if I calculated a delay, but is awkward to use since I want jobs to run at specific times of day in particular time zones.
In my case, I found that the issue was that the default timefunc in the sched.scheduler initializer is not time.time (as in the example), but rather is time.monotonic. time.monotonic does not make any sense for "absolute" time schedules as, from the docs, "The reference point of the returned value is undefined, so that only the difference between the results of consecutive calls is valid."
The solution for me was to initialize the scheduler as
scheduler = sched.scheduler(time.time, time.sleep)
It is unclear whether your time_module.time is actually time.time or time.monotonic, but it works fine when I initialize it properly.
dateSTR = datetime.datetime.now().strftime("%H:%M:%S" )
if dateSTR == ("20:32:10"):
#do function
print(dateSTR)
else:
# do something useful till this time
time.sleep(1)
pass
Just looking for a Time of Day / Date event trigger:
as long as the date "string" is tied to an updated "time" string, it works as a simple TOD function. You can extend the string out to a date and time.
whether its lexicographical ordering or chronological order comparison,
as long as the string represents a point in time, the string will too.
someone kindly offered this link:
String Comparison Technique Used by Python
had a really hard time getting these answers to work how i needed it to,
but i got this working and its accurate to .01 seconds
from apscheduler.schedulers.background import BackgroundScheduler
sched = BackgroundScheduler()
sched.start()
def myjob():
print('job 1 done at: ' + str(dt.now())[:-3])
dt = datetime.datetime
Future = dt.now() + datetime.timedelta(milliseconds=2000)
job = sched.add_job(myjob, 'date', run_date=Future)
tested accuracy of timing with this code:
at first i did 2 second and 5 second delay, but wanted to test it with a more accurate measurement so i tried again with 2.55 second delay and 5.55 second delay
dt = datetime.datetime
Future = dt.now() + datetime.timedelta(milliseconds=2550)
Future2 = dt.now() + datetime.timedelta(milliseconds=5550)
def myjob1():
print('job 1 done at: ' + str(dt.now())[:-3])
def myjob2():
print('job 2 done at: ' + str(dt.now())[:-3])
print(' current time: ' + str(dt.now())[:-3])
print(' do job 1 at: ' + str(Future)[:-3] + '''
do job 2 at: ''' + str(Future2)[:-3])
job = sched.add_job(myjob1, 'date', run_date=Future)
job2 = sched.add_job(myjob2, 'date', run_date=Future2)
and got these results:
current time: 2020-12-10 19:50:44.632
do job 1 at: 2020-12-10 19:50:47.182
do job 2 at: 2020-12-10 19:50:50.182
job 1 done at: 2020-12-10 19:50:47.184
job 2 done at: 2020-12-10 19:50:50.183
accurate to .002 of a second with 1 test
but i did run a lot of tests and accuracy ranged from .002 to .011
never going under the 2.55 or 5.55 second delay
#everytime you print action_now it will check your current time and tell you should be done
import datetime
current_time = datetime.datetime.now()
current_time.hour
schedule = {
'8':'prep',
'9':'Note review',
'10':'code',
'11':'15 min teabreak ',
'12':'code',
'13':'Lunch Break',
'14':'Test',
'15':'Talk',
'16':'30 min for code ',
'17':'Free',
'18':'Help ',
'19':'watever',
'20':'watever',
'21':'watever',
'22':'watever'
}
action_now = schedule[str(current_time.hour)]

How to run python script on start up of pc but only once in day?

I have created a python script which do birthday wish to a person automatically when birthdate is arrive. I added this script on window start up but it run every time when i start my pc and do birthday wish to person also. I want to run that script only once a day. What should i do?
Try this at the start of the file:
import datetime
actualday = datetime.datetime.today().day # get the actual day
actualmonth = datetime.datetime.today().month # get the actual month
bday = 1 # day of birthday
bmonth = 1 # month of birthday
if actualday == bday and actualmonth == bmonth :
# code
it should finish the process if the dates aren't equal
You can run this program when the system boot How to start a python file while Windows starts?
And after that, you need check the time of when the system started like:
import datetime
dayToday = datetime.datetime.today().day
monthToday = datetime.datetime.today().month
birthdayDay = 1
birthdayMonth = 10
if dayToday == birthdayDay and monthToday == birthdayMonth:
print "HPBD"

ASYNCIO Issues. "Future pending"

I am currently having issues with Joblib running multiprocessing, or a parallel program. I was able to get this to work before, and I was reaching times of 1 min total, however, I went about and changed up a lot, and messed something up. I have posted the barebones code, as I am receiving the same error with it. I am trying to loop through all 150 stock symbols, and use yahoo finance to receive the option chain for each one. I am trying to do this on a minute basis. I have also tried other libraries like asyncio, and have been unsuccessful with that. Any recommendations would be much appreciated.
import yfinance as yf
def background(f):
def wrapped(*args, **kwargs):
return asyncio.get_event_loop().run_in_executor(None, f, *args, **kwargs)
return wrapped
done = []
#background
def downloadChain(ticker):
print(ticker)
df = pd.DataFrame()
daysOut = 100
chain = 0
try:
yf_ticker = yf.Ticker(ticker)
expiration_dates = yf_ticker.options
for expiration_date in expiration_dates:
if (datetime.fromisoformat(expiration_date) - datetime.now()).days <= daysOut:
try:
chain = yf_ticker.option_chain(expiration_date)
df = df.append(chain)
except Exception as e:
pass
except Exception as e:
pass
done.append(ticker)
Main function:
symbols = ["WATT","TSLA","UVXY","VXX","KEYS","EGO","GLD","WORK","BYND","BLK","PINS","LYFT","SPCE","PAYC","WDAY","UBER","CHGG","SHAK","CMG","CTL","ACB","TLRY","CGC","MJ","ORCL","GRUB","RNG","JWN","TTWO","ADI","ATVI","EA","SNE","GAMR","TXN","TMUS","MCHP","TSM","XBI","ETFC","MS","IWM","EXPD","RCL","CCL","MOMO","BABA","VMW","CRM","ULTA","SKYY","SPLK","FLWS","AVGO","TWTR","PANW","RJF","SABR","LOW","RS","ON","VEEV","DOCU","FB","SNAP","HPQ","RACE","F","AMAT","MRO","STM","AAL","DAL","VICR","XLC","CRON","DELL","T","VZ","S","MELI","CVM","REGN","NVAX","APT","CODX","LAKE","MRNA","EBS","INO", "SPY","SH","QQQ","XLF","KRE","XLV","HYG","LQD","NET","NFLX","ROKU","SHOP","AMZN","AAPL","MSFT","GOOGL","GOOG","NVDA","MU","AMD","INTC","MRVL","QCOMM","SQ","PYPL","TTD","TSLA","ZM","TDOC","LVGO","MDB","HD","VNQ","ARI","ACC","IIPR","EQR","EPR","SPG","PLD","ACB","WHR","NVAX","APT","MDT","CLRX","COST","SDC","LK","PVH","KSS","M","LULU","NKE","KO","BAC","JPM","CS","WFC","ARKW","ARKK","MGM","AMAT","WYNN","TGT","ITT","FXI"]
for ticker in symbols:
downloadChain(ticker)
I added a separate loop to see the size of the "done" array, which holds all the symbols that have been completed. I am unsure what i have changed, but now this loop is completing in about 10-15 mins when 1 minute is expected.
while True:
clear_output(wait=True)
print(len(done))
There are two versions of the "fix". Adding them as an answer rather than using comments as a chat :)
import asyncio
import pandas as pd
import yfinance as yf
from concurrent.futures import ThreadPoolExecutor
def background(f):
def wrapped(*args, **kwargs):
return asyncio.get_event_loop().run_in_executor(executor, f, *args, **kwargs)
return wrapped
done = []
#background
def downloadChain(ticker):
print(ticker)
df = pd.DataFrame()
daysOut = 100
chain = 0
try:
yf_ticker = yf.Ticker(ticker)
expiration_dates = yf_ticker.options
for expiration_date in expiration_dates:
if (datetime.fromisoformat(expiration_date) - datetime.now()).days <= daysOut:
try:
chain = yf_ticker.option_chain(expiration_date)
df = df.append(chain)
except Exception as e:
pass
except Exception as e:
pass
done.append(ticker)
symbols = ["WATT","TSLA","UVXY","VXX","KEYS","EGO","GLD","WORK","BYND","BLK","PINS","LYFT","SPCE","PAYC","WDAY","UBER","CHGG","SHAK","CMG","CTL","ACB","TLRY","CGC","MJ","ORCL","GRUB","RNG","JWN","TTWO","ADI","ATVI","EA","SNE","GAMR","TXN","TMUS","MCHP","TSM","XBI","ETFC","MS","IWM","EXPD","RCL","CCL","MOMO","BABA","VMW","CRM","ULTA","SKYY","SPLK","FLWS","AVGO","TWTR","PANW","RJF","SABR","LOW","RS","ON","VEEV","DOCU","FB","SNAP","HPQ","RACE","F","AMAT","MRO","STM","AAL","DAL","VICR","XLC","CRON","DELL","T","VZ","S","MELI","CVM","REGN","NVAX","APT","CODX","LAKE","MRNA","EBS","INO", "SPY","SH","QQQ","XLF","KRE","XLV","HYG","LQD","NET","NFLX","ROKU","SHOP","AMZN","AAPL","MSFT","GOOGL","GOOG","NVDA","MU","AMD","INTC","MRVL","QCOMM","SQ","PYPL","TTD","TSLA","ZM","TDOC","LVGO","MDB","HD","VNQ","ARI","ACC","IIPR","EQR","EPR","SPG","PLD","ACB","WHR","NVAX","APT","MDT","CLRX","COST","SDC","LK","PVH","KSS","M","LULU","NKE","KO","BAC","JPM","CS","WFC","ARKW","ARKK","MGM","AMAT","WYNN","TGT","ITT","FXI"]
with ThreadPoolExecutor() as executor:
for ticker in symbols:
downloadChain(ticker)
The second being more standard. In which we define an async main which we ask asyncio to use as the main entry point.
import asyncio
import pandas as pd
import yfinance as yf
from concurrent.futures import ProcessPoolExecutor
symbols = ["WATT","TSLA","UVXY","VXX","KEYS","EGO","GLD","WORK","BYND","BLK","PINS","LYFT","SPCE","PAYC","WDAY","UBER","CHGG","SHAK","CMG","CTL","ACB","TLRY","CGC","MJ","ORCL","GRUB","RNG","JWN","TTWO","ADI","ATVI","EA","SNE","GAMR","TXN","TMUS","MCHP","TSM","XBI","ETFC","MS","IWM","EXPD","RCL","CCL","MOMO","BABA","VMW","CRM","ULTA","SKYY","SPLK","FLWS","AVGO","TWTR","PANW","RJF","SABR","LOW","RS","ON","VEEV","DOCU","FB","SNAP","HPQ","RACE","F","AMAT","MRO","STM","AAL","DAL","VICR","XLC","CRON","DELL","T","VZ","S","MELI","CVM","REGN","NVAX","APT","CODX","LAKE","MRNA","EBS","INO", "SPY","SH","QQQ","XLF","KRE","XLV","HYG","LQD","NET","NFLX","ROKU","SHOP","AMZN","AAPL","MSFT","GOOGL","GOOG","NVDA","MU","AMD","INTC","MRVL","QCOMM","SQ","PYPL","TTD","TSLA","ZM","TDOC","LVGO","MDB","HD","VNQ","ARI","ACC","IIPR","EQR","EPR","SPG","PLD","ACB","WHR","NVAX","APT","MDT","CLRX","COST","SDC","LK","PVH","KSS","M","LULU","NKE","KO","BAC","JPM","CS","WFC","ARKW","ARKK","MGM","AMAT","WYNN","TGT","ITT","FXI"]
done = []
def downloadChain(ticker):
print(ticker)
df = pd.DataFrame()
daysOut = 100
chain = 0
try:
yf_ticker = yf.Ticker(ticker)
expiration_dates = yf_ticker.options
for expiration_date in expiration_dates:
if (datetime.fromisoformat(expiration_date) - datetime.now()).days <= daysOut:
try:
chain = yf_ticker.option_chain(expiration_date)
df = df.append(chain)
except Exception as e:
pass
except Exception as e:
pass
done.append(ticker)
async def main():
with ProcessPoolExecutor() as executor:
for ticker in symbols:
asyncio.get_event_loop().run_in_executor(executor, downloadChain,
ticker)
if __name__ == '__main__':
asyncio.run(main())
Here you also have more refined control over which executor to use. Basically, we explicitly code under which event loop we're working with and under which we add work to an executor. Local tests didn't show great differences between ProcessPoolExecutor and ThreadPoolExecutor.

Sleeping time for running multiple function using python

I am running a program which has many functions that need to be run every day at 00:00. I am using APSchedular and was wondering if there is need of sleeping time to run 10-20 functions exactly at 00:00 every day?
Here is my program;
import time
from apscheduler.schedulers.blocking import BlockingScheduler
sched = BlockingScheduler()
#sched.scheduled_job('cron', day_of_week='mon-sun', hour=0, minute=0)
def ABC():
path1 = ('C:\Users\ABC.tsv')
date = time.strftime("%Y-%m-%d")
url2 = ("%sT00:00:00&to=%sT23:00:00"%(date,date))
data2 = requests.get(url2)
Z=zipfile.ZipFile(StringIO.StringIO(data2.content))
Z.extractall()
df1=pd.read_csv(path1, sep='\t',names = ["Datetime", "BAC"])
df1['Datetime']=pd.to_datetime(df1['Datetime'])
df1=df1.set_index('Datetime')
df1=df1.resample('H',how='sum')
ABC= df1.copy()
ABCD= ABC* 0.519
ABC.to_csv('C:\Users\ABC.tsv')
ABCD.to_csv('C:\Users\ABCD.tsv')
return
sched.start()
Also, APSchedular does not allow adding an argument to the function, is there any workaround to this? Please note: in the above example, I have also added one function.

Categories