分享

MetaTrader 4 自动中文语音报价脚本

 素人堂 2015-09-08
   自动语音报价.mq4这个脚本是用来配合MT4平台再汇率变动时进行中文语音的
自动报价, 具体包含有如下功能:
1. 可以设置使用买入价或者卖出价.
2. 可以设置两次语音报价之间的最小时间间隔.
3. 可以设置是否报出交易货币名称
4. 可以设置是否报出两次报价之间的点数变动
5. 可以设置两组需要进行语音报价的点数范围
 
安装过程:
    首先需要下载微软的TTS语音引擎, 以及简体中文的语音数据包.下载页面为:

http://www.microsoft.com/downloa ... &DisplayLang=en
或直接下载连接为: (包含引擎以及中文语音数据包, 约130M)
http://download.microsoft.com/do ... /speechsdk51msm.exe

    下载完按提示安装即可, 安装完成后你可以在控制面板中找到"语音"设置项, 在其中的“文字-语音转换”标签页里面能够对语音进行相关的测试以及语速设置.(中文语音在下拉表中名为Microsoft Simplified Chinese) 如果这里测试能正常进行
中文文字的语音朗读的话则可以进行下一步,另外这个微软的语音包以及引擎是系统标准引擎, 安装完后很多其他程序可以公用,比如可以进行文章/网页朗读之类的,虽说效果不是很好,但也还算用得上.然后可以进行脚本的安装, 只需要将附件"自动语音报价.mq4"复制到你MT4安装目录下的experts目录即可, 比如你MT4安装在:C:Program FilesMetaTrader 4则复制到C:Program FilesMetaTrader 4experts再重新启动MT4, 就应该可以在导航窗口里面的智能交易列表里面找到自动语音报价
这个项目, 安装到这里就算完成了.


使用方法:
    首先你需要开启MT4的智能交易系统, 在工具栏上点下启动智能交易的按钮,让其处于绿色的按下状态.然后打开你所要进行自动报价的商品的数据图, 再双击智能交易列表里面的自动语音报价, 然后确定就可以按照默认设置进行报价了. 如需更改设置, 可以在确定前点数如参数页里面进行更改或者在随时点击数据图右上角自动语音报价旁边的圆脸即可弹出设置窗口.

    设置项目名因为MT4的限制只能为英文字母和数字,这里做一下解释:

 

名称            类型                           说明
Enabled        布尔值       选true(是)则表示开启报价, false(否)则临时禁止报价.

UseBid         布尔值   是否选用买入价, true表示使用买入价,false表示使用卖出价.

SpeakInterval  整数      设置同一个图标两次报价之间的最小时间价格.以秒为单位,如
                     该数值设置为0, 则将在语速允许的范围内对每次的数据变动报价.

SpeakSymbol    布尔值 选true表示标价同时报出该商品名,如果同时在对多种商品报价时
                    候可以用这个帮助区分商品种类.false表示只报价格.可以缩短报价
                        语句便于对一两种货币集中监控.

SpeakDelta     整数 用来控制是否报两次报价之间的变化点数以及变化的范围. 设置为0
                    表示不报差价,否则如果两次报价间变化大于等于该设置数值则报价
               同时报上涨或者下跌了多少点. 如果该数值设置为1则每次都报变化点数.

Range1Min      实数                用来设置第一个报价范围的最小点数.

Range1Max      实数                用来设置第一个报价范围的最大点数.

Range2Min      实数                用来设置第二个报价范围的最小点数.

Range2Max      实数                用来设置第二个报价范围的最大点数.

LogMessage     布尔值         是否将每次报价记录到只能交易系统的日志窗口.

    只有当当前商品的价格处于[RangeMin1, RangeMax1] 或者[RangeMin2, RangeMax2]的范围内才会报价,这样可以用来避免不必要的报价.默认为所有价位范围 [0, 99999.9], 即对任何数据进行报价.这个范围需要根据自己需求以及货币种类进行设置使用.比如现在EURUSD在1.18下附近波动, 上升阻力位为1.1800, 则可以将Range1Min设置为1.1800, Range1Max设置为一个足够大的数据比如99999.9, 则汇价升破1.18的阻力位都将自动进行语音报价. 如果当前在支撑位1.1800附近震荡, 则可以将Range1Min设置为0, Range1Max设置为1.1800, Range2Min以及Range2Max保持为0即可。当大幅度在支撑和阻力间震荡时如需同时设置支撑和阻力范围可以通过Range1以及Range2配合进行设置.

    以上是对单种商品的自动报价处理, 如需同时对多种商品进行报价, 则另开一个数据窗口,重复以上步骤即可.如需要临时禁止单窗口的自动报价, 可以将设置里面的Enable设置为false.需要恢复时候重新改为true即可.如需要删除单窗口的自动报价, 可在该窗口点击右键选择智能交易->删除即可,但该窗口的自动报价设置将被删除.如需临时禁止所有窗口的自动报价, 点击工具栏上的启动智能交易将其弹起为红色即可.
