談談 C#.NET 連結 DDE Server 的設計觀

DDE (Dynamic Data Exchange)?,這似乎已經是微軟過時的一種通訊傳遞的技術了。 但是只要是跑券商提供的看盤交易應用軟體,諸如 永豐 e-leader, 元大 yeswin, 日盛 hts 等,都必然有提供 DDE 連結的功能。 探究原因,Excel 肯定是佔最大的因素了,因為一般交易者可以很容易地透過 Excel,抓取看盤軟體正在跳動(Tick)的即時金融商品資訊,在不需要太懂程式設計語法的情況下,也能利用 Excel 強大的統計功能,或者利用簡單的 VBScript 語法,撰寫指標或統計數據等。

先前我就曾經利用 Excel 撰寫過即時的「漲/跌/平 家統計數據」了,詳見:「利用 Excel 實現權值成分的漲跌平家走勢圖」。 不過,目前我正在研究其中關於大盤即時 “量” 的變化,也就是觀察 Top-100 的期貨成份股,在每一分鐘內,統計所有即時跳動(Tick)的成交買價量與賣價量。 所以幾乎每一秒,只要一有跳動,就必須觸發(trigger)統計運算的邏輯,把 100 支以上的權值成份股整個迴圈跑過一次。 不知道是否因為我對 VBScript 不習慣,還是寫法有問題,在 Excel 內的處理效能上還是來得不佳,喔,甚至還曾幾次出現過當掉的現象,而這在即時看盤中,當然是很忌諱的 ; 另外,我也可能想要開發個能同時連多個報價來源 DDE Server 的 “中介(intermediate)” Server,除了可以方便調整想要擷取的資料來源外,還能兼容有 “容錯(fault-tolerance)” 的功能。 反正啊,能具有高度的客製化(customization),以及無限想像的延展性(scalability),更是我想要的,而這些當然就要寫程式自行來去開發擴展囉。

DDE 是個老舊的傳輸技術,從微軟官方的角度,係制訂了 DDEML (Dynamic Data Exchange Management Library) 的規格,並提供給 Developer 最高階的連接方式就是 Windows 32-bit 的 APIs(Application Programming Interfaces),在實際 Windows-32 的作業系統下,是被實作在 “User32.DLL”。 所以,最適合用來開發 DDE-based 的程式語言,當屬可以直接連接 Win-32 APIs 的,諸如 VB6, C++ 等,開發上對於 DDE 的實際連結,會來得容易許多。

anyway, 我還是喜歡利用 .NET C# 來寫程式,最主要只有一個原因,我對它比較熟悉!

而我在一般關於「程式交易討論區」看到有些網友發言,說 .NET 並不支援 DDE! 這句話初看到挺覺得奇怪的,其實正確地來講,應該是說 .NET Framework 並沒有提供 DDEML 的 Wrapper 成為 .NET 元件,所以若要從 .NET 應用程式連結 DDE Server 的話,就必須自行實作呼叫底層(相對於 .NET)的 Win-32 APIs。 一個簡單的流程如下:

  C#/VB .NET Client → .NET DDEML Object(自行撰寫,因為官方沒有提供) → Win-32 DDEML APIs

西方的一個老諺語: “Don’t Reinvent the Wheel (不要重覆再造輪子)。” 那個 .NET DDEML Wrapper 物件,是否要自行撰寫,有待商榷! 若要自行撰寫,那就確定了,是要從造一個新的輪子開始,而且還要很熟悉 DDE 相關的通訊細節才行! 建議啦,這類的 “輪子建設” 工作,先查詢一下 Google,這可是 Google 最大的功用! 發現到,其實真的已經有許多其他行家已經造好可以在 .NET 環境開發的 “DDE 連結 輪子” 了。 包括 美國、中國大陸、甚至日本等都有人在造。 而其中這個: NDde ,看來應該是最為完整的開源 (open-source)專案了。 還包括文件、範例,甚至原始碼等,是可以充分在 .NET 2.0 環境下執行的,下載回來解壓縮放置某一個目錄後 (ex. “\Program Files\Ndde”),把你的 .NET 專案 Add Reference 該目錄內有個 “NDde.DLL” 檔案即可。 這使得寫 C# DDE Client 變得相當簡單,我個人已測過連結 e-leader DDE 來源,完全沒有問題!

要透過 C#/VB .NET 撰寫連結 DDE Server 的 Client 端程式,只要參考 NDde 目錄內的 /Samples 範例檔即可。 另外底下是我自己先暫時寫的一個小小控制程式,主要是測試是否可以確實連結 DDE Server 並取得 Topic/Item 的回傳資料。


TDControl.cs


using System;
using System.Text;

using NDde.Client;

namespace TradeDDE.Control
{
    public class TDControl
    {
        private DdeClient client;

        public void Connect(string service, string topic)
        {
            client = new DdeClient(service, topic);

            try
            {
                // Connect to the server.  It must be running or an exception will be thrown.
                client.Connect();

                //Start Advise
                this.startAdvise(this.client);
            }
            catch (Exception thrown)
            {
                throw new Exception("無法連結 DDE Server \n" + thrown.Message);
             }
        }

        private void startAdvise(DdeClient client)
        {
            // Advise Loop
            client.StartAdvise("VolAmount", 1, true, 60000);
            client.Advise += OnAdvise;
        }

        private static void OnAdvise(object sender, DdeAdviseEventArgs args)
        {
            Console.WriteLine("OnAdvise: " + args.Text);
        }

        public void DisConnect() 
        {
            try
            {
                client.Disconnect();
            }
            catch (Exception thrown)
            {
                throw new Exception("無法離線 DDE Server \n" + thrown.Message);
            }
        }
    }
}

