Capture Bloomberg screen and parsing content
本系列的主題如下,所有的程式碼可以從 這裡 下載。
-
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 畫面
上一篇建立 DDE 程式基礎架構後,接下來要思考的問題是透過程式執行Bloomberg的功能後,這對我們有什麼幫助?如果只是顯示查詢的結果,這對操作Bloomberg的人員而言沒有太大的幫助,但是若能自動將畫面複製存檔,就可當作分析的佐證資料,要是能更進一步的將畫面轉成文字內容,這對資料分析將會有莫大的幫助,以下將介紹實際作法。
Bloombertg畫面複製
用程式複製畫面一般有以下作法
- 用 API 複製畫面
- 用Bloomberg GRAB指令複製畫面並用 email 傳送
這兩種作法實作時會碰到一些問題,分析如下:
用API必需考量到要複製的畫面可能被其它視窗遮住,所以需先讓視窗跑到最上層(Active Window),另外若只想複製單一視窗,而不是複製整個桌面,這時就要處理要複製畫面的範圍。
用 GRAB指令透過email 傳送畫面的圖片,該圖片是存在email信箱,程式無法直接取得圖片,且這種作法速度較慢,不適合大量資料的處理。
Bloomberg 神奇的COPY指令
Bloomberg 有一個指令,在Bloombeg 鍵盤看不到,在Terminal 也不接受該指令,只有DDE才可接受這個指令,這個指令叫 COPY,顧名思義就是專門複製畫面的指令,這個指令有什麼特點呢?首先它解決畫面被其它視窗遮住的問題,例如我們要複製的Bloomberg 第1個視窗被其它視窗遮住時,COPY指令會先將這個視窗帶到前面成為Active Window,第2個特點是它只會複製指定的視窗,不會複製整個桌面,所以不需特別處理要複製的範圍,第3個特點是複製的圖片會存在Windows 的剪貼簿中,所以程式可以直接抓到圖片,這對於大量資料的處理非常有用。
我們先定義一個存放Bloomberg 指令的Class,目的是讓其它程式可以直接引用定義好的指令,我整理好常用的指令定義如下供各位參考:
public class BloombergKeys
{
public const string Go = "<GO>"; // Go
public const string Cancel = "<CANCEL>"; // Cancel
public const string TabRight = "<TABR>"; // TAB
public const string TabLeft = "<TABL>"; // Shift TAB
public const string CopyScreen = "<COPY>"; // Copy Screen
public const string PageForword = "<PAGEFWD>"; // Next Page
public const string PageBack = "<PAGEBACK>"; // Previous Page
}
接下來就是今天主角COPY指令的處理,在BloombergDDEBase Class 加上下列程式
public void CopyScreen(int windowNum)
{
DDEInputCommand(windowNum, BloombergKeys.CopyScreen);
}
CopyScreen 透過 DDEInputCommand method 指定要使用哪一個視窗執行指令,並將 <COPY> 指令傳送至Bloomberg,這樣就完成了本篇文章所需的功能,沒錯!就是這樣簡單。
接下來寫一支測試程式,我們繼續延用上一篇文章建立的 frmDDE Form , 增加 Copy Screen 按鈕
程式碼如下
private void btnCopyScreen_Click(object sender, EventArgs e)
{
using (BloombergDDEBase bloombergDDE = new BloombergDDEBase())
{
int windowNum = int.Parse(cboWindowNum.Text);
LogPrint("Before Execute Command: <COPY>");
bloombergDDE.CopyScreen(windowNum);
LogPrint("After Execute Command: <COPY>");
}
}
按下按鈕後,會看到Bloomberg 視窗會成為 Active Window,畫面內容不會有任何變化,因為COPY 指令只是將畫面放到剪貼簿,所以畫面不會有任何變化,此時可開啟小畫家軟體,按下貼上功能,就會出現Bloomberg 畫面的內容。
下圖是Bloomberg 原本的畫面內容
在小畫家軟體貼上剪貼簿的內容
從上面兩張圖可以看到剪貼簿的圖片背景是白色,會跟原本的黑色背景不同,另外畫面上的時間,原圖為 12:46:58 ,複製後的時間為12:47:11,不一樣的原因是我先人工剪下Bloomberg 的原圖,然後才用程式執行COPY的功能,所以會有時間落差。
接下來我們可以用C# 的 Clipboard.GetImage() 抓剪貼簿的圖片,就可以做到自行存成圖檔留存的功能。可是除此之外若可以作到解析畫面圖片的內容,成為文字格式供進一步的分析,如果能做到這樣就太完美了,在此要公布一個小技巧,要做到畫面的解析不需寫複雜的文字辦識OCR功能,也不用寫任何一行程式碼,是的,你沒看錯,真的不用寫程式,Bloomberg 已經為我們考慮到這個需求,在執行COPY指令複製畫面到剪貼簿的同時,也幫我們將畫面的內容以文字的格式存到剪貼簿,上面示範用小畫家軟體從剪貼簿取得圖片,現在你也可以另外開啟記事本(Notepad)軟體,再將剪貼簿內容貼上,你會發現貼上的內容就是Bloomberg畫面的文字內容,酷吧。
貼上的文字內容如下:
MSFT 3.7 08/08/46 Corp Stop Monitoring Settings All Quotes
12:47:11 ALLX Mode Overlay Axes Split Bid/Offer 94) Switch 95) Buy 96) Sell
Spreads vs T 2 ?08/15/47 Govt 100-05 / 100-06 2.742 / 2.741 77.9 / 72.3
Filter By All Execution Venue BGM Legend
PCS Firm Name Bid Px / Ask Px Bid Spd / Ask Spd BSz(M) x ASz(M) TimeDn
BGN BLOOMBERG GENERIC 103.117 / 104.262 79.4 / 73.1 x 05:59
TRAC FINRA - TRACE 103.176 Last Trd 78.2 Last Trd 7 Last Trd 12/13
BVAL BVAL (Score: 7) 103.546 / 103.932 75.9 / 73.9 x 05:00
EXCH EXCHANGE TRADED 103.176 / Last Trd 77.9 / x Last Trd 12/13
BMRK BBG REALTIME EVAL 103.675 / 103.988 76.3 / 74.6 2000 Indic Sz 12/13
USBC U.S. Bancorp 103.155 / 78.0 / 3170 x 12:46
DAIW Daiwa CapMkts AM 101.009 / 90.0 / 300 x 12:46
EDFA ED&F MAN 98.370 / 105.1 / 500 x 12:46
GSFO Global Securities 102.774 / 102.981 80.1 / 79.1 1000 x 1000 12/13
ODSB ODDOSEYDLER BANK AG 102.880 / 103.850 79.5 / 74.3 100 x 100 12/13
GETX GETTEX 102.733 / 103.650 80.3 / 75.4 100 x 100 12/13
TRMT FINRA TRACE (>=250M) 103.549 Last Trd 74.6 Last Trd 600 Last Trd 12/13
TRMB FINRA TRACE (>=500M) 103.549 Last Trd 74.6 Last Trd 600 Last Trd 12/13
TRST FINRA TRACE (<=1MM) 103.176 Last Trd 78.2 Last Trd 7 Last Trd 12/13
FRNK FRANKFURT EXCH 102.880 / 103.850 79.5 / 74.3 x 12/13
MNCH MUNICH EXCHANGE 102.733 / 103.650 80.3 / 75.4 x 12/13
HMBG HAMBURG EXCHANGE 102.670 / 103.650 80.7 / 75.4 x 12/13
HNVR HANOVER EXCHANGE 102.670 / 103.650 80.7 / 75.4 x 12/13
BRLN BERLIN EXCHANGE 102.622 / 103.854 81.0 / 74.3 x 12/13
DWZH DWZ - HAMBURG FIXING 102.500 / Last Trd 81.6 / x Last Trd 12/13
DWZG DWZ - GERMAN FIXING 102.500 / Last Trd 81.6 / x Last Trd 12/13
STGT STUTTGART EXCHANGE 102.490 / 103.580 81.7 / 75.8 x 12/13
文字內容看起來好像很雜亂,其實是因為每個欄位之間是用 TAB 當作分隔符號,所以畫面有點亂,只要知道這個規則就可拆解內容取出你所需的資料。之後在說明 ALLQ功能時會再說明剪貼簿中圖片與文字的處理。
下一篇文章將會說明用 DDE 達到 Login 及 Logout 的功能。