欢迎您光临博庭社区!

 找回密码
 立即注册
查看: 16437|回复: 26

金魔方新特性-嵌入C#脚本 [复制链接]

Rank: 9Rank: 9Rank: 9

发表于 2014-1-19 12:07:50 |显示全部楼层
金魔方新特性-嵌入C#脚本 使用说明
金魔方支持公式里直接嵌入C#脚本了,感谢 fantasynew 朋友的建议。
1.如何嵌入 C# 脚本
嵌入C#脚本和嵌入 VBScript 脚本类似.
嵌入 VBScript  使用<% %>
嵌入 C#多加一个# 就是 <%# %>


以下是一个改自飞狐 VBScript 的例子 改成 C#如下
  1. #MAINCHART
  2. 涨停价:C;
  3. <%#
  4. float[] ztj = (float[])GetVarData("涨停价");
  5. for (int i = 0; i < ztj.Length; i++)
  6.         ztj[i] = ztj[i] * (float)1.1;
  7. SetVarData("涨停价", ztj);
  8. %>
复制代码


2.嵌入C#脚本的三种模式
最简单的模式就是以上例子里写的,直接写C#语句,这种模式的优点是简单,不需要关心类,对象是什么,缺点是不能定义函数。
完整的模式则需要理解C#的类,命名空间等,也就是需要写一个完整的C# 类,优点是可以定义自己的函数来调用,可以用类成员变量来保存状态等。
以下是把例1里的脚本改成完整模式
  1. #MAINCHART
  2. 涨停价:C;
  3. <%#
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using fox.api;
  9. namespace N{
  10.     //  从 fox.api.Formula 继承 这样才能用 GetVarData, SetVarData
  11.         //  完整模式,需要定义命名空间,类,还必须定义个  Execute 函数作为入口点
  12.     public class Class1 : Formula{
  13.    public void Execute(){
  14.       float[] ztj = (float[])GetVarData("涨停价");
  15.       for (int i = 0; i < ztj.Length; i++)
  16.          ztj[i] = CalcZTJ(ztj[i]) ;
  17.       SetVarData("涨停价", ztj);
  18.    }
  19.    public float CalcZTJ(float fPrice){
  20.          return fPrice*(float)1.1;
  21.    }  
  22.     }
  23. }
  24. %>
复制代码
以上是完整模式的例子之一,需要从Formua继承,并实现 Execute 方法,你也可以定义别函数,并且调用,就像上面的例子里的 定义了一个 CalcZTJ 计算涨停价的函数,并调用。


另外一种完整模式的用法是:在脚本里定义函数,然后在公式里显式调用,就像调用dll里的函数一样
看以下例子,定义了一个 算 MA的函数,并在公式里调用。
  1. // 新dll接口调用规范只能在逐根模式下运行,因此要RUN_BY_BAR
  2. // 此公式适用于日线
  3. #MainChart
  4. #RUN_BY_BAR
  5. #NoDefaultOutPut
  6. // 这个函数声明表示 嵌入脚本里面 命名空间N中类名为Class1的成员函数my_ma
  7. extern void  N.Class1.my_ma(NumericSeries resultArray, NumericSeries array1, int n, int barpos);
  8. //C#脚本实现函数my_ma                                                               
  9. <%#
  10. namespace N
  11. {
  12. public class Class1
  13.     {
  14.         public void my_ma(ref float[] resultArray,  float[] array, int n, int barpos)
  15.         {
  16.                         int nK = barpos - 1;
  17.                         if (barpos >= n)
  18.                         {
  19.                                 float sum = 0;
  20.                                 for (int i = 0; i < n; i++)
  21.                                         sum += array[nK - i];
  22.                                 resultArray[nK] = sum / n;
  23.                         }
  24.                         else
  25.                                 resultArray[nK] = float.NaN;
  26.         }

  27.     }
  28. }
  29. %>
  30. ma1:0;
  31. my_ma(ma1, close, 5, barpos);//注意调用my_ma必须放在脚本后面调用
复制代码


3.如何在C#脚本调用 COM 组件
Winddows下,很多第三方库都是以 COM 组件 dll形式存在的。比如 AutoItX3 ,很人多用来做股票自动下单。
在金魔方嵌入的C#脚本里,可以使用using 和 import 来 很容易调用这样的dll.
以下是调用AutoItX3  来自动控制打开记事本并输入文字的例子
  1. #MainChart
  2. Variable : 记事本状态栏上的文字('');
  3. <%#
  4. using AutoItX3Lib;
  5. import AutoItX3.dll;

  6. AutoItX3Lib.AutoItX3Class autoit = new AutoItX3Lib.AutoItX3Class();
  7. autoit.Run("notepad.exe", "", 1);
  8. autoit.WinWaitActive("无标题 -", "", 1);
  9. autoit.Send(" Hello{!}", 0);
  10. string text = autoit.StatusbarGetText("无标题 -", "", 2);
  11. SetVarData("记事本状态栏上的文字", text);
  12. %>
  13. Comment('已经打开 记事本 并输入了 Hello\n记事本 状态栏上的文字是:'+记事本状态栏上的文字);
