public static TimeSpan PeriodTimeSpan(MT4Bridge.PeriodType period) { if ((int)period < 60) return TimeSpan.FromMinutes((int)period); else if ((int)period < 1440) return TimeSpan.FromHours((int)period); else if ((int)period == 1440) return TimeSpan.FromDays(1); else if ((int)period == 10080) return TimeSpan.FromDays(7); else return TimeSpan.FromDays(30); }
/// <summary> /// Copies data to Data and calculates. /// </summary> void SetDataAndCalculate(string symbol, MT4Bridge.PeriodType period, DateTime time, bool isPriceChange, bool isUpdateData) { lock (lockerDataFeed) { bool isUpdateChart = isUpdateData; MT4Bridge.Bars bars = bridge.GetBars(symbol, period); if (bars == null && JournalShowSystemMessages) { isSetRootDataError = true; Data.SoundError.Play(); JournalMessage jmsg = new JournalMessage(JournalIcons.Error, DateTime.Now, symbol + " " + period.ToString() + " " + Language.T("Cannot receive bars!")); AppendJournalMessage(jmsg); return; } if (bars.Count < MaxBarsCount((int)period) && JournalShowSystemMessages) { isSetRootDataError = true; Data.SoundError.Play(); JournalMessage jmsg = new JournalMessage(JournalIcons.Error, DateTime.Now, symbol + " " + period.ToString() + " " + Language.T("Cannot receive enough bars!")); AppendJournalMessage(jmsg); return; } if (isSetRootDataError && JournalShowSystemMessages) { isSetRootDataError = false; JournalMessage jmsg = new JournalMessage(JournalIcons.Information, DateTime.Now, symbol + " " + period.ToString() + " " + Language.T("Enough bars received!")); AppendJournalMessage(jmsg); } int countBars = bars.Count; if (countBars < 400) return; if (Data.Bars != countBars || Data.Time[countBars - 1] != bars.Time[countBars - 1] || Data.Volume[countBars - 1] != bars.Volume[countBars - 1] || Data.Close[countBars - 1] != bars.Close[countBars - 1]) { if (Data.Bars == countBars && Data.Time[countBars - 1] == bars.Time[countBars - 1] && Data.Time[countBars - 10] == bars.Time[countBars - 10]) { // Update the last bar only. Data.Open [countBars - 1] = bars.Open [countBars - 1]; Data.High [countBars - 1] = bars.High [countBars - 1]; Data.Low [countBars - 1] = bars.Low [countBars - 1]; Data.Close [countBars - 1] = bars.Close [countBars - 1]; Data.Volume[countBars - 1] = bars.Volume[countBars - 1]; } else { // Update all the bars. Data.Bars = countBars; Data.Time = new DateTime[countBars]; Data.Open = new double[countBars]; Data.High = new double[countBars]; Data.Low = new double[countBars]; Data.Close = new double[countBars]; Data.Volume = new int[countBars]; bars.Time.CopyTo(Data.Time, 0); bars.Open.CopyTo(Data.Open, 0); bars.High.CopyTo(Data.High, 0); bars.Low.CopyTo(Data.Low, 0); bars.Close.CopyTo(Data.Close, 0); bars.Volume.CopyTo(Data.Volume, 0); } // Calculate the strategy indicators. CalculateStrategy(true); isUpdateChart = true; } bool isBarChanged = IsBarChanged(Data.Time[Data.Bars - 1]); if (isTrading) { TickType tickType = GetTickType((DataPeriods)(int)period, Data.Time[Data.Bars - 1], time, Data.Volume[Data.Bars - 1]); if (tickType == TickType.Close || isPriceChange || isBarChanged) { if (JournalShowSystemMessages && tickType != TickType.Regular) { JournalIcons icon = JournalIcons.Warning; string text = string.Empty; if (tickType == TickType.Open) { icon = JournalIcons.BarOpen; text = Language.T("A Bar Open event!"); } else if (tickType == TickType.Close) { icon = JournalIcons.BarClose; text = Language.T("A Bar Close event!"); } else if (tickType == TickType.AfterClose) { icon = JournalIcons.Warning; text = Language.T("A new tick arrived after a Bar Close event!"); } JournalMessage jmsg = new JournalMessage(icon, DateTime.Now, symbol + " " + Data.PeriodMTStr + " " + time.ToString("HH:mm:ss") + " " + text); AppendJournalMessage(jmsg); } if (isBarChanged && tickType == TickType.Regular) { if (JournalShowSystemMessages) { JournalMessage jmsg = new JournalMessage(JournalIcons.Warning, DateTime.Now, symbol + " " + Data.PeriodMTStr + " " + time.ToString("HH:mm:ss") + " A Bar Changed event!"); AppendJournalMessage(jmsg); } tickType = TickType.Open; } if (tickType == TickType.Open && barOpenTimeForLastCloseEvent == Data.Time[Data.Bars - 3]) { if (JournalShowSystemMessages) { JournalMessage jmsg = new JournalMessage(JournalIcons.Warning, DateTime.Now, symbol + " " + Data.PeriodMTStr + " " + time.ToString("HH:mm:ss") + " A secondary Bar Close event!"); AppendJournalMessage(jmsg); } tickType = TickType.OpenClose; } CalculateTrade(tickType); isUpdateChart = true; if (tickType == TickType.Close || tickType == TickType.OpenClose) barOpenTimeForLastCloseEvent = Data.Time[Data.Bars - 1]; } } if (isUpdateChart) UpdateChart(); } return; }
/// <summary> /// Bridge OnTick /// </summary> void Bridge_OnTick(object source, MT4Bridge.TickEventArgs tea) { lock (lockerTickPing) { if (pingAttempt > 0 && JournalShowSystemMessages) { JournalMessage jmsgsys = new JournalMessage(JournalIcons.System, DateTime.Now, tea.Symbol + " " + tea.Period.ToString() + " " + Language.T("Tick received after an unsuccessful ping.")); AppendJournalMessage(jmsgsys); } pingAttempt = 0; if (!Data.IsConnected) return; tickLocalTime = DateTime.Now; tickServerTime = tea.Time; if (IsChartChangeged(tea.Symbol, (DataPeriods)(int)tea.Period)) { StopTrade(); Data.IsConnected = false; SetFormText(); if (Configs.PlaySounds) Data.SoundDisconnect.Play(); JournalMessage jmsg = new JournalMessage(JournalIcons.Warning, DateTime.Now, tea.Symbol + " " + tea.Period.ToString() + " " + Language.T("Tick received from a different chart!")); AppendJournalMessage(jmsg); return; } bool bNewPrice = Math.Abs(Data.Bid - tea.Bid) > Data.InstrProperties.Point / 2; Data.Bid = tea.Bid; Data.Ask = tea.Ask; Data.InstrProperties.Spread = tea.Spread; Data.InstrProperties.TickValue = tea.TickValue; Data.ServerTime = tea.Time; Data.SetTick(tea.Bid); bool isAccChanged = Data.SetCurrentAccount(tea.Time, tea.AccountBalance, tea.AccountEquity, tea.AccountProfit, tea.AccountFreeMargin); bool isPosChanged = Data.SetCurrentPosition(tea.PositionTicket, tea.PositionType, tea.PositionLots, tea.PositionOpenPrice, tea.PositionOpenTime, tea.PositionStopLoss, tea.PositionTakeProfit, tea.PositionProfit, tea.PositionComment); bool updateData = true; SetDataAndCalculate(tea.Symbol, tea.Period, tea.Time, bNewPrice, updateData); string bidText = tea.Bid.ToString(Data.FF); string askText = tea.Ask.ToString(Data.FF); SetLblBidAskText(bidText + " / " + askText); // Tick data label if (JournalShowTicks) { string tickInfo = string.Format("{0} {1} {2} {3} / {4}", tea.Symbol, tea.Period, tea.Time.ToString("HH:mm:ss"), bidText, askText); JournalMessage jmsg = new JournalMessage(JournalIcons.Globe, DateTime.Now, tickInfo); AppendJournalMessage(jmsg); } UpdateTickChart(Data.InstrProperties.Point, Data.ListTicks.ToArray()); SetEquityInfoText(string.Format("{0:F2} {1}", tea.AccountEquity, Data.AccountCurrency)); ShowCurrentPosition(isPosChanged); if (isAccChanged) { JournalMessage jmsg = new JournalMessage(JournalIcons.Currency, DateTime.Now, string.Format(Language.T("Account Balance") + " {0:F2}, " + Language.T("Equity") + " {1:F2}, " + Language.T("Profit") + ", {2:F2}, " + Language.T("Free Margin") + " {3:F2}", tea.AccountBalance, tea.AccountEquity, tea.AccountProfit, tea.AccountFreeMargin)); AppendJournalMessage(jmsg); } if (Data.IsBalanceDataChganged) UpdateBalanceChart(Data.BalanceData, Data.BalanceDataPoints); SetTickInfoText(string.Format("{0} {1} / {2}", tea.Time.ToString("HH:mm:ss"), bidText, askText)); SetConnIcon(2); // Sends OrderModify on SL/TP errors if (IsWrongStopsExecution()) ResendWrongStops(); } return; }