重新点击即可恢复.如需完全删除自动语音报价, 在智能交易列表中的自动语音报价右键点击后选删除.

    MT 4.0 Build 187以后的版本把SpeechText函数去掉了以前的朗读相关功能都无法再继续使用.现在必须用自己的DLL来实现了语音功能了, 简单写了一个dll版本的如下:
第一部分代码为MQ4代码,第二部分代码为dll源代码,改名为SpeechText.dll后放到MT4的expertslibraries目录下

//+------------------------------------------------------------------+
//|                                                     语音报价.mq4 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "fedforex@sohu.com"
#property link      "http://allfromforex.blog.sohu.com/"

#import "SpeechText.dll"
int MT_SpeechText(string text, int async);
#import

//---- input parameters
extern string    Version="0";
extern string    BuildInfo = "2006.01.18 by wfy05@talkforex.com";
extern string    Format = "%SELL_CURR% 兑 %BUY_CURR% ?TION% 价为 %PRICE% ?D_DIR% ?D%";
extern bool      UseBid=true;
extern int       SpeakInterval=10;
extern int       SpeakDelta=0;
extern double    Range1Min=0.0;
extern double    Range1Max=99999.9;
extern double    Range2Min=0.0;
extern double    Range2Max=0.0;
extern bool      Enabled=true;
extern bool      InitSpeak=false;
extern bool      LogMessage=false;

double LastPrice = 0;
int LastSpeakTime = 0;

string StrListGetVar(string & array[], string name)
{
   int i, n;
   
   n = ArraySize(array)/2;
   for (i=0; i
      if (array[i*2] == name) return (array[i*2+1]);
   }
   return ("");
}

bool StrListSetVar(string & array[], string name, string value)
{
   int i, n;
   
   n = ArraySize(array)/2;
   for (i=0; i
      if (array[i*2] == name) {
         array[i*2+1] = value;
         return (true);
      }
   }
   return (false);
}

