1

Every morning I get spot data on FX volumes via an email, I'd like to build a process to search two pieces of data within the body of the email and save them as a new variable which I can then refer to later.

I've got the process to search my emails, order them according to date and check whether the entered data exists within the emails, but because the data is contained within a format between two commas, I am unsure how to take that data out and assign it to a new variable.

Format for example is this:
BWP/USD,0
CHF/AMD T,0

This is what I've achieved thus far:

import win32com.client
import os
import time
import re

# change the ticker to the one you're looking for
FX_volume1 = "BWP/USD"
FX_volume2 = "CHF/AMD"
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
messages.Sort("[ReceivedTime]", True)

# find spot data
for message in messages:
    if message.subject.startswith("FX SPOT FIGURES"):
        if FX_volume1 and FX_volume2 in message.body: 
           data = message.body
           print(data)
    else:
        print('No data for', FX_volume1, 'or', FX_volume2, 'was found')
        break

Any idea how to take this forward?

Thanks for any assistance/pointers

alec22
  • 735
  • 2
  • 12

1 Answers1

1
import win32com.client
import os
import time
import re

# change the ticker to the one you're looking for
FX_volume1 = "BWP/USD"
FX_volume2 = "CHF/AMD"
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
messages.Sort("[ReceivedTime]", True)

# find spot data
for message in messages:
    if message.subject.startswith("FX SPOT FIGURES"):
        case1 = re.match(FX_volume1 + ",(\d*)", message.body)
        case2 = re.match(FX_volume2 + ",(\d*)", message.body)

case (1 and 2) will be match objects if a match is found, else they will be None. To retrieve your values just do val = case1.group(1). Hence:

EDIT:

if case1 not None:
    FX_vol1_val = case1.group(1)
if case2 not None:
    FX_vol2_val = case1.group(1)

For more info on match objects: https://docs.python.org/3/library/re.html#match-objects

If you are expecting floats, see the following link: Regular expression for floating point numbers

EDIT 2:

Hi, so as you couldn't get it working I gave it a quick try and it worked for me with the following example. Just to add to regex notation, anything that you put in brackets (), if the pattern matches, the contents between the brackets will be stored.

import re
    
my_text = "BWP/USD,1"
FX_pattern = "BWP/USD,"  # added the comma here for my convinience

my_match = re.match(FX_pattern, "(\d*)")

print("Group 0:", my_match.group(0))
print("Group 1:", my_match.group(1))

Printout:

Group 0: BWP/USD,1
Group 1: 1
pb.
  • 125
  • 1
  • 7
  • Hi pb, thanks for looking into this. I noticed a bit of an issue (I'm probably misunderstanding it somewhat). I added a couple of lines to your conditions as a test and it seems that the 'FX_vol1_val = case1.group(0)' and 'FX_vol2_val = case2.group(0)' are not assigning variables. I added: if case1 is not None: FX_vol1_val = case1.group(0) else: print('bop') if case2 is not None: FX_vol2_val = case2.group(0) else: print(case2) – alec22 Oct 11 '21 at 10:02
  • And all it does is print out: bop None bop None bop – alec22 Oct 11 '21 at 10:03
  • If I FX_vol1_val = case1.group(0) I get the error: 'NoneType' object has no attribute 'group' – alec22 Oct 11 '21 at 10:30
  • Sounds like a match is not being found, I ran a text and it worked for me. I will say I did make one mistake, its match.group(1) not 0. Will add my changes to the text now – pb. Oct 11 '21 at 10:42
  • can you printout the body of your message for me? – pb. Oct 11 '21 at 10:57
  • The email basically reads like this: "BWP/USD,0 CHF/AMD T,0 CHF/UAH T,0 CNH/KZT T,0 CNH/PHP,0 EUR/ALL,0 EUR/AMD T,0 ..." – alec22 Oct 11 '21 at 11:30
  • One line for each FX ticker – alec22 Oct 11 '21 at 11:30
  • I am assuming message.body returns a string. I plugged that in and it worked. If you have multiple lines with the same match you can either use the above method to loop through each line OR you could use my_matches = re.findall(FX_pattern, my_text) and this will return a LIST (EDIT: wrote string instead of list) – pb. Oct 11 '21 at 11:40