复制代码
import 后面的dll可以全路径,也可以直接写dll名字,如果只写dll名字,首先会在公式所在路径找,然后在fmldll找,最后还会在 金魔方根目录下找,你可以把dll放在以上任意地方。
using 后面需要写命名空间,一般来说,如果 import 的是 XXX.dll, using  后面的命名空间 就是 XXXLib


4.C#脚本如何调试和除错
默认情况下,编译错误都是能定位到行号的。
如果是运行类错误或者异常,默认情况是定位不到行号的,需要在 "工具“ 菜单里,选择 ”C#脚本调试",勾选了这个后,如果有异常可以定位到哪一行的代码问题。
另外  勾选了 ”C#脚本调试" 后,在 C# 代码里 的 Console.WriteLine 函数输出的信息会在 "公式日志" 窗口里显示,可以用这个来输出信息帮助调试。






附件: 你需要登录才可以下载或查看附件。没有帐号?立即注册

使用道具 举报

Rank: 2

发表于 2014-10-27 23:05:50 |显示全部楼层

不错~越来越有搞头了~

使用道具 举报

Rank: 2

发表于 2014-10-1 15:55:34 |显示全部楼层
好好学习天天提高!

使用道具 举报

Rank: 6Rank: 6

发表于 2014-7-28 00:35:36 |显示全部楼层
  1. Variable : sarr[8]('');
  2. <%#
  3. String[] sarr = (String[])GetVarData("sarr");
  4. %>
复制代码
字符串数组无法引入

使用道具 举报

Rank: 6Rank: 6

发表于 2014-7-27 22:30:20 |显示全部楼层
代码错误的原因找到了,多写了一个#

使用道具 举报

Rank: 6Rank: 6

发表于 2014-7-27 18:38:56 |显示全部楼层
本帖最后由 fantasynew 于 2014-7-27 20:13 编辑
  1. <%#
  2. using AutoItX3Lib;
  3. //import AutoItX3dll;
  4. #%>
复制代码

提示未能找到元数据文件“AutoItX3dll”,说明对//注释代码的处理不正确。
  1. <%#
  2. using System.Speech.Synthesis;
  3. using System.Speech;
  4. using System.Speech.Recognition;
  5. import System.Speech.dll;
  6. #%>
复制代码

提示CS1024:应输入预处理器指令,System.Speech.dll已复制到fmldll下。
直接用路径引用.net目录下的System.Speech.dll同样报错。

应该是
import

的问题


使用道具 举报

Rank: 6Rank: 6

发表于 2014-7-27 17:07:09 |显示全部楼层
还有一个问题:
  1. AutoItX3Lib.AutoItX3Class autoit = new AutoItX3Lib.AutoItX3Class();
复制代码
调用完毕,需要像VBS那样释放com接口吗?

我的理解:
  1. <%#

  2. #%>
复制代码
是代码的生命周期,被.net自动回收了。是否理解正确?

使用道具 举报

Rank: 6Rank: 6

发表于 2014-7-27 15:17:46 |显示全部楼层
  1. Variable : 记事本状态栏上的文字('');
  2. extern 'kernel32.dll' int GetTickCount();
  3. startTime = GetTickcount();
  4. <%#
  5. using AutoItX3Lib;
  6. import AutoItX3.dll;

  7. AutoItX3Lib.AutoItX3Class autoit = new AutoItX3Lib.AutoItX3Class();
  8. autoit.Run("notepad.exe", "", 1);
  9. //autoit.WinWaitActive("无标题 -", "", 1);
  10. //autoit.Send(" Hello{!}", 0);
  11. //string text = autoit.StatusbarGetText("无标题 -", "", 2);
  12. //SetVarData("记事本状态栏上的文字", text);
  13. %>
  14. //Comment('已经打开 记事本 并输入了 Hello\n记事本 状态栏上的文字是:'+记事本状态栏上的文字);
  15. endTime1 = GetTickcount();
  16. spent= endTime1 - startTime;
  17. Comment('运行耗时:', spent/1000, ' 秒');
复制代码
从公式编辑器里编译,只出现一个记事本窗口。
在指标里用鼠标中键滚动到下一个证券,出现了两个记事本窗口。
为什么是运行两次呢?我理解逐根应该只出现一个窗口才对。

使用道具 举报

Rank: 6Rank: 6

发表于 2014-7-27 15:02:02 |显示全部楼层
  1. using AutoItX3Lib;
  2. import AutoItX3.dll;
复制代码
如果是别的com接口呢,怎样用上面的调用方法?
  1. <%
  2. dim obj
  3. Set obj= CreateObject("SAPI.SpVoice")
  4. obj.Speak "LOVE"
  5. Set obj = nothing
  6. %>
复制代码
例如上面这段,用C#来引用,该如何写

使用道具 举报

Rank: 6Rank: 6

发表于 2014-7-27 14:59:31 |显示全部楼层
  1. using fox.api;
复制代码
如果是引用别的命名空间,需要把对应dll放到根目录吗?
  1. using AutoItX3Lib;
  2. import AutoItX3.dll;
复制代码
把对应dll放到fmldll目录下就可以直接使用命名空间?

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

bottom

Archiver|http://www.patiosoft.com

GMT+8, 2018-9-18 23:55 , Processed in 1.062506 second(s), 12 queries .

花生网 Copyrigh©2012

和讯信息科技有限公司 ALL Rights Reserved 版权所有 复制必究

回顶部