ForexConnect .NET API 使用入門 (Win32/Win64)
本文是 ForexConnect .NET API 的使用入門,其中描述了 API 的基礎知識,並按步驟詳細介紹了如何建立一個簡單交易應用程式的工作示例。
平台:在 MS Windows 32 位元/64 位元版本上執行的 Microsoft .NET Framework 2.0 及更高版本
語言:C# .NET
IDE:Microsoft Visual Studio 2005、2008、2010
不支援將 ForexConnect .NET 庫與 Microsoft Silverlight 應用程式框架配合使用。
不支援使用 Mono 執行 ForexConnect .NET 庫。
Contents
獲取並安裝 ForexConnect API 庫
- 下載最新版本的 ForexConnect API:
- 如果使用 32 位元版本的 Microsoft Windows,請下載 32 位元版本的 ForexConnect API。
- 如果使用 64 位元版本的 Microsoft Windows,請下載 64 位元版本的 ForexConnect API。
- 有關您的系統版本的資訊,請查看「系統內容」對話方塊。
- 請注意,在 Windows XP 系統中,如果「系統內容」對話方塊中沒有「x64 Edition」字樣,則為 32 位元版本的 Windows XP。
- 啟動安裝程式,然後根據安裝精靈的指示操作。
- 此外,我們將假設 ForexConnect API 的安裝路徑為 C:\Program Files\Candleworks\ForexConnectAPI\。
在 Microsoft Visual Studio 中使用 ForexConnect API
您應在 C# 專案中執行以下變更:
- 1. 設定專案建立後的事件,以將 ForexConnect API 庫和支援檔案複製到建立程式的資料夾中:
- 在專案的「屬性」→「建置事件」→「建置後」事件命令列中添加以下文字:
- copy "C:\Program Files\Candleworks\ForexConnectAPI\bin\*.*" "$(TargetDir)"
- 2. 向專案添加對 fxcore2.dll .NET 組件的引用。
- 如果您使用 .NET 4.0,則使用相應的 .NET fxcore2.dll 組件,該組件位於 "C:\Program Files\Candleworks\ForexConnectAPI\bin\net\dotnet40\" 資料夾。
- 如果您使用 .NET 2.0,則使用 "C:\Program Files\Candleworks\ForexConnectAPI\bin\net\dotnet20\" 資料夾中的 fxcore2.dll 組件。
- 3. 將命名空間 fxcore2 添加至程式碼:
using fxcore2;
發佈
您必須將您的程式和 C:\Program Files\Candleworks\ForexConnectAPI\bin 中的所有二進位庫及支援檔案一起發佈。ForexConnect 庫及支援檔案必須置於應用程式的安裝資料夾。
請注意,fxcore2.dll 組件也必須置於應用程式的安裝資料夾。
ForexConnect .NET API 的功能
事件驅動架構
ForexConnect 使用的所有 API 都是非同步的,所以您需要在程式碼中實現事件驅動架構。
事件驅動架構是一種軟體架構模式,用於管理事件的產生、偵測和使用行為,以及它們呼叫的回應。在此情境中,應將事件視為在被監視的連續輸入流中可識別的某種值或訊息,例如特定條件、信號或其他。
事件驅動架構通常包括事件製造者和事件使用者。事件使用者訂閱某種事件管理器,而事件製造者將事件發佈至這個管理器。接收到來自製造者的事件時,管理器將事件轉寄給所有註冊的使用者,或儲存事件以備稍後轉寄。
事件處理程式是一個回呼常式,用於以非同步的方式操作並處理程式收到的輸入(事件)。在此情境中,事件是來自基礎開發框架(通常是圖形化使用者介面 [GUI] 工具組)的某種有意義的應用程式資訊元素,或者某種輸入常式。例如,在 GUI 端,事件包括擊鍵、滑鼠活動、操作選擇或計時器超時。在輸入端,事件包括開啟或關閉檔案及資料流、讀取資料等。
事件處理即某個事件處理程式接收來自事件製造者的事件以及相關的後續流程。
事件處理涉及的流程包括:
- 識別應向哪里轉寄事件;
- 進行轉寄;
- 接收轉寄的事件;
- 執行適當的操作以作為回應,例如寫入日誌、傳送錯誤、恢復常式或傳送訊息;
- 事件處理程式最終可能將事件轉寄給事件使用者。
事件驅動架構的優勢在於支援任意多個使用者和製造者以及若干個管理器的集合,從而彼此交換即時狀態和回應資訊。事件發生時,該架構通常能夠正確回應,並且該架構同樣適用於非同步以及不可預測的通訊環境。
ForexConnect .NET 事件處理的特點
ForexConnect .NET API 已實現 IO2GSessionStatus
和 IO2GResponseListener
介面,可接收工作階段狀態變更及資料接收通知。因此,您可以使用 O2GSession 物件的相應 .NET 事件,而無需自行實現這些介面。不過,您也可以實現這些介面,並在訂閱後用它們來接收來自工作階段物件的通知(如果這種方式更適合您)。
請注意,針對 O2GSession
事件實現的所有事件處理程式均在單獨的執行緒中呼叫。因此,您必須牢記:
- 您必須始終對儲存在應用程式中、從事件處理程式更新的所有資料提供安全執行緒存取。
- 您無需同步事件處理程式的呼叫,也無需考慮事件處理程式的「重新輸入」,因為 API 的所有事件都已在一個執行緒中同步。所以,將按順序呼叫事件處理程式。
- 您應該儘快處理每個事件,因為它們已被 ForexConnect 庫同步至一個「處理程式」執行緒中。您可以執行自訂執行緒,以加速事件處理。
物件存留期管理
對於使用 ForexConnect .NET API 獲取的物件,您無需任何其他資源管理。
但建議對所有實現 Dispose()
方法的已獲取物件呼叫該方法。您可以透過這些呼叫更有效地釋放未使用的系統資源。您可以使用 using
陳述式達到此目的:
using (O2GValueMap valuemap = factory.createValueMap())
{
//...
}
使用 ForexConnect .NET API 的示例應用程式
概述
本示例是一個使用 ForexConnect .NET API 的簡單主控台應用程式。該應用程式具有以下功能:
- 使用預先定義的使用者認證連接至交易伺服器
- 擷取 EUR/USD 的價格
- 擷取使用者的賬戶表
- 在使用者輸入 'b'(買進)或 's'(賣出)時建立 EUR/USD 的「市價開倉單」
- 擷取訂單表格,並接收相應表格的更新通知
- 在使用者輸入 'q'(結束)時結束執行應用程式
為了簡化示例,整個應用程式邏輯在一個 MyApp
類別中實現。
您可以下載示例的完整原始程式碼:File:ForexConnect Sample Net.zip
連接交易伺服器
ForexConnect .NET API 的主物件是 fxcore2
命名空間中的一個工作階段物件 O2GSession
。
該物件代表一個使用者連接工作階段,可使用 O2GTransport
類別的靜態方法建立:
O2GTransport.createSession();
O2GSession
物件就連接狀態的所有變化通知訂閱者,方式為透過以下事件:
或者透過回呼介面 IO2GSessionStatus
。
資料接收通知可使用以下 O2GSession
事件處理:
或者透過回呼介面 IO2GResponseListener
處理。
要使用 ForexConnect .NET API 連接至交易伺服器,請執行以下操作:
- 建立一個工作階段物件。
- 實現工作階段物件的事件處理程式,以接收工作階段狀態變更通知。
- 為工作階段呼叫
login()
並等待,直至完成登入過程。 - 在
onSessionStatusChanged
中處理收到的連接狀態變更通知,以管理登入過程的狀態。
有關實現機制的詳細資訊,請參閱以下原始程式碼:
'"`UNIQ--toggledisplay-00000006-QINU`"'
請注意,由於 login()
呼叫是非同步的,所以我們需要等待登入完成通知。因此,我們將使用特殊的同步信號。呼叫 onSessionStatusChanged
時,該信號即設定為在 run()
方法的 mSyncSessionEvent.WaitOne(5000)
事件之後恢復執行緒的執行。
登入時選擇交易工作階段
如果使用者賬戶擁有多個交易工作階段,則登入過程將包含多個步驟:
- 1. 指定使用者名稱、密碼、伺服器 URL 以及資料庫名稱,然後呼叫工作階段物件的
login()
方法。 - 2. 在
onSessionStatusChanged
事件處理程式中處理收到的狀態TradingSessionRequested
。以下是處理TradingSessionRequested
狀態的通用步驟:- 2.1. 使用
getTradingSessionDescriptors()
方法從O2GSession
物件擷取交易工作階段清單。 - 2.2. 為使用者提供交易工作階段選擇。
- 2.3. 向使用者請求秘密 PIN。
- 2.4. 使用
setTradingSession()
設定指定的交易工作階段 ID 和 PIN。
- 2.1. 使用
'"`UNIQ--toggledisplay-00000007-QINU`"'
- 3. 如果
setTradingSession
成功,則onSessionStatusChanged
事件處理程式將收到Connected
狀態。
管理價格
價格管理包括以下步驟:
- 檢查登入期間是否自動請求了價格資料。
- 如果是,則轉到第 2 步。
- 如果否,則傳送一個對所有商品當前價格的請求。
- 處理回應。
- 處理特定商品的價格更新。
要接收請求回應或伺服器物件狀態變更的通知,您必須實現並訂閱事件處理程式,以獲取 O2G2Session
執行個體的相應事件。
為此,請修改 MyApp 類別以處理這些事件: '"`UNIQ--toggledisplay-00000008-QINU`"'
請求當前價格
根據交易伺服器的設定,您可在登入期間自動接收所有商品的當前價格,也可向交易伺服器明確請求此資料。因此,要獲取當前價格,請執行以下操作:
- 1. 使用
O2GLoginRules
執行個體的isTableLoadedByDefault()
方法檢查是否在登入時接收了報價。 - 2. 如果報價已載入,則使用
O2GLoginRules
執行個體的getTableRefeshResponse(Offers)
方法獲取已接收報價的回應物件。 - 處理該回應物件即可提取報價資料。要獲取報價讀取器以讀取回應資料,請執行以下操作:
- 使用 工作階段物件 執行個體的
getResponseReaderFactory()
方法獲取回應讀取器工廠。 - 使用
O2GResponseReaderFactory
執行個體的createOffersTableReader()
方法建立讀取器。
- 使用 工作階段物件 執行個體的
- 3. 如果未在登入時接收報價,則使用工作階段物件的
sendRequest()
方法明確傳送報價表請求。 - 要建立相應的請求,請執行以下操作:
- 使用 工作階段物件 的
getRequestFactory()
方法獲取請求工廠。 - 使用
O2GRequestFactory
執行個體的createRefreshTableRequest()
方法建立請求。
- 使用 工作階段物件 的
要請求當前價格,請在登入處理後將以下原始程式碼添加到本示例的 run()
方法中:
'"`UNIQ--toggledisplay-00000009-QINU`"'
在示例中,我們使用同步信號等待接收請求回應。因此,我們將「抓住」開始監視 EUR/USD 表的價格變化的時機。當然,我們應在收到價格資料時設定該信號。
在本示例中,使用了一個「小技巧」來避免程式碼重複。從後文可以看出,無論是從 O2GLoginRules
物件接收報價資料,還是我們明確擷取報價資料,其回應處理完全相同。因此,要處理接收自 O2GLoginRules
的回應物件,您可直接呼叫工作階段物件中 RequestCompleted
事件的已實現事件處理程式。
接收價格資料
由於 sendRequest()
的呼叫是非同步的,所以,要接收帶價格資料的回應,您需要實現 工作階段物件
中 RequestCompleted
事件的事件處理程式。由於該事件處理程式用於接收所有請求的回應通知,所以請執行以下操作:
- 檢查回應類型是否為
GetOffers
。 - 使用
O2GResponseReaderFactory
獲取O2GOffersTableResponseReader
回應讀取器,以從回應物件獲取價格資料。 - 使用讀取器處理報價表中的所有行。
您必須提供對您應用程式中所儲存報價的安全執行緒存取。
有關如何處理回應接收的示例,請參閱以下原始程式碼。要儲存 EUR/USD 的當前價格,應定義相應的變數,並為其實現安全執行緒存取。
'"`UNIQ--toggledisplay-0000000A-QINU`"' 報價資料接收完畢後,即可設定同步信號。透過這種「小技巧」,傳送請求後,我們即可等待在主執行緒中接收當前價格。
我們的示例應用程式可處理 RequestComplete
事件,並可提取 EUR/USD 賣出價和買進價。收到的賣出價和買進價將儲存在 mEURUSDBid
和 mEURUSDAsk
類別層級的變數中,讀取和修改這些變數的安全執行緒方法已實現。
接收報價更新
請注意,通知在一個單獨的執行緒內接收,所以您必須使用安全執行緒方法讀取並更新儲存所接收資料的變數。
將以下程式碼添加至 MyApp,以處理 EUR/USD 價格更新:
處理報價表更新包括以下步驟:
- 1. 從工作階段物件獲取 O2GResponseReaderFactory。
- 2. 透過 createTablesUpdatesReader 方法,使用工廠獲取 O2GTablesUpdatesReader 讀取器。
- 3. 建立一個迴圈以枚舉更新清單中的各個元素,因為收到的資料可能包含任何類型物件的更新,而不僅限於報價表。因此,您需要檢查所需表格類型的更新清單中的每一項,並更新操作類型。
- 4. 要處理變更,請使用讀取器的 getOfferRow() 方法擷取 O2GOfferRow 類型的物件:
O2GOfferRow offer = pReader.getOfferRow(i);
請注意,通知在一個單獨的執行緒內接收,所以您必須使用安全執行緒方法讀取並更新儲存所接收資料的變數。
將以下程式碼添加至 MyClass
,以處理 EUR/USD 價格更新:
'"`UNIQ--toggledisplay-0000000D-QINU`"'
本示例中,我們僅處理 EUR/USD 價格更新,並將其最近值儲存在 mEURUSDBid
和 mEURUSDAsk
變數中。我們已實現存取這些變數的安全執行緒方法。
訂單建立
要建立訂單,請執行以下操作:
- 1. 確保您至少擁有建立訂單所需的使用者賬戶 ID 和報價 ID。否則,請首先請求這些資訊。
- 2. 使用
O2GRequestFactory
執行個體建立O2GValueMap
,以指定訂單參數。 - 3. 使用所需的參數填充值對應,建立特定類型的訂單
- 有關建立訂單的命令參數的詳細資訊,請參閱 ForexConnectAPI SDK。
- 4. 使用
O2GRequestFactory
為已填充的值對應建立O2GRequest
物件。 - 5. 開始執行請求。
- 6. 接收請求回應,以確保成功執行請求。
因為本示例中需要一個賬戶 ID,所以我們首先需要擷取賬戶表。擷取賬戶表資料的操作與擷取報價表資料類似。要簡化示例,我們可從使用者賬戶清單中獲取第一個賬戶,然後將其儲存在類別層級的變數中,以備今後使用。 '"`UNIQ--toggledisplay-0000000E-QINU`"'
我們需要等待回應,以避免在擷取到賬戶 ID 之前建立訂單。
最佳方法是將訂單建立邏輯封裝到一個單獨的 MyApp 類別方法中。您還應在 onRequestCompleted 事件處理程式中處理訂單建立請求的回應,以確保建立訂單。
以下原始程式碼建立了一個交易量為 100K 的 EUR/USD 商品買進或賣出訂單: '"`UNIQ--toggledisplay-0000000F-QINU`"'
請注意,在使用訂單參數填充值對應物件時,在 fxcore2.Constants
命名空間中有一些非常實用的 helper 類別:
Constants.Commands
Constants.Order
等等。
您可以保存請求 ID,以處理某一個特定請求的回應:
request.RequestId;
擷取訂單表
我們可透過訂單表擷取現有訂單狀態的所有資訊。
透過 ForexConnect API,我們可僅為指定賬戶擷取訂單表。為此,您需要執行以下操作:
- 擷取賬戶表。
- 等待接收賬戶資料。
- 使用
O2GRequestFactory
執行個體的createRefreshTableRequestByAccount()
為每個已接收賬戶擷取訂單表。 - 在
RequestComplete
事件的事件處理程式中處理請求回應。 - 在
TablesUpdates
事件的事件處理程式中處理訂單表更新。
為簡化示例,我們選取儲存的賬戶 ID,並在訂單表擷取示例中使用。
'"`UNIQ--toggledisplay-00000012-QINU`"' 請注意,如果您儲存訂單資料,就必須提供到該資料的安全執行緒存取,以及對所儲存物件的引用計數器的正確管理。在本示例中未儲存訂單資料,因此未實現同步。
結束應用程式。登出
如您所見,MyApp
類別的 stop()
方法可釋放所有用過的系統資源,並從工作階段事件取消所有事件處理程式的訂閱,以停止接收通知。您應在結束應用程式前呼叫 logout()
。您還應在 _tmain() 返回控制之前呼叫工作階段執行個體的 Dispose()
方法。
'"`UNIQ--toggledisplay-00000013-QINU`"'
處理請求錯誤
如果在非同步執行請求期間發生錯誤,將呼叫 RequestFailed
事件的事件處理程式。
在本示例中,我們透過將錯誤描述放到主控台輸出中以及停止應用程式來處理錯誤:
void mSession_RequestFailed(object sender, RequestFailedEventArgs e)
{
Console.WriteLine(e.Error);
stop();
}
啟動示例
至此,我們的示例就可以登入、擷取 EUR/USD 價格變化、顯示現有訂單資訊,並提供建立「市價開倉單」的方法。
要在此階段啟動示例,我們需要實現 MyApp 類別的用法。為此,請執行以下操作:
- 在主控台應用程式的主函數中建立一個 MyApp 類別執行個體。
- 呼叫該執行個體的 run() 方法登入交易伺服器,並開始接收 EUR/USD 的更新。
- 提供對使用者輸入的讀取以執行命令:
- 當輸入 "b" 時,建立買進市價單;
- 當輸入 "s" 時,建立賣出市價單;
- 當輸入 "q" 時,結束應用程式。
class Program
{
static void Main(string[] args)
{
MyApp app = new MyApp();
if (app.run()) //等待登入完成並進行其他準備
{
char cKey;
while(true)
{
cKey = (char)Console.Read();
if (app.Status == O2GSessionStatusCode.Disconnected) //如果非同步後出錯,則呼叫 createOrder
break;
if (cKey == 'q')
{
app.stop();
break;
}
else if (cKey == 'b')
app.createOrder(true);
else if (cKey == 's')
app.createOrder(false);
}
}
}
}
示例的 run() 方法可為應用程式做好交易前準備。準備完成後,如果一切正常,它將返回 true。 如您所見,該方法非同步呼叫所有 API 函數,但透過特殊的同步物件等待其回應。請注意,這並非使用 ForexConnectAPI 的有效方法,但是它簡單易懂。
為呼叫 login() 方法,請務必指定有效的使用者名稱和密碼。
現在您即可生成並執行該示例。如果在生成示例時遇到任何問題,請對比示例的完整原始程式碼:File:ForexConnect Sample Net.zip。
進一步資訊
有關所有 API 類別及其方法的詳細資訊,請參閱 ForexConnectAPI SDK。
- 閱讀普通文章如何獲取交易表資料
- 閱讀文章如何使用批次命令
- 閱讀文章如何建立 OCO 掛單
- 閱讀文章如何訂閱和取消訂閱商品報價
其他語言版本
Language: | English • español • français • русский • 中文 • 中文(繁體) |
---|