Orders Execution
Miscellaneous
0
Views
0
Downloads
0
Favorites
Trade-Arbitrage
#property show_inputs
#include <stdlib.mqh> // string ErrorDescription(int error_code);
#define PAUSE 100 // Ïàóçà â ìèëëèñåêóíäàõ ìåæäó ðàñ÷åòàìè
#define ALPHA 0.001 // Äëÿ ñðàâíåíèÿ îáúåìîâ
#define STR_SHABLON "<!--STR-->"
#define MAX_CURRENCY 20 // Ìàêñèìàëüíîå êîëè÷åñòâî âàëþò (íå ïàð)
#define MAX_REALSYMBOLS 380 // Ìàêñèìàëüíîå êîëè÷åñâî ó÷èòûâàåìûõ ðåàëüíûõ ñèâîëîâ èç Market Watch (== (MAX_CURRENCY * (MAX_CURRENCY - 1)))
#define MAX_ALLSYMBOLS 380 // Ìàêñèìàëüíîå êîëè÷åñòâî âîçìîæíûõ ñèìâîëîâ (== (MAX_CURRENCY * (MAX_CURRENCY - 1)))
#define MAX_VARIANTSYMBOLS 74 // Ìàêñèìàëüíîå êîëè÷åñòâî âàðèàíòîâ ïîëó÷åíèÿ ñèìâîëà (== (4 * MAX_CURRENCY - 6))
#define MAX_VARIANTPAIRS 5402 // Ìàêñèìàëüíîå êîëè÷åñòâî ñî÷åòàíèé ïàð ñèìâîëîâ (== (MAX_VARIANTSYMBOLS * (MAX_VARIANTSYMBOLS - 1))
extern string Currencies = "AUD, EUR, USD, CHF, JPY, NZD, GBP, CAD, SGD, NOK, SEK, DKK, ZAR, MXN, HKD, HUF, CZK, PLN, RUR, TRY";
extern double MinPips = 0.5; // Ìèíèìàëüíàÿ ó÷èòûâàåìàÿ ðàçíèöà àðáèòðàæà â "ñòàðûõ" ïóíêòàõ
extern int SlipPage = 0; // Äîïóñòèìûé SlipPage äëÿ Market-çàïðîñîâ (íå âñåãäà ðàáîòàåò)
extern bool Lock = FALSE; // Ðàçðåøàòü ëîêè èëè íåò
extern double Lots = 1; // Îáúåì ïîçèöèè ïî ñãåíåðèðîâàííîìó ñèìâîëó
extern double MaxLot = 20; //
extern double MinLot = 0.1; // Íåîáõîäèìî çàäàâàòü èç-çà íåêîððåêòíîãî âîçâðàùàåìîãî çíå÷åíèÿ MarketInfo
extern bool Monitoring = TRUE; // Ïðîèçâîäèòü çàïèñü âñåõ ñëó÷àþùèõñÿ àðáèòðàæåé â ôàéë èëè íåò (çàïèñü çàíèìàåò âðåìÿ, êîòîðîå êðèòè÷íî äëÿ àðáèòðàæà)
extern int TimeToWrite = 5; // ×åðåç êàêîå âðåìÿ (â ìèíóòàõ) áóäóò çàïèñûâàòüñÿ â ôàéë ñòàòèñòè÷åñêèå äàííûå îá àðáèòðàæå
int DigitsLot; // Êîëè÷åñòâî öèôð ïîñëå çàïÿòîé â äåñÿòè÷íîé çàïèñè ëîòîâ
string SymbolPrefix = ""; // Ïðåôèêñ, êîòîðûé äîáàâëåí â Market Watch ïîñëå ñòàíäàðòíîãî íàïèñàíèÿ ïàðû
string Shablon = "<!--STR-->, <!--STR-->"; // Øàáëîí äëÿ âûäèðàíèÿ ÷åãî óãîäíî èç ñòðîêè. Íóæåí äëÿ Currencies
int AmountCurrency; // Îáùåå êîëè÷åñòâî ó÷èòûâàåìûõ âàëþò
string Currency[MAX_CURRENCY]; // Ó÷èòûâàåìûå âàëþòû
int AmountRealSymbols; // Îáùåå êîëè÷åñòâî ó÷èòûâàåìûõ ðåàëüíûõ ñèìâîëîâ èç Market Watch
string RealSymbols[MAX_REALSYMBOLS]; // Õðàíèò ñòàíäàðòíûå (áåç ïðåôèêñîâ) íàçâàíèÿ ðåàëüíûõ ñèìâîëîâ èç Market Watch
string REALSymbols[MAX_REALSYMBOLS]; // Õðàíèò ÐÅÀËÜÍÛÅ (ñ ó÷åòîì ïðåôèêñîâ) íàçâàíèÿ ðåàëüíûõ ñèìâîëîâ èç Market Watch
int AmountAllSymbols; // Îáùåå êîëè÷åñòâî ñãåíåðèðîâàííûõ ïàð (ðåàëüíûå + èñêóññòâåííûå)
int AllSymbols[MAX_ALLSYMBOLS][MAX_VARIANTSYMBOLS]; // [k][m] - õðàíèò íîìåðà ðåàëüíûõ ñèìâîëîâ äëÿ ñîçäàíèÿ k-ãî ñèìâîëà
int Math[MAX_ALLSYMBOLS][MAX_VARIANTSYMBOLS]; // [k][m] - õðàíèò ìàò. äåéñòâèå ñîçäàíèÿ k-ãî ñèìâîëà èç m-õ ðåàëüíûõ ñèìâîëîâ
int Count[MAX_ALLSYMBOLS]; // [k] - êîëè÷åñòâî âàðèàíòîâ ïîëó÷åíèÿ k-ãî ñèìâîëà.
double PointD[MAX_ALLSYMBOLS]; // [k] - õðàíèò ðàçìåð (ñòàðîãî) ïóíêòà k-ãî ñèìâîëà
double MinPipsD[MAX_ALLSYMBOLS]; // [k] - õðàíèò MinPips ñòàðûõ ïóíêòîâ k-ãî ñèìâîëà
double Bids[MAX_ALLSYMBOLS][MAX_VARIANTSYMBOLS]; // [k][m] - õðàíèò Bid ê-ãî ñèìâîëà ïîëó÷åííîãî èç m-õ ðåàëüíûõ ñèìâîëîâ
double Asks[MAX_ALLSYMBOLS][MAX_VARIANTSYMBOLS]; // [k][m] - õðàíèò Ask ê-ãî ñèìâîëà ïîëó÷åííîãî èç m-õ ðåàëüíûõ ñèìâîëîâ
double BidsReal[MAX_REALSYMBOLS]; // Bid-öåíû ðåàëüíûõ ñèìâîëîâ
double AsksReal[MAX_REALSYMBOLS]; // Ask-öåíû ðåàëüíûõ ñèìâîëîâ
double Position[MAX_REALSYMBOLS]; // Õðàíèò íàïðàâëåíèÿ è îáúåì ðåàëüíûõ ñèìâîëîâ äëÿ îòêðûòèÿ
double XPosition[MAX_ALLSYMBOLS][MAX_VARIANTPAIRS]; // [k][] - Õðàíèò àðáèòðàæíîå íàïðàâëåíèå (+/-) è îáúåì ñðàçó äâóõ âàðèàíòîâ ïîëó÷åíèÿ k-ãî ñèìâîëà
bool XTrade[MAX_ALLSYMBOLS][MAX_VARIANTPAIRS]; // [k][] - Õðàíèò ðàçðåøåíèå/çàïðåò íà îñóùåñòâëåíèå àðáèòðàæà ìåæäó äâóìÿ âàðèàíòàìè ïîëó÷åíèÿ k-ãî ñèìâîëà
// Äëÿ ñáîðà ñòàòèñòèêè
int CountArbitrage[MAX_ALLSYMBOLS][MAX_VARIANTPAIRS]; // [k][] - Õðàíèò êîëè÷åñòâî àðáèòðàæíåé ñðàçó äâóõ âàðèàíòîâ ïîëó÷åíèÿ k-ãî ñèìâîëà
int MaxCountArbitrage;
int PrevTime, CurrentTime; // Ïðåäûäóùåå (äëÿ çàïèñè ñòàòèñòèêè) è êðàéíåå âðåìÿ ñåðâåðà
string StrOut = ""; // Âûâîä â ëîã
//------------------------------------------------------------------------------------------------------------------------------
/************************************************* BEGIN BLOCK_1 *************************************************/
// ÁËÎÊ ÔÓÍÊÖÈÉ, ÈÑÏÎËÜÇÓÞÙÈÕÑß Â ÎÑÍÎÂÍÎÌ ÄËß ÈÍÈÖÈÀËÈÇÀÖÈÈ:
// string StrDelSpaces( string Str );
// int StrToStringS( string Str, string Razdelitel, string &Output[] );
// bool RealSymbol( string Str );
// void GetRealSymbols();
// int GetNumRealSymbol( string Str );
// void GetAllSymbols();
// void GetRealBidAsk();
// string SymbolToStr( int i, int j );
// void GetDataLot( string Symb );
// void GetSymbolPrefix( string Symb );
// void GetXTrade( string FileName );
// void GetPipsD();
// void InitArbitrage();
// void PrintXTrade();
// void PrintBeginInfo();
/************************************************* BEGIN BLOCK_1 *************************************************/
string StrDelSpaces( string Str )
{
int Pos, Length;
Str = StringTrimLeft(Str);
Str = StringTrimRight(Str);
Length = StringLen(Str) - 1;
Pos = 1;
while (Pos < Length)
if (StringGetChar(Str, Pos) == ' ')
{
Str = StringSubstr(Str, 0, Pos) + StringSubstr(Str, Pos + 1, 0);
Length--;
}
else
Pos++;
return(Str);
}
int StrToStringS( string Str, string Razdelitel, string &Output[] )
{
int Pos, LengthSh;
int Count = 0;
Str = StrDelSpaces(Str);
Razdelitel = StrDelSpaces(Razdelitel);
LengthSh = StringLen(Razdelitel);
while (TRUE)
{
Pos = StringFind(Str, Razdelitel);
Output[Count] = StringSubstr(Str, 0, Pos);
Count++;
if (Pos == -1)
break;
Pos += LengthSh;
Str = StringSubstr(Str, Pos);
}
return(Count);
}
// Ïðîâåðêà íà ðåàëüíîñòü (åñòü ëè â Market Watch) ñèìâîëà
// Âîçâðàùàåò: TRUE - ðåàëüíûé, FALSE - èñêóññòâåííûé
bool RealSymbol( string Str )
{
return(MarketInfo(Str + SymbolPrefix, MODE_BID) != 0);
}
// Ïîëó÷àåò â RealSymbols[] âñå ó÷èòûâàåìûå ðåàëüíûå ñèìâîëû èç Market Watch
void GetRealSymbols()
{
int i, j;
string Str;
AmountRealSymbols = 0;
for (i = 0; i < AmountCurrency; i++)
for (j = 0; j < AmountCurrency; j++)
if (i != j) // ïàðû äîëæíû áûòü èç ðàçíûõ âàëþò
{
Str = Currency[i] + Currency[j]; // îáðàçóåì ðàçëè÷íûå êîìáèíàöèè ïàð
if (RealSymbol(Str))
{
RealSymbols[AmountRealSymbols] = Str;
REALSymbols[AmountRealSymbols] = Str + SymbolPrefix; // â äàëüíåéøåì ïîíàäîáèòñÿ äëÿ óñêîðåíèÿ ðàñ÷åòîâ
AmountRealSymbols++;
}
}
return;
}
// Âîçâðàùàåò íîìåð ïîçèöèè, ãäå íàõîäèòñÿ ñèìâîë Str â RealSymbols[]. Ïðè íåóäà÷å âîçâðàùàåò -1.
int GetNumRealSymbol( string Str )
{
int i;
for (i = 0; i < AmountRealSymbols; i++)
if (RealSymbols[i] == Str)
return(i);
return(-1);
}
// Ïîëó÷àåò â AllSymbols[][] âàðèàíòû ñãåíåðèðîâàííûõ ïàð
void GetAllSymbols()
{
int i, j, k, m;
string Str, Str1[4], Str2[4];
AmountAllSymbols = 0; // èíèöèàëèçèðîâàëè êîëè÷åñòâî ó÷èòûâàåìûõ ñãåíåðèðîâàííûõ ïàð
for (i = 0; i < MAX_ALLSYMBOLS; i++)
Count[i] = 0; // èíèöèàëèçèðîâàëè êîëè÷åñòâî âàðèàíòîâ ïîëó÷åíèÿ ó÷èòûâàåìûõ ñãåíåðèðîâàííûõ ïàð
for (i = 0; i < AmountCurrency; i++) // Ñòðîèì ïàðó èìåííî ij (íå íàîáîðîò!!!)
for (j = 0; j < AmountCurrency; j++)
if (i != j) // Ïàðà äîëæíà ñîñòîÿòü èç ðàçíûõ âàëþò
{
Str = Currency[i] + Currency[j]; // Ñîçäàëè ïàðó ij
if (RealSymbol(Str)) // Åñëè ïàðà ðåàëüíàÿ, òî (ïåðâûé) âàðèàíò åå ïîëó÷åíèÿ - îíà ñàìà.
{
AllSymbols[AmountAllSymbols][Count[AmountAllSymbols]] = GetNumRealSymbol(Str);
Math[AmountAllSymbols][Count[AmountAllSymbols]] = -1; // -2 - "1 / S"; -1 - "S"; 0 - "S1 / S2"; 1 - "S1 * S2"; 2 - "1 / (S1 * S2)"; 3 - "S2 / S1"
Count[AmountAllSymbols]++;
}
Str = Currency[j] + Currency[i]; // Ñîçäàëè îáðàòíóþ ïàðó - ji
if (RealSymbol(Str)) // Åñëè îáðàòíàÿ ïàðà ðåàëüíàÿ, òî âàðèàíò ïîëó÷åíèÿ ïðÿìîé ïàðû - 1 / îáðàòíóþ.
{
AllSymbols[AmountAllSymbols][Count[AmountAllSymbols]] = GetNumRealSymbol(Str);
Math[AmountAllSymbols][Count[AmountAllSymbols]] = -2; // -2 - "1 / S"; -1 - "S"; 0 - "S1 / S2"; 1 - "S1 * S2"; 2 - "1 / (S1 * S2)"; 3 - "S2 / S1"
Count[AmountAllSymbols]++;
}
for (k = 0; k < AmountCurrency; k++)
if ((k != i) && (k != j))
{
// Îñòàëîñü ïðîâåðèòü 4-å âàðèàíòà ïîëó÷åíèÿ ij-ïàðû
Str1[0] = Currency[i] + Currency[k];
Str1[1] = Currency[i] + Currency[k];
Str1[2] = Currency[k] + Currency[i];
Str1[3] = Currency[k] + Currency[i];
Str2[0] = Currency[j] + Currency[k];
Str2[1] = Currency[k] + Currency[j];
Str2[2] = Currency[j] + Currency[k];
Str2[3] = Currency[k] + Currency[j];
for (m = 0; m < 4; m++)
if (RealSymbol(Str1[m]) && RealSymbol(Str2[m]))
{
// Òàêîé ñïîñîá õðàíåíèÿ ñðàçó äâóõ ïàð (Str1 è Str2) îäíèì ÷èñëîì
AllSymbols[AmountAllSymbols][Count[AmountAllSymbols]] = GetNumRealSymbol(Str1[m]) * AmountRealSymbols + GetNumRealSymbol(Str2[m]);
Math[AmountAllSymbols][Count[AmountAllSymbols]] = m; // 0 - "S1 / S2"; 1 - "S1 * S2"; 2 - "1 / (S1 * S2)"; 3 - "S2 / S1"
Count[AmountAllSymbols]++;
}
}
if (Count[AmountAllSymbols] >= 2) // Åñëè âàðèàíòîâ ïîëó÷åíèÿ ij-ïàðû íå ìåíüøå äâóõ
// (îïòèìèçàöèÿ äëÿ âàðèàíòà àðáèòðàæíîãî èñïîëüçîâàíèÿ, èíà÷å - ïðîâåðêà íà >= 1),
// ó÷èòûâàåì ýòó ïàðó äàëüøå
AmountAllSymbols++; // Óâåëè÷èëè êîëè÷åñòâî ó÷èòûâàåìûõ ñãåíåðèðîâàííûõ ïàð
else // Èíà÷å - íå ó÷èòûâàåì
Count[AmountAllSymbols] = 0;
}
return;
}
void GetRealBidAsk()
{
for (int i = 0; i < AmountRealSymbols; i++)
{
BidsReal[i] = MarketInfo(REALSymbols[i], MODE_BID);
AsksReal[i] = MarketInfo(REALSymbols[i], MODE_ASK);
}
return;
}
// Âîçâðàùàåò íàçâàíèå j-ãî âàðèàíòà ïîëó÷åíèÿ i-ãî ñãåíåðèðîâàííîãî ñèìâîëà
string SymbolToStr( int i, int j )
{
string Str = "", S1, S2;
if (Math[i][j] == -1) //
Str = RealSymbols[AllSymbols[i][j]];
else if (Math[i][j] == -2)
Str = "1 / " + RealSymbols[AllSymbols[i][j]];
else
{
S1 = RealSymbols[AllSymbols[i][j] / AmountRealSymbols]; // ïîëó÷èëè íàçâàíèå ïåðâîé ïàðû
S2 = RealSymbols[AllSymbols[i][j] % AmountRealSymbols]; // ïîëó÷èëè íàçâàíèå âòîðîé ïàðû
switch (Math[i][j])
{
case 0: // 0 - "S1 / S2"
Str = S1 + " / " + S2;
break;
case 1: // 1 - "S1 * S2"
Str = S1 + " * " + S2;
break;
case 2: // 2 - "1 / (S1 * S2)";
Str = "1 / (" + S1 + " * " + S2 + ")";
break;
case 3: // 3 - "S2 / S1"
Str = S2 + " / " + S1;
break;
}
}
return(Str);
}
void GetDataLot( string Symb )
{
int Tmp = 1 / MarketInfo(Symb, MODE_LOTSTEP) + 0.1;
Tmp /= 10;
DigitsLot = 0;
while (Tmp > 0)
{
DigitsLot++;
Tmp /= 10;
}
if (MaxLot > MarketInfo(Symb, MODE_MAXLOT))
MaxLot = MarketInfo(Symb, MODE_MAXLOT);
if (MinLot < MarketInfo(Symb, MODE_MINLOT))
MinLot = MarketInfo(Symb, MODE_MINLOT);
if (MinLot > MarketInfo(Symb, MODE_LOTSTEP) + ALPHA)
Alert(WindowExpertName(), " - WARNING: MinLot (", MinLot, ") > LotStep (", MarketInfo(Symb, MODE_MINLOT), ")");
return;
}
void GetSymbolPrefix( string Symb )
{
SymbolPrefix = StringSubstr(Symb, 6);
return;
}
// Îïðåäåëåíèå àðáèòðàæíûõ ñèìâîëîâ äëÿ òîðãîâëè
void GetXTrade( string FileName )
{
int i, j, k, m, Pos;
int handle;
int AmountStrings = 0;
string Str1, Str2, Str3, Str[MAX_VARIANTPAIRS];
handle = FileOpen(FileName, FILE_READ);
while (!FileIsEnding(handle))
{
Str[AmountStrings] = FileReadString(handle);
AmountStrings++;
}
FileClose(handle);
for (i = 0; i < AmountAllSymbols; i++)
{
Pos = 0;
for (j = 0; j < Count[i] - 1; j++)
{
Str1 = SymbolToStr(i, j);
Pos += j + 1;
for (k = j + 1; k < Count[i]; k++)
{
Str2 = Str1 + " && " + SymbolToStr(i, k);
Str3 = SymbolToStr(i, k) + " && " + Str1;
for (m = 0; m < AmountStrings; m++)
if ((Str[m] == Str2) || (Str[m] == Str3))
break;
if (m == AmountStrings)
XTrade[i][Pos] = FALSE;
else
XTrade[i][Pos] = TRUE;
XPosition[i][Pos] = 0;
CountArbitrage[i][Pos] = 0;
Pos++;
}
}
}
return;
}
void GetPipsD()
{
GetRealBidAsk();
for (int i = 0; i < AmountAllSymbols; i++)
{
GetBidAsk(i, 0);
// Îïðåäåëÿåì ðàçìåð (ñòàðîãî) ïóíêòà
if (Bids[i][0] > 10)
{
PointD[i] = 0.01;
MinPipsD[i] = MinPips * 0.01;
}
else
{
PointD[i] = 0.0001;
MinPipsD[i] = MinPips * 0.0001;
}
}
return;
}
void InitArbitrage()
{
GetDataLot(Symbol());
GetSymbolPrefix(Symbol());
AmountCurrency = StrToStringS(Currencies, ",", Currency);
GetRealSymbols();
GetAllSymbols();
GetPipsD();
MaxCountArbitrage = 0;
for (int i = 0; i < AmountRealSymbols; i++)
Position[i] = 0;
GetXTrade("Trade-Arbitrage.txt");
return;
}
void PrintXTrade()
{
int i, j, k, Pos;
for (i = 0; i < AmountAllSymbols; i++)
{
Pos = 0;
for (j = 0; j < Count[i] - 1; j++)
{
Pos += j + 1;
for (k = j + 1; k < Count[i]; k++)
{
if (XTrade[i][Pos])
Print(SymbolToStr(i, j) + " && " + SymbolToStr(i, k));
Pos++;
}
}
}
return;
}
void PrintBeginInfo()
{
int i, Max;
Print("MAX_CURRENCY = " + AmountCurrency);
Print("MAX_REALSYMBOLS = " + AmountRealSymbols);
Print("MAX_ALLSYMBOLS = " + AmountAllSymbols);
Max = 0;
for (i = 0; i < AmountAllSymbols; i++)
if (Count[i] > Max)
Max = Count[i];
Print("MAX_VARIANTSYMBOLS = " + Max);
Max = 0;
for (i = 0; i < AmountAllSymbols; i++)
if (Count[i] * (Count[i] - 1) > Max)
Max = Count[i] * (Count[i] - 1);
Print("MAX_VARIANTPAIRS = " + Max);
Max = 0;
for (i = 0; i < AmountAllSymbols; i++)
Max += Count[i];
Print("SumAllCounts = " + Max);
Max = 0;
for (i = 0; i < AmountAllSymbols; i++)
Max += Count[i] * (Count[i] - 1);
Print("SumAllVariants = " + Max);
PrintXTrade();
return;
}
/************************************************* END BLOCK_1 *************************************************/
// ÁËÎÊ ÔÓÍÊÖÈÉ, ÈÑÏÎËÜÇÓÞÙÈÕÑß Â ÎÑÍÎÂÍÎÌ ÄËß ÈÍÈÖÈÀËÈÇÀÖÈÈ:
// string StrDelSpaces( string Str );
// int StrToStringS( string Str, string Razdelitel, string &Output[] );
// bool RealSymbol( string Str );
// void GetRealSymbols();
// int GetNumRealSymbol( string Str );
// void GetAllSymbols();
// void GetRealBidAsk();
// string SymbolToStr( int i, int j );
// void GetDataLot( string Symb );
// void GetSymbolPrefix( string Symb );
// void GetXTrade( string FileName );
// void GetPipsD();
// void InitArbitrage();
// void PrintXTrade();
// void PrintBeginInfo();
/************************************************* END BLOCK_1 *************************************************/
//------------------------------------------------------------------------------------------------------------------------------
/************************************************* BEGIN BLOCK_2 *************************************************/
// ÁËÎÊ ÈÍÔÎÐÌÀÖÈÎÍÍÛÕ ÔÓÍÊÖÈÉ:
// string ArbitragePositions();
// string SymbolToFile( int i, int j );
// void StringToFile( string FileName, string Str );
// void MonitoringArbitrage( int NumSymbol, int Variant1, int Variant2 );
// void WriteStatistic( string FileName );
/************************************************* BEGIN BLOCK_2 *************************************************/
string ArbitragePositions()
{
string Str = WindowExpertName() + ": MinPips = " + DoubleToStr(MinPips, 1);
int i, j, k, Pos;
for (i = 0; i < AmountAllSymbols; i++)
{
Pos = 0;
for (j = 0; j < Count[i] - 1; j++)
{
Pos += j + 1;
for (k = j + 1; k < Count[i]; k++)
{
if (XTrade[i][Pos])
{
if (XPosition[i][Pos] < -ALPHA)
Str = Str + "\n" + SymbolToStr(i, j) + " (SELL) && " + SymbolToStr(i, k) + " (BUY)";
else if (XPosition[i][Pos] > ALPHA)
Str = Str + "\n" + SymbolToStr(i, j) + " (BUY) && " + SymbolToStr(i, k) + " (SELL)";
}
Pos++;
}
}
}
return(Str);
}
// Ãîòîâèò äàííûå äëÿ çàïèñè â ôàéë j-ãî âàðèàíòà ïîëó÷åíèÿ i-ãî ñãåíåðèðîâàííîãî ñèìâîëà
string SymbolToFile( int i, int j )
{
string Str = "";
int S1, S2;
if (Math[i][j] < 0)
{
S1 = AllSymbols[i][j];
Str = RealSymbols[S1] + ": " + DoubleToStr(BidsReal[S1], MarketInfo(REALSymbols[S1], MODE_DIGITS)) + " " +
DoubleToStr(AsksReal[S1], MarketInfo(REALSymbols[S1], MODE_DIGITS));
}
else
{
S1 = AllSymbols[i][j] / AmountRealSymbols;
S2 = AllSymbols[i][j] % AmountRealSymbols;
Str = RealSymbols[S1] + ": " + DoubleToStr(BidsReal[S1], MarketInfo(REALSymbols[S1], MODE_DIGITS)) + " " +
DoubleToStr(AsksReal[S1], MarketInfo(REALSymbols[S1], MODE_DIGITS)) + "\n" +
RealSymbols[S2] + ": " + DoubleToStr(BidsReal[S2], MarketInfo(REALSymbols[S2], MODE_DIGITS)) + " " +
DoubleToStr(AsksReal[S2], MarketInfo(REALSymbols[S2], MODE_DIGITS));
}
return(Str);
}
void StringToFile( string FileName, string Str )
{
int handle;
handle = FileOpen(FileName, FILE_READ|FILE_WRITE, "\t");
FileSeek(handle, 0, SEEK_END);
FileWrite(handle, Str);
FileClose(handle);
return;
}
void MonitoringArbitrage( int NumSymbol, int Variant1, int Variant2 )
{
int V;
string Str;
if (Variant1 < Variant2)
V = Variant1 * Count[NumSymbol] + Variant2;
else
V = Variant2 * Count[NumSymbol] + Variant1;
CountArbitrage[NumSymbol][V]++;
if (CountArbitrage[NumSymbol][V] > MaxCountArbitrage)
MaxCountArbitrage = CountArbitrage[NumSymbol][V];
if (Monitoring)
{
Str = "Time = " + TimeToStr(CurrentTime, TIME_DATE|TIME_SECONDS) + "\n";
Str = Str + "Bid \"" + SymbolToStr(NumSymbol, Variant1) + "\" (" + DoubleToStr(Bids[NumSymbol][Variant1], 5) +
") > (" + DoubleToStr(Asks[NumSymbol][Variant2], 5) + ") Ask \"" + SymbolToStr(NumSymbol, Variant2) +
"\", Difference = " + DoubleToStr((Bids[NumSymbol][Variant1] - Asks[NumSymbol][Variant2]) / PointD[NumSymbol], 1) + " pips";
Str = Str + "\n" + SymbolToFile(NumSymbol, Variant1) + "\n" + SymbolToFile(NumSymbol, Variant2) + "\n";
Str = Str + "Count = " + CountArbitrage[NumSymbol][V];
StringToFile("Arbitrage.txt", Str);
}
return;
}
void WriteStatistic( string FileName )
{
string Str = WindowExpertName() + ": MinPips = " + DoubleToStr(MinPips, 1);
int i, j, k, Pos;
int V1, V2;
int handle, Cnt;
int BenchTime = GetTickCount();
Cnt = MaxCountArbitrage;
while (Cnt >= 2) // Äëÿ çàêðûòèÿ è îòêðûòèÿ íóæíî, êàê ìèíèìóì, 2 ðàçà
{
for (i = 0; i < AmountAllSymbols; i++)
{
Pos = 0;
for (j = 0; j < Count[i] - 1; j++)
{
Pos += j + 1;
for (k = j + 1; k < Count[i]; k++)
{
if (CountArbitrage[i][Pos] == Cnt)
Str = Str + "\n" + CountArbitrage[i][Pos] + ": " + SymbolToStr(i, j) + " && " + SymbolToStr(i, k);
Pos++;
}
}
}
Cnt--;
}
handle = FileOpen(FileName, FILE_WRITE, "\t");
FileWrite(handle, Str);
FileClose(handle);
Print("MaxCountArbitrage = " + MaxCountArbitrage + ", Write Time Statistic = " +
DoubleToStr((GetTickCount() - BenchTime) / 1000, 0) + " s.");
return;
}
/************************************************* END BLOCK_2 *************************************************/
// ÁËÎÊ ÈÍÔÎÐÌÀÖÈÎÍÍÛÕ ÔÓÍÊÖÈÉ:
// string ArbitragePositions();
// string SymbolToFile( int i, int j );
// void StringToFile( string FileName, string Str );
// void MonitoringArbitrage( int NumSymbol, int Variant1, int Variant2 );
// void WriteStatistic( string FileName );
/************************************************* END BLOCK_2 *************************************************/
//------------------------------------------------------------------------------------------------------------------------------
/************************************************* BEGIN BLOCK_3 *************************************************/
// ÁËÎÊ ÎÑÍÎÂÍÛÕ ÒÎÐÃÎÂÛÕ ÔÓÍÊÖÈÉ:
// int OrderSlipPage( double OriginalPrice );
// double GetTradeVolume( int PrevTicket );
// int _OrderSend( string _symbol, int _cmd, double _volume, double _price, int _slippage, double _stoploss, double _takeprofit);
// double _OrderClose( int _ticket, double _lots, double _price, int _slippage);
/************************************************* BEGIN BLOCK_3 *************************************************/
int OrderSlipPage( double OriginalPrice )
{
double Tmp;
int Res;
if (OrderCloseTime() == 0)
{
if (OrderType() == OP_BUY)
Tmp = OriginalPrice - OrderOpenPrice();
else if (OrderType() == OP_SELL)
Tmp = OrderOpenPrice() - OriginalPrice;
}
else
{
if (OrderType() == OP_BUY)
Tmp = OrderClosePrice() - OriginalPrice;
else if (OrderType() == OP_SELL)
Tmp = OriginalPrice - OrderClosePrice();
}
if (Tmp > 0)
Res = Tmp / MarketInfo(OrderSymbol(), MODE_POINT) + 0.1;
else
Res = Tmp / MarketInfo(OrderSymbol(), MODE_POINT) - 0.1;
return(Res);
}
double GetTradeVolume( int PrevTicket )
{
if (OrderTicket() == PrevTicket) // Íåò íîâûõ îðäåðîâ
return(0);
return(OrderLots());
}
// Îáðàáàòûâàåò ñèòóàöèè Partial Fills. Ïðè àñèíõðîííîé îáðàáîòêå áðîêåðîì òîðãîâûõ ïðèêàçîâ ìîæåò ðàáîòàòü íåêîððåêòíî
int _OrderSend( string _symbol, int _cmd, double _volume, double _price, int _slippage, double _stoploss, double _takeprofit)
{
static string OrderTypeToString[7] = {"OP_BUY", "OP_SELL", "OP_BUYLIMIT", "OP_SELLLIMIT", "OP_BUYSTOP", "OP_SELLSTOP", "Balance"};
int PrevTicket;
int Ticket = -1;
int _GetLastError;
int SP = 0;
double Vol = 0;
OrderSelect(OrdersTotal() - 1, SELECT_BY_POS, MODE_TRADES);
PrevTicket = OrderTicket();
OrderSend(_symbol, _cmd, _volume, _price, _slippage, _stoploss, _takeprofit);
_GetLastError = GetLastError();
OrderSelect(OrdersTotal() - 1, SELECT_BY_POS, MODE_TRADES);
if (GetTradeVolume(PrevTicket) > ALPHA)
if (OrderSymbol() == _symbol) // íåîáõîäèìî èç-çà ñâÿçàííûõ ñ ðàçðûâàìè ñâÿçè ïðîáëåì
{
SP = OrderSlipPage(_price);
Ticket = OrderTicket();
Vol = OrderLots();
}
Print(Ticket, " = OrderSend(", _symbol, ", ", OrderTypeToString[_cmd], ", ", _volume, ", ", DoubleToStr(_price, MarketInfo(_symbol, MODE_DIGITS)),
", ", _slippage, ", ", _stoploss, ", ", _takeprofit, ") - ", ErrorDescription(_GetLastError), ", SlipPage = ", SP, ", Lots = ", Vol);
return(Ticket);
}
// Îáðàáàòûâàåò ñèòóàöèè Partial Fills. Ïðè àñèíõðîííîé îáðàáîòêå áðîêåðîì òîðãîâûõ ïðèêàçîâ ìîæåò ðàáîòàòü íåêîððåêòíî
double _OrderClose( int _ticket, double _lots, double _price, int _slippage)
{
int Ticket = -1;
int PrevTicket;
int _GetLastError;
int SP = 0;
double Vol = 0;
string _symbol;
double PrevLots;
OrderSelect(_ticket, SELECT_BY_TICKET);
_symbol = OrderSymbol();
PrevLots = OrderLots();
OrderSelect(OrdersHistoryTotal() - 1, SELECT_BY_POS, MODE_HISTORY);
PrevTicket = OrderTicket();
OrderClose(_ticket, _lots, _price, _slippage);
_GetLastError = GetLastError();
// Sleep(1000) // äëÿ MBTrading äàííàÿ ïàóçà íåîáõîäèìà è íå ðåøàåò íà 100% ïðîáëåìû àñèíõðîííîé îáðàáîòêè ïðèêàçîâ
OrderSelect(OrdersHistoryTotal() - 1, SELECT_BY_POS, MODE_HISTORY);
if (GetTradeVolume(PrevTicket) > ALPHA)
if (OrderSymbol() == _symbol) // íåîáõîäèìî èç-çà ñâÿçàííûõ ñ ðàçðûâàìè ñâÿçè ïðîáëåì
{
SP = OrderSlipPage(_price);
Ticket = OrderTicket();
Vol = OrderLots();
}
Print(Ticket, "(", _symbol, ") = OrderClose(", _ticket, ", ", _lots, "(", PrevLots, "), ", DoubleToStr(_price, MarketInfo(_symbol, MODE_DIGITS)),
", ", _slippage, ") - ", ErrorDescription(_GetLastError), ", SlipPage = ", SP, ", Lots = ", Vol);
return(Vol);
}
/************************************************* END BLOCK_3 *************************************************/
// ÁËÎÊ ÎÑÍÎÂÍÛÕ ÒÎÐÃÎÂÛÕ ÔÓÍÊÖÈÉ:
// int OrderSlipPage( double OriginalPrice );
// double GetTradeVolume( int PrevTicket );
// int _OrderSend( string _symbol, int _cmd, double _volume, double _price, int _slippage, double _stoploss, double _takeprofit);
// double _OrderClose( int _ticket, double _lots, double _price, int _slippage);
/************************************************* END BLOCK_3 *************************************************/
//------------------------------------------------------------------------------------------------------------------------------
/************************************************* BEGIN BLOCK_4 *************************************************/
// ÁËÎÊ ÂÑÏÎÌÎÃÀÒÅËÜÍÛÕ ÒÎÐÃÎÂÛÕ ÔÓÍÊÖÈÉ:
// int GetOrderTicket( string Symb, int Type, bool FlagMax );
// bool MyOrderSend( string Symb, int Type, double& Vol, int SlipPage, double MaxLot, bool Lock );
// void CloseLock();
// void RefreshPositions()
/************************************************* BEGIN BLOCK_4 *************************************************/
int GetOrderTicket( string Symb, int Type, bool FlagMax )
{
int Ticket, TicketMax = -1, TicketMin = -1;
double Max = 0;
double Min = 9999;
int Pos = OrdersTotal() - 1;
while (Pos >= 0)
{
OrderSelect(Pos, SELECT_BY_POS);
if (OrderSymbol() == Symb)
if (OrderType() == Type)
{
if (OrderLots() > Max) // Íàõîäèì íàèáîëüøèé îðäåð äëÿ ìèíèìèçàöèè êîëè÷åñòâà òîðãîâûõ çàïðîñîâ
{
Max = OrderLots();
TicketMax = OrderTicket();
}
if (OrderLots() < Min) // Íàõîäèì íàèìåíüøèé îðäåð äëÿ óäà÷íîãî CloseBy (ïðîáëåìû MinLot)
{
Min = OrderLots();
TicketMin = OrderTicket();
}
}
Pos--;
}
if (FlagMax)
Ticket = TicketMax;
else
Ticket = TicketMin;
if (Ticket > 0)
OrderSelect(Ticket, SELECT_BY_TICKET);
return(Ticket);
}
// Îáðàáîòêà ëîêîâ è Partial Fills
bool MyOrderSend( string Symb, int Type, double& Vol, int SlipPage, double MaxLot, bool Lock )
{
int TypeReverse;
double Price;
double VolTmp;
if (Type == OP_BUY)
{
Price = MarketInfo(Symb, MODE_ASK);
// Price = AsksReal[GetNumRealSymbol(Symb)]; // Ìîãóò áûòü ïðîáëåìû ñ öåíîé èç-çà îãðàíè÷åíèé MT4
TypeReverse = OP_SELL;
}
else // (Type == OP_SELL)
{
Price = MarketInfo(Symb, MODE_BID);
// Price = BidsReal[GetNumRealSymbol(Symb)]; // Ìîãóò áûòü ïðîáëåìû ñ öåíîé èç-çà îãðàíè÷åíèé MT4
TypeReverse = OP_BUY;
}
if (!Lock) // Òîðãîâëÿ áåç ëîêà (êðèòè÷íî äëÿ àðáèòðàæà èç-çà áîëüøîãî êîëè÷åñòâà "ëèøíèõ" òîðãîâûõ çàïðîñîâ)
while ((Vol > MinLot - ALPHA) && (GetOrderTicket(Symb, TypeReverse, TRUE) > 0)) // Vol >= MinLot
{
if (Vol > OrderLots() + MinLot - ALPHA) // Vol >= OrderLots() + MinLot
VolTmp = OrderLots();
else if (Vol < OrderLots() - MinLot + ALPHA) // Vol <= OrderLots() - MinLot
VolTmp = Vol;
else if (Vol > OrderLots() + ALPHA)// Vol > OrderLots()
VolTmp = OrderLots() - MinLot;
else if (Vol < OrderLots() - ALPHA) // Vol < OrderLots()
VolTmp = MathMin(OrderLots() - MinLot, Vol - MinLot);
else // Vol == OrderLots()
VolTmp = OrderLots();
if (VolTmp < MinLot - ALPHA) // VolTmp < MinLot
{
Alert("Cannot close Order ", OrderSymbol(), " ", OrderTicket(), " ", OrderLots(), " by ", Vol, " lots! Lock is needed!");
break;
}
// Ñ òàêèì âîçâðàùàåìûì ðåçóëüòàòîì ìîæíî ïðèêðóòèòü è àñèíõðîííóþ îáðàáîòêó îðäåðîâ áðîêåðà
VolTmp = _OrderClose(OrderTicket(), NormalizeDouble(VolTmp, DigitsLot), Price, SlipPage);
if (VolTmp < ALPHA)
return(FALSE);
Vol -= VolTmp;
}
while (Vol - MaxLot > ALPHA) // Vol > MaxLot
{
if (_OrderSend(Symb, Type, NormalizeDouble(MathMin(MaxLot, Vol - MinLot), DigitsLot), Price, SlipPage, 0, 0) < 0)
return(FALSE);
Vol -= OrderLots();
}
while (Vol > MinLot - ALPHA) // Vol >= MinLot
{
if (_OrderSend(Symb, Type, NormalizeDouble(Vol, DigitsLot), Price, SlipPage, 0, 0) < 0)
return(FALSE);
Vol -= OrderLots();
}
return(TRUE);
}
// Çàêðûòèå ëîêèðîâàííûõ ïîçèöèé
void CloseLock()
{
int BuyTicket, SellTicket;
double SellLots, Tmp;
string Symb;
bool FlagMax = TRUE;
bool FlagRepeat = FALSE;
for (int i = 0; i < AmountRealSymbols; i++)
{
Symb = REALSymbols[i];
BuyTicket = GetOrderTicket(Symb, OP_BUY, FlagMax);
SellTicket = GetOrderTicket(Symb, OP_SELL, !FlagMax);
while ((BuyTicket != -1) && (SellTicket != -1))
{
SellLots = OrderLots();
OrderSelect(BuyTicket, SELECT_BY_TICKET);
Tmp = MathAbs(OrderLots() - SellLots);
if ((ALPHA < Tmp) && (Tmp < MinLot - ALPHA))
{
if (FlagRepeat)
break;
FlagRepeat = TRUE;
FlagMax = !FlagMax;
}
else
{
if (!OrderCloseBy(BuyTicket, SellTicket))
return;
FlagRepeat = FALSE;
}
BuyTicket = GetOrderTicket(Symb, OP_BUY, FlagMax);
SellTicket = GetOrderTicket(Symb, OP_SELL, !FlagMax);
}
}
return;
}
// Îòêðûâàåò ïîñ÷èòàííûå ïîçèöèè - Position[]
void RefreshPositions()
{
bool Flag = FALSE; // Ôëàã íà íàëè÷èå èçìåíåíèé
double Vol;
for (int i = 0; i < AmountRealSymbols; i++)
{
Position[i] = NormalizeDouble(Position[i], DigitsLot); // Íå ñàìîå ëó÷øåå (ïî ñêîðîñòè èñïîëíåíèÿ) ðåøåíèå
if (Position[i] > ALPHA) // ïîêóïêà. Âîçìîæíû ïðîáëåìû èç-çà íåíîðìàëèçîâàííîñòè Position[i]
{
Vol = Position[i];
if (!MyOrderSend(REALSymbols[i], OP_BUY, Vol, SlipPage, MaxLot, Lock))
Print("Vol = ", Vol);
Position[i] = Vol; // Íå ïðîøåäøèé îáúåì èç-çà òîðãîâûõ îøèáîê
Flag = TRUE;
}
else if (Position[i] < -ALPHA) // ïðîäàæà
{
Vol = -Position[i];
if (!MyOrderSend(REALSymbols[i], OP_SELL, Vol, SlipPage, MaxLot, Lock))
Print("Vol = ", Vol);
Position[i] = -Vol; // Íå ïðîøåäøèé îáúåì èç-çà òîðãîâûõ îøèáîê
Flag = TRUE;
}
}
if (Flag) // Ïå÷àòàåì èçìåíåíèÿ
Comment(ArbitragePositions());
CloseLock(); // Ïðè Lock = FALSE èç-çà íþàíñîâ MinLot ÌÎÃÓÒ áûòü ëîêèðîâàííûå ïîçèöèè
return;
}
/************************************************* END BLOCK_4 *************************************************/
// ÁËÎÊ ÂÑÏÎÌÎÃÀÒÅËÜÍÛÕ ÒÎÐÃÎÂÛÕ ÔÓÍÊÖÈÉ:
// int GetOrderTicket( string Symb, int Type, bool FlagMax );
// bool MyOrderSend( string Symb, int Type, double& Vol, int SlipPage, double MaxLot, bool Lock );
// void CloseLock();
// void RefreshPositions()
/************************************************* END BLOCK_4 *************************************************/
//------------------------------------------------------------------------------------------------------------------------------
/************************************************* BEGIN BLOCK_5 *************************************************/
// ÁËÎÊ ÔÓÍÊÖÈÉ ÀÐÁÈÒÐÀÆÀ:
// void SymbolDone( double Vol, int Symb );
// void OpenSymbolPosition( int NumSymbol, int Variant, int Type, double Vol );
// void OpenArbitragePosition( int NumSymbol, int Variant1, int Variant2, double Vol );
// void GetBidAsk( int i, int j );
// void TradeArbitrage();
/************************************************* BEGIN BLOCK_6 *************************************************/
void SymbolDone( double Vol, int Symb )
{
if (Vol == 0)
return;
Position[Symb] += Vol;
if (Vol > 0)
StrOut = StrOut + "; BUY " + RealSymbols[Symb] + "(" + DoubleToStr(Vol, DigitsLot) + ") = " +
DoubleToStr(AsksReal[Symb], MarketInfo(REALSymbols[Symb], MODE_DIGITS)) + " Ask";
else // Vol < 0
StrOut = StrOut + "; SELL " + RealSymbols[Symb] + "(" + DoubleToStr(Vol, DigitsLot) + ") = " +
DoubleToStr(BidsReal[Symb], MarketInfo(REALSymbols[Symb], MODE_DIGITS)) + " Bid";
return;
}
// Îòêðûòèå Type-òèïà ïîçèöèè ïî ñãåíåðèðîâàííîìó ñèìâîëó AllSymbols[NumSymbol][Variant]
void OpenSymbolPosition( int NumSymbol, int Variant, int Type, double Vol )
{
int S1, S2;
double Tmp = 0, Tmp1 = 0, Tmp2 = 0;
int Symb = AllSymbols[NumSymbol][Variant];
int Mth = Math[NumSymbol][Variant];
if (Type == OP_SELL)
{
if (Mth == -2) // -2 - "1 / S"
Tmp = Vol / AsksReal[Symb];
else if (Mth == -1) // -1 - "S"
Tmp = -Vol;
else
{
S1 = Symb / AmountRealSymbols;
S2 = Symb % AmountRealSymbols;
switch (Mth)
{
case 0: // 0 - "S1 / S2"
Tmp1 = -Vol;
Tmp2 = Vol * Bids[NumSymbol][Variant];
break;
case 1: // 1 - "S1 * S2"
Tmp1 = -Vol;
Tmp2 = -Vol * BidsReal[S1];
break;
case 2: // 2 - "1 / (S1 * S2)";
Tmp1 = Vol / AsksReal[S1];
Tmp2 = Vol * Bids[NumSymbol][Variant];
break;
case 3: // 3 - "S2 / S1"
Tmp1 = Vol / AsksReal[S1];
Tmp2 = -Tmp1;
break;
}
}
}
else // (Type == OP_BUY)
{
if (Mth == -2) // -2 - "1 / S"
Tmp = -Vol / BidsReal[Symb];
else if (Mth == -1) // -1 - "S"
Tmp = Vol;
else
{
S1 = Symb / AmountRealSymbols;
S2 = Symb % AmountRealSymbols;
switch (Mth)
{
case 0: // 0 - "S1 / S2"
Tmp1 = Vol;
Tmp2 = -Vol * Asks[NumSymbol][Variant];
break;
case 1: // 1 - "S1 * S2"
Tmp1 = Vol;
Tmp2 = Vol * AsksReal[S1];
break;
case 2: // 2 - "1 / (S1 * S2)";
Tmp1 = -Vol / BidsReal[S1];
Tmp2 = -Vol * Asks[NumSymbol][Variant];
break;
case 3: // 3 - "S2 / S1"
Tmp1 = -Vol / BidsReal[S1];
Tmp2 = -Tmp1;
break;
}
}
}
SymbolDone(Tmp, Symb);
SymbolDone(Tmp1, S1);
SymbolDone(Tmp2, S2);
return;
}
// Bids[NumSymbol][Variant1] > Asks[NumSymbol][Variant2]
void OpenArbitragePosition( int NumSymbol, int Variant1, int Variant2, double Vol )
{
int V;
double XPos;
int j, k;
// Íè÷åãî íå äåëàåì, åñëè ïî òåêóùåìó àðáèòðàæó óæå îòêðûòà ïîçèöèÿ
if (Variant1 < Variant2)
{
V = Variant1 * Count[NumSymbol] + Variant2; // Òàêèì ñïîñîáîì õðàíèì íîìåð
XPos = XPosition[NumSymbol][V];
if (XPos < -ALPHA)
return;
XPos += Vol; // ó÷åò îáúåìà ïðåäûäóùåé ñäåëêè
XPosition[NumSymbol][V] = -Vol;
}
else
{
V = Variant2 * Count[NumSymbol] + Variant1;
XPos = XPosition[NumSymbol][V];
if (XPos > ALPHA)
return;
XPos = Vol - XPos; // ó÷åò îáúåìà ïðåäûäóùåé ñäåëêè
XPosition[NumSymbol][V] = Vol;
}
MonitoringArbitrage(NumSymbol, Variant1, Variant2);
if (XTrade[NumSymbol][V]) // Òîðãóåì òîëüêî çàäàííûå êîìáèíàöèè
{
OpenSymbolPosition(NumSymbol, Variant1, OP_SELL, XPos); // Ïðîäàëè ïåðâûé âàðèàíò
OpenSymbolPosition(NumSymbol, Variant2, OP_BUY, XPos); // Êóïèëè âòîðîé âàðèàíò
Print("Variant1 = " + SymbolToStr(NumSymbol, Variant1) + " (Bid = " + DoubleToStr(Bids[NumSymbol][Variant1], 6) +
"), Variant2 = " + SymbolToStr(NumSymbol, Variant2) + " (Ask = " + DoubleToStr(Asks[NumSymbol][Variant2], 6) +
"), Difference = " + DoubleToStr((Bids[NumSymbol][Variant1] - Asks[NumSymbol][Variant2]) / PointD[NumSymbol], 1) + " pips");
Print(StrOut);
StrOut = "";
}
return;
}
// Âû÷èñëÿåò â Bids[i][j] è Asks[i][j] öåíû j-ãî âàðèàíòà ïîëó÷åíèÿ i-ãî ñãåíåðèðîâàííîãî ñèìâîëà
void GetBidAsk( int i, int j )
{
double Bid1, Bid2;
double Ask1, Ask2;
int Mth, Symb;
int S1, S2;
Symb = AllSymbols[i][j];
Mth = Math[i][j];
if (Mth == -2) // -2 - "1 / S"
{
Bids[i][j] = 1 / AsksReal[Symb];
Asks[i][j] = 1 / BidsReal[Symb];
}
else if (Mth == -1) // -1 - "S"
{
Bids[i][j] = BidsReal[Symb];
Asks[i][j] = AsksReal[Symb];
}
else
{
S1 = Symb / AmountRealSymbols;
S2 = Symb % AmountRealSymbols;
Bid1 = BidsReal[S1];
Bid2 = BidsReal[S2];
Ask1 = AsksReal[S1];
Ask2 = AsksReal[S2];
switch (Mth)
{
case 0: // 0 - "S1 / S2"
Bids[i][j] = Bid1 / Ask2;
Asks[i][j] = Ask1 / Bid2;
break;
case 1: // 1 - "S1 * S2"
Bids[i][j] = Bid1 * Bid2;
Asks[i][j] = Ask1 * Ask2;
break;
case 2: // 2 - "1 / (S1 * S2)";
Bids[i][j] = 1 / (Ask1 * Ask2);
Asks[i][j] = 1 / (Bid1 * Bid2);
break;
case 3: // 3 - "S2 / S1"
Bids[i][j] = Bid2 / Ask1;
Asks[i][j] = Ask2 / Bid1;
}
}
return;
}
void TradeArbitrage()
{
int i, j, k;
double Bid1, Bid2, Ask1, Ask2;
GetRealBidAsk();
for (i = 0; i < AmountAllSymbols; i++)
{
for (j = 0; j < Count[i]; j++)
GetBidAsk(i, j);
for (j = 0; j < Count[i] - 1; j++)
{
Bid1 = Bids[i][j] - MinPipsD[i];
Ask1 = Asks[i][j] + MinPipsD[i];
for (k = j + 1; k < Count[i]; k++)
{
Bid2 = Bids[i][k];
Ask2 = Asks[i][k];
if (Bid1 > Ask2)
OpenArbitragePosition(i, j, k, Lots);
else if (Ask1 < Bid2)
OpenArbitragePosition(i, k, j, Lots);
}
}
}
RefreshPositions();
return;
}
/************************************************* END BLOCK_5 *************************************************/
// ÁËÎÊ ÔÓÍÊÖÈÉ ÀÐÁÈÒÐÀÆÀ:
// void SymbolDone( double Vol, int Symb );
// void OpenSymbolPosition( int NumSymbol, int Variant, int Type, double Vol );
// void OpenArbitragePosition( int NumSymbol, int Variant1, int Variant2, double Vol );
// void GetBidAsk( int i, int j );
// void TradeArbitrage();
/************************************************* END BLOCK_5 *************************************************/
//------------------------------------------------------------------------------------------------------------------------------
void init()
{
Comment(WindowExpertName() + ": MinPips = " + DoubleToStr(MinPips, 1)) ;
InitArbitrage();
PrintBeginInfo();
TimeToWrite *= 60;
PrevTime = TimeCurrent();
return;
}
void deinit()
{
Comment("");
return;
}
void start()
{
while(!IsStopped())
{
RefreshRates();
CurrentTime = TimeCurrent();
TradeArbitrage();
if (CurrentTime - PrevTime > TimeToWrite)
{
PrevTime = CurrentTime;
WriteStatistic("ArbitrageStatistic.txt");
}
Sleep(PAUSE);
}
return;
}
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---