#property show_inputs #import "user32.dll" int PostMessageA(int hWnd,int Msg,int wParam,int lParam); #import #define WM_COMMAND 0x0111 #define PAUSE 100 extern string Currency = "USD"; string Symbol1, Symbol2; bool Math; // 0 - S1 / S2, 1 - S1 * S2, 2 - 1 / (S1 * S2) int handle; string SymbolName; int time; double open, low, high, close; int volume; double PriceBid, PriceAsk; double Bid1 = 0, Bid2 = 0, Ask1 = 0, Ask2 = 0; int Digits1, Digits2; double MinSpread, MaxSpread, AverageSpread; bool RealSymbol( string Str ) { return(MarketInfo(Str, MODE_BID) != 0); } void GetSymbols() { string Currency1, Currency2; string SymbolPrefix; string Str1, Str2; Currency1 = StringSubstr(Symbol(), 0, 3); Currency2 = StringSubstr(Symbol(), 3, 3); SymbolPrefix = StringSubstr(Symbol(), 6, StringLen(Symbol()) - 6); Str1 = Currency1 + Currency + SymbolPrefix; Str2 = Currency + Currency1 + SymbolPrefix; if (RealSymbol(Str1)) { Symbol1 = Str1; Str1 = Currency2 + Currency + SymbolPrefix; Str2 = Currency + Currency2 + SymbolPrefix; if (RealSymbol(Str1)) { Symbol2 = Str1; Math = 0; // S1 / S2 } else if (RealSymbol(Str2)) { Symbol2 = Str2; Math = 1; // S1 * S2 } } else if (RealSymbol(Str2)) { Symbol2 = Str2; Str1 = Currency2 + Currency + SymbolPrefix; Str2 = Currency + Currency2 + SymbolPrefix; if (RealSymbol(Str1)) { Symbol1 = Str1; Math = 2; // 1 / (S1 * S2) } else if (RealSymbol(Str2)) { Symbol1 = Str2; Math = 0; // S1 / S2 } } return; } bool GetPrices() { switch (Math) { case 0: // S1 / S2 PriceBid = Bid1 / Ask2; PriceAsk = Ask1 / Bid2; break; case 1: // S1 * S2 PriceBid = Bid1 * Bid2; PriceAsk = Ask1 * Ask2; break; case 2: // 1 / (S1 * S2) PriceBid = 1 / (Ask1 * Ask2); PriceAsk = 1 / (Bid1 * Bid2); break; } return; } bool SymbolChange() { double NewBid1, NewBid2, NewAsk1, NewAsk2; NewBid1 = MarketInfo(Symbol1, MODE_BID); NewBid2 = MarketInfo(Symbol2, MODE_BID); NewAsk1 = MarketInfo(Symbol1, MODE_ASK); NewAsk2 = MarketInfo(Symbol2, MODE_ASK); if ((NormalizeDouble(NewBid1 - Bid1, Digits1) != 0) || (NormalizeDouble(NewBid2 - Bid2, Digits2) != 0) || (NormalizeDouble(NewAsk1 - Ask1, Digits1) != 0) || (NormalizeDouble(NewAsk2 - Ask2, Digits2) != 0)) { Bid1 = NewBid1; Bid2 = NewBid2; Ask1 = NewAsk1; Ask2 = NewAsk2; GetPrices(); return(TRUE); } return(FALSE); } void WriteBar() { FileWriteInteger(handle, time); FileWriteDouble(handle, open); FileWriteDouble(handle, low); FileWriteDouble(handle, high); FileWriteDouble(handle, close); FileWriteDouble(handle, volume); FileFlush(handle); return; } int GetLastTime() { int Tmp1, Tmp2; Tmp1 = iTime(Symbol1, Period(), 0); Tmp2 = iTime(Symbol2, Period(), 0); if (Tmp1 > Tmp2) return(Tmp1); return(Tmp2); } void CreateNewBar() { time = GetLastTime(); open = PriceBid; low = PriceBid; high = PriceBid; close = PriceBid; volume = 1; return; } void ModifyBar() { if (PriceBid > high) high = PriceBid; else if (PriceBid < low) low = PriceBid; close = PriceBid; volume++; } void CreateNewSpread() { MinSpread = (PriceAsk - PriceBid) / Point; MaxSpread = MinSpread; AverageSpread = MinSpread; return; } void ModifySpread() { double Spread = (PriceAsk - PriceBid) / Point; if (Spread > MaxSpread) MaxSpread = Spread; else if (Spread < MinSpread) MinSpread = Spread; AverageSpread += Spread; return; } void WriteSpread() { int hSpread = FileOpen(SymbolName + Period() + "_Spread.dat", FILE_BIN|FILE_READ|FILE_WRITE); AverageSpread /= volume; FileSeek(hSpread, 0, SEEK_END); FileWriteInteger(hSpread, time); FileWriteDouble(hSpread, MaxSpread); FileWriteDouble(hSpread, AverageSpread); FileWriteDouble(hSpread, MinSpread); FileClose(hSpread); return; } void CreateHandle() { string FileName; int Tmp[15], TmpTime; SymbolName = StringSubstr(Symbol(), 0, 6) + "_" + Currency; FileName = SymbolName + Period() + ".hst"; handle = FileOpenHistory(FileName, FILE_BIN|FILE_READ|FILE_WRITE); if (FileSize(handle) > 0) { if (FileSize(handle) > 148) { FileSeek(handle, -44, SEEK_END); TmpTime = FileReadInteger(handle); if (TmpTime == time) { open = FileReadDouble(handle); low = FileReadDouble(handle); high = FileReadDouble(handle); close = FileReadDouble(handle); volume = FileReadDouble(handle); return; } } FileSeek(handle, 0, SEEK_END); return; } FileClose(handle); handle = FileOpenHistory(FileName, FILE_BIN|FILE_WRITE); FileWriteInteger(handle, 400); FileWriteString(handle, "Created by " + WindowExpertName(), 64); FileWriteString(handle, SymbolName, 12); FileWriteInteger(handle, Period()); FileWriteInteger(handle, Digits); FileWriteArray(handle, Tmp, 0, 15); return; } void RefreshChart() { int hwnd = WindowHandle(SymbolName, Period()); PostMessageA(hwnd, WM_COMMAND, 33324, 0); return; } string GetComment() { int Spread = (Ask - Bid) / Point + 0.1; double SpreadX = (PriceAsk - PriceBid) / Point; string Str; Str = Symbol() + " spread = " + Spread + "\n" + SymbolName + " spread = " + DoubleToStr(SpreadX, 1); Str = Str + "\nDifference = " + DoubleToStr(Spread - SpreadX, 1); return(Str); } void init() { GetSymbols(); Digits1 = MarketInfo(Symbol1, MODE_DIGITS); Digits2 = MarketInfo(Symbol2, MODE_DIGITS); SymbolChange(); CreateNewBar(); CreateNewSpread(); CreateHandle(); return; } void deinit() { FileClose(handle); Comment(""); return; } void start() { while (!IsStopped()) { if (SymbolChange()) { Comment(GetComment()); if (time < GetLastTime()) { WriteBar(); WriteSpread(); CreateNewBar(); CreateNewSpread(); RefreshChart(); } else { ModifyBar(); ModifySpread(); } } Sleep(PAUSE); RefreshRates(); } return; }