Jogar JavaScript com o velho e criar um parceiro para fazer compras e vendas
No processo de desenvolvimento de robôs, muitos pequenos fragmentos de código foram acumulados, alguns dos quais podem ser aproveitados em seus próprios programas de estratégia de quantificação.
-
1, para converter qualquer ciclo de linha K
Este módulo de código não é escrito como uma biblioteca de classes, apenas escreve uma função, que também é conveniente para modificações posteriores. A função é a de sintetizar grandes ciclos de dados de linha K baseados em determinados ciclos.
O endereço do código fonte:https://www.fmz.com/strategy/35986
// K线周期合成 扩展为 根据基础K线 合成 为任意周期。
var cloneObj = function ((obj) { // Copiar profundamente funções de objetos
var str, newobj = obj.constructor === Array? [] : {};
if (typeof obj!== object) {
O retorno;
} else if (JSON) {
str = JSON.stringify ((obj); // Objeto serializado
newobj = JSON.parse ((str); // redundância
} else {
para (var i in obj) {
newobj[i] = typeof obj[i] === Objeto de barra?
cloneObj ((obj[i]) : obj[i];
Não.
Não.
return newobj;
O que você está fazendo?
O que é isso?
var DAY = 0;
Var HOURS = 1;
var MINUTES = 2;
var isFirstFind = verdadeiro;
var FirstStamp = null;
O que é isso?
função GetDHM ((objTime, BaseCycle, NewCycleForMS) {
var ret = [];
if ((BaseCycle % (1000 * 60 * 60 * 24) === 0) {
ret[0] = objTime.getDate (();
ret[1] = dia;
}else if ((BaseCycle % (1000 * 60 * 60) === 0) {
ret[0] = objTime.getHours (();
ret[1] = HOURS;
}else if ((BaseCycle % (1000 * 60) === 0) {
ret[0] = objTime.getMinutes (();
ret[1] = MINUTOS;
Não.
if ((NewCycleForMS % (1000 * 60 * 60 * 24) === 0) {
ret[2] = dia;
}else if ((NewCycleForMS % (1000 * 60 * 60) === 0) {
ret[2] = HOURS;
}else if ((NewCycleForMS % (1000 * 60) === 0) {
ret[2] = MINUTOS;
Não.
Retorno ret;
Não.
O que é isso?
função SearchFirstTime ((ret, BaseCycle, NewCycleForMS) {
if ((ret[1] === DAY && ret[2] === DAY) {
var array_day = [];
para ((var i = 1 ; i < 29; i += (NewCycleForMS / BaseCycle)) {
array_day.push ((i);
Não.
for ((var j = 0 ; j < array_day.length; j++) {
se ((ret[0] === array_day[j]) {
Retorno verdadeiro;
Não.
Não.
}else if(ret[1] === HOURS && ret[2] === HOURS) {
var array_hours = [];
For ((var i = 0 ; i < 24; i + = (NewCycleForMS / BaseCycle)) {
array_hours.push ((i);
Não.
for ((var j = 0 ; j < array_hours.length ; j++) {
se ((ret[0] === array_hours[j]) {
Retorno verdadeiro;
Não.
Não.
}else if(ret[1] === MINUTES && ret[2] === MINUTES) {
var array_minutes = [];
For ((var i = 0; i < 60; i += (NewCycleForMS / BaseCycle)) {
array_minutes.push ((i);
Não.
for ((var j = 0; j < array_minutes.length; j++) {
se ((ret[0] === array_minutes[j]) {
Retorno verdadeiro;
Não.
Não.
- O que foi?
throw O ciclo alvo não corresponde ao ciclo base! Milissegundos do ciclo alvo: + NewCycleForMS + " Milissegundos do ciclo base: " + BaseCycle;
Não.
Não.
O que é isso?
função Calc_High ((AssRecords, n, BaseCycle, NewCycleForMS) {
var max = AssRecords[n].High;
for ((var i = 1 ; i < NewCycleForMS / BaseCycle; i++) {
max = Math.max ((AssRecords[n + i].High, max);
Não.
retorno max;
Não.
O que é isso?
função Calc_Low ((AssRecords, n, BaseCycle, NewCycleForMS) {
var min = AssRecords[n].Low;
for ((var i = 1 ; i < NewCycleForMS / BaseCycle; i++) {
Min = Math.min ((AssRecords[n + i].Low, min);
Não.
Retorno de min;
Não.
O que é isso?
função AssembleRecords ((records, NewCycleForMS) {
var AssRecords = records.slice(0); // Cópia profunda
var AfterAssRecords = [];
if(!records || records.length < 2){
throw (!records) ? "传入的records参数为 错误" + records : "基础K线长度小于2";
}
var BaseCycle = records[records.length - 1].Time - records[records.length - 2].Time;
if(NewCycleForMS % BaseCycle !== 0){
throw "目标周期‘" + NewCycleForMS + "’不是 基础周期 ‘" + BaseCycle + "’ 的整倍数,无法合成!";
}
if(NewCycleForMS / BaseCycle > records.length){
throw "基础K线数量不足,请检查是否基础K线周期过小!";
}
// Determina a linha do tempo e encontra o tempo de início da linha K básica em relação à linha K alvo.
var objTime = new Date ();
para (var i = 0; i < AssRecords.length; i++) {
objTime.setTime ((AssRecords[i].Time);
var ret = GetDHM ((objTime, BaseCycle, NewCycleForMS);
if (isFirstFind === true && SearchFirstTime(ret, BaseCycle, NewCycleForMS) === true) {
FirstStamp = AssRecords[i].Time;
for (j = 0; j < i; j++) {
AssRecords.shift(); // 把目标K线周期前不满足合成的数据排除。
}
isFirstFind = false;
break; // 排除后跳出
}else if(isFirstFind === false){
if((AssRecords[i].Time - FirstStamp) % NewCycleForMS === 0){
for (j = 0; j < i; j++) {
AssRecords.shift(); // 把目标K线周期前不满足合成的数据排除。
}
break;
}
}
}
var BarObj = { // 定义一个 K线柱结构
Time: 0,
Open: 0,
High: 0,
Low: 0,
Close: 0,
Volume: 0,
};
var n = 0;
for (n = 0; n < AssRecords.length - (NewCycleForMS / BaseCycle); n += (NewCycleForMS / BaseCycle)) { // 合成
/*
{
Time :一个时间戳, 精确到毫秒,与Javascript的 new Date().getTime() 得到的结果格式一样
Open :开盘价
High :最高价
Low :最低价
Close :收盘价
Volume :交易量
}
*/
BarObj.Time = AssRecords[n].Time;
BarObj.Open = AssRecords[n].Open;
BarObj.High = Calc_High(AssRecords, n, BaseCycle, NewCycleForMS);
BarObj.Low = Calc_Low(AssRecords, n, BaseCycle, NewCycleForMS);
BarObj.Close = AssRecords[n + (NewCycleForMS / BaseCycle) - 1].Close;
BarObj.Volume = AssRecords[n + (NewCycleForMS / BaseCycle) - 1].Volume;
AfterAssRecords.push(cloneObj(BarObj));
}
BarObj.Time = AssRecords[n - (NewCycleForMS / BaseCycle)].Time + NewCycleForMS; // A última hora não pode ser alterada, mas a última data pode ser alterada.
BarObj.Open = AssRecords[n].Open;
BarObj.Close = AssRecords [AssRecords.length - 1].Close;
BarObj.Volume = AssRecords [AssRecords.length - 1].Volume;
var max = AssRecords[n].High;
var min = AssRecords[n].Low;
for ((var index_n = n + 1 ;index_n < AssRecords.length; index_n++) {
max = Math.max ((max, AssRecords[index_n].High);
Min = Math.min ((min, AssRecords[index_n].Low);
Não.
BarObj.High = max;
BarObj.Low = min;
DepoisAssRecords.push ((cloneObj ((BarObj)));
return AfterAssRecords;
Não.
O que é isso?
função main() { // Código de teste
while(!exchange.IO("status")
LogStatus (Logo não ligado!);
Não.
var Info = _C ((exchange.SetContractType, MMA705); // Síntese de dados da linha K do contrato do metanol 705
var records = exchange.GetRecords ();
while (!records.length < 24) {
registros = exchange.GetRecords ();
Não.
// Processar os parâmetros da interface, se você escrever sua própria política, você pode consultar
var Num_UI_NewCycleForMS = 1;
var arrayNum = UI_NewCycleForMS.split (("*");
for ((var indexNum = 0 ; indexNum < arrayNum.length ; indexNum++) {
Num_UI_NewCycleForMS = Num_UI_NewCycleForMS * Número ((arrayNum[indexNum]);
Não.
Log (( tempo de milissegundos do ciclo personalizado é: , Num_UI_NewCycleForMS);
while (true) {
registros = _C ((exchange.GetRecords);
// Log (( dados de linha K primários: barra de comprimento, records.length, barra de dados: barra, records);
records = AssembleRecords ((records, Num_UI_NewCycleForMS); // O primeiro parâmetro é a linha base K, o segundo parâmetro é o milissegundo de ciclo a ser convertido, 1000 * 60 * 20 ou a conversão para 20 minutos
// Log (após a conversão do ângulo para dados da linha K: ângulo de comprimento, records.length, ângulo de dados: ângulo, records);
O site oficial da empresa é o site oficial da empresa, que é o site oficial da empresa.
// throw stop ; // ceshi
Sleep ((1000);
Não.
Não.
- #### 2、传统期货差价监控 (CTP)
当需要分析两个品种差价走势的时候,会用上这段代码。有时候也会把这段代码修改集成到自己的策略程序里面(比如跨期对冲策略),代码会绘制出一个差价走势图,在学习如何让机器人程序画图也是很有帮助的,很好的例子。
源码地址: https://www.fmz.com/strategy/5379
var __lastDiff = 0;
var __AType = [Last, Buy, Sell][AType];
var __BType = [Last,Buy,Sell][BType];
O que é isso?
função _N ((v, precision) {
If (typeof(precision)!= number) {
Precision = 4;
Não.
var d = parseFloat ((v.toFixed ((Math.max ((10, precision + 5)));
s = d.toString (().split (("");
if (s.length < 2つの s[1].length <= precision) {
retorno d;
Não.
O que é isso?
var b = Math.pow ((10, precisão);
return Math.floor ((d * b) / b;
Não.
O que é isso?
Função AssureCall ((method) {
Var r;
while (!(r = method.apply(this, Array.prototype.slice.call ((argumentos).slice))) {
Sleep (intervalo);
Não.
return r;
Não.
O que é isso?
função on Tick (() {
var a = EnsureCall ((exchange.SetContractType, AInstrument);
Var ticker A = AssureCall (exchange.GetTicker);
var b = EnsureCall ((exchange.SetContractType, BInstrument);
Var ticker B = AssureCall (exchange.GetTicker);
var diff = _N ((ticker A [__AType] - ticker B [__BType]);
LogStatus ((a. InstrumentName, _N ((tickerA[__AType]), b. InstrumentName, _N ((tickerB[__BType]), diferença de valor: , diff);
Se (__lastDiff! = 0) {
if (Math.abs(Math.abs(diff) - Math.abs ((__lastDiff)) > 200) {
O retorno;
Não.
Não.
se (diff!= __lastDiff) {
// add adicionar dados para a série, com formato de parâmetro [series serial, data];
__chart.add (([0, [new Date (().getTime ((), diff)));
__lastDiff = diff;
Não.
Não.
O que é isso?
função main() {
if (exchange.GetName().indexOf(Futures_CTP) == -1) {
O jogo de lançamento só suporta o jogo de futuros tradicionais (CTP).
Não.
SetErrorFilter (loginreadydefendendo o controle de fluxo, falha de conexão ou timeout);
// O que é transmitido para a função Chart deve ser uma estrutura que não está relacionada com o contexto (incluindo as regras de HighStocks, os parâmetros detalhados de como usar HighStocks)
__chart = Chart (({
A dica é:
xDateFormat: %Y-%m-%d %H:%M:%S, %A
O que é isso?
title: {
text: Diagrama de análise de diferença de preços de alumínio
O que é isso?
rangeSelector: {
Não, não.
Tipo: hour,
Contagem: 1,
text: 1h
Não, não.
Tipo: hour,
Contagem: três.
text: 3h
Não, não.
Tipo: hour,
Contagem: 8
text: 8h
Não, não.
Tipo: O que é o que você quer?
text: All
O que é isso?
Selected: 0,
inputEnabled: false (InputAtivado: falso)
O que é isso?
E então, o eixo x é: {
tipo: barra de data/tempo barra
O que é isso?
E assim, o eixo y é: {
PlotLines: [{
Valor: NormalDiff
Cor: amarelo-verde, amarelo-verde.
DashStyle: O DashShortDash é um aplicativo de marketing de conteúdo que permite o acesso a conteúdos de qualquer tipo.
width: 1,
Não, não.
Valor: HighDiff
Cor: amarelo-vermelho.
DashStyle: O DashShortDash é um aplicativo de marketing de conteúdo que permite o acesso a conteúdos de qualquer tipo.
width: 1,
Não, não.
Valor: - NormalDiff,
Cor: amarelo-verde, amarelo-verde.
DashStyle: O DashShortDash é um aplicativo de marketing de conteúdo que permite o acesso a conteúdos de qualquer tipo.
width: 1,
Não, não.
Valor: -HighDiff,
Cor: amarelo-vermelho.
DashStyle: O DashShortDash é um aplicativo de marketing de conteúdo que permite o acesso a conteúdos de qualquer tipo.
width: 1,
Não.
O que é isso?
série: [{
name: Preço do alumínio em baixa
Data: [],
A dica é:
Valor decimais: 2
Não.
Não.
Não, não.
// reset Esvaziar todas as informações anteriores ao gráfico
// __chart.reset ();
var a = EnsureCall ((exchange.SetContractType, AInstrument);
var b = EnsureCall ((exchange.SetContractType, BInstrument);
Log ((a. InstrumentName + . + __AType, -, b. InstrumentName + . + __BType, diferença como ganho é mostrado na barra do gráfico);
TickInterval = Math.max ((TickInterval, 50);
Interval = Math.max ((Interval, 50);
enquanto (true) {
OnTick ();
Sleep (Tick Interval);
Não.
Não.
- #### 3、CTP手动全平CTP商品期货持仓
在Simnow 上测试 商品期货策略时经常需要把已经开过的仓位平掉重新测试代码,这样就需要个类似一键平仓的程序来处理 恢复模拟账号未开仓状态。这里使用了一个交易处理模块: $.NewPositionManager 就是该模块的接口函数,作用是生成一个对象,可以调用该对象的方法处理具体操作,比如 全平仓: CoverAll(); 。 做了一点额外的功能,在全部平仓完以后,会打印出所有交易的标的物名称。
var p = $.NewPositionManager (();
função principal (() {
Enquanto isso é verdade.
seexchange.IO("status") === true) {
p.CoverAll (();
Var positions = _C (exchange.GetPosition);
se ((positions.length === 0) {
Log ((positions is :, positions);
O que é o que você está fazendo?
Não.
- O que foi?
LogStatus (Logo não conectado ao servidor, aguardando para acessar);
Não.
Sleep ((2000);
Não.
Var dict =exchange.IO("instruments"); // Retorna a lista de todos os produtos da bolsa { nome do produto: detalhes }
For ((var k in dict) {
Log ((Nome do produto: , k, Informações detalhadas: Nome do produto: , dict[k]);
Não.
Log ((exit., _C ((exchange.GetPosition));
Não.
- #### 4、商品期货主力合约过滤
在处理商品期货合约的连续性时会遇到主力合约的问题,如何更快的过滤识别出主力合约呢? 同样也写了个代码模块,可以改造,嵌入,或者单独使用。
在 filter 变量中指定要 扫描的合约代码头。(即不含日期信息的合约代码的部分)
var str = null;
var strArray = [];
função main (() {
var filter = [MA,CF,zn,SR,pp,l,ni,i,v,jm,al,jd,cs,p];
var products = [];
Log (ponto de espera para se conectar ao servidor de transações);
enquanto (!exchange.IO("status")) Sleep ((1000);
Log (ou seja, você começa a obter todos os contratos);
var instrumentos = _C(exchange.IOA partir de agora, a maioria das pessoas não tem acesso a ele.
Log (Lista de contratos obtidos com sucesso);
var len = 0;
para (var instrumentId in instruments) {
Len++;
Não.
Log (Lista de comprimentos de contrato: len, len);
para (var instrumentId in instruments) {
If (instruments[instrumentId].IsTrading) {
var found = falso;
para (var i = 0; i < filter.length; i++) {
If (instruments[instrumentId].ProductID == filter[i]) {
Found = true;
Não.
Não.
se (!found) {
Continuar;
Não.
if (typeof(products[instruments[instrumentId].ProductID]) === undefined) {
products[instruments[instrumentId].ProductID] = [];
Não.
A partir de agora, o produto pode ser enviado para o servidor.
Não.
Não.
para (var produto em produtos) {
var ss = products[product];
Log ((Log de assinatura, produto, Longo de Longo, ss.length, Longo de Contratos, para identificar o Longo de Contratos Principal);
Var vol = 0,
volIdx = 0;
para (var i = 0; i < ss.length; i++) {
_C ((exchange.SetContractType, ss[i]);
Não.
Sleep ((5000);
para (var i = 0; i < ss.length; i++) {
_C ((exchange.SetContractType, ss[i]);
Var ticker = exchange.GetTicker (em inglês);
if (ticker) {
var obj = JSON.parse(exchange.GetRawJSON());
if (obj.OpenInterest > vol) {
vol = obj.OpenInterest;
volIdx = i;
}
}
}
// 取消订阅行情(之后此合约K线将停止收集), 当然也可以不取消, 这里演示用
for (var i = 0; i < ss.length; i++) {
_C(exchange.SetContractType, "-" + ss[i]);
}
strArray.push(ss[volIdx]);
Log("主力合约为", ss[volIdx], "持仓", vol, '#ff0000');
}
for(var i = 0 ; i < strArray.length; i++){
str += strArray[i] + ',';
}
Log("主力合约:", str);
}
- #### 5、交互模块
有时候需要给机器人交互,需要下命令、改参数、获取详细运行状态参数 就需要交互代码了。
função get_Command ((() {// função responsável pela interação, interação atualizada em tempo real Números relacionados, usuários familiarizados podem ser expandidos por conta própria
var keyValue = 0;// Parâmetros enviados pelo comando
var way = null; // Roteamento
var cmd = GetCommand ((); // Obter API de comando interativo
Se (cmd) {
Log (se você pressionar o botão: log, cmd);// mostra o log
arrStr = cmd.split ((":"); // O que a função GetCommand retorna é uma cadeia de caracteres, e aqui eu resolvi o problema, porque eu quero me familiarizar com o JSON
//, então, primeiro, você deve processar a string e dividir a string que a função retorna em duas strings:
if(arrStr.length === 2){//接受的不是 按钮型的,是数值型。
jsonObjStr = '{' + '"' + arrStr[0] + '"' + ':' + arrStr[1] + '}'; // 把 字符串数组中的元素重新
//拼接 ,拼接成 JSON 字符串 用于转换为JSON 对象。
jsonObj = JSON.parse(jsonObjStr); // 转换为JSON 对象
for(var key in jsonObj){ // 遍历对象中的 成员名
keyValue = jsonObj[key]; //取出成员名对应的 值 , 就是交互按钮的值
}
if(arrStr[0] == "upDateAmount"){// 此处为 数字型 。这里处理分为 按钮 和 数字型 。 详见 策略参数 设置界面 下的 交互设置
way = 1;
}
if(arrStr[0] == "扩展1"){
way = 2;
}
if(arrStr[0] == "扩展2"){
way = 3;
}
if(arrStr[0] == "扩展3"){
way = 4;
}
}else if(arrStr.length === 1){// 此处为 按钮型
//路由
if(cmd == "cmdOpen"){
way = 0;
}
if(cmd == "cmdCover"){
way = 5;
}
}else{
throw "error:" + cmd + "--" + arrStr;
}
switch(way){ // 分支选择 操作
case 0://处理 发出开仓信号
tiaojian = 1;
break;
case 1://处理
Amount = keyValue;//把交互界面设置的 数值 传递给 Amount
Log("开仓量修改为:",Amount);//提示信息
break;
case 2://处理
break;
case 3://处理
break;
case 4://处理
break;
case 5://处理 发出平仓信号
tiaojian = 2;
break;
default: break;
}
}
}
有时我们甚至需要在机器人运行时插入运行JS 代码:
var cmd = GetCommand ((); // Chama a API para obter a mensagem do controle de interação da interface.
if (cmd) { // Determina se há uma mensagem
var js = cmd.split ((:, 2) [1]; // Split Retorno de mensagens Estringência, restringindo o retorno de 2 elementos, dando o índice a 1 atribuindo um valor a uma variável chamada js
Log (( executar código de depuração:??, js); // output
Try { // Detecção de anomalias
eval ((js); // Executa a função eval, que executa o parâmetro de entrada ((código)).
} catch(e) { // Lançar anomalias
Log ((Exception, e); // Produção de mensagem de erro
Não.
Não.
当然还有很多代码工具尽在 : https://www.fmz.com/square
#### 先写到这,欢迎读者给我留言!提出建议和意见,如果感觉好玩可以分享给更多热爱程序热爱交易的朋友
https://www.fmz.com/bbs-topic/735
### 程序员 littleDream 原创