/// <summary> /// 获取K线静态数值 /// </summary> /// <param name="div">K线层</param> private void SetCandleStaticValue(SandBoxCandleDiv div) { SecurityData data = div.Data; SpinA spinOpen = GetSpin("txtOpen"); SpinA spinClose = GetSpin("txtClose"); SpinA spinHigh = GetSpin("txtHigh"); SpinA spinLow = GetSpin("txtLow"); SpinA spinVolume = GetSpin("txtVolume"); SpinA spinAmount = GetSpin("txtAmount"); LabelA lblDate = GetLabel("lblDate"); data.m_open = (float)spinOpen.Value; data.m_close = (float)spinClose.Value; data.m_high = (float)spinHigh.Value; data.m_low = (float)spinLow.Value; data.m_volume = spinVolume.Value; data.m_amount = spinAmount.Value; String strDate = lblDate.Text; if (strDate != null && strDate.Length > 0) { data.m_date = m_chart.Chart.ConvertDateToNum(Convert.ToDateTime(strDate)); } div.Data = data; }
/// <summary> /// 销毁方法 /// </summary> public override void Dispose() { if (!IsDisposed) { int divsSize = m_divs.Count; for (int i = 0; i < divsSize; i++) { SandBoxCandleDiv div = m_divs[i]; if (div.Moving) { m_native.RemoveControl(div); } else { m_window.RemoveControl(div); } div.Dispose(); } m_divs.Clear(); if (m_window != null) { m_window.UnRegisterEvent(m_timerEvent, EVENTID.TIMER); m_timerEvent = null; m_window.StopTimer(m_timerID); m_window.Close(); m_window.Dispose(); m_window = null; } base.Dispose(); } }
/// <summary> /// 添加 /// </summary> private void Add() { INativeBase native = Native; int divsSize = m_divs.Count; for (int i = 0; i < divsSize; i++) { SandBoxCandleDiv div = m_divs[i]; if (!div.Moving) { int clientX = native.ClientX(div); int clientY = native.ClientY(div); int direction = 0; if (clientY < 100) { direction = 1; clientY += 150; } else { clientY -= 150; } m_window.RemoveControl(div); div.Parent = null; m_native.AddControl(div); POINT newLocation = new POINT(clientX, clientY); div.Direction = direction; div.Location = newLocation; div.Moving = true; } } CreateNextData(true); CreatePreView(); m_native.Invalidate(); }
/// <summary> /// 执行秒表方法 /// </summary> /// <param name="timerID">秒表ID</param> public void OnTimer(int timerID) { if (m_timerID == timerID) { INativeBase native = Native; ChartA chart = m_chart.Chart; CTable dataSource = chart.DataSource; int divsSize = m_divs.Count; bool painting = false; int cx = native.ClientX(m_window); int cy = native.ClientY(m_window); List <SandBoxCandleDiv> removeDivs = new List <SandBoxCandleDiv>(); for (int i = 0; i < divsSize; i++) { SandBoxCandleDiv div = m_divs[i]; //判断是否需要重绘 if (div.Moving) { painting = true; } //执行秒表 if (m_divs[i].OnTimer()) { SecurityData data = div.Data; int rowIndex = dataSource.GetRowIndex(data.m_date); int[] fields = new int[7]; fields[0] = KeyFields.CLOSE_INDEX; fields[1] = KeyFields.HIGH_INDEX; fields[2] = KeyFields.LOW_INDEX; fields[3] = KeyFields.OPEN_INDEX; fields[4] = KeyFields.VOL_INDEX; fields[5] = KeyFields.AMOUNT_INDEX; fields[6] = KeyFields.AVGPRICE_INDEX; //插入数据 SecurityDataHelper.InsertLatestData(m_chart.Chart, dataSource, m_chart.Indicators, fields, data); removeDivs.Add(div); } } //移除控件 int removeDivsSize = removeDivs.Count; if (removeDivsSize > 0) { for (int i = 0; i < removeDivsSize; i++) { SandBoxCandleDiv div = removeDivs[i]; m_native.RemoveControl(div); m_divs.Remove(div); div.Dispose(); } removeDivs.Clear(); m_chart.Chart.Update(); } //重绘 if (painting) { m_native.Invalidate(); } } }
/// <summary> /// 根据输入的高开低收数据,生成K线预览图形 /// </summary> private void CreatePreView() { POINT newPoint = new POINT(); SIZE newSize = m_defaultCandleSize; float separator = 0; CreateCandleSize(ref newSize, ref separator); CreateCandlePos(newSize, separator, ref newPoint); SandBoxCandleDiv div = new SandBoxCandleDiv(); div.Chart = m_chart; div.Size = newSize; div.Location = newPoint; SetCandleStaticValue(div); m_window.AddControl(div); m_divs.Add(div); m_native.Invalidate(); }
/// <summary> /// 创建K线的尺寸 /// </summary> /// <param name="newSize">K线的大小</param> /// <param name="separator">K线间隔</param> private void CreateCandleSize(ref SIZE newSize, ref float separator) { int divsSize = m_divs.Count; int waitDivsSize = 0; for (int i = 0; i < divsSize; i++) { if (!m_divs[i].Moving) { waitDivsSize++; } } if (waitDivsSize == 0) { newSize.cx = m_defaultCandleSize.cx; newSize.cy = m_defaultCandleSize.cy; separator = 20; return; } int cw = m_defaultCandleSize.cx - waitDivsSize; int ch = m_defaultCandleSize.cy - waitDivsSize * (m_defaultCandleSize.cy / m_defaultCandleSize.cx); separator = 20 - divsSize * 0.67F; if (cw < 3) { cw = 3; ch = 6; } // 缩短K线之间的间距 if (separator < 0.5F) { separator = 0.5F; } newSize.cx = cw; newSize.cy = ch; for (int i = 0; i < divsSize; i++) { SandBoxCandleDiv div = m_divs[i]; if (!div.Moving) { div.Size = newSize; } } }
/// <summary> /// 数值输入变化方法 /// </summary> /// <param name="spinA">数值控件</param> public void OnSpinTextChanged(SpinA spin) { int divsSize = m_divs.Count; for (int i = 0; i < divsSize; i++) { SandBoxCandleDiv div = m_divs[i]; if (!div.Moving) { SecurityData data = div.Data; String name = spin.Name; double value = spin.Value; if (name == "txtOpen") { data.m_open = (float)value; } else if (name == "txtClose") { data.m_close = (float)value; } else if (name == "txtHigh") { data.m_high = (float)value; } else if (name == "txtLow") { data.m_low = (float)value; } else if (name == "txtVolume") { data.m_volume = value; } else if (name == "txtAmount") { data.m_amount = value; } div.Data = data; m_native.Invalidate(); break; } } }
/// <summary> /// 创建K线的位置 /// </summary> /// <param name="size">创建K线的大小</param> /// <param name="candleSeparater">创建的K线间隔</param> /// <param name="newPoint">创建的K线位置</param> private void CreateCandlePos(SIZE size, float candleSeparater, ref POINT newPoint) { SIZE wSize = m_window.Size; int divsSize = m_divs.Count; int waitDivsSize = 0; for (int i = 0; i < divsSize; i++) { if (!m_divs[i].Moving) { waitDivsSize++; } } if (waitDivsSize == 0) { newPoint.x = m_defaultCandleLocation.x; newPoint.y = m_defaultCandleLocation.y; return; } float xPosition = 0; float rightTotalWidth = (m_defaultWindowSize.cx - 20) / 0.618F; float divideWidth = rightTotalWidth / (waitDivsSize + 1); float start = 0, end = 0; for (int i = 0; i < divsSize; i++) { SandBoxCandleDiv div = m_divs[i]; if (!div.Moving) { end = start + divideWidth; xPosition = (start + end) / 2 + m_defaultWindowSize.cx; newPoint.x = (int)xPosition; newPoint.y = m_defaultCandleLocation.y; div.Location = newPoint; start = end; } } end = start + divideWidth; xPosition = (start + end) / 2 + m_defaultWindowSize.cx; newPoint.x = (int)xPosition; newPoint.y = m_defaultCandleLocation.y; }