200 likes | 461 Views
Office of Foreign Assets Control (OFAC) Identifying Specially Designated Nationals (SDN) . SunTrust – BICE SAS COE April 2010. Office of Foreign Assets Control (OFAC) – Mission Statement.
E N D
Office of Foreign Assets Control (OFAC) Identifying Specially Designated Nationals (SDN) SunTrust – BICE SAS COE April 2010
Office of Foreign Assets Control (OFAC) – Mission Statement The Office of Foreign Assets Control ("OFAC") of the US Department of the Treasury administers and enforces economic and trade sanctions based on US foreign policy and national security goals against targeted foreign countries and regimes, terrorists, international narcotics traffickers, those engaged in activities related to the proliferation of weapons of mass destruction, and other threats to the national security, foreign policy or economy of the United States. OFAC acts under Presidential national emergency powers, as well as authority granted by specific legislation, to impose controls on transactions and freeze assets under US jurisdiction. Many of the sanctions are based on United Nations and other international mandates, are multilateral in scope, and involve close cooperation with allied governments.
Specially Designated Nationals (SDN) - Definition "Specially designated nationals" are organizations and individuals who are restricted from doing business with the United States or American companies, or Americans.. This includes terrorist organizations, individual terrorists, and state sponsors of terrorism (such as Iran, and North Korea). The list of "specially designated nationals" is maintained by the U.S. Department of the Treasury's Office of Foreign Assets Control (OFAC). 3
Notification • Important Notice to All Financial Institutions • OFAC violations have serious consequences. Institutions are hereby informed that those who fail to comply with the • regulations: • 1. May be subject to severe disciplinary actions. • 2. May individually face civil and criminal penalties or fines and/or prison sentences. • All institutions and employees are to read and be familiar with all policies and procedures. Additional pages have been made available in order for each institution to input their specific information and guidelines. 4
SUMMARY OF OFAC REGULATIONS FOR FINANCIAL INSTITUTIONS Financial institutions must monitor all financial transactions performed by or through them to detect those that involve any entity or person subject to the OFAC laws and regulations. For most situations, a financial institution should accept deposits and funds subject to OFAC regulations, but freeze the funds and accounts, so that absolutely no funds can be withdrawn (this is called “blocking”). However, there are a few situations that require the financial institution to reject the transaction or funds instead of accepting and blocking them. Exact regulations vary, in accordance with requirements imposed by the eight federal statutes and the specific sanctions. A detailed description of specific regulations for each program is available on the official OFAC web site: www.treas.gov/ofac. In general, OFAC rules prohibit financial institutions from engaging in transactions with the governments of, or individuals or entities associated with, foreign countries against which federal law imposes economic sanctions. Federal law also imposes sanctions against certain countries associated with terrorists and narcotics traffickers and their front organizations. OFAC rules prohibit transactions with these entities as well. OFAC maintains a list of entities and individuals against whom these restrictions apply. You will need this list, known as the “SDN list” (Specially Designated Nationals) in order to Comply. 5
Overview of SAS Process Establish Run-Time Environment Fetch Data Validate Name Information / Order Data Drive Through Both Lists to determine congruence Save Critical Files for later reference Show potential matches 6
Establish Run-Time Environment ** Establish Non-Default Run-Time environment attributes ; options ls = 110 ps = 50 nocenter obs = max ; ** Allocate SAS Libraries ; libname save '/xxxx/yyyy/sas_users/sgreen/saslib/'; ** Save area for SAS Tables; libname OFAC '/xxxx/yyyy/sas_modeling/OFAC/data/' ; ** Original OFAC SAS Table ; ** Allocate Non-SAS RDBMS ; *ibname ccds ORACLE path="@CCDS" user=xxxxxx password="yyyyyyyyy" ; * libname nz sasionza server = 'xxx.yyy.zzz.1' database = turbop user = xxxxxx pw = yyyyyy port = 5480 connection=unique ; ** Clean-Up any potential existing objects; proc delete data = work.ccds ; run; proc delete data = work.ofac ; run; proc delete data = work.matched; run; proc delete data = work.names ; run; proc delete data = work.address; run; proc delete data = work.inofac ; run; 7
Fetch Data ** Pass-thru to Netezza for In-Database SQL execution -- Fetch Unique Names ; proc sql; connect to sasionza as ntz ( server = '10.24.32.1' database = turbop user = sgreen pw = "{sas001}bmVlcmdz )"; ** Encoded Password generated from PROC PWENCODE ; create table work.address as select * from connection to ntz ( select distinct primary_last_name, primary_first_name from ah_name_addresses ); quit; run; 8
Validate Name Information – Account Holders ** Validate Last Name -- Establish working variables -- CCRT Customer Names ; data work.ccds; set work.address ( keep= primary_last_name primary_first_name); if verify(substr(primary_last_name,1,1),'ABCDEFGHIJKLMNOPQRSTUVWXYZ') = 0 ; ** Last Name begins with character; ccds_last = upcase(trim(left(primary_last_name ))); ccds_first = upcase(trim(left(primary_first_name))); clen_last = length(ccds_last ); clen_first = length(ccds_first); run; ** Eliminate un-necessary WORK file; proc delete data = work.address ; run; ** Eliminate any Duplicate Names ; proc sort data = work.ccds out = save.ccds_all nodupkey; by primary_last_name primary_first_name ; run; ** Eliminate un-necessary WORK file; proc delete data = work.ccds ; run; 9
Sample Name Information – Specially Designated Nationals (SDN) SDN Names ABU DHESS, Mohamed ABU MARZOOK, Mousa Mohammed . . . ANGULO OROBIO (SEGUNDO), Jose Francisco . . . ORTIZ PALACIOS, Willington Alfonso . . . SALEH AL-SAADI, Nassim Ben Mohamed Al-Cherif ben Mohamed . . . VALENCIA DE JARAMILLO, Maria Diocelina . . . VALENZUELA OTALORA, Manuel Enrique . VILLANUEVA MADRID, Mario Ernesto . . . ZAMBRANO MADRONERO, CarmenAlicia Account Holder Name ABU , MOHAMED ABU, MOHAMMED . . . ANGULO , FRANCISCO . . . ORTIZ, ALFONSO . . . SALEH AL, MOHAMED . . . VALENCIA, LINA . . . VALENZUELA , ENRIQUE . VILLANUEVA , ERNESTO . . . ZAMBRANO, A 10
Validate Name Information – Specially Designated Nationals (SDN) ** Validate Last Name -- Establish working variables -- OFAC Alias Name List ; data work.ofac; format SDN_name $100. ; set ofac.SDN_aka ( keep= SDN_name ); if verify(substr(SDN_name,1,1) ,'ABCDEFGHIJKLMNOPQRSTUVWXYZ') = 0 ; ** Last Name begins with character; ok=index(SDN_name,','); if ok > 0 then do; ofac_last = upcase(trim(left(substr(SDN_name,1,index(SDN_name,',')-1)))); ofac_last1 = substr(ofac_last,1,index(ofac_last,' ' )); ofac_first = upcase(trim(left(substr(SDN_name, index(SDN_name,',')+1)))); end; else do ; ** This code never was executed so it was not debugged nor verified ; ofac_last = upcase(trim(left(SDN_name))); ofac_last1 = substr(ofac_last,1,index(ofac_last,' ' )); ofac_first = upcase(trim(left(substr(SDN_name, index(SDN_name,' ')+1)))); end; olen_last = length(ofac_last ); olen_first = length(ofac_first); run; ** Eliminate any Duplicate Names ; proc sort data = work.ofac out = save.ofac_all nodupkey; by SDN_name ; run; ** Eliminate un-necessary WORK file; proc delete data = work.ofac ; run; 11
Drive Through Both Lists to determine congruence ** Drive thru lists to determine congruence -- save matches and non-matches in separate files ; data work.matched (keep = SDN_name primary_first_name primary_last_name ) work.lastname(keep = SDN_name ofac_last olen_last ofac_first olen_first ) work.inofac (keep = SDN_name ofac_last olen_last ofac_first olen_first ) ; retain o_point c_point c_first 1 ; set save.ofac_all point=o_point nobs=o_nobs; ** Fetch Next OFAC Name ; c_point = c_first ; do while(c_point <= c_nobs ); set save.ccds_all point=c_point nobs=c_nobs ; ** Fetch Next CCDS Name ; if ofac_last = ccds_last then do; ** Last Names Match ; output work.lastname; if olen_first = clen_first then do; if ofac_first = ccds_first then goto foundit; ** First Names Match ; end; else if index (ofac_first,ccds_first) > 0 then goto foundit; ** CCDS Name Found In Alias List ; if substr(ccds_first,1,1) = substr(ofac_first,1,1) then do; ** Check spelling ; x = 0 ; do i = 1 to min(length(ofac_first), length(ccds_first)); if substr(ofac_first,i,1) = substr (ccds_first,i,1) then x = x + 1; end; if x > round(length(ofac_first)*.9 ) then goto foundit; ** Fuzz of 90% ; end; if olen_first <= clen_first then do; if ofac_first < substr(ccds_first,1, length(ofac_first)) then goto nomatch; end; if substr(ccds_first,1,1) >substr(ofac_first,1,1) then goto nomatch; end; else do; ** Last Names do NOT Match ; if ofac_last1 = substr(ccds_last,1,length(ofac_last1)) then do; x=0; ** 1st Last Name (Partial) ; if index(ofac_last,' ') > 1 then do; ** Multi-Part Last Name ; if index(ofac_first,ccds_first) > 0 then goto foundit; if substr(ccds_first,1,1)= substr(ofac_first,1,1) then do; ** Check spelling ; do i = 1 to min(length(ofac_first),length(ccds_first)); if substr(ofac_first,i,1) = substr (ccds_first,i,1) then x = x + 1; end; if x > round(length(ofac_first)*.90) then goto foundit; ** Fuzz of 90% ; end; if substr(ccds_first,1,1) >substr(ofac_first,1,1) then goto nomatch; end; end; if ofac_last1 < substr(ccds_last,1,length(ofac_last1)) then goto nomatch; end; if index(ccds_last,' ') = 0 & clen_last > length(trim(left(ofac_last1))) then goto getnext ; c_point = c_point + 1; ** Increment Counter ; end; nomatch: output work.inofac ; ** Did not find match ; ** Future enhancement -- Spin through Multi-part LAST NAME to create Individual Records for each part ; ** -- Output these records to separate file for subsequent match evalutation ; goto getnext ; foundit: out+1; output work.matched ; ** Duh!! ; c_first = c_point + 1; ** Increment Counter ; getnext: o_point = o_point + 1; ** Increment Counter ; if o_point > o_nobs then stop; ** Out of data -- aka eof; if c_first > c_nobs then stop; ** Ibid. ; run; 12
Drive Through Both Lists to determine congruence – Fetch OFAC ** Drive thru lists to determine congruence -- save matches and non-matches in separate files ; data work.matched (keep = SDN_name primary_first_name primary_last_name ) work.lastname(keep = SDN_name ofac_last olen_last ofac_first olen_first ) work.inofac (keep = SDN_name ofac_last olen_last ofac_first olen_first ) ; retain o_point c_point c_first 1 ; set save.ofac_all point=o_point nobs=o_nobs; ** Fetch Next OFAC Name ; 13
Additional Benefit of using the SET POINT= Technique Note that you can use this technique for several needs: Select a Random sample from a very large file: sample = 1000; seed = date(); do i = 1 to sample; x1 = int(ranuni(seed)*10000); seed = put(x1, z4.); if seed <= records then do; set xxx.yyy point=record nobs=records; end; end; stop; Select last N records from a very large file: sample = 1000; record = 1 ; set xxx.yyy point=record nobs=records; record = records ; do until (recs =sample); set xxx.yyy point=record nobs=records; output work.sample; record = record – 1; recs = recs + 1; end; stop; 14
Drive Through Both Lists to determine congruence - Use POINT= set save.ofac_all point=o_point nobs=o_nobs; ** Fetch Next OFAC Name ; c_point = c_first ; do while(c_point <= c_nobs ); set save.ccds_all point=c_point nobs=c_nobs ; ** Fetch Next CCDS Name ; if ofac_last = ccds_last then do; **Last Names Match ; output work.lastname; if olen_first = clen_first then do; if ofac_first = ccds_first then goto foundit; ** First Names Match ; end; else if index (ofac_first,ccds_first) > 0 then goto foundit; ** CCDS Name Found In Alias List ; if substr(ccds_first,1,1) = substr(ofac_first,1,1) then do; ** Check spelling ; x = 0 ; do i = 1 to min(length(ofac_first), length(ccds_first)); if substr(ofac_first,i,1) = substr (ccds_first,i,1) then x = x + 1; end; if x > round(length(ofac_first)*.9 ) then goto foundit; ** Fuzz of 90% ; end; if olen_first <= clen_first then do; if ofac_first < substr(ccds_first,1, length(ofac_first)) then goto nomatch; end; if substr(ccds_first,1,1) >substr(ofac_first,1,1) then goto nomatch; end; 15
Drive Through Both Lists to determine congruence else do; ** Last Names do NOT Match ; if ofac_last1 = substr(ccds_last,1,length(ofac_last1)) then do; x=0; ** 1st Last Name (Partial) ; if index(ofac_last,' ') > 1 then do; ** Multi-Part Last Name ; if index(ofac_first,ccds_first) > 0 then goto foundit; if substr(ccds_first,1,1)= substr(ofac_first,1,1) then do; ** Check spelling ; do i = 1 to min(length(ofac_first),length(ccds_first)); if substr(ofac_first,i,1) = substr (ccds_first,i,1) then x = x + 1; end; if x > round(length(ofac_first)*.90) then goto foundit; ** Fuzz of 90% ; end; if substr(ccds_first,1,1) >substr(ofac_first,1,1) then goto nomatch; end; end; if ofac_last1 < substr(ccds_last,1,length(ofac_last1)) then goto nomatch; end; if index(ccds_last,' ') = 0 & clen_last > length(trim(left(ofac_last1))) then goto getnext ; c_point = c_point + 1;** Increment Counter ; end; nomatch: output work.inofac ; ** Did not find match ; ** Future enhancement -- Spin through Multi-part LAST NAME to create Individual Records for each part ; ** -- Output these records to separate file for subsequent match evaluation ; goto getnext ; foundit: out+1; output work.matched ; c_first = c_point + 1; ** Increment Counter ; getnext: o_point = o_point + 1; ** Increment Counter ; if o_point > o_nobs then stop; ** Out of data -- aka eof; if c_first > c_nobs then stop; ** Ibid. ; run; 16
Save Critical Files for later reference ** Save Critical Files for later reference ; options nocenter ; title1 'OFAC Match to CCDS Account Information' ; proc append data = work.matched base = save.matched ; run; proc append data = work.inofac base = save.ofac ; run; ** Identify Unique Names which may need additional scrutiny ; proc summary data = work.lastname nway ; id ofac_last ofac_first olen_last olen_first; class SDN_name; output out = work.names; run; ** Save file for later reference; proc append data = work.names base = save.names ; run; 17
Show Potential Matches for Review and Validation ** Show Potential Matches -- Further investigation required !! ; title3 'First Pass Matches !!' ; proc print data = work.matched; format sdn_name $35. ; run; 18
Q & A Discussion SunTrust Bank, Inc. Business Intelligence Center of Excellence Mail Code: GA-ATL-4007 250 Piedmont Avenue, 14th Floor Atlanta, Georgia 30308 Sterling Green 404-813-3152 (Office) 727-365-1926 (Cell) Sterling.Green@SunTrust.com 19