Bloomberg Automation use DDE
本系列的主題如下,所有的程式碼可以從 這裡 下載。
-
Bloomberg Automation - (1).DDE 基礎架構
-
Bloomberg Automation - (2).Terminal 畫面留存並解析內容
-
Bloomberg Automation - (3).Login 及 Logout
-
Bloomberg Automation - (4).更改 Bloomberg 界面的語系
-
Bloomberg Automation - (5).自動執行ALLQ並抓取畫面的內容
-
Bloomberg Automation - (6).自動執行HP、輸入查詢條件並抓取畫面的內容
-
Bloomberg Automation - (7).使用 GRAB 指令 Email 畫面
金融業常會使用 Bloomberg 取得各項商品資料,為了快速取得所需的資料常會透過程式使用Excel VBA或是API的方式讀取Bloomberg的資料,這兩種作法雖然可以抓取資料,但若是碰到所需的資料無法直接抓取,必需在Bloomberg Terminal上輸入指令才可查到資料的情況下,這兩種作法就無法逹到要求。現在要介紹另一種DDE的作法,它雖然跟Excel VBA 一樣都是透過DDE的方式運作,但是Excel VBA 主要是以抓取資料為主,無法控制Bloomberg執行所需的指令,而這裡介紹的作法是直接傳送指令給Bloomberg,例如輸入DES、ALLQ、HP等指令,這樣就可模擬使用者操作 Terminal ,畫面也會依據輸入的指令顯示對應的內容。
我將會以一系列的文章說明如何用 DDE 傳送指令給 Bloomberg Terminal,並示範抓取 ALLQ 及 HP 畫面的內容並轉成圖片及文字,最後再介紹使用Bloomberg GRAB功能將畫面 email 給指定人員。
本系列以 Visual Studio 2015 的C# 為開發環境,採用 Windows Forms Application 為架構,首先先新增新的專案,名稱為 BloombergAutomation, DDE Library 可從 NetGet安裝,在 NuGet Package Manager 輸入 NDde並安裝此元件, 若需要NDde原始碼可從 這裡 下載。
在專案中建立 Infrastructure Folder, 並新增 BloombergDDEBase Class,這個Class是我們與Bloomberg 溝通的核心程式,後續將會陸續增加相關的功能。
public class BloombergDDEBase
{
private DdeClient _dc;
public BloombergDDEBase()
{
Connect();
}
private void Connect()
{
_dc = new DdeClient("winblp", "bbk");
_dc.Connect();
}
}
首先產生 _dc 變數,所有與Bloomberg溝通的指令都是透過此變數傳遞,Bloomberg DDE 連線的Service 指定為 winblp, Topic 指定為 bbk,最後執行 Connect() 連線Bloomberg 。
執行 Bloomberg 指令
使用Bloomberg 時,會輸入要查詢的Ticker及功能代碼,例如我要查 US594918BT09 這檔債券的基本資料,我會先輸入 US594918BT09,再輸入DES<GO>,出現的畫面如下圖:
透過DDE程式我們也可以直接傳送 US594918BT09 <Corp>DES<GO> 至Bloomberg逹到同樣的結果,在說明如何送指令之前要先了解Bloomberg DDE 運作方式,Bloomberg 總共有4個視窗可顯示資料,如下圖
Bloombeg 這4個視窗分別是1-BLOOMBERG, 2-BLOOMBERG,3-BLOOMBERG,4-BLOOMBERG,這4個視窗可以獨立運作顯示不同的資料,因此我們必需告訴Bloomberg 要用哪一個視窗執行指令,了解這個原理後就可以加上傳送指令的程式碼
public void DDEInputCommand(int windowNum, string commandText)
{
if (_dc == null)
{
throw new Exception("DDE Server not connected!");
}
_dc.Execute(GetDDEWindowNum(windowNum) + commandText, 5000);
}
private string GetDDEWindowNum(int windowNum)
{
return "<blp-" + (windowNum - 1) + ">";
}
DDEInputCommand 程式碼執行_dc.Execute 將指令傳送至Bloomberg,第一個參數是要執行的指令,第二個參數 5000 代表Timeout 時間 5000 milliseconds,前面說過Bloomberg 有4個視窗可執行指令,因此我們需要特別注意指令前面要先加上視窗號碼,這樣Bloomberg才知道要用哪一個視窗執行,視窗代碼的格式為 <blp-視窗代碼>,雖然畫面上的視窗代號從1開始(1~4),但DDE的視窗代號是從0開始算(0~3),所以若是要送DES指令給第一個視窗,內容為 <blp-0>DES<GO>,在程式中透過GetDDEWindowNum() 取得正確的視窗代碼編號,再串上 指令(commandText),將指令傳送給Bloombeg,Bloomberg 會依據指定的視窗執行指令。
接下來我們增加一個畫面測試我們寫的功能,在專案新增Forms Folder,再新增一個Form,名稱為 frmDDE,畫面加上Window Num 的ComboBox名稱為 cboWindowNum,一個DDE Command 的 TextBox名稱為txtCommand,一個Button名稱為 btnExecute,最後加上顯示Result的 TextBox,名稱為txtMessage,如下圖
測試的程式碼如下:
public partial class frmDDE : Form
{
public frmDDE()
{
InitializeComponent();
}
private void frmDDE_Load(object sender, EventArgs e)
{
ComboboxItem[] items = new ComboboxItem[]
{
new ComboboxItem("1", "1"),
new ComboboxItem("2", "2"),
new ComboboxItem("3", "3"),
new ComboboxItem("4", "4"),
};
cboWindowNum.Items.Clear();
cboWindowNum.Items.AddRange(items);
//Window Num default "1"
ComboboxItem selectItem = cboWindowNum.Items.Cast<ComboboxItem>().SingleOrDefault(x => x.Value.Equals("1"));
cboWindowNum.SelectedItem = selectItem;
}
private void btnExecute_Click(object sender, EventArgs e)
{
using (BloombergDDEBase bloombergDDE = new BloombergDDEBase())
{
int windowNum = int.Parse(cboWindowNum.Text);
LogPrint("Execute Command:" + txtCommand.Text);
bloombergDDE.DDEInputCommand(windowNum, txtCommand.Text);
}
}
private void LogPrint(string msg)
{
txtMessage.AppendText(msg);
txtMessage.AppendText(Environment.NewLine);
}
}
在frmDDE_Load中,將Winow Num ComboBox 增加1、2、3、4項目,用來選擇要將指令送到Bloomberg 的哪一個視窗,btnExecute_Click產生BloombergDDEBase物件後,執行 DDEInputCommand將畫面輸入的 DDE指令傳送至指定的Bloomberg視窗。
執行程式按下 Execute 按鈕,會看到Bloomberg 視窗會顯示 US594918BT09 這檔債券的基本資料。