ٹی وی پر سپر ٹرینڈ اشارے کے کئی ورژن ہیں، ایک نسبتا آسان سمجھنے کے لئے ایک الگورتھم کی نقل و حمل کے لئے تلاش کریں، مقابلے کے لئے موجد کی طرف سے مقداری ٹریڈنگ پلیٹ فارم کی جانچ پڑتال کے نظام ٹی وی چارٹ پر بھری ہوئی سپر ٹرینڈ اشارے، تھوڑا سا فرق پایا، فی الحال کی وجہ سمجھ میں نہیں آیا، امید ہے کہ آپ کے قارئین کو رہنمائی، میں نے سب سے پہلے ہراساں کرنا چھوڑ دیا.
// VIA: https://github.com/freqtrade/freqtrade-strategies/issues/30
function SuperTrend(r, period, multiplier) {
// atr
var atr = talib.ATR(r, period)
// baseUp , baseDown
var baseUp = []
var baseDown = []
for (var i = 0; i < r.length; i++) {
if (isNaN(atr[i])) {
baseUp.push(NaN)
baseDown.push(NaN)
continue
}
baseUp.push((r[i].High + r[i].Low) / 2 + multiplier * atr[i])
baseDown.push((r[i].High + r[i].Low) / 2 - multiplier * atr[i])
}
// fiUp , fiDown
var fiUp = []
var fiDown = []
var prevFiUp = 0
var prevFiDown = 0
for (var i = 0; i < r.length; i++) {
if (isNaN(baseUp[i])) {
fiUp.push(NaN)
} else {
fiUp.push(baseUp[i] < prevFiUp || r[i - 1].Close > prevFiUp ? baseUp[i] : prevFiUp)
prevFiUp = fiUp[i]
}
if (isNaN(baseDown[i])) {
fiDown.push(NaN)
} else {
fiDown.push(baseDown[i] > prevFiDown || r[i - 1].Close < prevFiDown ? baseDown[i] : prevFiDown)
prevFiDown = fiDown[i]
}
}
var st = []
var prevSt = NaN
for (var i = 0; i < r.length; i++) {
if (i < period) {
st.push(NaN)
continue
}
var nowSt = 0
if (((isNaN(prevSt) && isNaN(fiUp[i - 1])) || prevSt == fiUp[i - 1]) && r[i].Close <= fiUp[i]) {
nowSt = fiUp[i]
} else if (((isNaN(prevSt) && isNaN(fiUp[i - 1])) || prevSt == fiUp[i - 1]) && r[i].Close > fiUp[i]) {
nowSt = fiDown[i]
} else if (((isNaN(prevSt) && isNaN(fiDown[i - 1])) || prevSt == fiDown[i - 1]) && r[i].Close >= fiDown[i]) {
nowSt = fiDown[i]
} else if (((isNaN(prevSt) && isNaN(fiDown[i - 1])) || prevSt == fiDown[i - 1]) && r[i].Close < fiDown[i]) {
nowSt = fiUp[i]
}
st.push(nowSt)
prevSt = st[i]
}
var up = []
var down = []
for (var i = 0; i < r.length; i++) {
if (isNaN(st[i])) {
up.push(st[i])
down.push(st[i])
}
if (r[i].Close < st[i]) {
down.push(st[i])
up.push(NaN)
} else {
down.push(NaN)
up.push(st[i])
}
}
return [up, down]
}
// 测试指标用的main函数,并非交易策略
function main() {
while (1) {
var r = _C(exchange.GetRecords)
var st = SuperTrend(r, 10, 3)
$.PlotRecords(r, "K")
$.PlotLine("L", st[0][st[0].length - 2], r[r.length - 2].Time)
$.PlotLine("S", st[1][st[1].length - 2], r[r.length - 2].Time)
Sleep(2000)
}
}
ٹیسٹ کوڈ کی دوبارہ جانچ پڑتال:
تجارتی منطق کا حصہ ، جو کہ نسبتاً آسان ہے ، یہ ہے کہ جب خالی ٹرینڈ ٹرینڈ میں بدل جاتا ہے تو زیادہ پوزیشنیں کھولی جاتی ہیں۔ جب کثیر مقصود رجحان خالی ٹرینڈ میں بدل جاتا ہے تو خالی پوزیشنیں کھولیں۔
حکمت عملی کے پیرامیٹرز:
سپر ٹرینڈ تجارت کی حکمت عملی
/*backtest
start: 2019-08-01 00:00:00
end: 2020-03-11 00:00:00
period: 15m
basePeriod: 5m
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}]
*/
// 全局变量
var OpenAmount = 0 // 开仓后持仓的数量
var KeepAmount = 0 // 保留仓位
var IDLE = 0
var LONG = 1
var SHORT = 2
var COVERLONG = 3
var COVERSHORT = 4
var COVERLONG_PART = 5
var COVERSHORT_PART = 6
var OPENLONG = 7
var OPENSHORT = 8
var State = IDLE
// 交易逻辑部分
function GetPosition(posType) {
var positions = _C(exchange.GetPosition)
/*
if(positions.length > 1){
throw "positions error:" + JSON.stringify(positions)
}
*/
var count = 0
for(var j = 0; j < positions.length; j++){
if(positions[j].ContractType == Symbol){
count++
}
}
if(count > 1){
throw "positions error:" + JSON.stringify(positions)
}
for (var i = 0; i < positions.length; i++) {
if (positions[i].ContractType == Symbol && positions[i].Type === posType) {
return [positions[i].Price, positions[i].Amount];
}
}
Sleep(TradeInterval);
return [0, 0]
}
function CancelPendingOrders() {
while (true) {
var orders = _C(exchange.GetOrders)
for (var i = 0; i < orders.length; i++) {
exchange.CancelOrder(orders[i].Id);
Sleep(TradeInterval);
}
if (orders.length === 0) {
break;
}
}
}
function Trade(Type, Price, Amount, CurrPos, OnePriceTick){ // 处理交易
if(Type == OPENLONG || Type == OPENSHORT){ // 处理开仓
exchange.SetDirection(Type == OPENLONG ? "buy" : "sell")
var pfnOpen = Type == OPENLONG ? exchange.Buy : exchange.Sell
var idOpen = pfnOpen(Price, Amount, CurrPos, OnePriceTick, Type)
Sleep(TradeInterval)
if(idOpen) {
exchange.CancelOrder(idOpen)
} else {
CancelPendingOrders()
}
} else if(Type == COVERLONG || Type == COVERSHORT){ // 处理平仓
exchange.SetDirection(Type == COVERLONG ? "closebuy" : "closesell")
var pfnCover = Type == COVERLONG ? exchange.Sell : exchange.Buy
var idCover = pfnCover(Price, Amount, CurrPos, OnePriceTick, Type)
Sleep(TradeInterval)
if(idCover){
exchange.CancelOrder(idCover)
} else {
CancelPendingOrders()
}
} else {
throw "Type error:" + Type
}
}
function SuperTrend(r, period, multiplier) {
// atr
var atr = talib.ATR(r, period)
// baseUp , baseDown
var baseUp = []
var baseDown = []
for (var i = 0; i < r.length; i++) {
if (isNaN(atr[i])) {
baseUp.push(NaN)
baseDown.push(NaN)
continue
}
baseUp.push((r[i].High + r[i].Low) / 2 + multiplier * atr[i])
baseDown.push((r[i].High + r[i].Low) / 2 - multiplier * atr[i])
}
// fiUp , fiDown
var fiUp = []
var fiDown = []
var prevFiUp = 0
var prevFiDown = 0
for (var i = 0; i < r.length; i++) {
if (isNaN(baseUp[i])) {
fiUp.push(NaN)
} else {
fiUp.push(baseUp[i] < prevFiUp || r[i - 1].Close > prevFiUp ? baseUp[i] : prevFiUp)
prevFiUp = fiUp[i]
}
if (isNaN(baseDown[i])) {
fiDown.push(NaN)
} else {
fiDown.push(baseDown[i] > prevFiDown || r[i - 1].Close < prevFiDown ? baseDown[i] : prevFiDown)
prevFiDown = fiDown[i]
}
}
var st = []
var prevSt = NaN
for (var i = 0; i < r.length; i++) {
if (i < period) {
st.push(NaN)
continue
}
var nowSt = 0
if (((isNaN(prevSt) && isNaN(fiUp[i - 1])) || prevSt == fiUp[i - 1]) && r[i].Close <= fiUp[i]) {
nowSt = fiUp[i]
} else if (((isNaN(prevSt) && isNaN(fiUp[i - 1])) || prevSt == fiUp[i - 1]) && r[i].Close > fiUp[i]) {
nowSt = fiDown[i]
} else if (((isNaN(prevSt) && isNaN(fiDown[i - 1])) || prevSt == fiDown[i - 1]) && r[i].Close >= fiDown[i]) {
nowSt = fiDown[i]
} else if (((isNaN(prevSt) && isNaN(fiDown[i - 1])) || prevSt == fiDown[i - 1]) && r[i].Close < fiDown[i]) {
nowSt = fiUp[i]
}
st.push(nowSt)
prevSt = st[i]
}
var up = []
var down = []
for (var i = 0; i < r.length; i++) {
if (isNaN(st[i])) {
up.push(st[i])
down.push(st[i])
}
if (r[i].Close < st[i]) {
down.push(st[i])
up.push(NaN)
} else {
down.push(NaN)
up.push(st[i])
}
}
return [up, down]
}
var preTime = 0
function main() {
exchange.SetContractType(Symbol)
while (1) {
var r = _C(exchange.GetRecords)
var currBar = r[r.length - 1]
if (r.length < pd) {
Sleep(5000)
continue
}
var st = SuperTrend(r, pd, factor)
$.PlotRecords(r, "K")
$.PlotLine("L", st[0][st[0].length - 2], r[r.length - 2].Time)
$.PlotLine("S", st[1][st[1].length - 2], r[r.length - 2].Time)
if(!isNaN(st[0][st[0].length - 2]) && isNaN(st[0][st[0].length - 3])){
if (State == SHORT) {
State = COVERSHORT
} else if(State == IDLE) {
State = OPENLONG
}
}
if(!isNaN(st[1][st[1].length - 2]) && isNaN(st[1][st[1].length - 3])){
if (State == LONG) {
State = COVERLONG
} else if (State == IDLE) {
State = OPENSHORT
}
}
// 执行信号
var pos = null
var price = null
if(State == OPENLONG){ // 开多仓
pos = GetPosition(PD_LONG) // 检查持仓
// 判断是不是 满足状态,如果满足 修改状态
if(pos[1] >= Amount){ // 持仓超过或者等于参数设置的 开仓量
Sleep(1000)
$.PlotFlag(currBar.Time, "开多仓", 'OL') // 标记
OpenAmount = pos[1] // 记录开仓数
State = LONG // 标记为 做多状态
continue
}
price = currBar.Close - (currBar.Close % PriceTick) + PriceTick * 2 // 计算价格
Trade(OPENLONG, price, Amount - pos[1], pos, PriceTick) // 下单函数 (Type, Price, Amount, CurrPos, PriceTick)
}
if(State == OPENSHORT){ // 开空仓
pos = GetPosition(PD_SHORT) // 检查持仓
if(pos[1] >= Amount){
Sleep(1000)
$.PlotFlag(currBar.Time, "开空仓", 'OS')
OpenAmount = pos[1]
State = SHORT
continue
}
price = currBar.Close - (currBar.Close % PriceTick) - PriceTick * 2
Trade(OPENSHORT, price, Amount - pos[1], pos, PriceTick)
}
if(State == COVERLONG){ // 处理平多仓
pos = GetPosition(PD_LONG) // 获取持仓信息
if(pos[1] == 0){ // 判断持仓是否为 0
$.PlotFlag(currBar.Time, "平多仓", '----CL') // 标记
State = IDLE
continue
}
price = currBar.Close - (currBar.Close % PriceTick) - PriceTick * 2
Trade(COVERLONG, price, pos[1], pos, PriceTick)
}
if(State == COVERSHORT){ // 处理做多仓
pos = GetPosition(PD_SHORT)
if(pos[1] == 0){
$.PlotFlag(currBar.Time, "平空仓", '----CS')
State = IDLE
continue
}
price = currBar.Close - (currBar.Close % PriceTick) + PriceTick * 2
Trade(COVERSHORT, price, pos[1], pos, PriceTick)
}
if(State == COVERLONG_PART) { // 部分平多仓
pos = GetPosition(PD_LONG) // 获取持仓
if(pos[1] <= KeepAmount){ // 持仓小于等于 保持量,本次平仓完成
$.PlotFlag(currBar.Time, "平多仓,保留:" + KeepAmount, '----CL') // 标记
State = pos[1] == 0 ? IDLE : LONG // 更新状态
continue
}
price = currBar.Close - (currBar.Close % PriceTick) - PriceTick * 2
Trade(COVERLONG, price, pos[1] - KeepAmount, pos, PriceTick)
}
if(State == COVERSHORT_PART){
pos = GetPosition(PD_SHORT)
if(pos[1] <= KeepAmount){
$.PlotFlag(currBar.Time, "平空仓,保留:" + KeepAmount, '----CS')
State = pos[1] == 0 ? IDLE : SHORT
continue
}
price = currBar.Close - (currBar.Close % PriceTick) + PriceTick * 2
Trade(COVERSHORT, price, pos[1] - KeepAmount, pos, PriceTick)
}
LogStatus(_D())
Sleep(1000)
}
}
اسٹریٹجک ایڈریس:https://www.fmz.com/strategy/201837
پیرامیٹرز کی ترتیب، K لائن دورانیہ، حوالہ: homily خداSuperTrend V.1 - سپر ٹرینڈ لائن سسٹمK لائن سائیکل 15 منٹ کی سیٹ ، سپر ٹرینڈ پیرامیٹرز 45،3 کی سیٹ کریں۔ OKEX فیوچر کوارٹر معاہدے کا پچھلے سال کا وقت واپس کریں ، ہر تجارت پر ایک معاہدہ ترتیب دیں ، کیونکہ فی تجارت صرف ایک معاہدہ ترتیب دیا گیا ہے ، لہذا فنڈز کا استعمال بہت کم ہے ، لہذا شارپ کی قدر پر غور کرنے کی ضرورت نہیں ہے۔
یہ حکمت عملی صرف سیکھنے کے لئے ہے، لیکن احتیاط سے استعمال کریں۔
لیجنگ ایکس ایف ڈی جیکیا اس حکمت عملی کا اصل مسئلہ حل ہو گیا ہے؟ میں دیکھ رہا ہوں کہ ٹی وی کے پاس ٹی اے سپر اسٹینڈ کی پالیسی ہے ، لیکن جاوا اسکرپٹ لکھنے میں زیادہ آزادی ہے ، امید ہے کہ جاوا اسکرپٹ کے قابل ٹی اے میں بھی ایک درست سپر اسٹینڈ ورژن لپیٹا جائے گا۔
1070278998@qq.comاگر آپ کو یہ کام کرنے کی ضرورت ہے تو ، آپ کو یہ کام کرنے کی ضرورت نہیں ہے۔ اگر آپ کو یہ کام کرنے کی ضرورت ہے تو ، آپ کو یہ کام کرنے کی ضرورت نہیں ہے۔
اسکائیفائرخوابوں کی طاقت
وائلینٹی وی کے ساتھ اختلافات FMZ پیکج میں ATR حساب کے مسائل ہونا چاہئے، مثال کے طور پر، ان پٹ کے دورانیے 7 ہے، حساب سے باہر ATR کے پہلے 6 اقدار صفر ہونا چاہئے، لیکن اصل میں نہیں ہے
ایجاد کاروں کی مقدار - خوابفی الحال ، یہ ممکن نہیں ہے کہ براہ راست پائن اسکرپٹ کے افعال کو بلایا جاسکے۔ ممکنہ طور پر ہم آہنگی کی حمایت میں اضافہ کیا جائے گا۔
ایجاد کاروں کی مقدار - خواب.PlotLine پینٹنگ لائن کلاس لائبریری کا ایک انٹرفیس فنکشن ہے ، خاص طور پر حکمت عملی اسکوائر میں پینٹنگ لائن کلاس لائبریری کے اس سانچے کو نقل کیا جاسکتا ہے ، جس کا کوڈ عوامی ہے۔ ماخذ کوڈ کو دیکھ کر سمجھ میں آتا ہے۔
1070278998@qq.com$.PlotRecords ((r، "K") $.PlotLine (("L"، st[0][st[0].length - 2]، r[r.length - 2].Time) $.PlotLine (("S"، st[1][st[1].length - 2]، r[r.length - 2].Time) سوال یہ ہے کہ L کے بعد کا کوڈ کیا ہے؟ اگر یہ ایک نچلی لائن ہے تو کیا اس کے بعد کا r اس کے ساتھ استعمال کیا جانا چاہئے؟
1070278998@qq.com$.PlotRecords ((r، "K") $.PlotLine (("L"، st[0][st[0].length - 2]، r[r.length - 2].Time) $.PlotLine (("S"، st[1][st[1].length - 2]، r[r.length - 2].Time) اگر آپ کو یہ سوال کرنا ہے کہ کیا L کے بعد کا کوڈ اس کا مطلب ہے کہ اگر یہ نیچے کی لائن ہے تو کیا اس کے بعد کا r اس کے ساتھ کام کرنا چاہئے؟
ایجاد کاروں کی مقدار - خوابکیا ایس پی؟
ایجاد کاروں کی مقدار - خوابup[up.length - 1]، اشارے کا منفی پہلا اعداد و شمار، K لائن کے منفی پہلا بار کے مطابق؛
1070278998@qq.comsp کا دورانیہ کیسے طے کیا جاتا ہے؟ کس پیرامیٹر کو تبدیل کرنا ہے؟
1070278998@qq.com Up.length-1就是上边线最近的一个数字吗
ایجاد کاروں کی مقدار - خوابواپسی ایک دو جہتی صف ہے، اوپر لائن ہے، نیچے لائن ہے. واپسی پورے اشارے کے اعداد و شمار ہے.
ایجاد کاروں کی مقدار - خواباوہ، ذیل میں ٹریڈنگ ویو پر الگورتھم کی مزید تفصیلات ملاحظہ کریں۔
وائلینجی ہاں، میں نے اس مسئلے کی تصدیق کی ہے، یہ تھوڑا سا الجھا ہوا ہے، میں نہیں جانتا کہ کس کے ساتھ.
ایجاد کاروں کی مقدار - خوابٹھیک ہے ، شکریہ ، لیکن میں طالب کے ATR کا استعمال کر رہا ہوں ، اور یہ درست نہیں لگتا ہے ، اور اعداد و شمار میں تھوڑا سا فرق ہے جو براہ راست الگورتھم کے ذریعہ ATR کو لاگو کرتے ہیں۔