Nhiều người trong số các bạn chơi tương lai trực giác có thể hơi lạ với chiến lược Aberration, một hệ thống giao dịch huyền thoại được phát minh bởi Keith Fitschen vào năm 1986 với lợi nhuận hàng năm hơn 100%. Ông đã công bố hệ thống này trong tạp chí Future Truth của Mỹ vào năm 1993. Đây là một hệ thống giao dịch đường dài trung bình, thuộc chiến lược theo dõi xu hướng, nó hoạt động linh hoạt giữa 8 giống giống như ngũ cốc, thịt, kim loại, năng lượng, ngoại hối, tương lai chỉ số chứng khoán và thu được lợi nhuận bằng cách theo dõi xu hướng đường dài. Và vì nó giao dịch cùng một lúc trong nhiều thị trường không liên quan hoặc ít liên quan, do đó chỉ cần thu được lợi nhuận cao từ xu hướng trong một hoặc một vài thị trường, nó bù đắp cho những lỗ trong các thị trường bất ổn khác. Tần suất giao dịch của nó thường là giao dịch một giống 3-4 lần mỗi năm, 60% thời gian được giữ, trung bình mỗi giao dịch được giữ 60 ngày. Chiến lược mở sàn là: đầu tiên sử dụng đường trung bình di chuyển 35 ngày và chênh lệch tiêu chuẩn giá đóng cửa trong 35 ngày, tạo ra ba đường dẫn, khi giá đóng cửa của một Bar đi trên đường dẫn nhiều hơn khi đi trên đường dẫn, phía dưới đi trên đường dẫn trống, phía dưới đi qua đường dẫn trung bình nhiều hơn, phía trên đi qua đường dẫn trung bình và phía trên đi trên đường dẫn trung bình. Ý tưởng của chiến lược này rất đơn giản: sử dụng đường trung bình chuyển động và đường chuẩn khác biệt để đánh giá bất cứ lúc nào nếu đường đã được phá vỡ và bắt được xu hướng. Khi xu hướng dần suy yếu, đường trung tâm sẽ giảm dần, do đó, khi đường K đi ngược qua đường trung tâm, xu hướng có thể được coi là kết thúc và dừng ra khỏi đường trung tâm. Chiến lược này được phát hành sớm hơn và có thể không phù hợp với thị trường giao dịch hiện nay, nhưng ý tưởng nắm bắt xu hướng là lâu dài.
Hệ thống giao dịch Abberation được phát minh bởi Keith Fitschen vào năm 1986 và được công bố trên tạp chí Future Trust vào năm 1993. Điều thú vị là Keith không phải là một nhà giao dịch sinh ra, ông đã phục vụ trong Không quân Hoa Kỳ hơn 20 năm, chuyên về hệ thống định hướng vũ khí, có sức mạnh sâu sắc trong việc xử lý dữ liệu chuỗi thời gian. Hệ thống giao dịch Abberation được đặc trưng là theo xu hướng thụ động, sử dụng tín hiệu dài hạn, giao dịch 3-4 lần mỗi năm trên một loại, giữ thời gian hơn 60% tổng thời gian giao dịch và có thể phân bổ số lượng loại khác nhau theo quy mô vốn khác nhau. Nó thu được lợi nhuận lớn bằng cách giao dịch dài để nắm bắt xu hướng, đồng thời giao dịch trên nhiều thị trường không liên quan, khi một loại rút lui, loại khác có thể thu được lợi nhuận. Trong một năm, luôn có một hoặc nhiều loại có thể thu được lợi nhuận lớn. Cụ thể, hệ thống Abberation sử dụng 3 quỹ đạo để giao dịch. Đầu tiên, tính toán trung bình toán học MA (close) của giá đóng cửa N ngày trước đây của giống như MID, và tính toán MID + m theo quỹ đạo bằng cách đo lường sự biến động của giá đóng cửa theo tiêu chuẩn sai std (close).std ((close) và MID-m dưới đường raystd ((close) ); làm nhiều khi giá phá vỡ đường ray, hòa vốn khi giá quay trở lại đường ray; ngược lại, làm trống khi giá phá vỡ đường ray, hòa vốn khi giá quay trở lại đường ray.
Aberration cũng là một hệ thống vượt qua kênh, nhưng đường lên xuống của nó được quyết định bởi tỷ lệ biến động.
Một, xác định trên và dưới đường: Aberration bao gồm ba đường dẫn, trong đó đường trung tâm là đường trung bình di chuyển trong một chu kỳ nhất định (AveMa), đường đi lên và đi xuống là đường trung tâm dựa trên giá trị tiêu chuẩn nhất định (StdValue) cộng với giảm, tức là đường Brain mà chúng ta quen thuộc, hệ thống được xây dựng rất đơn giản và đẹp.
Các quy trình tính toán cụ thể như sau: (1) Tính trung gian: AveMa=Average ((Close[1],Length); (2) tính toán sai tiêu chuẩn: StdValue = StandardDev ((Close[1],Length); (3) Đường tính toán: UpperBand=Avema+StdDevUpStdValue; (StdDevUp là tham số trên đường ray) (4) Tính theo đường ray: LowerBand=Avema-StdDevDnStdValue; (StdDevDn là tham số dưới đường ray)
Điều kiện mua bán: Bước đầu: Giá đóng cửa vượt qua đường cao hơn để mở nhiều hơn, rơi ra đường trung tâm; Bước trống: Giá đóng cửa giảm xuống dưới đường ray làm việc trống, phá vỡ đường ray giữa.
function Aberration(q, e, symbol, period, upRatio, downRatio, opAmount) {
var self = {}
self.q = q
self.e = e
self.symbol = symbol
self.upTrack = 0
self.middleTrack = 0
self.downTrack = 0
self.nPeriod = period
self.upRatio = upRatio
self.downRatio = downRatio
self.opAmount = opAmount
self.marketPosition = 0
self.lastErrMsg = ''
self.lastErrTime = ''
self.lastBar = {
Time: 0,
Open: 0,
High: 0,
Low: 0,
Close: 0,
Volume: 0
}
self.symbolDetail = null
self.lastBarTime = 0
self.tradeCount = 0
self.isBusy = false
self.setLastError = function(errMsg) {
self.lastErrMsg = errMsg
self.lastErrTime = errMsg.length > 0 ? _D() : ''
}
self.getStatus = function() {
return [self.symbol, self.opAmount, self.upTrack, self.downTrack, self.middleTrack, _N(self.lastBar.Close), (self.marketPosition == 0 ? "--" : (self.marketPosition > 0 ? "多#ff0000" : "空#0000ff")), self.tradeCount, self.lastErrMsg, self.lastErrTime]
}
self.getMarket = function() {
return [self.symbol, _D(self.lastBarTime), _N(self.lastBar.Open), _N(self.lastBar.High), _N(self.lastBar.Low), _N(self.lastBar.Close), self.lastBar.Volume]
}
self.restore = function(positions) {
for (var i = 0; i < positions.length; i++) {
if (positions[i].ContractType == self.symbol) {
self.marketPosition += positions[i].Amount * ((positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) ? 1 : -1)
}
}
if (self.marketPosition !== 0) {
self.tradeCount++
Log("恢复", self.symbol, "当前持仓为", self.marketPosition)
}
}
self.poll = function() {
if (self.isBusy) {
return false
}
if (!$.IsTrading(self.symbol)) {
self.setLastError("不在交易时间内")
return false
}
if (!self.e.IO("status")) {
self.setLastError("未连接交易所")
return false
}
var detail = self.e.SetContractType(self.symbol)
if (!detail) {
self.setLastError("切换合约失败")
return false
}
if (!self.symbolDetail) {
self.symbolDetail = detail
Log("合约", detail.InstrumentName.replace(/\s+/g, ""), ", 策略一次开仓:", self.opAmount, "手, 一手", detail.VolumeMultiple, "份, 最大下单量", detail.MaxLimitOrderVolume, "保证金率:", detail.LongMarginRatio.toFixed(4), detail.ShortMarginRatio.toFixed(4), "交割日期", detail.StartDelivDate);
}
var records = self.e.GetRecords()
if (!records || records.length == 0) {
self.setLastError("获取柱线失败")
return false
}
var bar = records[records.length - 1]
self.lastBar = bar
if (records.length <= self.nPeriod) {
self.setLastError("柱线长度不够")
return false
}
if (self.lastBarTime < bar.Time) {
var sum = 0
var pos = records.length - self.nPeriod - 1
for (var i = pos; i < records.length - 1; i++) {
sum += records[i].Close
}
var avg = sum / self.nPeriod
var std = 0
for (i = pos; i < records.length - 1; i++) {
std += Math.pow(records[i].Close - avg, 2)
}
std = Math.sqrt(std / self.nPeriod)
self.upTrack = _N(avg + (self.upRatio * std))
self.downTrack = _N(avg - (self.downRatio * std))
self.middleTrack = _N(avg)
self.lastBarTime = bar.Time
}
var msg
var act = ""
if (self.marketPosition == 0) {
if (bar.Close > self.upTrack) {
msg = '做多 触发价: ' + bar.Close + ' 上轨:' + self.upTrack;
act = "buy"
} else if (bar.Close < self.downTrack) {
msg = '做空 触发价: ' + bar.Close + ' 下轨:' + self.downTrack;
act = "sell"
}
} else {
if (self.marketPosition < 0 && bar.Close > self.middleTrack) {
msg = '平空 触发价: ' + bar.Close + ' 平仓线:' + self.middleTrack;
act = "closesell"
} else if (self.marketPosition > 0 && bar.Close < self.middleTrack) {
msg = '平多 触发价: ' + bar.Close + ' 平仓线:' + self.middleTrack;
act = "closebuy"
}
}
if (act == "") {
return true
}
Log(self.symbol + ', ' + msg + (NotifyWX ? '@' : ''))
self.isBusy = true
self.tradeCount += 1
if (self.lastErrMsg != '') {
self.setLastError('')
}
self.q.pushTask(self.e, self.symbol, act, self.opAmount, function(task, ret) {
self.isBusy = false
if (!ret) {
return
}
if (task.action == "buy") {
self.marketPosition = 1
} else if (task.action == "sell") {
self.marketPosition = -1
} else {
self.marketPosition = 0
}
})
}
return self
}
function main() {
if (exchange.GetName() !== 'Futures_CTP') {
throw "只支持传统商品期货(CTP)"
}
SetErrorFilter("login|ready|初始化")
LogStatus("Ready...")
if (Reset) {
LogProfitReset()
LogReset()
}
// Ref: https://www.fmz.com/bbs-topic/362
if (typeof(exchange.IO("mode", 0)) == 'number') {
Log("切换行情模式成功")
}
LogStatus("等待与期货商服务器连接..")
while (!exchange.IO("status")) {
Sleep(500)
}
LogStatus("获取资产信息")
var tblRuntime = {
type: 'table',
title: '交易信息',
cols: ['品种', '每次开仓量', '上轨', '下轨', '中轨', '最后成交价', '仓位', '交易次数', '最后错误', '错误时间'],
rows: []
};
var tblMarket = {
type: 'table',
title: '行情信息',
cols: ['品种', '当前周期', '开盘', '最高', '最低', '最后成交价', '成交量'],
rows: []
};
var tblPosition = {
type: 'table',
title: '持仓信息',
cols: ['品种', '杠杆', '方向', '均价', '数量', '持仓盈亏'],
rows: []
};
var positions = _C(exchange.GetPosition)
if (positions.length > 0 && !AutoRestore) {
throw "程序启动时不能有持仓, 但您可以勾选自动恢复来进行自动识别 !"
}
var initAccount = _C(exchange.GetAccount)
var detail = JSON.parse(exchange.GetRawJSON())
if (positions.length > 0) {
initAccount.Balance += detail['CurrMargin']
}
var initNetAsset = detail['CurrMargin'] + detail['Available']
var initAccountTbl = $.AccountToTable(exchange.GetRawJSON(), "初始资金")
if (initAccountTbl.rows.length == 0) {
initAccountTbl.rows = [
['Balance', '可用保证金', initAccount.Balance],
['FrozenBalance', '冻结资金', initAccount.FrozenBalance]
]
}
var nowAcccount = initAccount
var nowAcccountTbl = initAccountTbl
var symbols = Symbols.replace(/\s+/g, "").split(',')
var pollers = []
var prePosUpdate = 0
var suffix = ""
var needUpdate = false
var holdProfit = 0
function updateAccount(acc) {
nowAcccount = acc
nowAcccountTbl = $.AccountToTable(exchange.GetRawJSON(), "当前资金")
if (nowAcccountTbl.rows.length == 0) {
nowAcccountTbl.rows = [
['Balance', '可用保证金', nowAcccount.Balance],
['FrozenBalance', '冻结资金', nowAcccount.FrozenBalance]
]
}
}
var q = $.NewTaskQueue(function(task, ret) {
needUpdate = true
Log(task.desc, ret ? "成功" : "失败")
var account = task.e.GetAccount()
if (account) {
updateAccount(account)
}
})
_.each(symbols, function(symbol) {
var pair = symbol.split(':')
pollers.push(Aberration(q, exchange, pair[0], NPeriod, Ks, Kx, (pair.length == 1 ? AmountOP : parseInt(pair[1]))))
})
if (positions.length > 0 && AutoRestore) {
_.each(pollers, function(poll) {
poll.restore(positions)
})
}
var isFirst = true
while (true) {
var cmd = GetCommand()
if (cmd) {
var js = cmd.split(':', 2)[1]
Log("执行调试代码:", js)
try {
eval(js)
} catch (e) {
Log("Exception", e)
}
}
tblRuntime.rows = []
tblMarket.rows = []
var marketAlive = false
_.each(pollers, function(poll) {
if (poll.poll()) {
marketAlive = true
}
tblRuntime.rows.push(poll.getStatus())
tblMarket.rows.push(poll.getMarket())
})
q.poll()
Sleep(LoopInterval * 1000)
if ((!exchange.IO("status")) || (!marketAlive)) {
if (isFirst) {
LogStatus("正在等待开盘...", _D())
}
continue
}
isFirst = false
var now = new Date().getTime()
if (marketAlive && (now - prePosUpdate > 30000 || needUpdate)) {
var pos = exchange.GetPosition()
if (pos) {
holdProfit = 0
prePosUpdate = now
tblPosition.rows = []
for (var i = 0; i < pos.length; i++) {
tblPosition.rows.push([pos[i].ContractType, pos[i].MarginLevel, ((pos[i].Type == PD_LONG || pos[i].Type == PD_LONG_YD) ? '多#ff0000' : '空#0000ff'), pos[i].Price, pos[i].Amount, _N(pos[i].Profit)])
holdProfit += pos[i].Profit
}
if (pos.length == 0 && needUpdate) {
LogProfit(_N(nowAcccount.Balance - initAccount.Balance, 4), nowAcccount)
}
}
needUpdate = false
if (RCMode) {
var account = exchange.GetAccount()
if (account) {
updateAccount(account)
var detail = JSON.parse(exchange.GetRawJSON())
var netAsset = detail['PositionProfit'] + detail['CurrMargin'] + detail['Available']
var risk = detail['CurrMargin'] / (detail['CurrMargin'] + detail['Available'] + detail['PositionProfit'])
suffix = ", 账户初始净值约: " + _N(initNetAsset, 2) + " , 风控最小净值要求" + MinNetAsset + " , 当前账户净值约: " + _N(netAsset, 2) + ", 盈亏约: " + _N(netAsset - initNetAsset, 3) + " 元, 风险: " + ((risk * 100).toFixed(3)) + "% #ff0000"
if (netAsset < MinNetAsset) {
Log("风控模块触发, 中止运行并平掉所有仓位, 当前净值约 ", netAsset, ", 要求低于最小净值:", MinNetAsset)
if (RCCoverAll) {
Log("开始平掉所有仓位")
$.NewPositionManager().CoverAll()
}
throw "中止运行"
}
}
}
}
LogStatus('`' + JSON.stringify([tblRuntime, tblPosition, tblMarket, initAccountTbl, nowAcccountTbl]) + '`\n价格最后更新: ' + _D() + ', 持仓最后更新: ' + _D(prePosUpdate) + '\n当前持仓总盈亏: ' + _N(holdProfit, 3) + suffix)
}
}
Trong khi đó, các nhà đầu tư khác cũng có thể tham gia vào việc xây dựng danh mục đầu tư.
Một, chiến lược này rất đa dạng và thích nghi với chu kỳ, phù hợp với hầu hết các loại giao dịch. 2. Chiến lược rút tiền lớn đòi hỏi quản lý tài chính và kiểm soát rủi ro nghiêm ngặt.