參考我原來所寫的一篇:「談談 C#.NET 連結 DDE Server 的設計觀」。 使用 NDde 這個開放源碼,來包裹(Wrap) Win32 APIs 連結 DDE 的通訊底層,使得 .NET-based 的應用程式也可以很便利地連結 DDE Server。
利用幾天的時間,我寫了一個算是比較完整的 C# DDE 用戶端(Client)程式,可以確實連結國內券商所提供的看盤軟體(本身即是 DDE Server)。目前測過包括 "永豐金 eLeader", "元大 Yeswin", "日盛 HTS", "康合 全都賺" 等,均可以正常連結並依據連結項目(Item)持續顯示所跳動(Tick)的值(Value)。 這算是一個簡易的範本,旨在展示利用 .NET OOP 語言可以確實連結 Legacy DDE Server,並進而讓有心的程式交易人員,可以再行擴展,自行撰寫包括報表統計、技術線型分析 等應用。
我寫的這個簡單 DDE Client,基本功能如下:
o 可以同時連結多個 DDE Server。
o 可以同時顯示多個項目(Item)所持續跳動(Tick)的數值(Value)。
o 可以正確顯示傳輸項目值為中文的編碼。
o 可以任意地刪除 DDE 連線與項目 的相關資訊。
簡單的源碼說明
DDE 的連線
- 看盤軟體本身即為 DDE Server! 這點要先弄清楚。 所以看盤軟體連線至券商的報價伺服器,那是另外一回事,DDE Server 作得好不好,是與看盤軟體本身的穩定度與資源管理有關,而不是與遠端的報價伺服器有關。
- 看盤軟體需不需要啟動 Excel? 不需要的,Excel 本身就是 DDE 的用戶端(Client),而且也因為 Excel 的關係,使得任一券商的看盤軟體,都必須符合能讓 Excel 這個用戶端正確地顯示資料。 這個有趣,是 Server 端必須符合 Client 端的傳輸規格,而且不能亂搞。 所以相對來說,對於程式開發人員自行要寫 DDE Client 程式來說,就不用擔心能不能正常顯示所傳輸過來的數值,要是有問題,肯定是自己寫的程式有問題,也方便自行 DEBUG。
- DDE Client 要能新增一條 DDE 連線(Connection),建立互動的 Conversation,需要有兩個資訊,一為 "Service",另一為 "Topic"。 所以,所謂的一條 DDE Connection 定義為:
1 DDE Connection = 1 Service + 1 Topic藉此也可以同時觀察,國內諸多看盤軟體他們對於所謂 DDE Connection 的實作方式。 例如 eLeader 是每一支股票代號即為一條 DDE 連線,所以,若要觀察前百大的期指成分股,就需要建立上百條的 DDE 連線;而 YesWin/康合 全都賺等看盤軟體,則是所有金融商品都只建立一條 DDE 連線而已。 這與穩定度及效能是否有關? 事實上,這應該是說牽涉到 DDE Server 內部關於 DDE 連線的資源控管(Resource Management)問題,一般來說,較為先進的應用伺服器(Application Server),都會提供諸如 "Connection Pooling" 的機制,來有效達成伺服器內資源上的協調。
- 連線很簡單,片段的程式碼參考如下:
DdeClient dc = new DdeClient(service, topic);
try{
// Connect to the server. It must be running or an exception will be thrown.
dc.Connect();
}catch (Exception thrown){
MessageBox.Show("無法連結 DDE Server:" + thrown.Message);
}
向 DDE Server 索取資料
- 建立可以相互對話的連線後,該條連線即為 "Stateful" 的狀態,Client 與 Server 可以互相傳遞資料。 Client 端向 DDE Server 要求資料有包括 "Request(同步)", "OnBeginRequest(非同步)", "Advise(通告)" 等幾種方式。 對於看盤軟體來說,最必要的就是 "Advise" 這個要求了,當 Client 發出 "StartAdvise" 這個訊息後,DDE Server 爾後只要針對該項目的值一有變更時,就會通知已註冊的 Client 來取得變更的值。
至於另外兩種需求的訊息,"Poke" 是 Client 端主動送資料給 DDE Server;"Command" 是 Client 端發出命令要求 DDE Server 執行某個指令。 對於看盤軟體來說,是沒有使用到的,所以在我的源碼內,並沒有實作。
- 國內幾個主要的看盤軟體,對於傳輸資料的實作,似乎有些差異 (但是在 Excel 都可以正常顯示)。 它們必然都有支援 "Advise" 這個訊息(Message),所以才能爾後持續地取得跳動的值。但是,我發現到,YesWin/HTS 這兩個兩個看盤軟體,如果盤後停止跳動時,DDEClient 只利用 "Advise" 這個訊息要求資料的話,是無法取得資料的(但也沒有錯誤);而相對 eLeader 與 全都賺來說,只利用這個訊息,就可以取得資料。 前面說過,Excel 卻都是可以正常顯示的,所以,我後來才加上 "Request" 這個同步要求資料的訊息,才使得所有的看盤軟體都能顯示當停止跳動時,也能取得第一次的值。
衍生的一個小問題是,eLeader/全都賺 並沒有支持 "Request" 這個訊息的實作,所以若發出 "Request",會出現錯誤。 這裡我使用的一個小技巧就是,讓它 "throw" 一個例外錯誤(Exception)的 事件(Event),但捕捉(catch)了這個事件後,忽略並不處理它。
- Client 端首先發出 "StartAdvise",通告 DDE Server 準備要求索取資料。 所帶的參數隻有一個,就是項目(Item)名稱。 至於 "Service", "Topic", "Item" 的名稱如何取得? 一般只要從看盤軟體中,對某個表單的畫面欄位,右鍵 Excel DDE 複製到 Excel 中,即可察看到。
Client 端另外要做的一件事就是,註冊可以取得來自 DDE Server 所傳來事件(Event)的相關資訊,包括連線資訊與變動的資料等。 註冊的方式就是在 Client 端的程式碼內宣告並實作 Advise 的處理函式。部分的片段程式碼參考如下:
dc.Advise += client_Advise; //register the Advise process event.
dc.StartAdvise(item, 1, true, 60000); // Advise Loopprivate void client_Advise(object sender, DdeAdviseEventArgs args) {
chg_value_row.Cells["col_iteminfo_value"].Value = args.Text; //顯示變動後的 Item 值.
}
- 事實上,後來請生魚片測試時,才發現到,中文編碼有問題! 我並沒有注意到,因為一般看盤軟體的數值都是純數字,但是 "康合 全都賺" 若要求如 期指的合約名稱,會傳回中文。 這裡相當感謝生魚片,他幫我解決了編碼傳輸的問題。 可以參考他寫的一篇:「在.NET正確顯示透過DDE傳送的文字編碼」。 所以在 client_Adivse() 這裡要改為:
private void client_Advise(object sender, DdeAdviseEventArgs args) {
int codepage = Encoding.Default.CodePage; //取得編碼的 codpage. 中文 Default: 950
string data = Encoding.GetEncoding(codepage).GetString(args.Data, 0, args.Data.Length);
chg_value_row.Cells["col_iteminfo_value"].Value = data;
}
UI 的實作問題
老實說,真正困擾我的,是關於 UI 的實作,這對我可以說是相當陌生的。 UI 要能設計的好,大概有兩個重點, 一為對 事件(Event)的控管處理,另一個就是如何讓 UI元件(Component)與所繫結(Binding)的一到多個資料源(Data Source),並保持展示與資料變動的一致性。
在 Windows Form,大概就是 .NET 的 DataGridView 這個 UI 元件最為多樣變化了,如何與 資料源 "Binding" 在一起,維護展示與資料變動的一致性更是個學問。 目前我算是用 "硬作" 的方式,並沒有採取 "Auto Binding" 的自動同步,而是自己利用 HashTable,以 "Service+Topic", "Item" 當成主要的索引鍵(key),來找出相關於 DDE Connection, DataGridView 所在變動列(或欲刪除列)的位置。
這裡我就是利用 DataGrideView 元件來展示連線與項目等相關資訊的。 一個 Connection 可以 "Hold" 住多個 Item, 所以必然是 "Master/Detail" 這樣的呈現。
※ 執行檔與原始程式碼:
我是上傳至 「聚財網」給有需要的程式交易人員參考研究。若需要該源碼,則需加入成為該網站的會員。
http://www.wearn.com/bbs/topic.asp?topic_id=139666&forum_id=5295&cat_id=19
原來是把該範例的程式碼放置於聚財網,但好像該論壇文章已過期而無法下載。 故改上傳至「程式交易聚寶盆」,供免費下載。