string CurrencyGetName(string c)
{
   if (c == "USD") {
      return ("美元");
   } else if (c == "EUR") {
      return ("欧元");
   } else if (c == "GBP") {
      return ("英镑");
   } else if (c == "JPY") {
      return ("日元");
   } else if (c == "CAD") {
      return ("加元");
   } else if (c == "CHF") {
      return ("瑞郎");
   } else if (c == "AUD") {
      return ("澳元");
   } else if (c == "SGD") {
      return ("星元");
   } else if (c == "NZD") {
      return ("纽元");
   } else if (c == "HKD") {
      return ("港币");
   } else if (c == "CNY") {
      return ("人民币");
   } else {
      return ("");
                 
}

string GetSymbolCurrency(bool first)
{
   string name = Symbol();
   string str;
   
   str = "";
   if (StringLen(name) != 6) {
      if (first) {
         if (name == "USDX" || name == "_DXY") {
            str = "美元指数";
         } else if (name == "GOLD") {
            str = "黄金";
         }
           
   } else {
      if (first) {
         str = CurrencyGetName(StringSubstr(name, 0, 3));
      } else {
         str = CurrencyGetName(StringSubstr(name, 3, 3));
      }
   }
   return (str);
}

string GetSymbolName(string name)
{
   string str, left, right;
      
   left = GetSymbolCurrency(true);
   right = GetSymbolCurrency(false);
   if (left != "" && right != "") {
      str = left + "兑" + right;
   } else {
      str = left;
   }
   return (str);
}


string StringReplaceVar(string str)
{
   int n1, n2, start;
   string out;
   
   start = 0;
   out = "";
   while (true) {
      n1 = StringFind(str, "%", start);
      if (n1 < 0) {
         out = StringConcatenate(out, StringSubstr(str, start));
         break;
      }
      if (n1 != start) {
         out = StringConcatenate(out, StringSubstr(str, start, n1-start));
              
      n2 = StringFind(str, "%", n1+1);
      if (n2 < 0) {
         break;
      }
      if (n2 > n1+1) {
         out = StringConcatenate(out, StringVarGetValue(StringSubstr(str, n1+1, n2-n1-1)));
      } else if (n2 == n1 + 1) {
         out = StringConcatenate(out, "%");      
       
      start = n2+1;
   }
   return (out);   
}

string StrList[] = {
   "SELL_CURR",,
   "BUY_CURR",,
   "PRICE",,
   "ACTION",,
   "ADD_DIR",,
   "ADD",,
   "BID_PRICE",,
   "ASK_PRICE",,
};

string StringVarGetValue(string name)
{
   return (StrListGetVar(StrList, name));
}

bool StringVarSetValue(string name, string value)
{
   return (StrListSetVar(StrList, name, value));
}

void DoSpeech()
{
   string str;
   
   UpdateVars();
   str = StringReplaceVar(Format);   
   MT_SpeechText(str, 1);
   LastSpeakTime = GetTickCount();
   if (LogMessage) Print (str);
   return;
}

double GetPriceChanged()
{
   double diff;
   double p = GetCurrPrice();
   int n = MathPow(10, Digits);
      
   diff = p * n -LastPrice *n;
   return (diff);
}

double GetCurrPrice()
{
   double p;
      
   if (UseBid) {
      p = Bid;
   } else {
      p = Ask;
   }
   return (p);
}


void UpdateVars()
{
   StringVarSetValue("BID_PRICE", DoubleToStr(Bid, Digits));
   StringVarSetValue("ASK_PRICE", DoubleToStr(Ask, Digits));
   StringVarSetValue("PRICE", DoubleToStr(GetCurrPrice(), Digits));
   
   string add, adddir;
   
   double diff = GetPriceChanged();
   double abs_diff = MathAbs(diff);
   double p = GetCurrPrice();
   
   if (abs_diff != 0) {
      if (diff > 0) {
         adddir = "上涨";
      } else if (diff < 0) {
         adddir = "下跌";
      }
      add = DoubleToStr(abs_diff, 0) + "点";
   } else {
      adddir = "";
      add = "";
   }
   LastPrice = p;
   
   StringVarSetValue("ADD_DIR", adddir);
   StringVarSetValue("ADD", add);

   return;  
}

void InitVars()
{
   StringVarSetValue("SELL_CURR", GetSymbolCurrency(true));
   StringVarSetValue("BUY_CURR", GetSymbolCurrency(false));
   if (UseBid) {
      StringVarSetValue("ACTION", "买入");
   } else {
      StringVarSetValue("ACTION", "卖出");
   }
   return;
}


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
//----
   LastPrice = GetCurrPrice();
   LastSpeakTime = 0;

   if (InitSpeak) {
      string str;
      str = "开始进行" + GetSymbolName(Symbol()) + "的自动报价";
      str = str + "当前价格为" + DoubleToStr(LastPrice, Digits);
      MT_SpeechText(str, 1);
   }
   InitVars();
   if (Enabled) DoSpeech();
   return(0);
}

//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
//----
   if (InitSpeak) {
      string str;
      str = "停止" + GetSymbolName(Symbol()) + "的自动报价";
      MT_SpeechText(str, 1);
        
//----
   return(0);
}

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
//----
   if (!Enabled) return (0);
   if (MathAbs(GetTickCount() - LastSpeakTime) < SpeakInterval * 1000) {
      return (0);
   }
   double p = GetCurrPrice();   
   if (!(p >= Range1Min && p <= Range1Max) && !(p >= Range2Min && p <= Range2Max)) {
      return (0);
   }
   double abs_diff = MathAbs(GetPriceChanged());   
   if (abs_diff < SpeakDelta) {
      return (0);
   }
   DoSpeech();
//----
   return(0);
}
//+------------------------------------------------------------------+

 

#include
#include

#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "sapi.lib")

ISpVoice * gpVoice = NULL;

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
        switch (fdwReason) {
                case DLL_PROCESS_ATTACH:
                        if (FAILED(CoInitialize(NULL))) {
                                return FALSE;
                        }
                        if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&gpVoice))) {
                                return FALSE;
                        }
                        if (!gpVoice) return FALSE;
                        break;
                case DLL_PROCESS_DETACH:
                       
                        gpVoice = NULL;
                        CoUninitialize();
                        break;
                default:
                        break;
        }
        return TRUE;
}

