Cześć ,
Mam bardzo wyjątkowy pomysł dla wszystkich, którzy obwiniają MT4MT5 za to, że nie rysuje właściwych i prawidłowych linii trendów za pomocą liniowych wykresów, których używa MT4MT5.
Niech każdy koder może zmienić ten Konwerter okresu z normalnych wykresów liniowych MT4 na wykresy logarytmiczne.
Myślę, że jest to jedyny sposób na uzyskanie Logarithmic Charts w MT4MT5 dla wszystkich technicznych Trendline-Lovers.
tutaj jest indi i kod źródłowy:
// ------------------------------------ ----------- -------------------
//| Period_Converter_Opt.mq4 |
//| Prawa autorskie (c) 2005, MetaQuotes Software Corp.
//|
http://www.metaquotes.net|
//| Ver.1.6 Zmodyfikowany przez micclly |
//| Wer.1.5 Zmodyfikowany przez fai |
//| Zmodyfikowane przez wfy05 @ talkforex na podstawie Period_Converter |
//|
http://www.talkforex.com|
// ------------------------------------ ----------- -------------------
#property copyright
Link #property http://www.mql4.com/codebase/indiors/277/
#property indior_chart_window
#include lt; WinUser32.mqhgt;
/*
Readme:
I. Funkcje:
Jest to ulepszona wersja konwertera okresów dla MT4 na podstawie
Domyślny konwerter okresów MT4 według metaquotes.
Domyślny skrypt konwertera okresów nie obsługuje odświeżania w czasie rzeczywistym,
i zużywają dużo CPU (50% -9x%), co spowalnia cały system.
Domyślnie jest to skrypt, który nie zapisuje się po wyjściu z MT4,
więc musisz ponownie zastosować każdy skrypt konwertera po ponownym uruchomieniu
denerwujący.
Ten naprawił wszystkie powyższe problemy:
1. ualizowanie w czasie rzeczywistym lub aktualizowanie na poziomie milisekund we własnym zakresie.
2. Niski koszt procesora, średnio 5% -10% lub mniej.
3. Działa jako wskaźnik, więc można go zapisać i ponownie załadować podczas restartu.
4. Nie ma jednego konwertera na ograniczenie mapy, ponieważ nie jest to skrypt
więcej, możesz użyć tylko jednego okna jako źródła do wygenerowania wielu
nowy plan czasowy, jak to możliwe.
5. Automatyczna aktualizacja w przypadku załadowania nowego bloku historii.
II. Jak używać:
Skopiuj plik mq4 do folderu wskaźników MT4 (eksperci \ wskaźniki)
zainstalować go jako wskaźnik, a nie skrypt. następnie we wskaźniku niestandardowym
listę, dołącz period_converter_opt do wykresu, który chcesz.
Obsługuje 4 parametry:
Współczynnik okresu: nowy współczynnik mnożnika okresu, domyślnie wynosi 2
UpdateInterval: interwał aktualizacji w milisekundach,
zero oznacza aktualizację w czasie rzeczywistym. domyślnie jest zero.
Włączone: Możesz wyłączyć tę opcję bez usuwania jej za pomocą tej opcji.
Inne parametry to komentarze lub debugowanie, można je zignorować.
Upewnij się również, że opcja Zezwalaj na import Dll jest zaznaczona na wspólnej karcie lub
to nie zadziała
Następnie FileOpen Offline, aby otworzyć wygenerowane dane offline. następnie
dane offline zostaną automatycznie zaktualizowane.
Tak długo, jak utrzymujesz otwarty wykres źródłowy i wskaźnik konwertera
uruchomiony, wygenerowany wykres zawierający wskaźniki wewnątrz będzie zawsze
być na bieżąco. możesz również zamknąć wygenerowany wykres i otworzyć go ponownie
później z FileOpen Offline bez problemu.
Jeśli chcesz zamknąć MT4, możesz pozostawić te wykresy offline jako inne
normalne wykresy online. kiedy następnym razem uruchomisz MT4, te wykresy będą
również być załadowane i zaktualizowane.
III. Uwagi:
1. NIE usuwaj zaznaczenia opcji wykresu offline we wspólnych właściwościach wykresu offline.
lub po ponownym uruchomieniu MT4 potraktuje ten wykres jako wykres online i żądanie
dane z serwera, wynikające z pustego okna wykresu.
2. Możesz dołączyć więcej niż jeden konwerter do tego samego okna z innym
PeriodMultiplik, np .: możesz dołączyć 3 konwerter z
PerymMultiplier = 2, 4, 10 do M1, aby wygenerować M2, M4, M10 w tym samym czasie.
Można nawet używać wykresu M1 do generowania wykresu godzinowego, takiego jak H2, który
kosztuje tylko kilka dodatkowych zasobów procesora podczas początkowej konwersji. ale zazwyczaj
większość serwerów nie ma zbyt wielu danych w tym krótkim okresie. wynikły
wygenerowane dane nie są wystarczająco długie przez długi czas. więc jest to sugerowane
w razie potrzeby korzystać z wykresów godzinowychdziennych jako źródła.
3. ualizacje trybu aktualizacji w czasie rzeczywistym cytują tak szybko, jak to możliwe, ale jako
odbywa się to za pomocą skryptu, a MT pominie wywołanie funkcji start (), gdy
Twój komputer jest zajęty i ma dużo dochodów. tak czy inaczej, to się rzadko zdarza,
i możesz uzyskać co najmniej 10 aktualizacji co sekundę, co jest znacznie więcej
niż wystarczająco.
4. Wykres offline nie ma linii stawki pokazanej na wykresie, ale wszystkie dane
na wykresie zawierającym wskaźniki jest wciąż aktualizowany,
więc nie martw się. możesz wyświetlić linię licytacji, usuwając wykres offline
opcja we właściwościach wykresu. ale które niewiele pomagają, a jeśli zapomnisz
aby sprawdzić opcję wykresu offline przed wyjściem. spowoduje to błędy i
stają się puste przy następnym uruchomieniu. musisz zamknąć okno i otworzyć
ponownie z FileOpen w trybie offline, które nie są warte problemów.
IV. Historia:
2014.03.10 1.6 Zmodyfikowany do obsługi kompilacji 600 i późniejszych
2009.08.07 1.5 Dodano 3 opcje. (ShiftTiming, GMTShift, OmitD igit)
2005.12.24 1.4 szybciej wykrywa, czy dane zostały zmienione poprzez usunięcie punktu ruchomego
operacje, dodano obsługę wyjściowego pliku CSV w czasie rzeczywistym.
OutputCSVFile = 0 oznacza brak pliku CSV.
OutputCSVFile = 1 oznacza CSV HST
OutputCSVFile = 2 tylko CSV, bez HST.
(przydatne, jeśli chcesz wygenerować plik CSV dla wbudowanych okresów)
Plik CSV będzie taki sam jak plik HST z wyjątkiem rozszerzenia.
dodano bezpieczne sprawdzanie mnożnika okresu.
2005.12.04 1.3 Naprawiono brakujące dane w przypadku dużej ilości danych
ładowane w kilku blokach i obsługują automatyczne aktualizacje
po wczytaniu nowej historii.
2005.11.29 1.2 Dodatkowa poprawka dla brakujących danych i zmiany serwera.
2005.11.29 1.1 Naprawiono brakujące częściowe dane po restarcie.
Reinicjalizuj po zmianie serwera lub danych uszkodzonych.
2005.11.28 1.0 Pierwsze wydanie
*
wersja zewnętrzna podwójna = 1,6;/wersja kodu
zewnętrzny ciąg BuildInfo = 2014.03.10 przez micclly;
extern int PeriodMultiplier = 1;/nowy współczynnik mnożnika okresu
extern int OutputCSVFile = 0;/również wyjściowy plik CSV?
extern int UpdateInterval = 0;/interwał aktualizacji w milisekundach, zero oznacza aktualizację w czasie rzeczywistym.
extern bool Enabled = true;
extern bool Debug = false;
extern int ShiftTiming = 0;/0-3, Używanie H1Chart i PeriodMultiplier = 4;
//jeśli 1, ServerH4Chart = 00: 00/04: 00/08: 00/12: 00 ...
//= gt; OfflineH4Chart = 01: 00/05: 00/09: 00/13: 00 ...
extern int GMTShift = 0;/jeśli 9, Server Time = GMT 0 Offline Chart Time = GMT 9
extern int OmitDigit = 0;/jeśli 1, 5 cyfr 4 cyfry
int FileHandle = -1;
int CSVHandle = -1;
int NewPeriod = 0;
string MySymbol =;
int ShiftBase;
#define OUTPUT_HST_ONLY 0
#define OUTPUT_CSV_HST 1
#define OUTPUT_CSV_ONLY 2
#define CHART_CMD_UPDATE_DATA 33324
void DebugMsg (ciąg msg)
{
alert (debugowania) (msg);
}
int init ()
{
ShiftBase = Period () * 60;/sekunda
ciąg znaków suffix =;
if (ShiftTiming! = 0) suffix = StringConenate (sufiks, s, przesunięcie czasowe);
jeśli (GMTShift! = 0) suffix = StringConenate (przyrostek, g, GMTSh ift);
if (OmitDigit! = 0) suffix = StringConenate (sufiks, o*, OmitDigit *);
MySymbol = Symbol () _ przyrostek;
if (StringLen (MySymbol) gt; 11)
MySymbol = StringConenate (StringSubstr (MySy mbol, 0,11-StringLen (sufiks)), sufiks);
//bezpieczne sprawdzanie mnożnika okresu.
if (PerymMultiplier lt; = 1 przyrostek ==) {
//tylko wyjściowy plik CSV
Mnożnik okresu = 1;
Wyjściowy plik CSV = 2;
}
NewPeriod = Period () * PerymMaster;
if (OpenHistoryFile () lt; 0) return (-1);
WriteHistoryHeader ();
UpdateHistoryFile (Bars-1, true);
UpdateChartWindow ();
return (0);
}
void deinit ()
{
//Zamknij uchwyt pliku
if (FileHandle gt; = 0) {
FileClose (FileHandle);
FileHandle = -1;
}
if (CSVHandle gt; = 0) {
FileClose (CSVHandle);
CSVHandle = -1;
}
}
int OpenHistoryFile ()
{
nazwa ciągu;
name = MySymbol NewPeriod;
if (OutputCSVFile! = OUTPUT_CSV_ONLY) {
FileHandle = FileOpenHistory (name .hst, FILE_BIN | FILE_WRITE | FILE_SHARE_READ);
if (FileHandle lt; 0) return (-1);
}
if (OutputCSVFile! = OUTPUT_HST_ONLY) {
CSVHandle = FileOpen (nazwa .csv, FILE_CSV | FILE_WRITE | FILE_SHARE_READ | FILE_ANSI, ',');
if (CSVHandle lt; 0) return (-1);
}
return (0);
}
int WriteHistoryHeader ()
{
ciąg c_copyright;
int i_digits = Digits-OmitDigit;
int i_unused [13] = {0};
int wersja = 400;
if (FileHandle lt; 0) return (-1);
c_copyright = (C) opyright 2003, MetaQuotes Software Corp .;
FileWriteInteger (FileHandle, wersja, LONG_VALUE);
FileWriteString (FileHandle, c_copyright, 64);
FileWriteString (FileHandle, MySymbol, 12);
FileWriteInteger (FileHandle, NewPeriod, LONG_VALUE);
FileWriteInteger (FileHandle, i_digits, LONG_VALUE);
FileWriteInteger (FileHandle, 0, LONG_VALUE);/timesign
FileWriteInteger (FileHandle, 0, LONG_VALUE);/last_sync
FileWriteArray (FileHandle, i_unused, 0, ArraySize (i_unused));
return (0);
}
statyczne podwójne d_open, d_low, d_high, d_close, d_volume;
static int i_time;
void WriteHistoryData ()
{
if (FileHandle gt; = 0) {
FileWriteInteger (FileHandle, i_time GMTShift * 60 * 60, LONG_VALUE);
FileWriteDouble (FileHandle, d_open, DOUBLE_VALUE);
FileWriteDouble (FileHandle, d_low, DOUBLE_VALUE);
FileWriteDouble (FileHandle, d_high, DOUBLE_VALUE);
FileWriteDouble (FileHandle, d_close, DOUBLE_VALUE);
FileWriteDouble (FileHandle, d_volume, DOUBLE_VALUE);
}
if (CSVHandle gt; = 0) {
int i_digits = Digits-OmitDigit;
FileWrite (CSVHandle,
TimeToStr (i_time, TIME_DATE),
TimeToStr (i_time, TIME_MINUTES),
DoubleToStr (d_open, i_digits),
DoubleToStr (d_high, i_digits),
DoubleToStr (d_low, i_digits),
DoubleToStr (d_close, i_digits),
d_volume);
}
}
int UpdateHistoryFile (int start_pos, bool init = false)
{
static int last_fpos, csv_fpos;
int i, ps;
//jeśli (FileHandle lt; 0) return (-1);
//normalizuj czas otwarty
ps = NewPeriod * 60;
i_time = (Czas [start_pos] -ShiftBase * ShiftTiming)ps;
i_time = i_time * ps ShiftBase * ShiftTiming;
if (init) {
//pierwszy raz, dane init
d_open = Otwórz [start_pos];
d_low = Low [start_pos];
d_high = Wysoki [start_pos];
d_close = Zamknij [start_pos];
d_volume = Volume [start_pos];
i = start_pos - 1;
if (FileHandle gt; = 0) last_fpos = FileTell (FileHandle);
if (CSVHandle gt; = 0) csv_fpos = FileTell (CSVHandle);
} else {
i = start_pos;
if (FileHandle gt; = 0) FileSeek (FileHandle, last_fpos, SEEK_ SET);
if (CSVHandle gt; = 0) FileSeek (CSVHandle, csv_fpos, SEEK_SET);
}
jeśli (i lt; 0) return (-1);
int cnt = 0;
int LastBarTime;
//przetwarzanie pasków
while (i gt; = 0) {
LastBarTime = Czas [i];
//nowy pasek
if (LastBarTime gt; = i_time ps) {
//zapisz dane paska
WriteHistoryData ();
cnt ;
i_time = (LastBarTime-ShiftBase * ShiftTiming)ps;
i_time = i_time * ps ShiftBase * ShiftTiming;
d_open = Otwórz [i];
d_low = Low [i];
d_high = Wysoki [i];
d_close = Zamknij [i];
d_volume = Volume [i];
} else {
//brak nowego paska
d_volume = Volume [i];
if (Low [i] lt; d_low) d_low = Niski [i];
if (High [i] get; d high) d'high = High [i];
d_close = Zamknij [i];
}
ja--;
}
//zapisz last_fpos przed wpisaniem ostatniego paska.
if (FileHandle gt; = 0) last_fpos = FileTell (FileHandle);
if (CSVHandle gt; = 0) csv_fpos = FileTell (CSVHandle);
WriteHistoryData ();
cnt ;
d_volume - = Volume [0];
//przepłucz zapisane dane
if (FileHandle gt; = 0) FileFlush (FileHandle);
if (CSVHandle gt; = 0) FileFlush (CSVHandle);
return (cnt);
}
int UpdateChartWindow ()
{
static int hwnd = 0;
if (FileHandle lt; 0) {
//brak pliku HST, nie trzeba aktualizować.
return (-1);
}
if (hwnd == 0) {
//próba wykrycia okna wykresu w celu aktualizacji
hwnd = WindowHandle (MySymbol, NewPeriod);
}
if (hwnd! = 0) {
if (IsDllsAllowed () == false) {
//Wywołania DLL muszą być dozwolone
DebugMsg (wywołania Dll muszą być dozwolone);
return (-1);
}
if (PostMessageA (hwnd, WM_COMMAND, CHART _CMD_UPDATE_DATA, 0) == 0) {
//PostMessage nie powiodło się, okno wykresu zostało zamknięte
hwnd = 0;
} else {
//PostMessage się powiedzie
return (0);
}
}
//Nie znaleziono okna lub wystąpił błąd PostMessage
return (-1);
}
/*
int PerfCheck (bool Start)
{
static int StartTime = 0;
static int Index = 0;
if (Start) {
StartTime = GetTickCount ();
Indeks = 0;
return (StartTime);
}
Indeks ;
int diff = GetTickCount () - StartTime;
Alert (używany czas [ Index ]: diff);
StartTime = GetTickCount ();
return (diff);
}
*
static int LastStartTime = 0;
static int LastEndTime = 0;
static int LastBarCount = 0;
void reinit ()
{
deinit ();
w tym();
LastStartTime = Time [Bars-1];
LastEndTime = Time [0];
LastBarCount = Bars;
}
bool IsDataChanged ()
{
/*
static int LastBars = 0, LastTime = 0, LastVolume = 0;
statyczne podwójne LastOpen = 0, LastClose = 0, LastHigh = 0, LastLow = 0;
if (LastVolume! = Volume [0] || LastBars! = Bars || LastTime! = Czas [0] ||
LastClose! = Zamknij [0] || LastHigh! = High [0] || LastLow! = Low [0] ||
LastOpen! = Open [0]) {
LastBars = Bars;
LastVolume = Volume [0];
Ostatni czas = czas [0];
LastClose = Zamknij [0];
LastHigh = High [0];
LastLow = Low [0];
LastOpen = Otwórz [0];
return (true);
}
return (false);
*
/*
szybka wersja bez działania punktu pływaka
*
static int LastBars = 0, LastTime = 0, LastVolume = 0;
bool ret;
ret = false;
if (LastVolume! = Volume [0]) {
LastVolume = Volume [0];
ret = true;
}
if (LastTime! = Time [0]) {
Ostatni czas = czas [0];
ret = true;
}
if (LastBars! = Bars) {
LastBars = Bars;
ret = true;
}
return (ret);
}
int CheckNewData ()
{
static string LastServer =;
if (Bars lt; 2) {
//dane nie są jeszcze załadowane.
DebugMsg (Dane nie są załadowane, tylko Paski Paski);
return (-1);
}
string serv = ServerAddress ();
if (serv ==) {
//jeszcze nie ma serwera
DebugMsg (brak połączenia z serwerem);
return (-1);
}
//serwer zmieniony? sprawdź to i ponownie wprowadź, aby zapobiec błędnym danym podczas zmiany serwera.
if (LastServer! = serv) {
DebugMsg (Serwer zmieniono z Ostatni serwer na serwer);
LastServer = serv;
reinit ();
return (-1);
}
if (! IsDataChanged ()) {
//return, jeśli nie zmieniono danych, aby zapisać zasób
//DebugMsg (Brak danych);
return (-1);
}
if (Time [Bars-1]! = LastStartTime) {
DebugMsg (Zmieniono czas rozpoczęcia, załadowano nową historię lub zmieniono serwer);
reinit ();
return (-1);
}
int i, cnt;
//spróbuj znaleźć pasek LastEndTime, który powinien być czasem [0] lub czasem [1],
//więc operacja jest szybka
dla (i = 0; i lt; Bars; i ) {
if (Time [i] lt; = LastEndTime) {
przerwa;
}
}
if (i gt; = Bars || Time [i]! = LastEndTime) {
DebugMsg (Czas zakończenia TimeToStr (LastEndTime) nie znaleziony);
reinit ();
return (-1);
}
cnt = Bars - i;
if (cnt! = LastBarCount) {
DebugMsg (Dane wczytane, cnt to cnt LastBarCount to LastBarCount);
reinit ();
return (-1);
}
//nie załadowano nowych danych, wróć z pozycją LastEndTime.
LastBarCount = Bars;
LastEndTime = Time [0];
return (i);
}
// ------------------------------------ ----------- -------------------
//| funkcja uruchamiania programu |
// ------------------------------------ ----------- -------------------
int start ()
{
static int last_time = 0;
if (! Enabled) return (0);
//zawsze aktualizuj lub aktualizuj tylko po upływie określonego czasu
if (UpdateInterval! = 0) {
int cur_time;
cur_time = GetTickCount ();
if (MathAbs (cur_time - last_time) lt; UpdateInterval) {
return (0);
}
last_time = cur_time;
}
//if (Debug) PerfCheck (true);
int n = CheckNewData ();
//if (Debug) PerfCheck (false);
jeśli (n <0) powróci (0);
//zaktualizuj plik historii o nowe dane
UpdateHistoryFile (n);
//odśwież okno wykresu
UpdateChartWindow ();
//if (Debug) PerfCheck (false);
return (0);
}
Wskaźnik załącznika:
Załączony plik
https://www.forex-instant.com/attach...9574793598.mq460 KB | 0 pobrań