//+------------------------------------------------------------------+ //| Publisher.mq4 | //| Greatshore | //| greatshore@live.cn | //+------------------------------------------------------------------+ #property copyright "Greatshore" #property link "greatshore@live.cn" #define GVARUP "Publisher_UpdateTime" // 更新时间全局变量名 #define GVARHASH "Publisher_LastOrdersHash" // 上一次持仓的Hash #define DATAPATH "Publisher\\" // 数据文件目录 #define VARPREFIX "" // 替换变量后缀 #define REALSTR "$" // 显示真实值标记 #define DAYSECOND 86400 // 每天多少秒 #define ORDERPART 7 // 每个持仓项目数 //---- input parameters extern int UpdatePeriod = 15; // 更新周期,分钟,最少5分钟,0表示持仓有变化即更新 extern bool ShowPending = true; // 是否显示挂单信息 extern int HistoryNum = 1; // 历史交易单周期数目 extern int HistoryPeriod = 2; // 历史交易单周期单位,0-个,1-天, 2-周,3-月 extern int TZOffset = 6; // 服务器时区换算 extern string TZComment = "Beijing Time:"; // 时间标注 extern string FTPPath = "/forexbot"; // 上传到服务器的目录 extern string WebFileName = "state.htm"; // 上传到服务器的文件名 extern string TemplateName = "Publisher.template.htm"; // 发布页面使用的模版文件名 extern string ShowAccount = "$"; // 显示的账户号,$表示实际账户 extern string ShowName = "$"; // 显示的账户名,$表示实际账户名 extern string ShowBroker = "$"; // 显示的公司名,$表示实际公司名 extern bool ShowTicket = true; // 是否显示订单号 extern bool ShowOpenTime = true; // 是否显示开仓时间 extern bool ShowSize = true; // 是否显示手数 extern bool ShowTPSL = true; // 是否显示获利止损价 extern bool ShowSwap = true; // 是否显示过夜利息 extern int ShowProfitType = 2; // 显示获利方式:0-不显示,1-点数,2-价值 extern bool ShowComment = false; // 是否显示注释项 extern bool ShowEquity = true; // 是否显示账户净值 extern bool ShowFreeMargin = true; // 是否显示自由保证金数 extern string HiddenText = "---"; // 隐藏值显示字符 string OpStr[] = {"buy", "sell", "buy limit", "sell limit", "buy stop", "sell stop"}; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { if (!ShowSize) // 如果不显示持仓手数,则隔夜利息和获利都不能显示 { ShowSwap = false; if (ShowProfitType == 2) ShowProfitType = 1; } if ((UpdatePeriod < 5) && (UpdatePeriod > 0)) UpdatePeriod = 5; return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { GlobalVariableDel(GVARUP); GlobalVariableDel(GVARHASH); return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { datetime LastUpdate, CurrentTime; bool NeedUpdate; CurrentTime = TimeCurrent(); LastUpdate = GlobalVariableGet(GVARUP); if (UpdatePeriod == 0) NeedUpdate = CheckOrderChange(); else NeedUpdate = (CurrentTime - LastUpdate) / 60 >= UpdatePeriod; if (NeedUpdate) { GlobalVariableSet(GVARUP, CurrentTime); GeneratePage(DATAPATH + WebFileName); SendFTP(DATAPATH + WebFileName, FTPPath); FileDelete(DATAPATH + WebFileName); } return(0); } //+------------------------------------------------------------------+ // ===== 生成持仓报告页面 ===== void GeneratePage(string FileName) { int fin, fout, i, j; string linestr; fin = FileOpen(DATAPATH + TemplateName, FILE_READ | FILE_BIN); if (fin < 0) Print("Error in reading template file."); else { fout = FileOpen(DATAPATH + WebFileName, FILE_WRITE | FILE_CSV, ' '); while (!FileIsEnding(fin)) { linestr = GetOneLine(fin); if (StringLen(linestr) > 0) { i = StringFind(linestr, VARPREFIX); if (i >= 0) ReplaceVarStr(fout, linestr, i); else FileWrite(fout, linestr); } } FileClose(fin); FileClose(fout); } } // ===== 从文件中读取一行 ===== string GetOneLine(int InFile) { int i, j; string ret, char; ret = ""; while (!FileIsEnding(InFile)) { char = FileReadString(InFile, 1); if ((char == "\r") || (char == "\n")) break; else ret = ret + char; } return(ret); } // ===== 替换变量字符串的内容 ===== void ReplaceVarStr(int OutFile, string linestr, int start) { string VarName, LeftStr, RightStr, MidStr; int end, i; end = StringFind(linestr, VARSUFFIX, start); i = start + StringLen(VARPREFIX); if (start > 0) LeftStr = StringSubstr(linestr, 0, start); RightStr = StringSubstr(linestr, end + StringLen(VARSUFFIX)); MidStr = ""; VarName = StringSubstr(linestr, i, end - i); if (VarName == "ACCOUNTNUM") // 账户号码 { if (ShowAccount == REALSTR) MidStr = AccountNumber(); else MidStr = ShowAccount; } else if (VarName == "ACCOUNTNAME") // 账户名称 { if (ShowName == REALSTR) MidStr = AccountName(); else MidStr = ShowName; } else if (VarName == "BROKER") // 公司名 { if (ShowBroker == REALSTR) MidStr = AccountCompany(); else MidStr = ShowBroker; } else if (VarName == "CURRENCY") // 账户货币 MidStr = AccountCurrency(); else if (VarName == "EQUITY") // 账户净值 { if (ShowEquity) MidStr = DoubleToStr(AccountEquity(), 2); else MidStr = HiddenText; } else if (VarName == "FREEMARGIN") // 可用保证金 { if (ShowFreeMargin) MidStr = DoubleToStr(AccountFreeMargin(), 2); else MidStr = HiddenText; } else if (VarName == "UPDATETIME") // 更新时间 { MidStr = TimeToStr(TimeCurrent()); if ((TZOffset != 0) && (StringLen(TZComment) > 0)) MidStr = MidStr + " [" + TZComment + TimeToStr(TimeCurrent() + TZOffset * 3600) + "]"; } else if (VarName == "HISTORYPERIOD") // 历史单周期 { if (HistoryNum > 0) { MidStr = " last " + HistoryNum; switch (HistoryPeriod) { case 0 : MidStr = MidStr + " order"; break; case 1 : MidStr = MidStr + " day"; break; case 2 : MidStr = MidStr + " week"; break; case 3 : MidStr = MidStr + " month"; } if (HistoryNum > 1) MidStr = MidStr + "s"; } else MidStr = ""; } else if (VarName == "HOLDINGORDERS") // 持仓列表 WriteHoldingOrders(OutFile); else if ((VarName == "PENDINGORDERS") && ShowPending) // 挂单列表 WritePendingOrders(OutFile); else if ((VarName == "CLOSEDORDERS") && (HistoryNum > 0)) // 历史交易单列表 WriteClosedOrders(OutFile); else MidStr = HiddenText; FileWrite(OutFile, LeftStr+ MidStr + RightStr); } // ===== 写入持仓列表 ===== void WriteHoldingOrders(int OutFile) { int i, c, op; string symb; for (i = 0, c = 0; i < OrdersTotal(); i++) { OrderSelect(i, SELECT_BY_POS); op = OrderType(); if (op < 2) { symb = OrderSymbol(); c++; WriteLeftColums(OutFile, c, op, symb, MarketInfo(symb, MODE_DIGITS)); WriteSwapProfit(OutFile, op, symb); WriteComment(OutFile); FileWrite(OutFile, ""); } } } // ===== 写入挂单列表 ===== void WritePendingOrders(int OutFile) { int i, c, op; string symb, str = ""; datetime exp; for (i = 0, c = 0; i < OrdersTotal(); i++) { OrderSelect(i, SELECT_BY_POS); op = OrderType(); if (op > 1) { symb = OrderSymbol(); c++; WriteLeftColums(OutFile, c, op, symb, MarketInfo(symb, MODE_DIGITS)); exp = OrderExpiration(); // 过期时间 if (exp > 0) str = TimeToStr(exp); FileWrite(OutFile, "