private Draw _Line(int sx, int sy, int ex, int ey, LineThickNess?_thicknessOverride, HV hvHint) { var thickness = _thicknessOverride ?? Thickness; IBoxStyle line = thickness == LineThickNess.Single ? _thin : _thick; // hv hint is only required when sx, sy and ex, ey are all the same // added to try to sort out issue I have with box 3 lines high resulting // in the line height being only 1 high, and thus sx, sy, ex, ey all being // equal, meaning the default as per code without this change results in a // horzontal line. // I was certain I could fix this by changing the calling code to call // drawHorizontal, drawVertical but that didnt work? need to test again. if (hvHint != HV.Undefined) { if (hvHint == HV.Horizontal) { return(DrawVertical(sx, sy, ey, line)); } if (hvHint == HV.Vertical) { return(DrawVertical(sx, sy, ey, line)); } } // horizontal or vertical? if (sy == ey) { return(DrawHorizontal(sx, sy, ex, line)); } if (sx == ex) { return(DrawVertical(sx, sy, ey, line)); } // throw new ArgumentOutOfRangeException("cannot draw diagonal lines"); return(this); }
/// <summary> /// Метод под флаг TemplateTypes.SECURITY, чтобы подключаться к источнику-БА /// </summary> public IList <double> Execute(ISecurity sec) { if (sec == null) { // [{0}] Empty input (security is NULL). string msg = RM.GetStringFormat("OptHandlerMsg.SecurityIsNull", GetType().Name); m_context.Log(msg, MessageType.Warning, true); return(Constants.EmptyListDouble); } Dictionary <DateTime, double> hvSigmas = null; int barLengthInSeconds = m_timeframe; string cashKey = HV.GetGlobalCashKey(sec.Symbol, false, m_useAllData, barLengthInSeconds, m_annualizingMultiplier, m_period); try { object globalObj = Context.LoadGlobalObject(cashKey, true); hvSigmas = globalObj as Dictionary <DateTime, double>; // 'Важный' объект if (hvSigmas == null) { var container = globalObj as NotClearableContainer; if ((container != null) && (container.Content != null)) { hvSigmas = container.Content as Dictionary <DateTime, double>; } } } catch (NotSupportedException nse) { string fName = "", path = ""; if (nse.Data["fName"] != null) { fName = nse.Data["fName"].ToString(); } if (nse.Data["path"] != null) { path = nse.Data["path"].ToString(); } string msg = String.Format("[{0}.PrepareData] {1} when loading 'hvSigmas' from global cache. cashKey: {2}; Message: {3}\r\n\r\nfName: {4}; path: {5}\r\n\r\n{6}", GetType().Name, nse.GetType().FullName, cashKey, nse.Message, fName, path, nse); m_context.Log(msg, MessageType.Warning, true); } catch (Exception ex) { string msg = String.Format("[{0}.PrepareData] {1} when loading 'hvSigmas' from global cache. cashKey: {2}; Message: {3}\r\n\r\n{4}", GetType().Name, ex.GetType().FullName, cashKey, ex.Message, ex); m_context.Log(msg, MessageType.Warning, true); } if (hvSigmas == null) { // Данного ключа в глобальном кеше нет? Тогда выход. // [{0}.PrepareData] There is no HV in global cache. Probably, you have to start agent 'HV (ALL)' for security '{1}'. string msg = RM.GetStringFormat("OptHandlerMsg.GlobalHv.CacheNotFound", GetType().Name, sec); if (m_context.Runtime.IsAgentMode) { throw new ScriptException(msg); } // А если в режиме лаборатории, тогда только жалуемся и продолжаем. m_context.Log(msg, MessageType.Warning, true); return(Constants.EmptyListDouble); } List <double> res = new List <double>(); int len = sec.Bars.Count; if (len <= 0) { return(res); } int oldResLen = res.Count; double prevHv = Double.NaN; for (int j = oldResLen; j < len; j++) { DateTime now = sec.Bars[j].Date; double hv; if ((hvSigmas.TryGetValue(now, out hv)) && (!Double.IsNaN(hv)) && (hv > 0)) { prevHv = hv; res.Add(hv); } else { if (m_repeatLastHv) { if (!Double.IsNaN(prevHv)) { hv = prevHv; } else { hv = Constants.NaN; if (j == 0) { #region Отдельно обрабатываю нулевой бар double tmp = Double.NaN; DateTime foundKey = new DateTime(1, 1, 1); // [2016-02-02] Когда история становится слишком длинной, это может вызывать проблемы // при итерировании в foreach. Потому что другой поток может в этот момент добавить новую точку в коллекцию. int repeat = 7; while (repeat > 0) { tmp = Double.NaN; foundKey = new DateTime(1, 1, 1); try { lock (hvSigmas) { foreach (var kvp in hvSigmas) { if (kvp.Key > now) { continue; } if (foundKey < kvp.Key) { foundKey = kvp.Key; tmp = kvp.Value; } } } repeat = -100; } catch (InvalidOperationException invOpEx) { repeat--; Thread.Sleep(10); if (repeat <= 0) { string msg = String.Format("[{0}.Execute] {1} when iterate through 'hvSigmas'. cashKey: {2}; Message: {3}\r\n\r\n{4}", GetType().Name, invOpEx.GetType().FullName, cashKey, invOpEx.Message, invOpEx); m_context.Log(msg, MessageType.Warning, true); throw; } } } if ((foundKey.Year > 1) && (!Double.IsNaN(tmp)) && (tmp > 0)) { hv = tmp; prevHv = hv; } #endregion Отдельно обрабатываю нулевой бар } } res.Add(hv); } else { res.Add(Constants.NaN); } } } return(res); }