/// <summary> /// 创建方法 /// </summary> /// <param name="indicator">指标</param> /// <param name="id">ID</param> /// <param name="name">名称</param> /// <param name="withParameters">是否有参数</param> public NFunctionBase(FCScript indicator, int id, String name, FCNative native) { m_indicator = indicator; m_ID = id; m_name = name; m_native = native; }
/// <summary> /// 创建方法 /// </summary> /// <param name="indicator">指标</param> /// <param name="id">ID</param> /// <param name="name">名称</param> /// <param name="withParameters">是否有参数</param> public NFunctionEx(FCScript indicator, int id, String name, FCUIXml xml) { m_indicator = indicator; m_ID = id; m_name = name; m_xml = xml; }
/// <summary> /// 创建指标 /// </summary> /// <param name="id">编号</param> /// <param name="script">脚本</param> /// <param name="xml">XML</param> /// <returns>指标</returns> public static FCScript createIndicator(String id, String script, FCUIXml xml) { FCScript indicator = new FCScript(); indicator.Name = id; FCDataTable table = new FCDataTable(); indicator.DataSource = table; NFunctionBase.addFunctions(indicator); NFunctionUI.addFunctions(indicator, xml); NFunctionWin.addFunctions(indicator); int index = STARTINDEX; String[] functions = FUNCTIONS.Split(new String[] { "," }, StringSplitOptions.RemoveEmptyEntries); int functionsSize = functions.Length; for (int i = 0; i < functionsSize; i++) { indicator.addFunction(new NFunctionEx(indicator, index + i, functions[i], xml)); } indicator.Script = script; table.addColumn(0); table.set(0, 0, 0); indicator.onCalculate(0); return(indicator); }
/// <summary> /// 启动线程 /// </summary> /// <param name="param">参数</param> private void createThread(object param) { FCScript indicator = CreateScript(FCHttpMonitor.MainMonitor.Script, m_native); indicator.callFunction(param.ToString()); indicator.delete(); }
/// <summary> /// 计算指标 /// </summary> /// <param name="id">指标ID</param> /// <param name="code">代码</param> /// <param name="path">路径</param> /// <param name="type">类型</param> /// <param name="cycle">周期</param> /// <param name="subscription">复权方式</param> /// <param name="date">日期</param> /// <param name="open">开盘价</param> /// <param name="high">最高价</param> /// <param name="low">最低价</param> /// <param name="close">收盘价</param> /// <param name="volume">成交量</param> /// <param name="amount">成交额</param> /// <returns>返回数据</returns> public static double[] calculateIndicatorExtern(int id, String code, ref double result) { if (m_indicators.ContainsKey(id)) { FCScript indicator = m_indicators[id]; List <FCScript> indicators = new List <FCScript>(); indicators.Add(indicator); List <SecurityData> datas = new List <SecurityData>(); if (SecurityService.m_historyDatas.ContainsKey(code)) { datas = SecurityService.m_historyDatas[code]; SecurityLatestData latestData = null; if (SecurityService.m_latestDatas.ContainsKey(code)) { latestData = SecurityService.m_latestDatas[code]; } if (latestData != null) { SecurityData newData = new SecurityData(); getSecurityData(latestData, latestData.m_lastClose, 1440, 0, ref newData); if (datas.Count == 0) { datas.Add(newData); } else { if (newData.m_date > datas[datas.Count - 1].m_date) { datas.Add(newData); } else { datas[datas.Count - 1] = newData; } } } FCDataTable dataSource = indicator.DataSource; int[] fields = new int[] { KeyFields.CLOSE_INDEX, KeyFields.HIGH_INDEX, KeyFields.LOW_INDEX, KeyFields.OPEN_INDEX, KeyFields.VOL_INDEX, KeyFields.AMOUNT_INDEX }; SecurityDataHelper.bindHistoryDatas(m_chart, dataSource, indicators, fields, datas);; int rowsCount = dataSource.RowsCount; int variablesSize = indicator.MainVariables.Count; double[] list = new double[variablesSize]; if (rowsCount > 0) { int pos = 0; foreach (String name in indicator.MainVariables.Keys) { int field = indicator.MainVariables[name]; double value = dataSource.get2(rowsCount - 1, field); list[pos] = value; pos++; } } result = indicator.m_result; dataSource.clear(); return(list); } } return(null); }
/// <summary> /// 添加方法 /// </summary> /// <param name="indicator">方法库</param> /// <param name="native">脚本</param> /// <param name="xml">XML</param> /// <returns>指标</returns> public static void addFunctions(FCScript indicator, FCNative native) { string[] functions = FUNCTIONS.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); int functionsSize = functions.Length; for (int i = 0; i < functionsSize; i++) { indicator.addFunction(new NFunctionBase(indicator, STARTINDEX + i, PREFIX + functions[i], native)); } }
/// <summary> /// 删除指标 /// </summary> /// <param name="id">指标ID</param> public static void deleteIndicatorExtern(int id) { if (m_indicators.ContainsKey(id)) { FCScript indicator = m_indicators[id]; m_indicators.Remove(id); indicator.clear(); indicator.DataSource.delete(); indicator.DataSource = null; indicator.delete(); } }
/// <summary> /// 添加指标 /// </summary> /// <param name="chart">股票控件</param> /// <param name="dataSource">数据源</param> /// <param name="text">文本</param> /// <param name="parameters">参数</param> public static FCScript createIndicator(FCChart chart, FCDataTable dataSource, String text, String parameters) { FCScript indicator = new FCScript(); indicator.DataSource = dataSource; indicator.Name = ""; //indicator.FullName = ""; if (dataSource != null) { indicator.setSourceField(KeyFields.CLOSE, KeyFields.CLOSE_INDEX); indicator.setSourceField(KeyFields.HIGH, KeyFields.HIGH_INDEX); indicator.setSourceField(KeyFields.LOW, KeyFields.LOW_INDEX); indicator.setSourceField(KeyFields.OPEN, KeyFields.OPEN_INDEX); indicator.setSourceField(KeyFields.VOL, KeyFields.VOL_INDEX); indicator.setSourceField(KeyFields.AMOUNT, KeyFields.AMOUNT_INDEX); indicator.setSourceField(KeyFields.CLOSE.Substring(0, 1), KeyFields.CLOSE_INDEX); indicator.setSourceField(KeyFields.HIGH.Substring(0, 1), KeyFields.HIGH_INDEX); indicator.setSourceField(KeyFields.LOW.Substring(0, 1), KeyFields.LOW_INDEX); indicator.setSourceField(KeyFields.OPEN.Substring(0, 1), KeyFields.OPEN_INDEX); indicator.setSourceField(KeyFields.VOL.Substring(0, 1), KeyFields.VOL_INDEX); indicator.setSourceField(KeyFields.AMOUNT.Substring(0, 1), KeyFields.AMOUNT_INDEX); } IndicatorData indicatorData = new IndicatorData(); indicatorData.m_parameters = parameters; indicatorData.m_script = text; indicator.Tag = indicatorData; String constValue = ""; if (parameters != null && parameters.Length > 0) { String[] strs = parameters.Split(new String[] { ";" }, StringSplitOptions.RemoveEmptyEntries); int strsSize = strs.Length; for (int i = 0; i < strsSize; i++) { String str = strs[i]; String[] strs2 = str.Split(new String[] { "," }, StringSplitOptions.RemoveEmptyEntries); constValue += "const " + strs2[0] + ":" + strs2[3] + ";"; } } if (text != null && text.Length > 0) { indicator.Script = constValue + text; } return(indicator); }
/// <summary> /// 启动监听 /// </summary> public void start() { m_useScript = FCFile.isFileExist(m_fileName); if (m_useScript) { m_native = new FCNative(); FCFile.read(m_fileName, ref m_script); m_indicator = CFunctionEx.CreateScript(m_script, m_native); Console.WriteLine(m_script); } try { //string host = "127.0.0.1"; //IPAddress ip = IPAddress.Parse(host); if (m_indicator != null) { m_indicator.callFunction("ONHTTPSERVERSTARTING('" + m_fileName + "');"); } IPEndPoint ipe = new IPEndPoint(IPAddress.Any, m_port); m_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); m_listener.Bind(ipe); m_listener.Listen(0); } catch (Exception ex) { if (m_indicator != null) { m_indicator.callFunction("ONHTTPSERVERSTARTFAIL('" + ex.Message + "\r\n" + ex.StackTrace + "');"); } return; } int minThreadNum = 0, portThreadNum = 0, maxThreadNum = 0; ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum); ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum); if (m_indicator != null) { m_indicator.callFunction("ONHTTPSERVERSTART(" + FCStr.convertIntToStr(maxThreadNum) + "," + FCStr.convertIntToStr(minThreadNum) + ");"); } while (true) { Socket socket = m_listener.Accept(); ThreadPool.QueueUserWorkItem(new WaitCallback(readData), socket); } m_listener.Close(); }
/// <summary> /// 创建指标 /// </summary> /// <param name="text">脚本</param> /// <param name="parameters">参数</param> /// <returns>指标ID</returns> public static int createIndicatorExtern(String text, String parameters, StringBuilder fields) { try { if (m_native == null) { m_native = new FCNative(); } if (m_chart == null) { m_chart = new FCChart(); m_chart.Native = m_native; } m_serialNumber++; FCDataTable dataSource = new FCDataTable(); dataSource.addColumn(KeyFields.CLOSE_INDEX); dataSource.addColumn(KeyFields.HIGH_INDEX); dataSource.addColumn(KeyFields.LOW_INDEX); dataSource.addColumn(KeyFields.OPEN_INDEX); dataSource.addColumn(KeyFields.VOL_INDEX); dataSource.addColumn(KeyFields.AMOUNT_INDEX); FCScript indicator = SecurityDataHelper.createIndicator(m_chart, dataSource, text, parameters); m_indicators[m_serialNumber] = indicator; indicator.onCalculate(0); int pos = 0; int variablesSize = indicator.MainVariables.Count; foreach (String field in indicator.MainVariables.Keys) { fields.Append(field); if (pos != variablesSize - 1) { fields.Append(","); } pos++; } } catch (Exception ex) { Console.WriteLine(ex.Message + "\r\n" + ex.StackTrace); } return(m_serialNumber); }
/// <summary> /// 创建指标 /// </summary> /// <param name="native">方法库</param> /// <param name="script">脚本</param> /// <returns>指标</returns> public static FCScript CreateScript(String script, FCNative native) { FCScript indicator = new FCScript(); FCDataTable table = new FCDataTable(); indicator.DataSource = table; CFunctionBase.addFunctions(indicator); CFunctionHttp.addFunctions(indicator); int index = STARTINDEX; string[] functions = FUNCTIONS.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); int functionsSize = functions.Length; for (int i = 0; i < functionsSize; i++) { indicator.addFunction(new CFunctionEx(indicator, index + i, functions[i], native)); } indicator.Script = script; table.addColumn(0); table.set(0, 0, 0); indicator.onCalculate(0); return(indicator); }
/// <summary> /// 检查脚本 /// </summary> public void checkScript() { String newScript = ""; FCFile.read(m_fileName, ref newScript); if (m_script != newScript) { Console.WriteLine("检测到脚本被修改..."); m_script = newScript; lock (m_indicators) { while (true) { try { FCScript indicator = m_indicators.Pop(); indicator.delete(); } catch { break; } } } } }
/// <summary> /// 创建方法 /// </summary> /// <param name="indicator">指标</param> /// <param name="id">ID</param> /// <param name="name">名称</param> public CFunctionBase(FCScript indicator, int id, String name) { m_indicator = indicator; m_ID = id; m_name = name; }
/// <summary> /// 设置脚本 /// </summary> /// <param name="text">脚本</param> public void setText(String text) { m_text = text; m_script = NFunctionEx.createIndicator(text, m_xml); }
/// <summary> /// 接受请求 /// </summary> /// <param name="param">参数</param> private static void readData(object param) { Socket socket = (Socket)param; FCHttpMonitor nodeService = FCHttpMonitor.MainMonitor; int newSocketID = (int)socket.Handle; try { byte[] buffer = new byte[102400]; int len = socket.Receive(buffer); MemoryStream memoryStream = new MemoryStream(buffer); StreamReader reader = new StreamReader(memoryStream); FCHttpData data = new FCHttpData(); data.m_remoteIP = ((IPEndPoint)socket.RemoteEndPoint).Address.ToString(); data.m_remotePort = ((IPEndPoint)socket.RemoteEndPoint).Port; String requestHeader; int contentLength = 0; string parameters = ""; while ((requestHeader = reader.ReadLine()) != null && !String.IsNullOrEmpty(requestHeader)) { String lowerHeader = requestHeader.ToLower(); if (lowerHeader.IndexOf("get") == 0) { int end = lowerHeader.IndexOf("http/"); data.m_method = "GET"; parameters = requestHeader.Substring(5, end - 6); } else if (lowerHeader.IndexOf("post") == 0) { int end = lowerHeader.IndexOf("http/"); data.m_method = "POST"; parameters = requestHeader.Substring(5, end - 6); } else if (lowerHeader.IndexOf("accept: ") == 0) { try { data.m_contentType = requestHeader.Substring(8, requestHeader.IndexOf(',') - 8); } catch { } } else if (lowerHeader.IndexOf("content-type:") == 0) { data.m_contentType = requestHeader.Substring(14); } else if (lowerHeader.IndexOf("host:") == 0) { data.m_url = requestHeader.Substring(requestHeader.IndexOf(':') + 2); } else if (lowerHeader.IndexOf("content-length") == 0) { int begin = lowerHeader.IndexOf("content-length:") + "content-length:".Length; String postParamterLength = requestHeader.Substring(begin).Trim(); contentLength = Convert.ToInt32(postParamterLength); } } if (contentLength > 0) { int idx = 0, ide = 0; data.m_body = new byte[contentLength]; while (idx < contentLength) { int recvData = reader.Read(); if (recvData != -1) { if (recvData != 0) { ide++; } idx++; } else { break; } } reader.Close(); memoryStream.Dispose(); if (ide == 0) { socket.Receive(data.m_body); } else { for (int i = 0; i < contentLength; i++) { data.m_body[i] = buffer[len - contentLength + i]; } } data.m_contentLength = contentLength; } else { reader.Close(); memoryStream.Dispose(); } if (data.m_method.Length == 0) { return; } int cindex = parameters.IndexOf('?'); if (cindex != -1) { data.m_url = data.m_url + "/" + parameters; parameters = parameters.Substring(cindex + 1); String[] strs = parameters.Split(new string[] { "&" }, StringSplitOptions.RemoveEmptyEntries); int strsSize = strs.Length; for (int i = 0; i < strsSize; i++) { String[] subStrs = strs[i].Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries); data.m_parameters.put(subStrs[0].ToLower(), subStrs[1]); } } else { data.m_url += "/" + parameters; } FCScript indicator = null; if (nodeService.UseScript) { try { lock (nodeService.m_indicators) { indicator = nodeService.m_indicators.Pop(); } } catch { indicator = CFunctionEx.CreateScript(nodeService.Script, nodeService.Native); } ArrayList <CFunction> functions = indicator.getFunctions(); int functionsSize = functions.Count; for (int i = 0; i < functionsSize; i++) { CFunctionHttp function = functions.get(i) as CFunctionHttp; if (function != null) { function.m_data = data; } } } data.m_socketID = newSocketID; lock (nodeService.m_httpDatas) { nodeService.m_httpDatas.put(newSocketID, data); } if (indicator != null) { indicator.callFunction("ONHTTPREQUEST();"); } if (data.m_close) { return; } int resContentLength = 0; if (data.m_resBytes != null) { resContentLength = data.m_resBytes.Length; } else { if (data.m_resStr != null) { resContentLength = Encoding.Default.GetBytes(data.m_resStr).Length; } } StringBuilder bld = new StringBuilder(); bld.Append("HTTP/1.0 " + data.m_statusCode.ToString() + " OK\r\n"); bld.Append(String.Format("Content-Length: {0}\r\n", resContentLength)); bld.Append("Connection: close\r\n\r\n"); if (data.m_resBytes != null) { socket.Send(Encoding.Default.GetBytes(bld.ToString())); socket.Send(data.m_resBytes); } else { bld.Append(data.m_resStr); socket.Send(Encoding.Default.GetBytes(bld.ToString())); } if (indicator != null) { lock (nodeService.m_indicators) { nodeService.m_indicators.Push(indicator); } } } catch (Exception ex) { Console.WriteLine(ex.Message + "\r\n" + ex.StackTrace); } finally { lock (nodeService.m_httpDatas) { nodeService.m_httpDatas.Remove(newSocketID); } socket.Close(); } }