花生网

标题: 金魔方新特性-嵌入C#脚本 [打印本页]

作者: ktdev    时间: 2014-1-19 12:07     标题: 金魔方新特性-嵌入C#脚本

金魔方新特性-嵌入C#脚本 使用说明
金魔方支持公式里直接嵌入C#脚本了,感谢 fantasynew 朋友的建议。 [attach]5996[/attach]
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 函数输出的信息会在 "公式日志" 窗口里显示,可以用这个来输出信息帮助调试。
[attach]5995[/attach]






作者: bluechina    时间: 2014-1-19 14:34

收藏,学习!
作者: 古月908    时间: 2014-1-19 15:57

au3好玩,谢谢老大!
作者: xipies    时间: 2014-1-19 19:50

望C#兴叹!
作者: justtemp    时间: 2014-1-19 21:13

不错~越来越有搞头了~
作者: fantasynew    时间: 2014-1-19 22:57

感谢开发团队,这么快就把这功能做出来了
扩展性更强
作者: nttz    时间: 2014-1-26 09:52

什么时侯支持单步调试
作者: msedu    时间: 2014-1-30 20:46

直接内嵌C++也挺不错嘛!
作者: 18012355268    时间: 2014-1-31 11:24

有罗搞头,我又不会C++
作者: bjdyh    时间: 2014-2-19 13:05


作者: asdf2188    时间: 2014-3-20 17:21

不错,C#比C++好多了。
作者: szyzgx    时间: 2014-4-1 11:26


作者: 信念    时间: 2014-4-28 21:55


作者: leefengqi    时间: 2014-5-22 10:09

太强大了,要好好学习l
作者: smartmanp    时间: 2014-6-1 14:31

能支持lua就更好了。

作者: 312gd    时间: 2014-7-2 22:17


不错!!


作者: fantasynew    时间: 2014-7-27 14:59

  1. using fox.api;
复制代码运行代码
如果是引用别的命名空间,需要把对应dll放到根目录吗?
  1. using AutoItX3Lib;
  2. import AutoItX3.dll;
复制代码运行代码
把对应dll放到fmldll目录下就可以直接使用命名空间?
作者: fantasynew    时间: 2014-7-27 15: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#来引用,该如何写

作者: fantasynew    时间: 2014-7-27 15:17

  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, ' 秒');
复制代码运行代码
从公式编辑器里编译,只出现一个记事本窗口。
在指标里用鼠标中键滚动到下一个证券,出现了两个记事本窗口。
为什么是运行两次呢?我理解逐根应该只出现一个窗口才对。
作者: fantasynew    时间: 2014-7-27 17:07

还有一个问题:
  1. AutoItX3Lib.AutoItX3Class autoit = new AutoItX3Lib.AutoItX3Class();
复制代码运行代码
调用完毕,需要像VBS那样释放com接口吗?

我的理解:
  1. <%#

  2. #%>
复制代码运行代码
是代码的生命周期,被.net自动回收了。是否理解正确?
作者: fantasynew    时间: 2014-7-27 18:38

本帖最后由 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

的问题



作者: fantasynew    时间: 2014-7-27 22:30

代码错误的原因找到了,多写了一个#
作者: fantasynew    时间: 2014-7-28 00:35

  1. Variable : sarr[8]('');
  2. <%#
  3. String[] sarr = (String[])GetVarData("sarr");
  4. %>
复制代码运行代码
字符串数组无法引入
作者: gf66wj88    时间: 2014-10-1 15:55

好好学习天天提高!
作者: rongnaibin    时间: 2014-10-27 23:05


不错~越来越有搞头了~
作者: chunfeng169    时间: 2014-11-16 10:38

精华,实用,赞一个
作者: 8388015    时间: 2014-12-23 20:54


收藏,学习!
作者: 8388015    时间: 2014-12-23 20:54


作者: 好奇的火星    时间: 2015-1-10 20:29

好强大,只是不会用
作者: testware    时间: 2015-2-25 12:54

求救啊,我要在c#脚本中引用已有的DotNet DLL。
可是无论如何都报这样的错误:
error CS0246, The type or namespace name 'TestLib' could not be found.

能否麻烦金魔方提供一个样例?

我尝试着将自己的DLL放到fmldll、金魔方根目录、公式目录以及安装到GAC中,都找不到命名空间。

快崩溃了!!
作者: aman_gu    时间: 2015-3-6 22:04

程序做到这个份上,真是不易。
祝金魔方越做越好!
作者: chmp    时间: 2015-3-11 19:55

金魔方软件功能强大,为能得到最大效用,看来得学C#
作者: wushilu    时间: 2015-4-12 17:39


谢谢楼主
作者: wushilu    时间: 2015-4-12 17:39


谢谢楼主
作者: 天池怪手    时间: 2015-4-21 08:16

