지난 기사손잡이, 손잡이, 손잡이, 손잡이자바스크립트 언어의 간단한 메이 언어 전략에 대한 이식 테스트를 수행했습니다. 조금 더 복잡한 메이 언어의 경우 자바스크립트 언어의 전략에 대한 이식 테스트를 어떻게 수행합니까?
이 경우, 우리는 이식 전략에 대해 먼저 살펴볼 것입니다.
(*backtest
start: 2019-05-01 00:00:00
end: 2019-11-12 00:00:00
period: 1d
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}]
args: [["SlideTick",10,126961],["ContractType","quarter",126961]]
*)
N1:=10;
N2:=21;
AP:=(HIGH+LOW+CLOSE)/3;
ESA:=EMA(AP,N1);
D:=EMA(ABS(AP-ESA),N1);
CI:=(AP-ESA)/(0.015*D);
TCI:=EMA(CI,N2);
WT1:TCI;
WT2:SMA(WT1,4,1);
AA:=CROSS(WT1,WT2);
BB:=CROSSDOWN(WT1,WT2);
REF(AA,1),BPK;
REF(BB,1),SPK;
이 메이 언어 전략의 시작 부분(*backtest...*)
이 전략은 또한 무작위로 찾아내는 전략이기도 하며, 너무 복잡하지도 않습니다. 이전 기사에서 비교적 복잡하지만, 비교적 대표적인 전략입니다. 메이 언어 전략을 옮기는 것은 먼저 내용을 살펴보고, 메이 언어 전략 코드가 간단하며, 기본적으로 전략을 전반적으로 이해할 수 있습니다. 이 전략은 몇 가지 지표 함수를 사용하여 볼 수 있습니다.EMA
,SMA
:
EMA
이 지표 함수는 FMZ 플랫폼에서 자바스크립트 언어로 정책을 작성할 때 바로 준비된 지표 덤비 함수이다.TA.MA
SMA
우리가 해야 할 일은SMA
이 지표는 FMZ의 TA에서 SMA 지표 기능을 지원하지 않는 것으로 나타났습니다.보시다시피, 변수 부분에는 주기 변수 외에도 무게 변수가 있습니다.
FMZ API 문서에서 talib 라이브러리의 SMA 지표 함수의 설명은 다음과 같습니다.
볼 수 있습니다.talib.SMA
이 지표는 단순한 이동 평균이다.
그리고 그 다음에는,SMA
자바스크립트 언어를 사용하는 개발자로서 전략 작성하는 것은 필수적인 기술 중 하나이기도 합니다.
사실, 지표와 같은 것에 대한 연구는 거의 없으며, 일반적으로는 이해되지 않습니다.
이 알고리즘의 프로세스는 매우 신뢰할 수 있다고 느껴집니다.
function SMA (arr, n, m) {
var sma = []
var currSMA = null
for (var i = 0; i < arr.length; i++) {
if (arr[i] && !isNaN(arr[i])) {
if (!currSMA) {
currSMA = arr[i]
sma.push(currSMA)
continue
}
// [M*C2+(N-M)*S1]/N
currSMA = (m * arr[i] + (n - m) * currSMA) / n
sma.push(currSMA)
} else {
sma.push(NaN)
}
}
return sma
}
전략 프레임워크 사용손잡이, 손잡이, 손잡이, 손잡이이 문서는 두 개의 부분으로 구성되어 있습니다.
첫 번째, 시장 데이터 처리, 지표 계산.
우리는 메이어의 이 부분의 기능을 문장별로 다루고 있습니다.
1、AP:=(HIGH+LOW+CLOSE)/3;
이 문장은 K선 데이터의 각 BAR의 최고가치, 최저가치, 클로저가치를 더하여 3로 나누면 평균을 계산하고, 그 다음 하나의 대수열로 저장하여 각 BAR에 대해 1을 대응하는 것으로 이해할 수 있습니다. 이런 식으로 처리할 수 있습니다.
function CalcAP (r) { // AP:=(HIGH+LOW+CLOSE)/3;
var arrAP = [] // 声明一个空数组
for (var i = 0; i < r.length; i++) { // r为传入的K线数据,是一个数组,用for遍历这个数组
v = (r[i].High + r[i].Low + r[i].Close) / 3 // 计算 平均值
arrAP.push(v) // 添加在 arrAP数组的尾部,arrAP是空的时候尾部就是第一个。
}
return arrAP // 返回 这个平均值数组,即麦语言中计算的 AP
}
이 함수는 주 루프의 OnTick 함수에서 호출할 수 있습니다. 예를 들어:
// 计算指标
// AP
var ap = CalcAP(records)
2 AP 계산이 완료되면 계산을 계속합니다.ESA:=EMA(AP,N1);
:
여기서는 앞서 계산한 AP 데이터를 사용하여 ESA를 계산합니다. 사실 이 ESA는 AP의 "지수 이동 평균" 즉 EMA 지표입니다. 그래서 우리는 AP를 데이터로 사용하고, N1을 EMA 지표의 매개 변수로 사용하여 EMA 지표를 계산할 수 있습니다.
function CalcESA (ap, n1) { // ESA:=EMA(AP,N1);
if (ap.length <= n1) { // 如果AP的长度小于指标参数,是无法计算出有效数据的,这个时候让函数返回false。
return false
}
return TA.EMA(ap, n1)
}
3、D:=EMA(ABS(AP-ESA),N1);
계산을 통해AP
、ESA
계산 데이터D
ᅳ
여기 코드 코너트에서 몇 가지 지표 계산 기법을 볼 수 있습니다.
function CalcD (ap, esa, n1) { // D:=EMA(ABS(AP-ESA),N1);
var arrABS_APminusESA = []
if (ap.length != esa.length) {
throw "ap.length != esa.length"
}
for (var i = 0; i < ap.length; i++) {
// 计算指标数值时,必须判断一下数据的有效性,因为前几次EMA计算可能数组中的开始部分的数据是NaN,或者null
// 所以必须判断,参与计算的数据都是有效数值才能进行,如果有任何无效数值,就用NaN向arrABS_APminusESA填充
// 这样计算得到的数据,每个位置和之前的数据都是一一对应的,不会错位。
if (ap[i] && esa[i] && !isNaN(ap[i]) && !isNaN(esa[i])) {
v = Math.abs(ap[i] - esa[i]) // 根据ABS(AP-ESA) , 具体计算数值,然后放入arrABS_APminusESA数组
arrABS_APminusESA.push(v)
} else {
arrABS_APminusESA.push(NaN)
}
}
if (arrABS_APminusESA.length <= n1) {
return false
}
return TA.EMA(arrABS_APminusESA, n1) // 计算数组arrABS_APminusESA的EMA指标,得到数据D(数组结构)
}
4、CI:=(AP-ESA)/(0.015*D);
이 계산 방식은 단계 1과 비슷하며 코드를 직접 방출합니다.
function CalcCI (ap, esa, d) { // CI:=(AP-ESA)/(0.015*D);
var arrCI = []
if (ap.length != esa.length || ap.length != d.length) {
throw "ap.length != esa.length || ap.length != d.length"
}
for (var i = 0; i < ap.length; i++) {
if (ap[i] && esa[i] && d[i] && !isNaN(ap[i]) && !isNaN(esa[i]) && !isNaN(d[i])) {
v = (ap[i] - esa[i]) / (0.015 * d[i])
arrCI.push(v)
} else {
arrCI.push(NaN)
}
}
if (arrCI.length == 0) {
return false
}
return arrCI
}
TCI:=EMA ((CI,N2)); CI 행렬의 EMA를 계산하는 것뿐입니다.
function CalcTCI (ci, n2) { // TCI:=EMA(CI,N2);
if (ci.length <= n2) {
return false
}
return TA.EMA(ci, n2)
}
WT2:SMA(WT1,4,1);
그리고 마지막 단계는 우리가 전에 만든 바퀴를 이용해서입니다.SMA
이 함수들은
function CalcWT2 (wt1) { // WT2:SMA(WT1,4,1);
if (wt1.length <= 4) {
return false
}
return SMA(wt1, 4, 1) // 使用我们自己实现的SMA函数计算出wt1的SMA指标。
}
트레이드 신호를 옮기는 것은 매우 간단합니다.
AA:=CROSS(WT1,WT2);
BB:=CROSSDOWN(WT1,WT2);
REF(AA,1),BPK;
REF(BB,1),SPK;
이 몇 문장을 읽으면, WT1와 WT2의 두 지표 라인의 금포, 죽은포가 거래 개시 조건으로 결정된다는 것을 알 수 있습니다. 이 문헌은 한글에 대한 문헌을 직접적으로 분석한 결과,
마어 언어 전략의 실제 실행 관찰을 통해 알 수 있듯이, 오픈 포인트 검출 시 신호는 실제로 오픈 포인트 이 BAR의 앞 2개의 BAR의 위치가 금포크인지 검출하는 것이다. 위의 그림은 분명히 볼 수 있다:
신호 탐지 부분의 채식 코드는 다음과 같이 쓸 수 있습니다.
if ((_State == IDLE || _State == SHORT) && wt1[wt1.length - 4] < wt2[wt2.length - 4] && wt1[wt1.length - 3] > wt2[wt2.length - 3]) {
if (_State == IDLE) {
_State = OPENLONG
Log("OPENLONG") // 测试
}
if (_State == SHORT) {
_State = COVERSHORT
Log("COVERSHORT") // 测试
}
isOK = false
}
if ((_State == IDLE || _State == LONG) && wt1[wt1.length - 4] > wt2[wt2.length - 4] && wt1[wt1.length - 3] < wt2[wt2.length - 3]) {
if (_State == IDLE) {
_State = OPENSHORT
Log("OPENSHORT") // 测试
}
if (_State == LONG) {
_State = COVERLONG
Log("COVERLONG") // 测试
}
isOK = false
}
여기서 왜 MAC 언어의 SPK, BPK 명령어가 위의 코드에서 구현될 수 있는지 생각해 볼 수 있습니다.
재검토 설정:
자바스크립트 버전 확인:
OnTick 함수의 시작 부분의 코드는, 회색 속도를 조금 더 빠르게 하기 위해 사용되며, 정책이 종점 가격 모델로 실행되도록 하기 때문에, 상세한 분석이 흥미롭다.
function OnTick(){
// 驱动策略的行情处理部分
var records = _C(exchange.GetRecords)
if (records[records.length - 1].Time == preTime) {
if (isOK) {
Sleep(500)
return
}
} else {
preTime = records[records.length - 1].Time
}
...
..
.
교육 전략의 전체 코드는:https://www.fmz.com/strategy/174457