ट्रेडिंग व्यू का अक्सर उपयोग करने वाले ट्रेडर जानते हैं कि ट्रेडिंग व्यू संदेशों को अन्य प्लेटफार्मों पर पुश कर सकता है। एफएमजेड प्लेटफॉर्म के हमारे
कुछ नौसिखियों को इस लेख के शीर्षक और उपरोक्त विवरण से भ्रम हो सकता है, इससे कोई फर्क नहीं पड़ता! आइए मांग परिदृश्यों और सिद्धांतों के स्पष्ट विवरण के साथ शुरू करें। ठीक है, आइए यहां विषय पर जाएं।
मांग के परिदृश्य: तो हम इसे किस तरह का काम करना चाहते हैं? इसे सरलता से रखने के लिए, हमारे पास बहुत सारे संकेतक, रणनीतियाँ, कोड, आदि हैं जिनका हम ट्रेडिंग व्यू पर उपयोग करने के लिए चुन सकते हैं, जिन्हें सीधे ट्रेडिंग व्यू पर लाइन खींचने, गणना करने और ट्रेडिंग सिग्नल प्रदर्शित करने के लिए चलाया जा सकता है। इसके अलावा, ट्रेडिंग व्यू में वास्तविक समय के मूल्य डेटा और विभिन्न संकेतकों की गणना की सुविधा के लिए पर्याप्त के-लाइन डेटा है। ट्रेडिंग व्यू पर इन स्क्रिप्ट कोड को PINE भाषा कहा जाता है। एकमात्र बात सुविधाजनक नहीं है कि ट्रेडिंग व्यू पर वास्तविक बॉट ट्रेडिंग है। हालांकि PINE भाषा FMZ पर समर्थित है, लेकिन इसका उपयोग वास्तविक बॉट ट्रेडिंग के लिए भी किया जा सकता है। हालांकि, कुछ ट्रेडिंग व्यू प्रशंसक अभी भी हैं जो ट्रेडिंग व्यू पर चार्ट से संकेतों का उपयोग करके ऑर्डर देना चाहते हैं, इसलिए इसे FMZ द्वारा हल किया जा सकता है। इसलिए इस लेख में, हम समाधान के विवरण की व्याख्या करेंगे।
सिद्धांत:
संपूर्ण योजना में चार विषय शामिल हैं, जो संक्षेप में निम्नलिखित हैंः
तो अगर आप इसे इन तरीकों से उपयोग करना चाहते हैं, तो आपको इन तैयारी की आवश्यकता हैः
पिछले संस्करण में
फिर ट्रेडिंग व्यू को सेट किया जा सकता है जैसा कि चित्र में दिखाया गया है ताकि अनुरोध बॉडी में संदेश लिखा जा सके और इसे एफएमजेड के विस्तारित एपीआई इंटरफेस पर भेजा जा सके। एफएमजेड के विस्तारित एपीआई इंटरफेस को कैसे कॉल करें?
एफएमजेड के विस्तारित एपीआई इंटरफेस की एक श्रृंखला में, हमेंCommandRobot
इंटरफेस, जिसे आमतौर पर इस प्रकार कहा जाता हैः
https://www.fmz.com/api/v1?access_key=xxx&secret_key=yyyy&method=CommandRobot&args=[186515,"ok12345"]
..access_key
औरsecret_key
मेंquery
इस अनुरोध का url विस्तारित हैAPI KEY
FMZ मंच के, यहाँ डेमो सेट करने के लिएxxx
औरyyyy
. तो कैसे इस कुंजी बनाने के लिए? इस पृष्ठ मेंःhttps://www.fmz.com/m/account
, उस पर निर्माण करें, इसे ठीक से रखें, इसका खुलासा न करें।
वापस बिंदु पर, चलो इंटरफेस समस्या के बारे में बात करने के लिए जारीCommandRobot
. यदि आपको एक्सेस करने की आवश्यकता हैCommandRobot
इंटरफ़ेस,method
अनुरोध में निम्न पर सेट किया जाएगा:CommandRobot
.CommandRobot
इंटरफेस FMZ मंच के माध्यम से एक आईडी के साथ एक असली बॉट के लिए एक इंटरैक्टिव संदेश भेजने के लिए है, इसलिए पैरामीटरargs
वास्तविक बॉट आईडी और संदेश शामिल है. ऊपर अनुरोध यूआरएल उदाहरण संदेश भेजने के लिए हैok12345
एक असली बॉट प्रोग्राम के लिए एक आईडी के साथ 186515
पहले, इस विधि का उपयोग FMZ विस्तारित एपीआई के कमांडरोबोट इंटरफ़ेस का अनुरोध करने के लिए किया गया था। संदेश केवल उपरोक्त उदाहरण में लिखे जा सकते हैं, जैसे किok12345
. यदि संदेश अनुरोधित निकाय में है, तो आपको एक और विधि का उपयोग करने की आवश्यकता हैः
https://www.fmz.com/api/v1?access_key=xxx&secret_key=yyyy&method=CommandRobot&args=[130350,+""]
इस तरह से अनुरोध एक इंटरैक्टिव संदेश के रूप में अनुरोध में शरीर की सामग्री भेज सकते हैं आईडी के साथ असली बॉट के लिए130350
एफएमजेड प्लेटफॉर्म के माध्यम से. यदि ट्रेडिंग व्यू पर संदेश सेट किया गया हैः{"close": {{close}}, "name": "aaa"}
, तो असली बॉट के साथ आईडी130350
इंटरैक्टिव निर्देश प्राप्त करेंगे:{"close": 39773.75, "name": "aaa"}
ताकि
{
Flag: "45M103Buy", // Marker, which can be specified at will
Exchange: 1, // Specify exchange trading pairs
Currency: "BTC_USDT", // Trading pair
ContractType: "swap", // Contract type, swap, quarter, next_quarter, fill in spot for spot
Price: "{{close}}", // Opening position or closing position price, -1 is the market price
Action: "buy", // Transaction type [buy: spot buying, sell: spot selling, long: go long futures, short: go short futures, closesell: buy futures and close short positions, close buy: sell futures and close long positions]
Amount: "0", // Transaction amount
}
रणनीति एक बहु-विनिमय वास्तुकला के रूप में डिज़ाइन की गई है, इसलिए इस रणनीति पर कई विनिमय वस्तुओं को कॉन्फ़िगर किया जा सकता है, अर्थात, कई अलग-अलग खातों के ऑर्डर प्लेसिंग ऑपरेशन को नियंत्रित किया जा सकता है। सिग्नल संरचना में केवल एक्सचेंज ही एक्सचेंज को संचालित करने के लिए निर्दिष्ट करता है। सेटिंग 1 इस सिग्नल को पहले जोड़े गए एक्सचेंज ऑब्जेक्ट के अनुरूप एक्सचेंज खाते को संचालित करने में सक्षम बनाना है। यदि स्पॉट कॉन्ट्रैक्टटाइप स्पॉट पर सेट किया गया है, तो वायदा विशिष्ट अनुबंध लिखेंगे, जैसे कि, स्थायी अनुबंधों के लिए स्वैप। बाजार मूल्य सूची -1 में पारित की जा सकती है। वायदा, स्पॉट, उद्घाटन और समापन पदों के लिए कार्रवाई सेटिंग अलग हैं, और इसे गलत तरीके से सेट नहीं किया जा सकता है।
इसके बाद, आप रणनीति कोड डिजाइन कर सकते हैं। पूर्ण रणनीति कोडः
//Signal structure
var Template = {
Flag: "45M103Buy", // Marker, which can be specified at will
Exchange: 1, // Specify exchange trading pairs
Currency: "BTC_USDT", // Trading pair
ContractType: "swap", // Contract type, swap, quarter, next_quarter, fill in spot for spot
Price: "{{close}}", // Opening position or closing position price, -1 is the market price
Action: "buy", // Transaction type [buy: spot buying, sell: spot selling, long: go long futures, short: go short futures, closesell: buy futures and close short positions, close buy: sell futures and close long positions]
Amount: "0", // Transaction amount
}
var BaseUrl = "https://www.fmz.com/api/v1" // FMZ extended API interface address
var RobotId = _G() // Current real bot ID
var Success = "#5cb85c" // Color for success
var Danger = "#ff0000" // Color for danger
var Warning = "#f0ad4e" // Color for alert
var buffSignal = []
// Check signal message format
function DiffObject(object1, object2) {
const keys1 = Object.keys(object1)
const keys2 = Object.keys(object2)
if (keys1.length !== keys2.length) {
return false
}
for (let i = 0; i < keys1.length; i++) {
if (keys1[i] !== keys2[i]) {
return false
}
}
return true
}
function CheckSignal(Signal) {
Signal.Price = parseFloat(Signal.Price)
Signal.Amount = parseFloat(Signal.Amount)
if (Signal.Exchange <= 0 || !Number.isInteger(Signal.Exchange)) {
Log("The minimum number of the exchange is 1 and it is an integer", Danger)
return
}
if (Signal.Amount <= 0 || typeof(Signal.Amount) != "number") {
Log("The transaction amount cannot be less than 0 and it is numerical type", typeof(Signal.Amount), Danger)
return
}
if (typeof(Signal.Price) != "number") {
Log("Price must be a value", Danger)
return
}
if (Signal.ContractType == "spot" && Signal.Action != "buy" && Signal.Action != "sell") {
Log("The command is to operate spot, Action error, Action:", Signal.Action, Danger)
return
}
if (Signal.ContractType != "spot" && Signal.Action != "long" && Signal.Action != "short" && Signal.Action != "closesell" && Signal.Action != "closebuy") {
Log("The command is to operate future, Action error, Action:", Signal.Action, Danger)
return
}
return true
}
function commandRobot(url, accessKey, secretKey, robotId, cmd) {
// https://www.fmz.com/api/v1?access_key=xxx&secret_key=xxx&method=CommandRobot&args=[xxx,+""]
url = url + '?access_key=' + accessKey + '&secret_key=' + secretKey + '&method=CommandRobot&args=[' + robotId + ',+""]'
var postData = {
method:'POST',
data:cmd
}
var headers = "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36\nContent-Type: application/json"
var ret = HttpQuery(url, postData, "", headers)
Log("Simulate a webhook request from TradingView, sending a POST request for testing purposes:", url, "body:", cmd, "response:", ret)
}
function createManager() {
var self = {}
self.tasks = []
self.process = function() {
var processed = 0
if (self.tasks.length > 0) {
_.each(self.tasks, function(task) {
if (!task.finished) {
processed++
self.pollTask(task)
}
})
if (processed == 0) {
self.tasks = []
}
}
}
self.newTask = function(signal) {
// {"Flag":"45M103Buy","Exchange":1,"Currency":"BTC_USDT","ContractType":"swap","Price":"10000","Action":"buy","Amount":"0"}
var task = {}
task.Flag = signal["Flag"]
task.Exchange = signal["Exchange"]
task.Currency = signal["Currency"]
task.ContractType = signal["ContractType"]
task.Price = signal["Price"]
task.Action = signal["Action"]
task.Amount = signal["Amount"]
task.exchangeIdx = signal["Exchange"] - 1
task.pricePrecision = null
task.amountPrecision = null
task.error = null
task.exchangeLabel = exchanges[task.exchangeIdx].GetLabel()
task.finished = false
Log("Create task:", task)
self.tasks.push(task)
}
self.getPrecision = function(n) {
var precision = null
var arr = n.toString().split(".")
if (arr.length == 1) {
precision = 0
} else if (arr.length == 2) {
precision = arr[1].length
}
return precision
}
self.pollTask = function(task) {
var e = exchanges[task.exchangeIdx]
var name = e.GetName()
var isFutures = true
e.SetCurrency(task.Currency)
if (task.ContractType != "spot" && name.indexOf("Futures_") != -1) {
// Non-spot, then set the contract
e.SetContractType(task.ContractType)
} else if (task.ContractType == "spot" && name.indexOf("Futures_") == -1) {
isFutures = false
} else {
task.error = "The ContractType in the command does not match the configured exchange object type"
return
}
var depth = e.GetDepth()
if (!depth || !depth.Bids || !depth.Asks) {
task.error = "Order book data exception"
return
}
if (depth.Bids.length == 0 && depth.Asks.length == 0) {
task.error = "No orders on the market entry position"
return
}
_.each([depth.Bids, depth.Asks], function(arr) {
_.each(arr, function(order) {
var pricePrecision = self.getPrecision(order.Price)
var amountPrecision = self.getPrecision(order.Amount)
if (Number.isInteger(pricePrecision) && !Number.isInteger(self.pricePrecision)) {
self.pricePrecision = pricePrecision
} else if (Number.isInteger(self.pricePrecision) && Number.isInteger(pricePrecision) && pricePrecision > self.pricePrecision) {
self.pricePrecision = pricePrecision
}
if (Number.isInteger(amountPrecision) && !Number.isInteger(self.amountPrecision)) {
self.amountPrecision = amountPrecision
} else if (Number.isInteger(self.amountPrecision) && Number.isInteger(amountPrecision) && amountPrecision > self.amountPrecision) {
self.amountPrecision = amountPrecision
}
})
})
if (!Number.isInteger(self.pricePrecision) || !Number.isInteger(self.amountPrecision)) {
task.err = "Failed to obtain precision"
return
}
e.SetPrecision(self.pricePrecision, self.amountPrecision)
// buy: spot buying, sell: spot selling, long: go long futures, short: go short futures, closesell: buy futures and close short positions, close buy: sell futures and close long positions
var direction = null
var tradeFunc = null
if (isFutures) {
switch (task.Action) {
case "long":
direction = "buy"
tradeFunc = e.Buy
break
case "short":
direction = "sell"
tradeFunc = e.Sell
break
case "closesell":
direction = "closesell"
tradeFunc = e.Buy
break
case "closebuy":
direction = "closebuy"
tradeFunc = e.Sell
break
}
if (!direction || !tradeFunc) {
task.error = "Wrong transaction direction:" + task.Action
return
}
e.SetDirection(direction)
} else {
if (task.Action == "buy") {
tradeFunc = e.Buy
} else if (task.Action == "sell") {
tradeFunc = e.Sell
} else {
task.error = "Wrong transaction direction:" + task.Action
return
}
}
var id = tradeFunc(task.Price, task.Amount)
if (!id) {
task.error = "Failed to place an order"
}
task.finished = true
}
return self
}
var manager = createManager()
function HandleCommand(signal) {
// Detect whether interactive command is received
if (signal) {
Log("Receive interactive command:", signal) // Receive the interactive command, print the interactive command
} else {
return // If it is not received, it will be returned directly without processing
}
// Check whether the interactive command is a test instruction. The test instruction can be sent out by the current strategy interaction control for testing
if (signal.indexOf("TestSignal") != -1) {
signal = signal.replace("TestSignal:", "")
// Call the FMZ extended API interface to simulate the webhook of the TradingView, and the message sent by the interactive button TestSignal: {"Flag":"45M103Buy","Exchange":1,"Currency":"BTC_USDT","ContractType":"swap","Price":"10000","Action":"buy","Amount":"0"}
commandRobot(BaseUrl, FMZ_AccessKey, FMZ_SecretKey, RobotId, signal)
} else if (signal.indexOf("evalCode") != -1) {
var js = signal.split(':', 2)[1]
Log("Execute debug code:", js)
eval(js)
} else {
// Process signal command
objSignal = JSON.parse(signal)
if (DiffObject(Template, objSignal)) {
Log("Received transaction signal command:", objSignal)
buffSignal.push(objSignal)
// Check the trading volume and exchange number
if (!CheckSignal(objSignal)) {
return
}
// Create task
manager.newTask(objSignal)
} else {
Log("Command cannot be recognized", signal)
}
}
}
function main() {
Log("WebHook address:", "https://www.fmz.com/api/v1?access_key=" + FMZ_AccessKey + "&secret_key=" + FMZ_SecretKey + "&method=CommandRobot&args=[" + RobotId + ',+""]', Danger)
Log("Transaction type [buy: spot buying, sell: spot selling, long: go long futures, short: go short futures, closesell: buy futures and close short positions, close buy: sell futures and close long positions]", Danger)
Log("Command template:", JSON.stringify(Template), Danger)
while (true) {
try {
// Process interactions
HandleCommand(GetCommand())
// Process tasks
manager.process()
if (buffSignal.length > maxBuffSignalRowDisplay) {
buffSignal.shift()
}
var buffSignalTbl = {
"type" : "table",
"title" : "Signal recording",
"cols" : ["Flag", "Exchange", "Currency", "ContractType", "Price", "Action", "Amount"],
"rows" : []
}
for (var i = buffSignal.length - 1 ; i >= 0 ; i--) {
buffSignalTbl.rows.push([buffSignal[i].Flag, buffSignal[i].Exchange, buffSignal[i].Currency, buffSignal[i].ContractType, buffSignal[i].Price, buffSignal[i].Action, buffSignal[i].Amount])
}
LogStatus(_D(), "\n", "`" + JSON.stringify(buffSignalTbl) + "`")
Sleep(1000 * SleepInterval)
} catch (error) {
Log("e.name:", error.name, "e.stack:", error.stack, "e.message:", error.message)
Sleep(1000 * 10)
}
}
}
रणनीतिक मापदंड और बातचीतः
रणनीति चलाने से पहले, विनिमय वस्तु को कॉन्फ़िगर किया जाना चाहिए, और दो मापदंडों
यह वेबहूक पता, समर्थित क्रिया आदेश, और संदेश प्रारूप जो ट्रेडिंग व्यू पर भरने की आवश्यकता है प्रिंट करेगा। महत्वपूर्ण बात यह है कि वेबहूक पता हैः
https://www.fmz.com/api/v1?access_key=22903bab96b26584dc5a22522984df42&secret_key=73f8ba01014023117cbd30cb9d849bfc&method=CommandRobot&args=[505628,+""]
बस कॉपी और सीधे ट्रेडिंग व्यू पर संबंधित स्थान पर चिपकाएँ।
यदि आप ट्रेडिंग व्यू द्वारा भेजे गए सिग्नल का अनुकरण करना चाहते हैं, तो आप रणनीति बातचीत पर टेस्ट सिग्नल बटन पर क्लिक कर सकते हैं.
यह रणनीति एक अनुरोध भेजती है (एक सिग्नल अनुरोध भेजने वाले ट्रेडिंगव्यू का अनुकरण करती है), रणनीति को संदेश भेजने के लिए FMZ
{"Flag":"45M103Buy","Exchange":1,"Currency":"BTC_USDT","ContractType":"swap","Price":"16000","Action":"buy","Amount":"1"}
वर्तमान रणनीति एक और इंटरैक्टिव संदेश प्राप्त करेगा और निष्पादित करेगा, और लेनदेन के लिए एक आदेश रखेगा।
TradingView परीक्षण का उपयोग करने के लिए आवश्यक है कि TradingView खाता प्रो स्तर पर हो. परीक्षण से पहले, आपको कुछ पूर्व ज्ञान की आवश्यकता है.
उदाहरण के रूप में एक सरल पाइन स्क्रिप्ट (यादृच्छिक रूप से ट्रेडिंग व्यू पर पाया और संशोधित) लें
//@version=5
strategy("Consecutive Up/Down Strategy", overlay=true)
consecutiveBarsUp = input(3)
consecutiveBarsDown = input(3)
price = close
ups = 0.0
ups := price > price[1] ? nz(ups[1]) + 1 : 0
dns = 0.0
dns := price < price[1] ? nz(dns[1]) + 1 : 0
if (not barstate.ishistory and ups >= consecutiveBarsUp and strategy.position_size <= 0)
action = strategy.position_size < 0 ? "closesell" : "long"
strategy.order("ConsUpLE", strategy.long, 1, comment=action)
if (not barstate.ishistory and dns >= consecutiveBarsDown and strategy.position_size >= 0)
action = strategy.position_size > 0 ? "closebuy" : "short"
strategy.order("ConsDnSE", strategy.short, 1, comment=action)
निम्नलिखित प्लेसहोल्डर हैं. उदाहरण के लिए, अगर मैं लिख{{strategy.order.contracts}}
अलर्ट के
{{strategy.position_size}}
- पाइन में एक ही कीवर्ड का मान लौटाएं, अर्थात वर्तमान स्थिति का आकार।{{strategy.order.action}}
- निष्पादित आदेश के लिए स्ट्रिंग {{strategy.order.contracts}}
- उन अनुबंधों की संख्या लौटाएं जिनके लिए आदेश निष्पादित किए गए हैं।{{strategy.order.price}}
- निष्पादित आदेश की कीमत लौटाओ।{{strategy.order.id}}
- निष्पादित आदेश की आईडी लौटाएं (ऑर्डर उत्पन्न करने वाले फ़ंक्शन कॉल में से एक में पहले पैरामीटर के रूप में उपयोग की जाने वाली स्ट्रिंगः strategy.entry,strategy.exitया रणनीति.आदेश) ।{{strategy.order.comment}}
- निष्पादित आदेश की टिप्पणी लौटाता है (ऑर्डर उत्पन्न करने वाले फ़ंक्शन कॉल में से एक में टिप्पणी पैरामीटर में प्रयुक्त स्ट्रिंगः strategy.entry,strategy.exit, या strategy.order) यदि कोई टिप्पणी निर्दिष्ट नहीं की जाती है, तोstrategy.order.idका उपयोग किया जाएगा।{{strategy.order.alert_message}}
- alert_message पैरामीटर का मूल्य लौटाता है जिसका उपयोग strategy{{strategy.market_position}}
- स्ट्रैटेजी की वर्तमान स्थिति को स्ट्रिंग के रूप में लौटाएंः {{strategy.market_position_size}}
- एक पूर्ण मान (यानी एक गैर-ऋणात्मक संख्या) के रूप में वर्तमान स्थिति का आकार लौटाता है।{{strategy.prev_market_position}}
- स्ट्रैटेजी की पिछली स्थिति को स्ट्रिंग के रूप में लौटाएं: {{strategy.prev_market_position_size}}
- एक पूर्ण मान (यानी एक गैर-ऋणात्मक संख्या) के रूप में पिछली स्थिति का आकार लौटाता है।
{
"Flag":"{{strategy.order.id}}",
"Exchange":1,
"Currency":"BTC_USDT",
"ContractType":"swap",
"Price":"-1",
"Action":"{{strategy.order.comment}}",
"Amount":"{{strategy.order.contracts}}"
}
जब ट्रेडिंग व्यू पर PINE स्क्रिप्ट लेनदेन को ट्रिगर करती है, तो एक वेबहूक यूआरएल अनुरोध भेजा जाएगा.
FMZ असली बॉट इस संकेत को निष्पादित करेगा।
इस लेख में कोड केवल संदर्भ के लिए है, और इसे वास्तविक उपयोग में स्वयं समायोजित और विस्तारित किया जा सकता है।