Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 27

TRM Market Data Management:

Datafeed: Configuration.

Using Datafeed we can upload Market data into SAP automatically from different Market
data providers.
I want to show you an example how you can use Datafeed.
Input data
I have a web site of National Bank of the Republic of Belarus ( Exchange Rates,
Refinancing Rate, News | National Bank of the Republic of Belarus) from where i can get
information about:

 Refinancing Rate | National Bank of the Republic of Belarus


 Official Exchange Rate of the Belarusian Ruble Against Foreign Currencies Set on
a Daily Basis | National Bank of the …
 Accounting Prices on Precious Metals in Standard Bars, Set By the National Bank
of the Republic of Belarus | National B…

Each of mentioned Market data has API which can retrieve information. API is the URL
with parameters. API returns a string with information.

 For Refinaning Rate – http://www.nbrb.by/API/RefinancingRate?onDate=2016-7-


8.
Parameter “onDate” is the date on which we want to get information.

 For Exchange rates


– http://www.nbrb.by/API/ExRates/Rates/Dynamics/190?startDate=2016-6-
1&endDate=2016-6-30.
Parameters: “startDate”, “endDate” are the date on which we want to get
information and “XXX” – external codes for currencies.
 For precious metals
– http://www.nbrb.by/API/BankIngots/Prices/0?startDate=2016-6-
1&endDate=2016-7-30
Parameters “startDate” and “endDate” makes period for each we want to get
information.

As a result we need to get information into SAP and parse it into the special table
“Answer”.
Before we can use Datafeed, we need to configure the system.
Configuration
Create Market Data Provider
IMG -> Financial Supply Chain Management -> Treasury and Risk Management -> Basic
Functions ->Market Data Management -> Datafeed -> Technical Settings -> Define
Datafeed Name (tr.S_ALR_87007834)
Here we create Market Data provider in order to separate the different sources of
information:

 Data provider – name of data provider.


 Usage log – If you need to log all data retrievals. SAP Menu -> Accounting ->
Financial Supply Chain Management -> Treasury and Risk Management -> Basic
Functions -> Market Data Management -> Datafeed -> Usage Log -> …
 Feed active? – distinguish active and inactive feeds.
 Quotation source – Quotation source for commodity.
RFC Settings for External Partner Program
We can contact external partners in two different ways:

 Using RFC (remote function call) and calling external funciton.


 Web Access (URL or Web Services).

Let’s start with Web Access.


In my case i will use Web Acces.
IMG -> Financial Supply Chain Management -> Treasury and Risk Management -> Basic
Functions -> Market Data Management -> Datafeed -> Technical Settings -> RFC
Settings for External Partner Program ->Assign Datafeed RFC Destination (tr. SM30 ->
V_VTB_DFD)

 Datafeed operating mode:


 •’1′ synchronous: SAP waits until the external partner program has delivered all
the data.
 •’2′ asynchronous: SAP does not wait until the external partner program has
delivered all the data but immediately switches control back to the calling program.
The data is delivered from the external partner program at a later date (possibly in
separate blocks).

For Web Access we choose Synchronous operation mode.

 Function: There is a standard SAP function module


TB_DATAFEED_INTERNET_ACCESS to get information from web. But as i
described earlier my data provider has special API – so i need to modify standard
FM. So i created ZTB_DATAFEED_INTERNET_ACCESS
 RFC destination, Back-up RFC destination: For Web Access in my case i do not