BOOL WINAPI MT_SpeechText(char const * text, BOOL async)
{
        WCHAR * msg;
        BOOL ret;
        int len;
        DWORD dwFlags;

        len = strlen(text) + 1;
        msg = new WCHAR[len];
        MultiByteToWideChar(CP_ACP, 0, text, len, msg, len);
        if (async) {
                dwFlags = SPF_ASYNC;
        } else {
                dwFlags = SPF_DEFAULT;
        }
        if (FAILED(gpVoice->Speak(msg, dwFlags, NULL))) {
                ret = FALSE;
        } else {
                ret = TRUE;
        }
        delete msg;
        return ret;
}

 

 

 

 

//=================================================

//--自动报价脚本,注意现行mt4不能直接支持SpeechText函数

//=================================================

//+------------------------------------------------------------------+
//| 语音报价.mq4 |
//| |
//| |
//+------------------------------------------------------------------+
#property copyright "wfy05@talkforex.com"
#property link "www.talkforex.com"

//---- input parameters
extern bool Enabled=true;
extern bool UseBid=true;
extern int SpeakInterval=10;
extern bool SpeakSymbol=true;
extern int SpeakDelta=1;
extern doubleRange1Min=0.0;
extern doubleRange1Max=99999.9;
extern doubleRange2Min=0.0;
extern doubleRange2Max=0.0;
extern bool InitSpeak=false;
extern bool LogMessage=false;

double LastPrice = 0;
int LastSpeakTime = 0;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+

double GetCurrPrice()
{
double p;

if (UseBid) {
p = Bid;
} else {
p = Ask;
}
return (p);
}

string CurrencyGetName(string c)
{
if (c == "USD") {
return ("美元");
} else if (c == "EUR") {
return ("欧元");
} else if (c == "GBP") {
return ("英镑");
} else if (c == "JPY") {
return ("日元");
} else if (c == "CAD") {
return ("加元");
} else if (c == "CHF") {
return ("瑞郎");
} else if (c == "AUD") {
return ("澳元");
} else if (c == "SGD") {
return ("星元");
} else if (c == "NZD") {
return ("纽元");
} else if (c == "HKD") {
return ("港币");
} else if (c == "CNY") {
return ("人民币");
} else {
return ("");
}
}

string GetSymbolName(string name)
{
string str;

str = "";
if (StringLen(name) != 6) {
if (name == "USDX" || name == "_DXY") {
str = str+"美元指数";
} else if (name == "GOLD") {
str = str+"黄金";
}
} else {
string left, right;
left = CurrencyGetName(StringSubstr(name, 0, 3));
right = CurrencyGetName(StringSubstr(name, 3, 3));
if (left != "" && right != "") {
str = str+(left + "兑" + right);
}
}
return (str);
}

string GetSpeechText()
{
string str;

str = "";
if (SpeakSymbol) {
str = str + GetSymbolName(Symbol());
if (str != "") {
if (UseBid) {
str = str+"买入价为";
} else {
str = str+"卖出价为";
}
}
}
double p;
p = GetCurrPrice();
str = str+DoubleToStr(p, Digits);
if (SpeakDelta != 0 ) {
int n = MathPow(10, Digits);
double diff = MathAbs(p*n-LastPrice*n);
if (diff >= SpeakDelta) {
if (p > LastPrice) {
str = str+"上涨"+DoubleToStr(diff,0)+"点";
} else {
str = str+"下跌"+DoubleToStr(diff,0)+"点";
}
}
// Print(LastPrice + "->" + p + " : " + diff);
}
LastPrice = p;
if (LogMessage) Print (str);
return (str);
}

int init()
{
//----
//----
LastPrice = GetCurrPrice();
LastSpeakTime = 0;

if (InitSpeak) {
string str;
str = "开始进行" + GetSymbolName(Symbol()) + "的自动报价,";
str = str + "当前价格为" + DoubleToStr(LastPrice, Digits);
SpeechText(str, SPEECH_NATIVE);
}
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
if (InitSpeak) {
string str;
str = "停止" + GetSymbolName(Symbol()) + "的自动报价";
SpeechText(str, SPEECH_NATIVE);
}
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function|
//+------------------------------------------------------------------+
int start()
{
//----
if (!Enabled) return (0);
double p = GetCurrPrice();
if (MathAbs(GetTickCount() - LastSpeakTime) < SpeakInterval * 1000) {
return (0);
}
if ((p >= Range2Min && p <= Range1Max) || (p >= Range2Max && p <= Range2Min)) {
SpeechText(GetSpeechText(), SPEECH_NATIVE);
LastSpeakTime = GetTickCount();
}
//----
return(0);
}
//+------------------------------------------------------------------+

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约