訂閱 RSS (by FeedBurner)
訂閱 RSS (by Wordpress)![[克莉絲汀] 水晶串珠吊飾- 粉蜻蜓](/wp-content/medias/ads/opus/DSC02940.jpg)

這個東西真是不錯啊…看來可以應用到同時接二到三家的 DDE 同商品資料..然後判斷哪個正常再丟給 TradeStation 作判斷來下單了..雖然用 Excel 也是可以…不過 Excel 用起來就是不太好用…
Hello D.K.
其實這個算是給會寫 .NET 的程式交易人員參考用的,然後再據此擴展,寫出更具應用價值的分析模型。 然後若能再行分享出來的話,那就會更好。 ^^
有空我會來研究一下的..:p
這個好!!!
我一直在找C#寫DDE的文件跟範例
感謝版主整理這麼清楚!
Hello dancer:
這到挺難得的,我是因為 "股票看盤軟體" 的關係,才 "不得不" 研究這個 DDE 連結。
沒想到您還會有其他需求喔。 !^^
有一個東西不錯,可利用NDDE + Flee 寫自定條件的選股
http://www.codeplex.com/Flee
Hello 小言:
不知道這個的主要作用呢。 !^^
克明大,好久沒上來你的基地了,
才發現已經改名囉! :-p,
最近正好在找程式交易的資料,
結果就找到您這來了!
哈哈,真是有緣!
想像您請教一下,我對 c# 不熟,
如果要學習的話,可以推薦幾本好書嗎?
另外不知道克明大,對下單機的部份,
是否也有研究?
Hello~
學 C# 不用買書的,就是透過 Google 查詢範例;以及利用 MSDN 查詢語法即可的。
我到目前為止,對於寫程式自動下單這事,一直興趣缺缺的。 ^^
這方面想研究參考的話,可以至聚財網的程式交易區參考的,其實也不會太難的。 ^^
那我了解了,謝謝!
克明大,
請問一下,您的文中提到"
"至於 “Service”, “Topic”, “Item” 的名稱如何取得? 一般只要從看盤軟體中,對某個表單的畫面欄位,右鍵 Excel DDE 複製到 Excel 中,即可察看到。"
我試了用寶來的點金靈還有hts,都還是不了解你說的方式,
還是說要在盤中有資料的時候,才能試呢? 還是說有什麼其他的方法,
可以取得 “Service”, “Topic”, “Item” ?
另外您寫到"右鍵 Excel DDE "這是在看盤軟體中嗎?還是在 excel 裡?
感謝您的回答 ^^
如果可以透過 Excel 連線至你的看盤軟體並可以即時顯示跳動的資訊,那就代表著設定是沒有問題的。 然後就是在 Excel 的每一個欄位,觀察其上方的公式欄,即可取得 Service. Topic, Item 的欄位值。
這一些問題,你可以至「聚財網」的程式交易區提問討論的。
小弟我用VB6 ,要直接讀 eLeader,全都賺的資料有辦法嗎
現在透過EXCEL
最近遇到一個問題,用eLeader或全都賺軟體
DDE link data直接拉到 EXCEL,會發生EXCEL無反應
不知版大猜測可能是什麼錯誤ㄚ
感謝ㄡ
是否是 Excel 的巨集與安全設定等有沒有開啟呢?
沒呢,我都試過了,包含了安全性的設定
Hi~
我最近都是使用 eLeader,並且常以 Excel 開啟 DDE 測試,一切均安好。
應該是可能你的 Excel 設定有問題吧。 (設定問題請勿問我)
DK你好:想請教幾個問題。
1. 當我使用的是這個 “Request(同步)” 的指令時,是代表跟DDE Server端的資料變動同步嗎?不管是不是有成交,也都會將資料回傳給我?
2. 若使用 “Advise(通告)” 的方式。如同你文中所說的,只要針對該項目的值一有變更時,就會通知已註冊的 Client 來取得變更的值。那今日如果我要抓取的是"成交時間"、"價格"與"數量"3種數值的話,我需要針對這3個不同的item各自去下"Advise"嗎?
3. 我目前遇到最大問題是,抓取的tick數量,與期交所公布的成交資訊有落差。所以,特來請教。
感恩
我不是 D.K ?
1. 不是喔,是 DDE Client 主動向 DDE Server 取得最新的資料。
2. Yes, 每個數值都是個別獨立的 Item.
3. 必然會有誤差的,DDE 並不是穩定的傳輸規格。
另, 使用 NDDE 這個 APIs 最近我在測試時,發生了非常嚴重的問題, 當有太多連線時,DDE 連線會遺失! 一直找不出問題。
現在不得已又轉回 Excel 尋求解決方法,實在很麻煩。
Kenming:
不好意思,把你大名誤植了!
如果以第一點" DDE Client 主動向 DDE Server 取得最新的資料",那我是在迴圈中一直重複下"Request",迴圈執行幾次,tick就會抓幾次回來,這部分似乎很難跟server同步。一天下來,至少也有30000個ticks以上。
我是使用台證的Office Quote當資料源,我有查到資料說他是一種COM傳輸技術,小弟學淺,實在沒聽過,不知道Kenming是否有聽過這樣的技術呢?
謝謝
1. 所以本來就不是用 Request 取資料的啊。 我在文內有提及,那是為了第一次能抓到資料而實做的。
2. 先前才剛爬網查過這個。 反正簡單的說,就是依循它的通訊協定來取得 Tick 資料。 我想應該是比 DDE 的傳輸好上太多了。 可惜,台證有最低口數限制,我也沒有帳號,無法取得來測測看。
請問~
為什麼,用VB.net接DDE,還是要開EXCEL才行?而且在excel裡,還得要有想連結的資料?
照理來說,就像您文中所述,應該是VB直接可以接到DDE,而不是透過excel才對
這是為甚麼?
同樣的,為了瞭解是不是VB的問題,還是我哪裡弄錯了
我有下載聚才網的程式碼,執行bin\下的執行檔
也是一樣,要開excel,數值才會顯示&跳動
請教有甚麼方式可以不透過EXCEL直接接到DDE嗎?
Hello~
1. 該程式我是用 C#.NET 寫的,與 VB.NET 應該無關吧。
2. 在範例圖上應該表達算很清楚,並不需要透過 Excel,報價 Server 即為 DDE Server,並不再需要透過 Excel 當為中介的。
我也是覺得很奇怪,或許是VB的問題,謝謝囉~
Dear Kenming
您的詳細解說,對於程式新手的我來說,受益良多,感謝您的無私分享,目前我正在寫DDE 用 vb.net來實作,
碰到您上面所提的windows Form 的UI難題,剛好您有範例在聚財網上,但,可能時間比較久了,該網址找不到您的文章,
可否幫忙ㄧ下,感恩。
我去查的確不見了 !^^
這樣的話,我寄給你好了。 Email 是你現在這個所留的嗎?
Dear Kenming
感謝您,Email是我所留的這個msa帳號,昨日也剛好使用NDde.dll,
嘗試用1 connection (1 service 1 topic)多個item的方式,
苦思許久,仍尚未試出來,您範例程式中都有提到,
再麻煩您寄給我了,感恩。
Dear Kenming您好:
小弟近日正在學著以C#來撰寫DDE程式, 大大的文章對我幫助很大
然而在截取日盛報價的過程中, 還是遇到一些困難
不曉得能否厚顏的請大大也寄一份範例檔給小弟當作參考, 謝謝!!
我是阿丁
MAIL: chaser1213@yahoo.com.tw
BLOG: http://blog.xuite.net/chaser1213/autotx
PLURK: http://www.plurk.com/ding1213
諸位有興趣原始程式碼的讀者們:
請至:「程式交易聚寶盆」免費下載。
網址: http://www.programtrading.tw/viewtopic.php?f=4&t=2890
能否請kenming兄在通化街開一場收費的下午茶會,直接講授DDE的這一部分?
DDE 這一塊實在沒啥好講的勒。
如果有機會,我到昰想把自己研究開發的工具打包成套件,附在書本上出版,然後有機會辦講座課程,可能更實在些。 !^^
非常感謝您能大方的分享C# DDE的程式碼和說明,我目前也對程式交易有興趣,您的文章對我現在的幫助很大,感謝您!
非常好,也希望屆時您可以分享更多的心得。 ^^