There is no need to declare any of those things global. A global declaration is useful and necessary when there is a variable outside of your def which you need to change from inside.
For writing CSV data, probably use the csv library.
import csv
# ...
def event_handler_quote_update(message):
# print(f"quote update {message}")
token = message['token']
ltp = message['ltp']
date = message['exchange_time_stamp']
with open('results.csv', 'a+') as csvfile:
writer = csv.writer(csvfile)
writer.writerow([token, ltp, date])
It would be a lot better if there was a way to open the CSV file for writing and instantiate the writer object just once, outside the callback, and simply pass in writer as the second argument after message; though then, you will need to close() it separately when you are done.
import csv
# ...
def event_handler_quote_update(message, writer):
# print(f"quote update {message}")
token = message['token']
ltp = message['ltp']
date = message['exchange_time_stamp']
writer.writerow([token, ltp, date])
# ...
if __name__ == '__main__':
# whatever else you have here
csvfile = open('results.csv', 'w')
writer = csv.writer(csvfile)
# ... whatever else your program needs to do
csvfile.close()
But maybe you don't have control over how the callback gets called. Then maybe you do need writer to be global inside the def.
There's no need really to copy each field into a separate variable; if there are a lot of fields you want to extract, probably switch to something like
writer.writerow([message[x] for x in ('token', 'ltp', 'exchange_time_stamp')])
See the documentation link above if you need to use a different variant of CSV format, like tab or semicolon delimited, or write a header at the top, etc. It's all there.