need RFC connection.
FUNCTION ztb_datafeed_internet_access.
*"----------------------------------------------------------------------
*"*"Локальный интерфейс:
*" IMPORTING
*" VALUE(FEEDNAME) LIKE VTB_DFDEST-RFEEDNAME
*" VALUE(HISTORY) LIKE VTB_DFCU-RUPDHIST
*" VALUE(UPDATE) LIKE VTB_DFCU-RUPDHIST
*" VALUE(BLANKSTOCRLF) TYPE VTB_DFDEST-BLANKSTOCRLF DEFAULT 'X'
*" VALUE(CLEAR_REQUEST_ENTITY_BODY) TYPE BOOLEAN DEFAULT 'X'
*" EXPORTING
*" VALUE(E_MESSAGE_BUFFER) LIKE VTB_MARKET-ERROR
*" TABLES
*" ANSWER STRUCTURE VTB_DFANS
*" REQUEST STRUCTURE VTB_DFREQ
*" EXCEPTIONS
*" DATAFEED_FAILURE
*"----------------------------------------------------------------------
************************************************************************
* Declarations
CONSTANTS: rworkmodus LIKE vtb_dfdest-rworkmodus VALUE '1'.
DATA: zresponse_body TYPE TABLE OF zchar9000 WITH HEADER LINE, "
STRING TYPE
zstr TYPE zchar9000,
zsplit TYPE STANDARD TABLE OF char200 WITH HEADER LINE,
zresponse_headers TYPE TABLE OF char50 WITH HEADER LINE,
text_to_be_scanned TYPE char200, " String of market data
regular_expression_pattern TYPE char200, " REGEXP to find data in String of
market data
res TYPE match_result, " Found result in String of market data
text TYPE char200, " Temporary variable to pass market data into
answer table
zuri TYPE tb_dfuri, " URL from VTB_DFDEST table. We will modify
URL to match requests.
zmetal TYPE char15,
zcur TYPE tb_key1_ex, " External data provider currency code
zmet TYPE tb_prpty. " External data provider metal code
TABLES: vtb_dfdest.
* Temp answer table
DATA: BEGIN OF temp_answer OCCURS 100.
INCLUDE STRUCTURE vtb_dfans.
DATA: END OF temp_answer.
DATA: hlp_message_buffer(50) TYPE c.
* Request tables
DATA: BEGIN OF request_headers OCCURS 100,
line LIKE tline-tdline.
DATA: END OF request_headers.
DATA: BEGIN OF request_entity_body OCCURS 100,
line LIKE vtbdfin-line.
DATA: END OF request_entity_body.
* Response tables
DATA: BEGIN OF response_headers OCCURS 10,
line LIKE tline-tdline.
DATA: END OF response_headers.
DATA: BEGIN OF response_entity_body OCCURS 10,
line LIKE vtb_dfans,
newlinechar(2) TYPE c,
END OF response_entity_body.
* status code RFC1945
DATA: status_code(3) TYPE c.
* length of response body
DATA: response_entity_body_length TYPE i.
DATA: request_entity_body_length TYPE i.
************************************************************************
* Initialization
CLEAR: e_message_buffer, hlp_message_buffer.
REFRESH: request_headers, response_headers, request_entity_body,
response_entity_body, temp_answer.
* read table vtb_dfdest for URI and PROXY Information.
SELECT SINGLE * FROM vtb_dfdest CLIENT SPECIFIED
WHERE mandt = sy-mandt
AND rfeedname = feedname
AND rworkmodus = rworkmodus.
* fill HTTP request page header
request_headers-line = "/ HTML version 3.2
'content-type: text/plain'. "#EC *
APPEND request_headers.
IF clear_request_entity_body IS NOT INITIAL.
CLEAR request_entity_body.
REFRESH request_entity_body.
ENDIF.
************************************************************************
* Retrieving market data from Data Provider
" Save the initial URL. We will modify vtb_dfdest-uri for different market data classes.
zuri = vtb_dfdest-uri.
" Loop at 'Data source' to get data
LOOP AT request.
CASE request-rinid2. "'Data source'
" Refinance rate
WHEN 'REFINANCE'.
" Create the right API URL for Refinance rate.
" If we have From (zreq-dfromdate) and To (zreq-dtodate) fields initial - then we
request data on curren date (tr. TBD4).
" If we have From (zreq-dfromdate) and To (zreq-dtodate) fields NOT initial - then
we requst history data (tr. TBDJ).
CLEAR vtb_dfdest-uri.
IF request-dfromdate IS INITIAL OR request-dtodate IS INITIAL.
CONCATENATE zuri '/RefinancingRate?onDate=' sy-datum+0(4) '-' sy-
datum+4(2) '-' sy-datum+6(2) INTO vtb_dfdest-uri.
ELSE.
CONCATENATE zuri '/RefinancingRate' INTO vtb_dfdest-uri.
ENDIF.
CLEAR zresponse_body.
REFRESH zresponse_body.
CLEAR zresponse_headers.
REFRESH zresponse_headers.
CLEAR zstr.
CLEAR zsplit.
REFRESH zsplit.
CLEAR text_to_be_scanned.
WAIT UP TO 2 SECONDS.
" Requesting information.
CALL FUNCTION 'HTTP_GET'
EXPORTING
absolute_uri = vtb_dfdest-uri
user = vtb_dfdest-foreign_user
password = vtb_dfdest-foreign_passwd
blankstocrlf = blankstocrlf "VTB_DFDEST-BLANKSTOCRLF
IMPORTING
status_code = status_code
response_entity_body_length = response_entity_body_length
TABLES
request_entity_body = request_entity_body
request_headers = request_headers
response_entity_body = zresponse_body[]
response_headers = zresponse_headers[]
EXCEPTIONS
connect_failed =1
timeout =2
internal_error =3
tcpip_error =4
OTHERS = 5.
" error handling!!!
IF sy-subrc <> 0. "/ no connection
CASE sy-subrc.
WHEN '1'.
e_message_buffer =
'Сonnect_failed'(890).
WHEN '2'.
e_message_buffer =
'Timeout'(891).
WHEN '3'.
e_message_buffer =
'Internal_error'(892).
WHEN '4'.
e_message_buffer =
'TCP/IP error'(893).
WHEN OTHERS.
e_message_buffer =
'HTTP-GET error'(894).
ENDCASE.
EXIT.
" error handling!!!
ELSEIF status_code <> '200'. "/ connection ok, other problems
LOOP AT response_headers.
hlp_message_buffer = response_headers-line.
"/ first line contains error
EXIT.
ENDLOOP.
" concatenate 'Fehler: '(910) status_code hlp_message_buffer
MOVE hlp_message_buffer TO e_message_buffer.
CONDENSE e_message_buffer.
EXIT.
ELSE.
" everything was fine...
CLEAR answer.
LOOP AT zresponse_body INTO zstr.
" All data is diveded by '},{'. Let's split it into 1 string - 1 market data.
SPLIT zstr AT '},{' INTO TABLE zsplit IN CHARACTER MODE.
" Loop through and retrieve data that we need.
LOOP AT zsplit INTO text_to_be_scanned.
" Searching for date.
regular_expression_pattern = '\d{4}-\d{2}-\d{2}'.
FIND REGEX regular_expression_pattern IN text_to_be_scanned RESULTS
res.
IF sy-subrc = 0.
CLEAR text.
text = text_to_be_scanned+res-offset(res-length).
CONCATENATE text+0(4) text+5(2) text+8(2) INTO answer-ddate.
ENDIF.
" Searching for time.
regular_expression_pattern = '\d{2}:\d{2}:\d{2}'.
FIND REGEX regular_expression_pattern IN text_to_be_scanned RESULTS
res.
IF sy-subrc = 0.
CLEAR text.
text = text_to_be_scanned+res-offset(res-length).
CONCATENATE text+0(2) text+3(2) text+6(2) INTO answer-ttime.
ENDIF.
" Searching for value.
regular_expression_pattern = '\d{1,}\.\d{1,5}'.
FIND REGEX regular_expression_pattern IN text_to_be_scanned RESULTS
res.
IF sy-subrc = 0.
answer-value = text_to_be_scanned+res-offset(res-length).
ENDIF.
" Other parameters (tr. SM30 -> V_DFCU03)
answer-rinid1 = 'REFINANCE'. "Instrument
answer-rinid2 = 'REFINANCE'. "Data Source
answer-sprpty = 'REFINANCE'. "Instrument property
answer-uname = sy-uname.
" Save market data into Answer table.
APPEND answer.
ENDLOOP.
ENDLOOP.
ENDIF.
" Exchange rate
WHEN 'CURRENCY'.
CLEAR vtb_dfdest-uri.
" Get external codes for currency codes.
SELECT SINGLE rkey1 FROM mducr INTO zcur WHERE vendor = 'NBRB.by' AND
source = 'F' AND waers = request-rinid1+3(3).
IF sy-subrc <> 0.
CONCATENATE 'Error: Convert Codes for Currency Names: ' request-rinid1+3(3)
'SM30 -> V_MDUDFCR' INTO e_message_buffer.
EXIT.
ENDIF.
" Create the right API URL for Exchange rates.
" If we have From (zreq-dfromdate) initial or ( From (zreq-dfromdate) and To (zreq-
dtodate) fields initial - then we request data on curren date (tr. TBD4).
" Otherwise - we requst history data on zreq-dfromdate (tr. TBDJ).
IF request-dfromdate IS INITIAL OR ( request-dtodate IS INITIAL AND request-
dfromdate IS INITIAL ). " tr. TBD4
CONCATENATE zuri " http://www.nbrb.by/API
'/ExRates/Rates/Dynamics/'
zcur
'?startDate='
sy-datum+0(4) '-'
sy-datum+4(2) '-'
sy-datum+6(2)
'&endDate='
sy-datum+0(4) '-'
sy-datum+4(2) '-'
sy-datum+6(2)
INTO vtb_dfdest-uri.
sy-tcode = 'TBD4'.
ELSE. " tr. TBDJ
CONCATENATE zuri " http://www.nbrb.by/API
'/ExRates/Rates/Dynamics/'
zcur
'?startDate='
request-dfromdate+0(4) '-'
request-dfromdate+4(2) '-'
request-dfromdate+6(2)
'&endDate='
request-dtodate+0(4) '-'
request-dtodate+4(2) '-'
request-dtodate+6(2)
INTO vtb_dfdest-uri.
sy-tcode = 'TBDJ'.
ENDIF.
CLEAR zresponse_body.
REFRESH zresponse_body.
CLEAR zresponse_headers.
REFRESH zresponse_headers.
CLEAR zstr.
CLEAR zsplit.
REFRESH zsplit.
CLEAR text_to_be_scanned.
WAIT UP TO 2 SECONDS.
" Requesting information.
CALL FUNCTION 'HTTP_GET'
EXPORTING
absolute_uri = vtb_dfdest-uri
user = vtb_dfdest-foreign_user
password = vtb_dfdest-foreign_passwd
blankstocrlf = blankstocrlf "VTB_DFDEST-BLANKSTOCRLF
IMPORTING
status_code = status_code
response_entity_body_length = response_entity_body_length
TABLES
request_entity_body = request_entity_body
request_headers = request_headers
response_entity_body = zresponse_body[]
response_headers = zresponse_headers[]
EXCEPTIONS
connect_failed =1
timeout =2
internal_error =3
tcpip_error =4
OTHERS = 5.
" error handling!!!
IF sy-subrc <> 0. "/ no connection
CASE sy-subrc.
WHEN '1'.
e_message_buffer =
'Сonnect_failed'(890).
WHEN '2'.
e_message_buffer =
'Timeout'(891).
WHEN '3'.
e_message_buffer =
'Internal_error'(892).
WHEN '4'.
e_message_buffer =
'TCP/IP error'(893).
WHEN OTHERS.
e_message_buffer =
'HTTP-GET error'(894).
ENDCASE.
EXIT.
ELSEIF status_code <> '200'. "/ connection ok, other problems
" error handling!!!
LOOP AT response_headers.
hlp_message_buffer = response_headers-line.
"/ first line contains error
EXIT.
ENDLOOP.
" concatenate 'Fehler: '(910) status_code hlp_message_buffer
MOVE hlp_message_buffer TO e_message_buffer.
CONDENSE e_message_buffer.
EXIT.
ELSE.
" everything was fine...
CLEAR answer.
READ TABLE zresponse_body INTO zstr INDEX 1.
" All data is diveded by '},{'. Let's split it into 1 string - 1 market data.
SPLIT zstr AT '},{' INTO TABLE zsplit IN CHARACTER MODE.
" Loop through and retrieve data that we need.
LOOP AT zsplit INTO text_to_be_scanned.
" Searching for date.
regular_expression_pattern = '\d{4}-\d{2}-\d{2}'.
FIND REGEX regular_expression_pattern IN text_to_be_scanned RESULTS
res.
IF sy-subrc = 0.
CLEAR text.
text = text_to_be_scanned+res-offset(res-length).
CONCATENATE text+0(4) text+5(2) text+8(2) INTO answer-ddate.
ENDIF.
" Searching for time.
regular_expression_pattern = '\d{2}:\d{2}:\d{2}'.
FIND REGEX regular_expression_pattern IN text_to_be_scanned RESULTS
res.
IF sy-subrc = 0.
CLEAR text.
text = text_to_be_scanned+res-offset(res-length).
CONCATENATE text+0(2) text+3(2) text+6(2) INTO answer-ttime.
ENDIF.
" Searching for echange rate.
regular_expression_pattern = '\d{1,}\.\d{1,5}'.
FIND REGEX regular_expression_pattern IN text_to_be_scanned RESULTS
res.
IF sy-subrc = 0.
answer-value = text_to_be_scanned+res-offset(res-length).
ENDIF.
" Other parameters
answer-currency = request-rinid1+3(3).
answer-rinid1 = request-rinid1.
answer-rinid2 = 'CURRENCY'.
answer-sprpty = 'M'.
answer-uname = sy-uname.
" Save market data into Answer table.
APPEND answer.
ENDLOOP.
ENDIF.
WHEN 'METALS'.
CLEAR vtb_dfdest-uri.
" Get external codes for commodities.
SELECT SINGLE sprpty FROM mducmv INTO zmet WHERE vendor = 'NBRB.by'
AND source = 'F' AND quotyp = request-rinid1.
IF sy-subrc <> 0.
CONCATENATE 'Error: Convert Codes for Metal: ' request-rinid1+3(3) 'SM30 ->
V_MDUCMV' INTO e_message_buffer.
EXIT.
ENDIF.
" URL for tr. TBD4
IF request-dfromdate IS INITIAL OR ( request-dtodate IS INITIAL AND request-
dfromdate IS INITIAL ).
CONCATENATE zuri "http://www.nbrb.by/API
'/BankIngots/Prices/'
zmet
'?startDate='
sy-datum+0(4) '-' sy-datum+4(2) '-' sy-datum+6(2)
'&endDate='
sy-datum+0(4) '-' sy-datum+4(2) '-' sy-datum+6(2)
INTO vtb_dfdest-uri.
" URL for tr. TBDJ
ELSEIF request-dfromdate IS NOT INITIAL AND request-dtodate IS INITIAL.
CONCATENATE zuri "http://www.nbrb.by/API
'/BankIngots/Prices/'
zmet
'?startDate='
request-dfromdate+0(4) '-' request-dfromdate+4(2) '-' request-
dfromdate+6(2)
'&endDate='
request-dfromdate+0(4) '-' request-dfromdate+4(2) '-' request-
dfromdate+6(2)
INTO vtb_dfdest-uri.
" URL for tr. TBDJ
ELSE.
CONCATENATE zuri "http://www.nbrb.by/API
'/BankIngots/Prices/'
zmet
'?startDate='
request-dfromdate+0(4) '-'
request-dfromdate+4(2) '-'
request-dfromdate+6(2)
'&endDate='
request-dtodate+0(4) '-'
request-dtodate+4(2) '-'
request-dtodate+6(2)
INTO vtb_dfdest-uri.
ENDIF.
CLEAR zresponse_body.
REFRESH zresponse_body.
CLEAR zresponse_headers.
REFRESH zresponse_headers.
CLEAR zstr.
CLEAR zsplit.
REFRESH zsplit.
CLEAR text_to_be_scanned.
WAIT UP TO 2 SECONDS.
" Requesting information.
CALL FUNCTION 'HTTP_GET'
EXPORTING
absolute_uri = vtb_dfdest-uri
user = vtb_dfdest-foreign_user
password = vtb_dfdest-foreign_passwd
blankstocrlf = blankstocrlf "VTB_DFDEST-BLANKSTOCRLF
IMPORTING
status_code = status_code
response_entity_body_length = response_entity_body_length
TABLES
request_entity_body = request_entity_body
request_headers = request_headers
response_entity_body = zresponse_body[]
response_headers = zresponse_headers[]
EXCEPTIONS
connect_failed =1
timeout =2
internal_error =3
tcpip_error =4
OTHERS = 5.
" error handling!!!
IF sy-subrc <> 0. "/ no connection
CASE sy-subrc.
WHEN '1'.
e_message_buffer =
'Сonnect_failed'(890).
WHEN '2'.
e_message_buffer =
'Timeout'(891).
WHEN '3'.
e_message_buffer =
'Internal_error'(892).
WHEN '4'.
e_message_buffer =
'TCP/IP error'(893).
WHEN OTHERS.
e_message_buffer =
'HTTP-GET error'(894).
ENDCASE.
EXIT.
ELSEIF status_code <> '200'. "/ connection ok, other problems
" error handling!!!
LOOP AT response_headers.
hlp_message_buffer = response_headers-line.
"/ first line contains error
EXIT.
ENDLOOP.
" concatenate 'Fehler: '(910) status_code hlp_message_buffer
MOVE hlp_message_buffer TO e_message_buffer.
CONDENSE e_message_buffer.
EXIT.
ELSE.
" everything was fine...
CLEAR answer.
READ TABLE zresponse_body INTO zstr INDEX 1.
" All data is diveded by '},{'. Let's split it into 1 string - 1 market data.
SPLIT zstr AT '},{' INTO TABLE zsplit IN CHARACTER MODE.
" Loop through and retrieve data that we need.
LOOP AT zsplit INTO text_to_be_scanned. "response_entity_body.
" Search for date
regular_expression_pattern = '\d{4}-\d{2}-\d{2}'.
FIND REGEX regular_expression_pattern IN text_to_be_scanned RESULTS
res.
IF sy-subrc = 0.
CLEAR text.
text = text_to_be_scanned+res-offset(res-length).
CONCATENATE text+0(4) text+5(2) text+8(2) INTO answer-ddate.
ENDIF.
" Search for time
regular_expression_pattern = '\d{2}:\d{2}:\d{2}'.
FIND REGEX regular_expression_pattern IN text_to_be_scanned RESULTS
res.
IF sy-subrc = 0.
CLEAR text.
text = text_to_be_scanned+res-offset(res-length).
CONCATENATE text+0(2) text+3(2) text+6(2) INTO answer-ttime.
ENDIF.
" Search for commodity rate
regular_expression_pattern = '\d{1,}\.\d{1,5}'.
FIND REGEX regular_expression_pattern IN text_to_be_scanned RESULTS
res.
IF sy-subrc = 0.
answer-value = text_to_be_scanned+res-offset(res-length).
ENDIF.
" Search for external commodity code
regular_expression_pattern = '"MetalId":[0-9]{1}'.
FIND REGEX regular_expression_pattern IN text_to_be_scanned RESULTS
res.
IF sy-subrc = 0.
zmetal = text_to_be_scanned+res-offset(res-length).
ENDIF.
" Other parameters
CASE zmetal+10(1).
WHEN '0'.
answer-rinid1 = 'GOLD'.
WHEN '1'.
answer-rinid1 = 'SILVER'.
WHEN '2'.
answer-rinid1 = 'PLATINUM'.
WHEN '3'.
answer-rinid1 = 'PALADIUM'.
ENDCASE.
answer-rinid2 = 'METALS'.
answer-sprpty = 'METALS'.
answer-uname = sy-uname.
" Save market data into Answer table.
APPEND answer.
ENDLOOP.
ENDIF.
WHEN OTHERS.
ENDCASE.
ENDLOOP.
" Delete empty lines
LOOP AT answer WHERE rinid1 IS INITIAL
AND rinid2 IS INITIAL
AND sprpty IS INITIAL.
DELETE answer.
ENDLOOP.
" Find missing requests and build up error answer
LOOP AT request.
LOOP AT answer WHERE rinid1 = request-rinid1
AND rinid2 = request-rinid2
AND sprpty = request-sprpty.
ENDLOOP.
IF sy-subrc NE 0. "/ no answer for reques
MOVE-CORRESPONDING request TO temp_answer.
temp_answer-sstats = '99'.
CONCATENATE 'There is no answer from DataFeed: ' e_message_buffer INTO
temp_answer-error .
APPEND temp_answer.
ENDIF.
ENDLOOP.
" add missing entries to answer
LOOP AT temp_answer.
MOVE-CORRESPONDING temp_answer TO answer.
APPEND answer.
ENDLOOP.
" that´s it
ENDFUNCTION.