單元測試程式程式碼如下(利用 NUnit Test Framework),利用它可以先取代 UI Form 的執行,而直接觀察在 Console 的執行結果。

TDControlTest.cs


using System;
using System.Text;

using TradeDDE.Control;
using NDde.Client;
using NUnit.Framework;

namespace TradeDDE.Control.Test
{
    [TestFixture]
    public class TDControlTest
    {
        private TDControl control;

        [SetUp]
        protected void SetUp()
        {
            control = new TDControl();
        }

        [Test]
        public void tesConnect()
        {
            try
            {
                control.Connect("myapp", "myservice");
            }
            catch (Exception thrown)
            {
                Console.WriteLine(thrown.Message);
            }
        }
    }
}

順帶提一下 IDE 工具。 對於這類要自行開發小程式的開發工具而言,在 Java 這邊的首選當然就是 Eclipse (或者衍生的 EasyEclipse)。 .NET 這邊呢? Visual Studio .NET 2005/2008 這可是要付費的,而且還不便宜! 不過這兩三年來,微軟真是佛心來著,竟然也提供完全免費的 Visual Studio 2005/2008 Express 系列,雖然是 By 個別語言就要個別下載 (C#/VB .NET 各一套),但也真的夠用了,還是挺好用的呢。

screenshot_vs2008_express_c#

唯有一個美中不足的地方,MS 還是不夠大方,不允許 3rd party 在 vs express 的版本上 “加值”,也就是無法撰寫 add-in 的擴充功能程式,”plug-in” 到 vs express 的平台上。 影響最大的是什麼呢? 你無法在 express 的環境內執行 unit-test,諸如下載回來的 NUnit,你只能在 IDE 的環境外,自行透過 NUnit 內建的 GUI 測試工具來測試,而如此就不容易與 IDE 的 DEBUG 機制整合在一起。

倒是也有另外一套非屬於 MS 的 .NET 開源專案— SharpDevelop,也是提供在 .NET 的 IDE 開發工具,完全免費,甚至還整合了 C#/VB/F# .NET 等 OOP 語言,也提供了無限的擴展功能,耗費資源也小,執行效率也僅比 VS Express 稍慢一些些而已,看來前景還挺看好的。 截至目前為止,SharpDevelop 3.0 beta-2 版本(2008/08/22),是完全相容於 .NET Framework 3.5 環境,但是呢,我利用它的 Form Developer 開發 Windows Form 會出問題,雖然該社群網站似乎有提供說明解決方案,不過,總覺得很不安心,拉一拉表單畫面就要提心吊膽出錯,實在沒道理,所以現在我暫時只用它來開啟已開發好如 NDde 的專案。 很不錯的一點是,SharpDevelop 完全相容 VS Express 的 Solution/Project 格式,完全互通! 總的來說,現在我開發個 C#.NET 應用程式,大概會打開至少一個 VS Express 2008,以及一個 SharpDevelop 的 IDE,系統執行效率也不至於受多大影響。

screenshot_sharpdevelop3b2_with_unit_test

文章導覽

   

共有 16 則迴響

  1. Kenming大你好:

    最近在研究DDE的傳輸
    目前在本機端嘗試以server和client溝通是ok的
    但碰上跨電腦或網域則沒辦法
    想請問您是否有遇過此問題,是否有解決的辦法

    感謝

  2. DDE最簡單的就要有下單軟體而且還要考慮連結的方便性,跟營業員是否清楚知道如何協助,畢竟營業員懂電腦下單程式的比例還是略嫌偏低,可以跟我聯絡,全省都可 “即時 “幫您處理電腦問題,http://blog.cnyes.com/My/t5653t1967/

  3. Kenming大你好:

    我最近有再研究DDE的連結,想請問一下假設我要連日盛DDE,
    是不是要先開日盛的軟體,畢竟DDE服務是由卷商提供!
    還是可以不用開卷商的軟體,就能連到該DDE的Server?

    感謝你的專業回應!

  4. 請問王兄
    如果透過您的C#.net,連上DDE server.同時對400支股票做監控.及整點即時運算的可能性如何呢
    感謝您思考這個問題喔

    邦得

  5. 網上爬了兩天文, 看到大大的 po 文真是高興!!
    因為也想撰寫 DDE 整合各資料來源,
    不知可否請教:
    遞送給 TradeStation 的 Global Server 可否直接以 DDE 遞送資料呢??
    Global Server 是 DDE 的 Client 或是 Server 呢??

    拜謝先~~

    • 我並沒有使用 Tradstation Global Server。 不過,這些交易分析軟體基本上都會有提供 DDE 連結的機制。 應該查看該軟體文件的開發手冊規格,就可以知道的。

  6. To Daniel:
    DDE只提供即時的資料,如果你要錄製可能得自己透過EXCEL或者其他程式來針對所收到的資料做記錄

    當然如果你想要分K台指期的成交明細,我在收盤後都將各類期貨的分K明細放置網路上,你可以直接下載使用
    http://blog.alvin.tw/data/

  7. 小弟最近在做錄製台指期即時資料,用excel做的。
    看到版大的文章介紹真是收獲良多。

    最近也改用dde進行資料讀取的動作。

    可是遇上idq的台指期成交明細 無法抓取 >

  8. 一直希望能有一個自動下單的軟體來用,意即見到某價位後, 能自動
    發出買進或賣出的指令到期貨商的系統, 而不需要利用期貨商的下單系統手工鍵入資料, 目的是手打下單慢, 等你打好後, 行情已跑一大段去了,效率上差很多,我對軟體是門外漢,我的想法可行嗎? 是否已有這樣的軟體存在?不吝指正.

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *