c# - 如何从 MQL4 将数据发布到 C# 网络服务
问题描述
我正在尝试使用 MQL4 将 Metatrader 的历史数据发布到用 C# 编写的 Web 服务。我遇到的问题是 MQL4 中的字符串是占用 2 个字节的 Unicode,而 C# 中的字符串是 ANSI。因此看起来接收方的每个字符之间都有一个空格。
#import "Wininet.dll"
int InternetOpenW(string, int, string, string, int);
int InternetOpenUrl(int, string, string, int, int, int);
int InternetCloseHandle(int);
int HttpOpenRequestW(int, string, string, string, string, string& AcceptTypes[], int, int);
bool HttpSendRequestW(int, string, int, string, int);
int InternetConnectW(int, string, int, string, string, int, int, int);
#import
#import "kernel32.dll"
int GetLastError(void);
#import
void SendHistory()
{
int i,hstTotal=HistoryTotal();
for(i=0;i<hstTotal;i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==true)
{
if(OrderSymbol()!="") // Skip balance statements for now
{
string body=GetBody();
//--- Reset the last error code
ResetLastError();
// Only send newer Tickets
if (OrderTicket() > lastOrderSent)
{
string headers = "Content-Type: application/x-www-form-urlencoded";
string data = "";
string acceptTypes[1] = {"application/json"};
int HttpOpen = InternetOpenW(" ", 0, " ", "", 0);
int HttpConnect = InternetConnectW(HttpOpen, serverName, 27408, "", "", 3, 0, 0);
int HttpRequest = HttpOpenRequestW(HttpConnect, "POST","/api/Transactions", "", "", acceptTypes, 0, 0);
bool result = HttpSendRequestW(HttpRequest, headers, StringLen(headers), body), StringLen(body));
string lastError = kernel32::GetLastError();
Print ("Last MSDN Error =: ", lastError);
int read[1];
Print("This is the POST result: ", result);
InternetCloseHandle(HttpOpen);
InternetCloseHandle(HttpRequest);
}
}
}
}
return;
}
string GetBody()
{
string bodyPart1=
StringConcatenate("{","\"Order\"",":",OrderTicket(),",",
"\"Time\"",":","\"",GetTimeString(OrderOpenTime()),"\"",",",
"\"Type\"",":",OrderType(),",",
"\"Lots\"",":",OrderLots(),",",
"\"Symbol\"",":","\"",OrderSymbol(),"\"",",",
"\"Price\"",":",OrderOpenPrice(),",",
"\"StopLoss\"",":",OrderStopLoss(),",",
"\"TakeProfit\"",":",OrderTakeProfit(),",",
"\"CloseTime\"",":","\"",GetTimeString(OrderCloseTime()),"\"",","
);
string bodyPart2=
StringConcatenate("\"ClosePrice\"",":",OrderClosePrice(),",",
"\"Swap\"",":",OrderSwap(),",",
"\"Profit\"",":",OrderProfit(),",",
"\"Comment\"",":","\"",OrderComment(),"\"",",",
"\"Commission\"",":",OrderCommission(),",",
"\"Expiration\"",":","\"",OrderExpiration(),"\"",",",
"\"MagicNumber\"",":",OrderMagicNumber(),",",
"\"AccountNumber\"",":","\"",AccountNumber(),"\"",",",
"\"Id\"",":","\"",OrderTicket(),"\"","}"
);
return(StringConcatenate(bodyPart1,bodyPart2));
}
在 C# 端,它看起来像这样:
// POST: api/Transactions
[ResponseType(typeof(Transaction))]
public async Task<IHttpActionResult> PostTransaction(Transaction transaction)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Transactions.Add(transaction);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateException)
{
if (TransactionExists(transaction.Id))
{
return Conflict();
}
else
{
throw;
}
}
return CreatedAtRoute("DefaultApi", new { id = transaction.Id }, transaction);
}
事务类是
public class Transaction
{
public string Id { get; set; }
public int Order { get; set; }
public DateTime Time { get; set; }
public int Type { get; set; }
public decimal Lots { get; set; }
public string Symbol { get; set; }
public decimal Price { get; set; }
public decimal StopLoss { get; set; }
public decimal TakeProfit { get; set; }
public DateTime? CloseTime { get; set; }
public decimal ClosePrice { get; set; }
public decimal Swap { get; set; }
public decimal Profit { get; set; }
[StringLength(255)]
public string Comment { get; set; }
public decimal Commission { get; set; }
public DateTime? Expiration { get; set; }
public int MagicNumber { get; set; }
public string AccountNumber { get; set; }
}
但由于 Unicode 与 ANSI 在字符串处理上的差异,Web Api 控制器接收到的 Transaction 对象始终为空。我尝试使用 StringToCharArray 将 Unicode 字符串转换为 ANSI,但 HttpSendRequestW 需要一个字符串作为正文参数。Wininet.dll 的 Internet*A 函数甚至不会到达 Web Api 端点,因为 URL 也是 Unicode 并且它尝试调用http: //localhost 而不是http://localhost。
我无法使用 WebRequest,因为它仅限于端口 80 和 443。我的端口(至少用于测试)是 27408。
任何人都可以帮助我们完成这项工作吗?
解决方案
推荐阅读
- gwt - 如何根据 GWT 中另一个中的选择填充一个下拉列表?
- junit - 如何在测试用例 HTTP 方法 URL 中访问变量值
- postgresql - 如何将“YYYY-DD-MM HH:MI:SS.MS +00:00”形式的字符串转换为postgres timestamptz,其中最后四个字符是时区偏移量?
- scala - 使用 scala spark 将固定宽度的文件插入 Hive
- azure - Azure IoT 中心 - 数据可视化教程 - 未显示数据
- ios - 当应用程序未运行即被终止或暂停时,如何获取用户的当前位置并发送到 iOS 应用程序中的服务器?
- swift - 使用 SearchController 推送 ViewController 在搜索栏下显示黑色矩形
- gcc - STM32H743 微控制器 (Cortex-M7) 的链接脚本中是否使用了所有 RAM 部分?
- javascript - 伊斯坦布尔覆盖与 mocha 测试用例仅显示规范文件(测试文件)的覆盖率报告
- ios - CAGradientLayer 未应用于整个屏幕