The code also attached to this article in TXT file.


Using RFC
For RFC we need to Enter our RFC destionation (tr. SM59, RFC with type T (TCP/IP) )
and indicate partner’s function. For example, with RFC we connect to Data Provider and
the SAP calls special partners function in order to get Market data. Usually, you can get
description of RFC configuration and list of function from your partner (Reuters, Blumberg,
Teletrade, etc). Using RFC we can retrieve information in Real-time if your provider allows
it.
Internet settings for WEB Server Access
IMG -> Financial Supply Chain Management -> Treasury and Risk Management -> Basic
Functions -> Market Data Management -> Datafeed -> Technical Settings -> Internet
Settings for External Partner Program ->Define Internet Settings for WEB Server Access
(tr. SM30 -> V_VTB_DFD2)
Here we define URL (required) and User name and Password (optional) if your Data
Provider requeres it.
As you can see earlier in URL we have constant part (http://www.nbrb.by/API/) and
variable part depending on market data class.
So in this configuration i will put constant part. Variable part is added inside of
FM ZTB_DATAFEED_INTERNET_ACCESS.
Proxy Configuration
IMG -> Financial Supply Chain Management -> Treasury and Risk Management -> Basic
Functions -> Market Data Management -> Datafeed -> Technical Settings -> Internet
Settings for External Partner Program ->HTTP Proxy Configuration -> Define Proxy
Configuration (SM30 -> THTTP)

If according to your companie’s policy you use Proxy to enter to internet, then you can
configure your proxy with Proxy user and Proxy password.

Define Data Sources for Datafeed


IMG -> Financial Supply Chain Management -> Treasury and Risk Management -> Basic
Functions -> Market Data Management -> Datafeed -> Translation Table -> Define Data
Sources for Datafeed (tr.S_ALR_87007888)
Here we define different Data Sources of our Data Provider.

Translation Table
Translation tables can be filled in two ways:

1. Automatically. You need to configure Datafeed Conversion Codes


2. Manually.

Translation Table: automatically


Create Tables for Code Conversion
This operation fills Converstion tables with SAP data: Exchange rate types, Currency
names, etc.
IMG -> Financial Supply Chain Management -> Treasury and Risk Management -> Basic
Functions -> Market Data Management -> Datafeed -> Translation Table -> Define
Datafeed Conversion Codes -> Create Tables for Code Conversion (tr. TBDK)
Convert Codes for Exchange Rate Types
IMG -> Financial Supply Chain Management -> Treasury and Risk Management -> Basic
Functions -> Market Data Management -> Datafeed -> Translation Table -> Define
Datafeed Conversion Codes -> Convert Codes for Exchange Rate Types (tr. SM30 ->
V_MDUDFCV)

Before creating tables for Code Conversion, the table was empty. After creating tables –
it will be filled with SAP data. All you need to map SAP Data with External Providers’
data.

In our case SAP data is equal to External data.


Adjust converstion tables to your need: IMG -> Financial Supply Chain Management -
> Treasury and Risk Management -> Basic Functions -> Market Data Management -
> Datafeed -> Translation Table -> Define Datafeed Conversion Codes -> …

For my purpse i created the following talbes:

Convert Codes for Currency Names: tr. SM30 -> V_MDUDFCR

Convert Commodity Price Types: tr. SM30 -> V_MDUCMV


I will use these tables to get external codes for currencies and commodities.
Import R/3 Master Data
Now it’s turn to create Translation tables Automatically.

 First select Master data: for example Currency.


 Then select Quantity. If you leave these fields empty then all combination of
currency 1, currency 2 and rate type will be uploaded into translation tables. I will
use combination of BYN-USD, BYN-EUR, BYN-RUB with rate type M. So, field “1
key definition” is filled with BYN, field “2 key definition” if filled with USD, EUR,
RUB. Rate type is M. For mentioned field there is a help, data inside these fields
depends on Master data: currency, security, etc.
 Datafeed: “Name” is NBRB.by, “Data source” is Currency.
 Test run – to test if transaction works perfect.
 Save market data – if you want to save data into Translation tables.
Start transaction.
Now we see, that SAP selected what we requested on selection screen. If you uncheck
Test field, SAP will fill translation table for Currency. Let’s see this translation talbe.
Translation Table: Currency
IMG -> Financial Supply Chain Management -> Treasury and Risk Management -> Basic
Functions -> Market Data Management -> Datafeed -> Translation Table -> Define
Currencies (tr. S_ALR_87007920)
Select you data provider.

SAP created translation tables for currency. Make a double click on any parameters in
the table.
Most of fields are entered by SAP, selected fields with red box – you have to enter
yourself.

 Save markter data permanently in system: tell your system to save data into SAP
tables. For example, Exhange rates – tr. OB08, Reference Interest rates – tr.
JBIRM, etc.
 Instrument – ask you data provider about this data or create your own. I created
my own Instrument – combination of currencies.
 External data feed currency settings: according to external data.
If you didn’t use Automatic creation of Translation tables then you have to fill these tables
manually.
Translation Table: Interse rates
IMG -> Financial Supply Chain Management -> Treasury and Risk Management -> Basic
Functions -> Market Data Management -> Datafeed -> Translation Table -> Define
Reference Interest Rates (tr. S_ALR_87007812)
Translation table for Refinance rate.
Translation Table: Commodity
IMG -> Financial Supply Chain Management -> Treasury and Risk Management -> Basic
Functions -> Market Data Management -> Datafeed -> Translation Table -> Define
Commodities (tr. S_ALR_87007868)
Translation table for Commodity.
That’s all. For configuration.
Conclusion
If your provider is Reuters (or Bloombers, or Teletrade, or similar services) – it’s very
good. Reuters, for example, is licensed with SAP to provide market data. All you need is
to configure RFC connection, list of Reuters functions to call and translation tables.
If your data provider has Web-Services or APIs – it’s also not a problem to get data. You
have to retrieve simple data structures and parse them into the SAP tables.
Even if you have access to data which is presented as a web page – you can get this
information also (as HTML), but you have to find out how to parse this information.
Now it’s time to process datafeed market data: TRM Market Data Management: Datafeed:
Processing market data.

You might also like