学习        
作者: xiaoyouke    时间: 2015-5-10 08:21

看不懂怎么弄
作者: 版图无    时间: 2015-5-19 04:00

很强大!
作者: dglihw    时间: 2015-6-18 09:05

学习了!不错
作者: cmsjdq    时间: 2015-6-28 14:14

看了一下,比较简单,比c51简单,不涉及硬件,容易学习,不错
作者: 天池怪手    时间: 2015-7-18 06:43

学习了!楼主好厉害!
作者: liubing19860405    时间: 2015-7-21 21:40

希望高手多搞点范例,让我们小白学习学习。。
作者: liubing19860405    时间: 2015-7-24 21:45

CSharp_AutoIt例子在我这用不了,不知道是什么原因,代码没有任何改动。AutoItX3.dll‪ 的路径也是D:\KingTrader\FmlDll\AutoItX3.dll。有高手知道原因吗???
作者: zhfeng77    时间: 2015-8-13 12:42

我复制了提供的Autoit代码,但是出现错误,不知道怎么回事啊
DLL也已经拷贝到了对应的Fmldll目录中了
显示错误:System.ExecutionEngineException:  error cs0246: The type or namespace name 'AutoItX3Lib' could not be found.
请楼主帮一下忙,是什么原因,该如何处理,谢谢

作者: 天热热0721    时间: 2015-8-26 02:07

- -.......
作者: zhouxg    时间: 2015-11-10 19:20

有搞头,会C#
作者: jenite    时间: 2015-12-1 00:12

求大神帮忙,编一个小程序,执行的时候报错:dll参数类型调用错误。。。。。。。实在是找不到了呢。。。
//趋势向上返回1,趋势向下返回-1,趋势盘整返回0,以MA20为判断依据
extern void  N.Class1.mytrend(NumericSeries trend, NumericSeries array1, int nk, int mav,int barpos);
<%#
namespace N
{
public class Class1
{
        public void mytrend(int[] trend, float[] array1, int nk,int mav, int barpos)
        {
                if(barpos>mav){
                        int count1=0,count2=0;
                        for(int i=0;i<nk;i++){
                                if(array1[i]>=array1[i+1]){count1++;continue;}
                                if(array1[i]<array1[i+1]){count2++;continue;}
                                }
                        if(count1==nk)trend[barpos-1]=20;
                        else if(count2==nk)trend[barpos-1]=-20;
                        else trend[barpos-1]=0;
                        }
                else
                        trend[barpos-1]=0;
        }
}
}
%>
//input:NN(5,5,100),Mav(20,10,180);//N日走势确定Mavar日趋势线
trend:0;
M:ma(C,20);
mytrend(trend,M,5,20,barpos);
作者: luogan129    时间: 2015-12-26 20:08

非常感谢
作者: jamesni88    时间: 2015-12-27 04:56

不错
作者: tanghe791    时间: 2016-3-13 14:48

很好,谢谢你啊,辛苦了~~
作者: pachen949    时间: 2016-4-2 07:49

看看吧....
作者: pachen949    时间: 2016-4-4 15:51

牛牛牛牛呀
作者: pachen949    时间: 2016-4-6 08:23

不错!值得学习,楼主继续
作者: windir    时间: 2016-4-11 19:55

还是直接windows api系统性能要好的多啊,就是难度大
作者: mougua783    时间: 2016-4-13 10:44

真不错,赞一个,继续努力啊
作者: louhaihua    时间: 2016-5-18 15:27

管理员你好,我用 AutoItX3来操作股票下单软件成功
问题是,用金魔方写的指标线,画不出来。。。似乎是AutoItX3,在一直读,不休息一样
作者: 本宫不死    时间: 2016-5-20 10:09

说的好,一定回复~
作者: susfly    时间: 2016-6-12 23:20

很棒,祝越来越好
作者: doned    时间: 2016-6-16 15:48

学习了,待研究
作者: willyxinqq    时间: 2016-6-21 13:50

收藏,学习!
作者: canbao    时间: 2016-7-13 10:52

学习了,真好!
作者: mopimg    时间: 2016-12-10 23:03

asdf2188 发表于 2014-3-20 17:21
不错,C#比C++好多了。

这个有什么作用啊

作者: xiaoyouke    时间: 2017-1-15 10:02

C#很强大,金魔方更强大
作者: 橘香    时间: 2017-2-13 11:12

沙发,板凳都没偶的份了。
作者: 金敏    时间: 2017-4-18 00:45

学习啦!谢谢。
作者: monkfair    时间: 2017-11-30 18:51

谢谢!!!
作者: gnuhub    时间: 2018-1-21 15:36

谢谢分享,万分感谢!




欢迎光临 花生网 (http://www.hs633.com/) Powered by Discuz! X2