//+------------------------------------------------------------------+
//| 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 VARSUFFIX "--->" // Ìæ»»±äÁ¿ºó׺
#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, "</tr>");
}
}
}
// ===== дÈë¹Òµ¥Áбí =====
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, "<td class=msdate nowrap>" + str + "</td>");
WriteComment(OutFile);
FileWrite(OutFile, "</tr>");
}
}
}
// ===== дÈëÀúÊ·½»Ò×µ¥ =====
void WriteClosedOrders(int OutFile)
{
int i, c, end, op, d;
string symb, str = "";
datetime StartTime, OpenTime;
// ¼ÆËãÊä³ö¶àÉÙÌõÀúÊ·¼Ç¼
if (HistoryPeriod == 0)
end = OrdersHistoryTotal() - HistoryNum;
else
{
end = 0;
StartTime = GetStartTime(TimeCurrent());
}
for (i = OrdersHistoryTotal() - 1, c = 0; i >= 0; i--)
{
OrderSelect(i, SELECT_BY_POS, MODE_HISTORY);
OpenTime = OrderOpenTime();
if ((HistoryPeriod != 0) && (OpenTime < StartTime))
break;
op = OrderType();
if (op < 2)
{
c++;
symb = OrderSymbol();
d = MarketInfo(symb, MODE_DIGITS);
WriteLeftColums(OutFile, c, op, symb, d);
// ƽ²Öʱ¼ä¼°Æ½²Ö¼Û
FileWrite(OutFile, "<td class=msdate nowrap>" + TimeToStr(OrderCloseTime()) + "</td>");
FileWrite(OutFile, "<td>" + DoubleToStr(OrderClosePrice(), d) + "</td>");
WriteSwapProfit(OutFile, op, symb);
WriteComment(OutFile);
FileWrite(OutFile, "</tr>");
}
}
}
// ===== дÈëǰ°ë²¿·Ö =====
void WriteLeftColums(int OutFile, int c, int op, string symb, int d)
{
string str, str2;
int i, p, cl;
double SL, TP;
// µÚÒ»ÐУ¬Ðб³¾°É«
if (c % 2 == 1)
str = ">";
else
str = " bgcolor=#E0E0E0>";
FileWrite(OutFile, "<tr align=right" + str);
// Ticket
if (ShowTicket)
str = OrderTicket();
else
str = HiddenText;
FileWrite(OutFile, "<td>" + str + "</td>");
// ½»Ò×»õ±Ò¶ÔºÍ¿ª²Ö·½Ïò
FileWrite(OutFile, "<td>" + symb + "</td>");
FileWrite(OutFile, "<td>" + OpStr[op] + "</td>");
// ¿ª²ÖÊÖÊý
if (ShowSize)
str = DoubleToStr(OrderLots(), 2);
else
str = HiddenText;
FileWrite(OutFile, "<td class=mspt>" + str + "</td>");
// ¿ª²Öʱ¼ä
if (ShowOpenTime)
str = TimeToStr(OrderOpenTime());
else
str = HiddenText;
FileWrite(OutFile, "<td class=msdate nowrap>" + str + "</td>");
// ¿ª²Ö¼Û
FileWrite(OutFile, "<td>" + DoubleToStr(OrderOpenPrice(), d) + "</td>");
// »ñÀûÖ¹Ëð¼Û
if (ShowTPSL)
{
SL = OrderStopLoss();
TP = OrderTakeProfit();
if (OrderCloseTime() > 0) // ÒѾƽ²ÖµÄµ¥×Ó
{
p = MathPow(10, d);
cl = OrderClosePrice() * p;
if (cl == SL * p) // Ö¹Ëðµ¥
str = " bgcolor=\"#FFA0A0\">";
else
str = ">";
if (cl == TP * p) // Ö¹Ó®µ¥
str2 = " bgcolor=\"#60F060\">";
else
str2 = ">";
}
else
{
str = ">";
str2 = ">";
}
str = str + DoubleToStr(SL, d);
str2 = str2 + DoubleToStr(TP, d);
}
else
{
str = ">" + HiddenText;
str2 = ">" + HiddenText;
}
FileWrite(OutFile, "<td" + str + "</td>");
FileWrite(OutFile, "<td" + str2 + "</td>");
}
// ===== дÈëÀûÏ¢ºÍ»ñÀû =====
void WriteSwapProfit(int OutFile, int op, string symb)
{
double cp;
string str;
// ¸ôÒ¹ÀûÏ¢
if (ShowSwap)
str = DoubleToStr(OrderSwap(), 2);
else
str = HiddenText;
FileWrite(OutFile, "<td class=mspt>" + str + "</td>");
// Ȗ˞
switch (ShowProfitType)
{
case 0 :
str = ">" + HiddenText;
break;
case 1 :
if (op == OP_BUY)
cp = MarketInfo(symb, MODE_BID);
else
cp = MarketInfo(symb, MODE_ASK);
str = ">" + DoubleToStr((cp - OrderOpenPrice()) / MarketInfo(symb, MODE_POINT), 0) + "p";
break;
case 2 :
str = " class=mspt>" + DoubleToStr(OrderProfit(), 2);
}
FileWrite(OutFile, "<td" + str + "</td>");
}
// ===== дÈë×¢ÊÍ =====
void WriteComment(int OutFile)
{
string str;
str = OrderComment();
if (!ShowComment && (StringLen(str) > 0))
str = HiddenText;
FileWrite(OutFile, "<td>" + str + "</td>");
}
// ===== ¼ì²é³Ö²ÖÓÐûÓб仯 =====
bool CheckOrderChange()
{
int LastOrdersHash, CurrnetOrdersHash;
LastOrdersHash = GlobalVariableGet(GVARHASH);
CurrnetOrdersHash = GetOrdersHash(OrdersTotal());
if (CurrnetOrdersHash != LastOrdersHash)
{
GlobalVariableSet(GVARHASH, CurrnetOrdersHash);
return(true);
}
else
return(false);
}
// ===== ¼ÆË㵱ǰ³Ö²ÖµÄHash =====
int GetOrdersHash(int OrdersCount)
{
int Orders[][ORDERPART], i, j, k, Hash = 0;
string OrderSymb, str;
ArrayResize(Orders, OrdersCount);
// ½«³Ö²Öת»¯³ÉÕûÊý
for (i = 0; i < OrdersCount; i++)
{
OrderSelect(i, SELECT_BY_POS);
OrderSymb = OrderSymbol();
k = MarketInfo(OrderSymb, MODE_POINT);
Orders[i][0] = OrderTicket();
Orders[i][1] = SymbolToInt(OrderSymb);
Orders[i][2] = OrderType() << 24 + OrderLots() * 100;
Orders[i][3] = OrderOpenPrice() / k;
Orders[i][4] = OrderTakeProfit() / k;
Orders[i][5] = OrderStopLoss() / k;
Orders[i][6] = OrderSwap() * 100;
}
if (OrdersCount > 0)
{
ArraySort(Orders);
// ¼ÆËãHashÖµ
for (i = 0; i < OrdersCount; i++)
for (j = 0; j < ORDERPART; j++)
for (k = 3; k >= 0; k--)
Hash += (Hash << 5) + ((Orders[i][j] >> (k * 8)) & 0xFF);
}
return(Hash);
}
// ==== ¼ÆËãÀúÊ·³Ö²ÖÆðʼʱ¼ä ====
datetime GetStartTime(datetime EndTime)
{
datetime StartTime;
int y, m, d;
switch (HistoryPeriod)
{
case 1 :
StartTime = EndTime - (HistoryNum - 1) * DAYSECOND;
break;
case 2 :
StartTime = EndTime - HistoryNum * 7 * DAYSECOND;
while (TimeDayOfWeek(StartTime) > 0)
StartTime += DAYSECOND;
break;
case 3 :
StartTime = EndTime - (HistoryNum - 1) * 30 * DAYSECOND;
}
y = TimeYear(StartTime);
m = TimeMonth(StartTime);
if (HistoryPeriod == 3)
d = 1;
else
d = TimeDay(StartTime);
StartTime = StrToTime(y + "." + m + "." + d);
return(StartTime);
}
// ===== °Ñ»õ±Ò¶Ôת»»³ÉÕûÐÎ =====
int SymbolToInt(string Symb)
{
int i, r;
for (r = 0, i = 0; i < StringLen(Symb); i++)
r += r << 5 + StringGetChar(Symb, i);
return(r);
}
Comments