[TOC]
এই টিউটোরিয়াল শেখার আগে, আপনি অধ্যয়ন করতে হবেএফএমজেড কোয়ান্ট প্ল্যাটফর্ম দিয়ে শুরু করুনএবংএফএমজেড কোয়ান্ট প্ল্যাটফর্ম কৌশল লেখার জন্য প্রাথমিক টিউটোরিয়াল, এবং প্রোগ্রামিং ভাষায় দক্ষতা অর্জন করুন।প্রাথমিক টিউটোরিয়ালটি সর্বাধিক ব্যবহৃত ফাংশনগুলিকে কভার করে, তবে অনেকগুলি ফাংশন এবং বৈশিষ্ট্য রয়েছে যা চালু করা হয়নি, এবং এগুলি এই টিউটোরিয়ালে অন্তর্ভুক্ত করা হবে না। এগুলি নিজেরাই বুঝতে আপনাকে এফএমজেড প্ল্যাটফর্মের এপিআই ডকুমেন্টটি ব্রাউজ করতে হবে।এই টিউটোরিয়ালটি শেখার পর, আপনি আরো বিনামূল্যে এবং কাস্টমাইজড কৌশল লিখতে সক্ষম হবে, এবং FMZ Quant প্ল্যাটফর্ম শুধুমাত্র একটি টুল.
এফএমজেড কোয়ান্ট প্ল্যাটফর্ম সমস্ত সমর্থিত প্ল্যাটফর্মকে ক্যাপসুল করে। অভিন্নতা বজায় রাখার জন্য, একক প্ল্যাটফর্ম এপিআইয়ের জন্য আমাদের সমর্থন এখনও সম্পূর্ণ নয়। উদাহরণস্বরূপ, গেট রেকর্ডস কে-লাইন সংখ্যা বা শুরু করার সময় পাস করতে পারে, যখন এটি এফএমজেড প্ল্যাটফর্মে স্থির থাকে; কিছু প্ল্যাটফর্ম ব্যাচ অর্ডারিং সমর্থন করে, যখন এফএমজেড এটি সমর্থন করে না, ইত্যাদি। সুতরাং প্ল্যাটফর্মের ডেটা সরাসরি অ্যাক্সেস করার উপায়ের প্রয়োজন রয়েছে।পাবলিক ইন্টারফেসের জন্য (যেমন মার্কেট কোটেশন), আপনি ব্যবহার করতে পারেনHttpQuery
, এবং এনক্রিপ্ট করা ইন্টারফেসের জন্য (অ্যাকাউন্টের তথ্য জড়িত), আপনাকে ব্যবহার করতে হবেIO
.নির্দিষ্ট ইনকামিং পরামিতি জন্য, অনুগ্রহ করে সংশ্লিষ্ট প্ল্যাটফর্ম API নথি পড়ুন. পূর্ববর্তী টিউটোরিয়াল চালু করেছে যেInfo
ক্ষেত্রটি কাঁচা তথ্য ফেরত দেয়, কিন্তু এটি ইন্টারফেসগুলিকে সমর্থন না করার সমস্যার ক্ষেত্রে এখনও কোনও পার্থক্য করে না।
এটি শেষ REST API দ্বারা অনুরোধ করা কাঁচা সামগ্রী (স্ট্রিং) ফেরত দেয়, যা নিজের দ্বারা বর্ধিত তথ্য বিশ্লেষণ করতে ব্যবহার করা যেতে পারে।
function main(){
var account = exchange.GetAccount() //the account doesn't contain all data returned by the request
var raw = JSON.parse(exchange.GetRawJSON())//raw data returned by GetAccount()
Log(raw)
}
পাবলিক ইন্টারফেস অ্যাক্সেস করতে, জেএস ব্যবহার করতে পারেনHttpQuery
, এবং পাইথন সম্পর্কিত প্যাকেজ ব্যবহার করতে পারেন, যেমনurllib
অথবাrequests
.
HttpQuery GET পদ্ধতিতে ডিফল্ট, এবং আরো ফাংশন সমর্থন করে; আরও বিস্তারিত জানার জন্য API নথিটি দেখুন।
var exchangeInfo = JSON.parse(HttpQuery('https://api.binance.com/api/v1/exchangeInfo'))
Log(exchangeInfo)
var ticker = JSON.parse(HttpQuery('https://api.binance.com/api/v1/ticker/24hr'))
var kline = JSON.parse(HttpQuery("https://www.quantinfo.com/API/m/chart/history?symbol=BTC_USD_BITFINEX&resolution=60&from=1525622626&to=1561607596"))
অনুরোধ ব্যবহার করে পাইথনের উদাহরণঃ
import requests
resp = requests.get('https://www.quantinfo.com/API/m/chart/history?symbol=BTC_USD_BITFINEX&resolution=60&from=1525622626&to=1561607596')
data = resp.json()
API-KEY স্বাক্ষরগুলির প্রয়োজন এমন ইন্টারফেসের জন্য, IO ফাংশনটি ব্যবহার করা যেতে পারে, এবং ব্যবহারকারীদের কেবল ইনকামিং পরামিতি সম্পর্কে চিন্তা করতে হবে, এবং নির্দিষ্ট স্বাক্ষর প্রক্রিয়াটি আন্ডারলেয়ার দ্বারা সম্পন্ন হবে।
এফএমজেড প্ল্যাটফর্ম বর্তমানে বিটমেক্স স্টপ-লস অর্ডার সমর্থন করে না, যা নিম্নলিখিত পদক্ষেপ অনুসারে আইও এর মাধ্যমে বাস্তবায়ন করা যেতে পারেঃ
https://www.bitmex.com/api/explorer/
;https://www.bitmex.com/api/v1/order
, পদ্ধতির সাথেPOST
; FMZ এর জন্য ইতিমধ্যে অভ্যন্তরীণভাবে বেস ঠিকানা নির্দিষ্ট করা হয়েছে, আপনাকে কেবল symbol=XBTUSD&side=Buy&orderQty=1&stopPx=4000&ordType=Stop
.নির্দিষ্ট কোডঃ
var id = exchange.IO("api", "POST", "/api/v1/order", "symbol=XBTUSD&side=Buy&orderQty=1&stopPx=4000&ordType=Stop")
// You can also pass in the object
var id = exchange.IO("api", "POST", "/api/v1/order", "", JSON.stringify({symbol:"XBTUSD",side:"Buy",orderQty:1,stopPx:4000,ordType:"Stop"}))
আরও আইও উদাহরণঃhttps://www.fmz.com/bbs-topic/3683
মূলত, সমস্ত ক্রিপ্টোকারেন্সি প্ল্যাটফর্ম বাজারের উদ্ধৃতি প্রেরণের জন্য ওয়েবসকেট সমর্থন করে এবং কিছু প্ল্যাটফর্ম অ্যাকাউন্টের তথ্য আপডেট করার জন্য ওয়েবসকেট সমর্থন করে। বিশ্রাম এপিআইয়ের তুলনায়, ওয়েবসকেটের সাধারণত সুবিধাগুলি রয়েছে, যেমন কম বিলম্ব, উচ্চ ফ্রিকোয়েন্সি এবং প্ল্যাটফর্ম বিশ্রাম এপিআইয়ের ফ্রিকোয়েন্সি দ্বারা সীমাবদ্ধ নয় ইত্যাদি। অসুবিধাটি হ'ল একটি বিঘ্ন সমস্যা রয়েছে, যার প্রক্রিয়াজাতকরণ স্বজ্ঞাত নয়।
এই নিবন্ধটি প্রধানত জাভাস্ক্রিপ্ট ভাষা ব্যবহার এবং কিভাবে প্ল্যাটফর্ম দ্বারা ক্যাপসুল করা ডায়াল ফাংশন ব্যবহার করার জন্য পরিচয় করিয়ে দেবে, এফএমজেড কোয়ান্ট প্ল্যাটফর্মে সংযোগ করতে; নির্দিষ্ট নির্দেশাবলী এবং পরামিতিগুলির জন্য ডকুমেন্টে রয়েছে, আপনি ডায়াল অনুসন্ধান করতে পারেন; বিভিন্ন ফাংশন উপলব্ধি করতে, ডায়াল ফাংশনটি বেশ কয়েকবার আপডেট করা হয়েছে। এই নিবন্ধটি এটিকে কভার করবে এবং wss ভিত্তিক ইভেন্ট-চালিত কৌশলগুলি, পাশাপাশি একাধিক প্ল্যাটফর্ম সংযোগের বিষয়টি পরিচয় করিয়ে দেবে। পাইথন ডায়াল ফাংশন, বা সংশ্লিষ্ট লাইব্রেরি ব্যবহার করতে পারে।
সাধারণভাবে, সরাসরি ওয়েবসকেট দ্বারা সংযোগ করুন; উদাহরণস্বরূপ, বিন্যান্স ট্রিকারের ধাক্কা পেতেঃ
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
যদি ফিরে আসা ডেটা সংকুচিত ফরম্যাটে থাকে, তাহলে সংযোগ করার সময় স্পেসিফিকেশন করা উচিত;
var client = Dial("wss://real.okex.com:10441/websocket?compress=true|compress=gzip_raw&mode=recv")
ডায়াল ফাংশন পুনরায় সংযোগ সমর্থন করে, যা অন্তর্নিহিত গোলং দ্বারা করা হয়। যদি সনাক্ত সংযোগটি ভেঙে যায় তবে এটি পুনরায় সংযোগ করা হবে। অনুরোধের ডেটা ইতিমধ্যে ইউআরএলে রয়েছে, যেমন বাইনারেন্সের উদাহরণটি এখনই, এটি খুব সুবিধাজনক এবং প্রস্তাবিত। যারা সাবস্ক্রিপশন বার্তা প্রেরণের প্রয়োজন তাদের জন্য, তারা পুনরায় সংযোগ প্রক্রিয়াটি নিজেরাই বজায় রাখতে পারে।
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr|reconnect=true")
wss বার্তাগুলিতে সাবস্ক্রাইব করার জন্য, কিছু প্ল্যাটফর্ম অনুরোধ ইউআরএলে রয়েছে এবং কিছুকে সাবস্ক্রাইব করা চ্যানেলগুলি নিজেই পাঠাতে হবে, যেমন coinbase:
client = Dial("wss://ws-feed.pro.coinbase.com", 60)
client.write('{"type": "subscribe","product_ids": ["BTC-USD"],"channels": ["ticker","heartbeat"]}')
সাধারণভাবে, ওয়েবসকেট বাজার কোট পড়ার জন্য ব্যবহৃত হয়, তবে এটি অর্ডার এবং অ্যাকাউন্ট পুশ পেতেও ব্যবহার করা যেতে পারে। এই জাতীয় এনক্রিপ্ট করা ডেটাগুলির পুশ কখনও কখনও দীর্ঘ বিলম্ব হয় এবং সতর্কতার সাথে ব্যবহার করা উচিত। যেহেতু এনক্রিপশন পদ্ধতিটি আরও জটিল, এখানে রেফারেন্সের জন্য কয়েকটি উদাহরণ দেওয়া হয়েছে। মনে রাখবেন যে কেবল অ্যাক্সেসকি প্রয়োজন, যা একটি কৌশল পরামিতি হিসাবে সেট করা যেতে পারে। যদি সিক্রেটকি প্রয়োজন হয় তবে এটি নিরাপত্তার জন্য এক্সচেঞ্জ দ্বারা নিছকভাবে কল করা যেতে পারে। এইচএমএসি ()) ফাংশন।
//Push example of Huobi Futures
var ACCESSKEYID = 'accesskey of your Huobi account'
var apiClient = Dial('wss://api.hbdm.com/notification|compress=gzip&mode=recv')
var date = new Date();
var now_utc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
var utc_date = new Date(now_utc)
var Timestamp = utc_date.toISOString().substring(0,19)
var quest = 'GET\napi.hbdm.com\n/notification\n'+'AccessKeyId='+ACCESSKEYID+'&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=' + encodeURIComponent(Timestamp)
var signature = exchange.HMAC("sha256", "base64", quest, "{{secretkey} }") // Remove the extra blank spaces between }}
auth = {op: "auth",type: "api",AccessKeyId: ACCESSKEYID, SignatureMethod: "HmacSHA256",SignatureVersion: "2", Timestamp: Timestamp, Signature:encodeURI(signature)}
apiClient.write(JSON.stringify(auth))
apiClient.write('{"op": "sub","cid": "orders","topic": "orders.btc'}')
while (true){
var data = datastream.read()
if('op' in data && data.op == 'ping'){
apiClient.write(JSON.stringify({op:'pong', ts:data.ts}))
}
}
// Push example of Binance; pay attention that listenKey needs to be updated regularly
var APIKEY = 'accesskey of your Binance account'
var req = HttpQuery('https://api.binance.com/api/v3/userDataStream',{method: 'POST',data: ''},null,'X-MBX-APIKEY:'+APIKEY);
var listenKey = JSON.parse(req).listenKey;
HttpQuery('https://api.binance.com/api/v3/userDataStream', {method:'DELETE',data:'listenKey='+listenKey}, null,'X-MBX-APIKEY:'+APIKEY);
listenKey = JSON.parse(HttpQuery('https://api.binance.com/api/v3/userDataStream','',null,'X-MBX-APIKEY:'+APIKEY)).listenKey;
var datastream = Dial("wss://stream.binance.com:9443/ws/"+listenKey+'|reconnect=true',60);
var update_listenKey_time = Date.now()/1000;
while (true){
if (Date.now()/1000 - update_listenKey_time > 1800){
update_listenKey_time = Date.now()/1000;
HttpQuery('https://api.binance.com/api/v3/userDataStream', {method:'PUT',data:'listenKey='+listenKey}, null,'X-MBX-APIKEY:'+APIKEY);
}
var data = datastream.read()
}
// push example of BitMEX
var APIKEY = "your Bitmex API ID"
var expires = parseInt(Date.now() / 1000) + 10
var signature = exchange.HMAC("sha256", "hex", "GET/realtime" + expires, "{{secretkey} }")// secretkey is automatically replaced during execution, so no need to fill in
var client = Dial("wss://www.bitmex.com/realtime", 60)
var auth = JSON.stringify({args: [APIKEY, expires, signature], op: "authKeyExpires"})
var pos = 0
client.write(auth)
client.write('{"op": "subscribe", "args": "position"}')
while (true) {
bitmexData = client.read()
if(bitmexData.table == 'position' && pos != parseInt(bitmexData.data[0].currentQty)){
Log('position change', pos, parseInt(bitmexData.data[0].currentQty), '@')
pos = parseInt(bitmexData.data[0].currentQty)
}
}
সাধারণভাবে, এটি একটি অসীম লুপে অবিচ্ছিন্নভাবে পড়তে পারে। কোডটি নিম্নরূপঃ
function main() {
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
while (true) {
var msg = client.read()
var data = JSON.parse(msg) // Parse json strings into quotable objects
// Process data
}
}
ডাব্লুএসএস ডেটা পুশ গতি খুব দ্রুত। গোলং এর আন্ডারলেয়ারটি সারিতে থাকা সমস্ত ডেটা ক্যাশে করবে, এবং যখন প্রোগ্রাম কলগুলি পড়বে, তখন ডেটা পাল্টা ফিরে আসবে। তবে, বটে অর্ডার দেওয়ার মতো ক্রিয়াকলাপগুলি বিলম্বের কারণ হবে, যার ফলে ডেটা জমা হতে পারে। ট্রেডিং এক্সিকিউশন পুশ, অ্যাকাউন্ট পুশ এবং গভীরতা অন্তর্ভুক্তি পুশের মতো তথ্যের জন্য, আমাদের ইতিহাসের ডেটা দরকার। কোট মার্কেট ডেটার জন্য, বেশিরভাগ ক্ষেত্রে, আমরা কেবলমাত্র সর্বশেষ ডেটা নিয়ে চিন্তা করি, ইতিহাসের ডেটা নয়।
যদিread()
কোন প্যারামিটার যোগ করে, এটা পুরোনো তথ্য ফেরত হবে, এবং অবরোধ পর্যন্ত ফেরত যখন কোন তথ্য নেই. আপনি সর্বশেষ তথ্য চান, আপনি ব্যবহার করতে পারেনclient.read(-2)
অবিলম্বে সর্বশেষ তথ্য ফেরত দিতে হবে, কিন্তু যখন কোন তথ্য নেই, এটি null ফেরত দেবে, যা রেফারেন্সের আগে বিচার করা প্রয়োজন।
পুরানো ক্যাশেড ডেটা কীভাবে মোকাবেলা করা যায় এবং কোনও ডেটা না থাকলে এটি ব্লক করা হয় কিনা তার উপর নির্ভর করে,
এই ক্ষেত্রে, এটি স্পষ্ট যে কেবলমাত্র
function main() {
var binance = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
var coinbase = Dial("wss://ws-feed.pro.coinbase.com", 60)
coinbase.write('{"type": "subscribe","product_ids": ["BTC-USD"],"channels": ["ticker","heartbeat"]}')
while (true) {
var msgBinance = binance.read(-1) // Parameter -1 represents no data and return null immediately; it will not occur that being blocked before there is data to be returned
var msgCoinbase = coinbase.read(-1)
if(msgBinance){
// at this time, Binance has data to return
}
if(msgCoinbase){
// at this time, coinbase has data to return
}
Sleep(1) // Sleep for 1 millisecond
}
}
প্রসেসিংয়ের এই অংশটি আরও ঝামেলাজনক, কারণ পুশ ডেটা বাধাগ্রস্ত হতে পারে, বা পুশ বিলম্ব অত্যন্ত দীর্ঘ। এমনকি যদি হার্টবিটটি গ্রহণ করা যায় তবে এর অর্থ এই নয় যে ডেটা এখনও চাপানো হচ্ছে। আপনি একটি ইভেন্ট অন্তরাল সেট করতে পারেন; যদি অন্তরালের পরে কোনও আপডেট না পাওয়া যায় তবে পুনরায় সংযোগ করুন; ডেটা সঠিক কিনা তা দেখতে কিছু সময়ের পরে
Push ডেটা ব্যবহার করা হয়েছে, প্রোগ্রামটি স্বাভাবিকভাবেই ইভেন্ট-ট্রিগার হিসাবে লেখা হবে; তথ্য চাপার ফ্রিকোয়েন্সিতে মনোযোগ দিন, কারণ উচ্চ-ফ্রিকোয়েন্সি অনুরোধগুলি ব্লক হওয়ার কারণ হবে; সাধারণত আপনি লিখতে পারেনঃ
var tradeTime = Date.now()
var accountTime = Date.now()
function trade(data){
if(Date.now() - tradeTime > 2000){//Here it limits only one trade in 2 seconds
tradeTime = Date.now()
// Trading logic
}
}
function GetAccount(){
if(Date.now() - accountTime > 5000){//Here it limits GetAccount only once in 5 seconds
accountTime = Date.now()
return exchange.GetAccount()
}
}
function main() {
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr|reconnect=true");
while (true) {
var msg = client.read()
var data = JSON.parse(msg)
var account = GetAccount()
trade(data)
}
}
সংযোগ পদ্ধতি, ডেটা ট্রান্সমিশন পদ্ধতি, সাবস্ক্রাইব করা সামগ্রী এবং প্রতিটি প্ল্যাটফর্মের ওয়েবসকেটের ডেটা ফর্ম্যাট প্রায়শই পৃথক হয়, তাই প্ল্যাটফর্মটি এটিকে ক্যাপসুল করে না এবং নিজের দ্বারা সংযোগ স্থাপনের জন্য ডায়াল ফাংশনটি ব্যবহার করতে হবে। এই নিবন্ধটি মূলত কিছু প্রাথমিক সতর্কতা কভার করে। আপনার যদি আরও প্রশ্ন থাকে তবে দয়া করে জিজ্ঞাসা করতে দ্বিধা করবেন না।
PS: যদিও কিছু প্ল্যাটফর্ম ওয়েবসকেট উদ্ধৃতি প্রদান করে না, আসলে, যখন আপনি ডিবাগিং ফাংশন ব্যবহার করার জন্য ওয়েবসাইটে লগ ইন করেন, তখন আপনি দেখতে পাবেন যে তারা সবাই ওয়েবসকেট ধাক্কা ব্যবহার করছে। অনুসন্ধানের পরে, আপনি দেখতে পাবেন যে কিছু সাবস্ক্রিপশন ফর্ম্যাট এবং রিটার্ন ফর্ম্যাটগুলি এনক্রিপ্ট করা বলে মনে হচ্ছে, যা বেস 64 দিয়ে ডিকোডিং এবং ডিকম্প্রেসিং দ্বারা দেখা যেতে পারে।
জাভাস্ক্রিপ্ট Go ফাংশন দ্বারা সম্মিলন উপলব্ধি করতে পারে, এবং পাইথন সংশ্লিষ্ট মাল্টিথ্রেড লাইব্রেরি ব্যবহার করতে পারে।
পরিমাণগত কৌশল বাস্তবায়নের সময়, সমান্তরাল কার্যকরকরণ সময় বিলম্ব হ্রাস এবং দক্ষতা উন্নত করতে পারে। উদাহরণস্বরূপ হেজিং কৌশল বট নিন। এটি দুটি মুদ্রার গভীরতা পেতে হবে এবং ক্রমে কার্যকর করা কোডটি দেখানো হয়েছেঃ
var depthA = exchanges[0].GetDepth()
var depthB = exchanges[1].GetDepth()
যখন একটি অনুরোধের বিশ্রাম এপিআই বিলম্বিত হয়, উদাহরণস্বরূপ বিলম্বিত সময় 100 মিলিসেকেন্ড হয়, তখন গভীরতা অর্জনের জন্য সময় দুবার আসলে আলাদা; যদি আরও অ্যাক্সেস প্রয়োজন হয়, বিলম্ব সমস্যাগুলি আরও সুস্পষ্ট হবে, যা কৌশলটির কার্যকরকরণকে প্রভাবিত করবে।
যেহেতু জাভাস্ক্রিপ্টে মাল্টিথ্রেড নেই, তাই আন্ডারলেয়ারটি এই সমস্যা সমাধানের জন্য গো ফাংশনকে ক্যাপসুল করে। নেটওয়ার্ক অ্যাক্সেসের প্রয়োজন এমন এপিআইগুলির জন্য গো ফাংশন ব্যবহার করা যেতে পারে, যেমনGetDepth
, GetAccount
ইত্যাদি।IO
এছাড়াও সমর্থন করা হয়, যেমনঃexchange.Go("IO", "api", "POST", "/api/v1/contract_batchorder", "orders_data=" + JSON.stringify(orders))
, কিন্তু নকশা প্রক্রিয়া কারণে, এটি বাস্তবায়ন আরো ক্লান্তিকর।
var a = exchanges[0].Go("GetDepth")
var b = exchanges[1].Go("GetDepth")
var depthA = a.wait() // Call "wait" method to wait for the return of the asynchronous GetDepth result
var depthB = b.wait()
বেশিরভাগ সহজ ক্ষেত্রে, এইভাবে কৌশলগুলি লেখা ঠিক আছে। তবে মনে রাখবেন যে কৌশল লুপের প্রতিটি সময় প্রক্রিয়াটি পুনরাবৃত্তি করা হয়, এবং মধ্যবর্তী পরিবর্তনশীলগুলি a এবং b আসলে কেবল সাময়িকভাবে সহায়ক। যদি আমাদের প্রচুর সমান্তরাল কাজ থাকে তবে আমাদের অতিরিক্তভাবে a এবং depthA, b এবং depthB এর মধ্যে চিঠিপত্র রেকর্ড করা দরকার। যখন আমাদের সমান্তরাল কাজগুলি অনিশ্চিত হয়, পরিস্থিতি আরও জটিল হয়। অতএব, আমরা একটি ফাংশন উপলব্ধি করার আশা করিঃ যখন Go ফাংশনটি সমান্তরালভাবে লিখুন, একই সময়ে একটি পরিবর্তনশীলকে আবদ্ধ করুন; যখন সমান্তরাল চলমান ফলাফল ফিরে আসে, ফলাফলের মানটি স্বয়ংক্রিয়ভাবে পরিবর্তনশীলকে নির্ধারিত হয়, এইভাবে মধ্যবর্তী পরিবর্তনশীলগুলির প্রয়োজনীয়তা দূর করে এবং প্রোগ্রামটিকে আরও সংক্ষিপ্ত করে তোলে। নির্দিষ্ট বাস্তবায়নটি নিম্নরূপঃ
function G(t, ctx, f) {
return {run:function(){
f(t.wait(1000), ctx)
}}
}
আমরা একটি G ফাংশন সংজ্ঞায়িত করেছি, যেখানে প্যারামিটার
এই সময়ে, সামগ্রিক প্রোগ্রাম ফ্রেমওয়ার্কটি একটি মডেল হিসাবে লেখা যেতে পারে,
var Info = [{depth:null, account:null}, {depth:null, account:null}] // If we need to obtain the depth and account of the two platforms, more information can also be put in, such as order ID and status, etc.
var tasks = [ ] // Global task list
function produce(){ // Issue all kinds of concurrent tasks
// Here the task producing logic has been omitted, only for demo
tasks.push({exchange:0, ret:'depth', param:['GetDepth']})
tasks.push({exchange:1, ret:'depth', param:['GetDepth']})
tasks.push({exchange:0, ret:'sellID', param:['Buy', Info[0].depth.Asks[0].Price, 10]})
tasks.push({exchange:1, ret:'buyID', param:['Sell', Info[1].depth.Bids[0].Price, 10]})
}
function worker(){
var jobs = []
for(var i=0;i<tasks.length;i++){
var task = tasks[i]
jobs.push(G(exchanges[task.exchange].Go.apply(this, task.param), task, function(v, task) {
Info[task.exchange][task.ret] = v // Here "v" is the return value of the concurrent Go function "wait()", and you can think about it
}))
}
_.each(jobs, function(t){
t.run() // Here all tasks are executed concurrently
})
tasks = []
}
function main() {
while(true){
produce() // Give trading command
worker() // Concurrently execute
Sleep(1000)
}
}
মনে হচ্ছে উপরের অপারেশনগুলিতে কেবল একটি সহজ ফাংশন বাস্তবায়িত হয়েছে। আসলে, এটি কোডের জটিলতাকে ব্যাপকভাবে সরল করেছে। আমাদের কেবলমাত্র প্রোগ্রামটি কী কাজগুলি তৈরি করতে হবে সে সম্পর্কে যত্নবান হওয়া দরকার এবং
প্রাথমিক টিউটোরিয়ালে, অঙ্কন শ্রেণীর লাইব্রেরি অঙ্কন প্রবর্তনে সুপারিশ করা হয়, যা বেশিরভাগ ক্ষেত্রে চাহিদা পূরণ করতে পারে। যদি আপনার আরও কাস্টমাইজেশনের প্রয়োজন হয় তবে আপনি সরাসরি
অভ্যন্তরীণ পরামিতিChart({…})
HighStock এবং HighCharts এর বস্তু, কিন্তু একটি অতিরিক্ত পরামিতি__isStock
FMZ মূলত HighCharts এবং HighStock এর মৌলিক মডিউলগুলিকে সমর্থন করে, কিন্তু অতিরিক্ত মডিউলগুলিকে সমর্থন করে না।
হাইচার্টসের নির্দিষ্ট উদাহরণঃhttps://www.highcharts.com/demoহাইস্টক উদাহরণঃhttps://www.highcharts.com/stock/demoআপনি এই উদাহরণগুলির কোডগুলি উল্লেখ করতে পারেন এবং এফএমজেডে তাদের ট্রান্সপ্ল্যান্ট করতে পারেন।
আপনি নির্দিষ্ট সূচক সহ সিরিজে ডেটা যুক্ত করতে add ([সিরিজ সূচক ((যেমন ০, ডেটা]) কল করতে পারেন। চার্ট ডেটা পরিষ্কার করতে কল রিসেট (()) করতে পারেন; রিসেট একটি নম্বর প্যারামিটার নিতে পারে এবং সংরক্ষণ করা পরিমাণ নির্দিষ্ট করতে পারে। একাধিক চার্ট প্রদর্শন সমর্থিত, যা কেবল কনফিগারেশনের সময় অ্যারে প্যারামিটারে পাস করতে হবে, যেমনঃ var চার্ট = চার্ট (([{...}, {...}, {...}]) । উদাহরণস্বরূপ, যদি Chart1 এর দুটি সিরিজ থাকে, Chart2 এর একটি সিরিজ থাকে এবং Chart3 এর একটি সিরিজ থাকে, যখন add কল করা হয়, সিরিজ আইডি 0 এবং 1 নির্দিষ্ট করা হয় যাতে আপডেট করা Chart1-এ দুটি সিরিজের ডেটা আলাদাভাবে উপস্থাপন করা হয়; সিরিজ আইডি 2 নির্দিষ্ট করা হয় যাতে Chart2-এ প্রথম সিরিজের ডেটা উপস্থাপন করা হয়; সিরিজ আইডি 3 নির্দিষ্ট করা হয় যাতে Chart3-এ প্রথম সিরিজের ডেটা উপস্থাপন করা হয়।
একটি নির্দিষ্ট উদাহরণঃ
var chart = { // This "chart" in JS is an object; before using the Chart function, we need to declare the object variable of a configured chart "chart"
__isStock: true, // Mark whether it is a general chart; you can change it to false and try to operate it, if you are interested
tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'}, // Zoom tool
title : { text : 'spread chart'}, // Theme
rangeSelector: { // Choose the range
buttons: [{type: 'hour',count: 1, text: '1h'}, {type: 'hour',count: 3, text: '3h'}, {type: 'hour', count: 8, text: '8h'}, {type: 'all',text: 'All'}],
selected: 0,
inputEnabled: false
},
xAxis: { type: 'datetime'}, // Horizontal axis, namely X axis; currently set type: time
yAxis : { // Vertical axis, namely Y axis; the default changes according to the data
title: {text: 'spread'}, // Theme
opposite: false, // whether to enable the vertical axis on the right
},
series : [ // Data series; the attribute saves all kinds of data series (lines, K-lines, labels, etc.)
{name : "line1", id : "line1,buy1Price", data : []}, // The index is 0; the data stroed in the data array is the data of the index series
{name : "line2", id : "line2,lastPrice", dashStyle : 'shortdash', data : []}, // The index is 1; set dashStyle: 'shortdash', namely: set dashed line
]
};
function main(){
var ObjChart = Chart(chart); // Call the Chart function, and initialize the chart
ObjChart.reset(); // Empty
while(true){
var nowTime = new Date().getTime(); // Obtain the timestamp of this polling, namely a millisecond tiemstamp, to ensure the location of writing to the X axis in the chart
var ticker = _C(exchange.GetTicker); // Obtain the market quotes data
var buy1Price = ticker.Buy; // Get buy one price from the return value of the market quotes
var lastPrice = ticker.Last + 1; // Get the final executed price, and we add 1 to split the 2 lines
ObjChart.add([0, [nowTime, buy1Price]]); // Use the timestamp as the value of X, and buy one price as the value of Y; pass in the data series of index 0
ObjChart.add([1, [nowTime, lastPrice]]); // Same as above.
Sleep(2000);
}
}
চার্ট লেআউট ব্যবহারের উদাহরণঃhttps://www.fmz.com/strategy/136056
নির্দিষ্ট ওপেন সোর্স ঠিকানাঃhttps://github.com/fmzquant/backtest_python
ইনস্টলেশন
কমান্ড লাইনে নিম্নলিখিত কমান্ড লিখুনঃ
pip install https://github.com/fmzquant/backtest_python/archive/master.zip
সহজ উদাহরণ
ব্যাকটেস্ট প্যারামিটারগুলি একটি মন্তব্যের আকারে কৌশল কোডের শুরুতে সেট করুন, এবং বিস্তারিত তথ্যগুলি এফএমজেড ওয়েবসাইটের
'''backtest
start: 2018-02-19 00:00:00
end: 2018-03-22 12:00:00
period: 15m
exchanges: [{"eid":"OKEX","currency":"LTC_BTC","balance":3,"stocks":0}]
'''
from fmz import *
task = VCtx(__doc__) # initialize backtest engine from __doc__
print exchange.GetAccount()
print exchange.GetTicker()
print task.Join() # print backtest result
ব্যাকটেস্ট
সম্পূর্ণ কৌশলগুলির জন্য অসীম লুপ প্রয়োজন, ব্যাকটেস্ট শেষ হওয়ার পরে EOF ত্রুটি উত্থাপিত হবে; অতএব, আমাদের ভুল সহনশীলতা ভাল করা উচিত।
# !/usr/local/bin/python
# -*- coding: UTF-8 -*-
'''backtest
start: 2018-02-19 00:00:00
end: 2018-03-22 12:00:00
period: 15m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD","balance":10000,"stocks":3}]
'''
from fmz import *
import math
import talib
task = VCtx(__doc__) # initialize backtest engine from __doc__
# ------------------------------ Start of the Strategy --------------------------
print exchange.GetAccount() # Call some interfaces, and print their return values
print exchange.GetTicker()
def adjustFloat(v): # the custom functions in the strategy
v = math.floor(v * 1000)
return v / 1000
def onTick():
Log("onTick")
# Specific strategy code
def main():
InitAccount = GetAccount()
while True:
onTick()
Sleep(1000)
# ------------------------------ End of the Strategy --------------------------
try:
main() # The end of the backtest will raise EOFError() to stop stop the backtest loop. Therefore, we should handle with the error, and call task.Join() to print the backtest result, after the error is detected
except:
print task.Join()
exchange.SetData(arr) ব্যাকটেস্ট ডেটা উত্স স্যুইচ করে এবং কাস্টম কে-লাইন ডেটা ব্যবহার করে। প্যারামিটার
arr অ্যারেতে, একটি একক উপাদানের ডেটা ফরম্যাটঃ
[
1530460800, // time Timestamp
2841.5795, // open Open Price
2845.6801, // high Highest Price
2756.815, // low Lowest Price
2775.557, // close Close Price
137035034 // volume Executed Volume
]
function init() { // The init function in the template will be executed first when the template is loaded; ensure the exchange.SetData(arr) function is executed first, initialized, and set the data to the backtest system
var arr = [ // The K-line data to be used during backtest
[1530460800,2841.5795,2845.6801,2756.815,2775.557,137035034], // The data of the earliest K-line bar
... , // If the K-line data is too long, use "..." to represent the omitted data here
[1542556800,2681.8988,2703.5116,2674.1781,2703.5116,231662827] // The data of the latest K-line bar
]
exchange.SetData(arr) // Import the custom data mentioned above
Log("Import data successfully")
}
দ্রষ্টব্যঃ শুরু করার সময় প্রথমে কাস্টম ডেটা আমদানি করতে ভুলবেন না (অর্থাৎ, ডেটা সেট করতে এক্সচেঞ্জ.সেটডাটা ফাংশন কল করুন) । কাস্টম কে-লাইন ডেটা সময়কাল ব্যাকটেস্ট পৃষ্ঠায় সেট করা আন্ডারলেয়ার কে-লাইন সময়ের সাথে সামঞ্জস্যপূর্ণ হতে হবে, অর্থাৎঃ কাস্টম কে-লাইন ডেটা; একটি কে-লাইনের সময় 1 মিনিট, তাই ব্যাকটেস্টে সেট করা আন্ডারলেয়ার কে-লাইনের সময়কালও 1 মিনিটে সেট করা উচিত।
যদি একটি অসমর্থিত প্ল্যাটফর্মের এপিআই সমর্থন করা প্ল্যাটফর্মের ঠিক একই হয়, তবে বেস ঠিকানা ব্যতীত,সমর্থিত প্ল্যাটফর্মটি বেস ঠিকানাটি স্যুইচ করে সমর্থিত হতে পারে। নির্দিষ্ট হতে, একটি প্ল্যাটফর্ম যুক্ত করার সময় একটি সমর্থিত প্ল্যাটফর্ম নির্বাচন করুন, তবে অসমর্থিত প্ল্যাটফর্মের এপিআই-কী পূরণ করুন এবং কৌশলটিতে বেস ঠিকানা পরিবর্তন করতে আইও ব্যবহার করুন, যেমনঃ
exchange.IO("base", "http://api.huobi.pro")
//http://api.huobi.pro is the base address of the unsupported platform API, and notice not to add api/v3 and so on, for the address will be automatically completed
সব প্ল্যাটফর্ম FMZ দ্বারা সমর্থিত হয় না, কিন্তু আমাদের প্ল্যাটফর্ম সাধারণ প্রোটোকলের অ্যাক্সেস পদ্ধতি প্রদান করেছে। নির্দিষ্ট নীতিগুলি হলঃ
সাধারণ প্রোটোকল একটি মধ্যস্থতাকারী, ডকারের অনুরোধ প্রক্সি এবং সংশ্লিষ্ট মান অনুযায়ী ডেটা ফেরত দেয়। সাধারণ প্রোটোকলের কোডটি আপনাকে নিজের দ্বারা সম্পূর্ণ করতে হবে। সাধারণ প্রোটোকল লেখার অর্থ আসলে আপনি কেবল প্ল্যাটফর্মটি অ্যাক্সেস করতে এবং কৌশলটি সম্পূর্ণ করতে পারেন। এফএমজেড অফিসিয়াল কখনও কখনও প্ল্যাটফর্মগুলির সাধারণ প্রোটোকলের এক্সই সংস্করণ প্রকাশ করে। সাধারণ প্রোটোকলটি পাইথনেও করা যেতে পারে, যা তারপরে ডকারটিতে একটি সাধারণ বট হিসাবে চালানো যেতে পারে।
সাধারণ প্রোটোকলের বিশেষ প্রবর্তনঃhttps://www.fmz.com/bbs-topic/9120পাইথনে সাধারণ প্রোটোকল লেখার উদাহরণঃhttps://www.fmz.com/strategy/101399
ঠিক যেমন একটি প্ল্যাটফর্মের বিভিন্ন ক্রিয়াকলাপ এপিআই এর মাধ্যমে বাস্তবায়ন করা যেতে পারে, এফএমজেড ওয়েবসাইটও এপিআই ভিত্তিক। আপনি
এফএমজেড কোয়ান্ট প্ল্যাটফর্মের শক্তিশালী সম্প্রসারণযোগ্যতার কারণে, আপনি এপিআই এক্সটেনশনের উপর ভিত্তি করে আপনার নিজের পরিমাণগত প্ল্যাটফর্ম তৈরি করতে পারেন, আপনার ব্যবহারকারীদের আপনার প্ল্যাটফর্মে বট চালানোর অনুমতি দেয় ইত্যাদি। নির্দিষ্ট রেফারেন্সঃhttps://www.fmz.com/bbs-topic/1697 .
ক্রিপ্টোকারেন্সি ট্রেডিং বাজারটি এর স্বতন্ত্রতার কারণে পরিমাণগত ব্যবসায়ীদের কাছ থেকে আরও বেশি মনোযোগ আকর্ষণ করেছে। প্রকৃতপক্ষে, প্রোগ্রাম ট্রেডিং ক্রিপ্টোকারেন্সির মূলধারায় পরিণত হয়েছে এবং হেজিং এবং মার্কেট মেকিংয়ের মতো কৌশলগুলি সর্বদা বাজারে সক্রিয়। দুর্বল প্রোগ্রামিং ফাউন্ডেশন সহ নতুনরা এই নতুন ক্ষেত্রে প্রবেশ করতে চান, অসংখ্য প্ল্যাটফর্ম এবং পরিবর্তনশীল এপিআইগুলির মুখোমুখি হয়ে, সমস্যার সাথে পূর্ণ। এফএমজেড কোয়ান্ট প্ল্যাটফর্ম, (পূর্ব বটভি,www.fmz.com) বর্তমানে বৃহত্তম ক্রিপ্টোকারেন্সি পরিমাণগত কমিউনিটি এবং প্ল্যাটফর্ম, ৪ বছরেরও বেশি সময় ধরে পরিমাণগত ট্রেডিংয়ের পথে হাজার হাজার নতুনদের সহায়তা করেছে।
প্রোমোশননেটইজ ক্লাউড ক্লাসরুমে ক্রিপ্টোকারেন্সি পরিমাণগত ট্রেডিং কোর্স. নেটইজ ক্লাউড ক্লাসরুমে লগ ইন করুন এবং আপনার কোর্সের লিঙ্কটি ভাগ করুন (লিঙ্কের একটি অনন্য কোর্স আইডি রয়েছে) । অন্যরা, যারা এই লিঙ্কের মাধ্যমে নিবন্ধন করে এবং কোর্সটি কিনে, তারা আপনাকে কমিশন হিসাবে মোটের 50%, যথা 10 ইউয়ান আনবে। নগদ উত্তোলনের জন্য
প্রোমোশন লিঙ্কে ক্লিক করে অর্ধ বছরের মধ্যে নিবন্ধন এবং রিচার্জ করা গ্রাহকরা নীতিটি উপভোগ করবেন যে আমাদের সংস্থা বৈধ ক্রমে কার্যকর পরিমাণ অনুসারে ছাড় দেবে। কমিশনটি পয়েন্ট আকারে প্রোমোটারের অ্যাকাউন্টে ফিরিয়ে দেওয়া হবে। ব্যবহারকারীরা পয়েন্টগুলিকে এফএমজেড প্ল্যাটফর্মের অ্যাকাউন্ট ব্যালেন্সে ১০ঃ১ অনুপাতে বিনিময় করতে পারেন এবং ব্যবহারকারীরা ভবিষ্যতে এফএমজেড কোয়ান্টের সম্পর্কিত পণ্যগুলি বিনিময় করতে পয়েন্টগুলিও ব্যবহার করতে পারেন। ক্রিয়াকলাপের জন্য নির্দিষ্ট লিঙ্কঃhttps://www.fmz.com/bbs-topic/3828
সম্পূর্ণ এফএমজেড ওয়েবসাইটটি সম্পূর্ণ নিয়ন্ত্রণ এবং কার্যকরী কাস্টমাইজেশনের জন্য কোনও এন্টারপ্রাইজ বা একটি দলের একচেটিয়া সার্ভারে স্থাপন করা যেতে পারে। এফএমজেড ওয়েবসাইটটি প্রায় 100,000 ব্যবহারকারী ব্যবহার করেছেন এবং পরীক্ষা করেছেন এবং উচ্চ প্রাপ্যতা এবং সুরক্ষা অর্জন করেছেন, যা পরিমাণগত দল এবং উদ্যোগের জন্য সময় সাশ্রয় করতে পারে। এন্টারপ্রাইজ সংস্করণটি মাঝারি আকারের পরিমাণগত ট্রেডিং দল, পণ্য ফিউচার পরিষেবা সরবরাহকারী ইত্যাদির জন্য। নির্দিষ্ট উদ্ধৃতির জন্য প্রশাসকের সাথে যোগাযোগ করুন।
পেশাদার সিস্টেম, যা প্ল্যাটফর্মগুলির জন্য বাজার তরলতা এবং তহবিল পরিচালনা সরবরাহ করে, এটি বাজারের সবচেয়ে উন্নত মার্কেট মেকিং সিস্টেম হতে পারে। এটি অনেক প্ল্যাটফর্ম এবং দল দ্বারা ব্যাপকভাবে ব্যবহৃত হয়।
এফএমজেড প্রযুক্তি ট্রেডিং সিস্টেম মেমরি ম্যাচিং প্রযুক্তি গ্রহণ করে এবং অর্ডার প্রক্রিয়াকরণের গতি প্রতি সেকেন্ডে 2 মিলিয়ন ট্রেডের মতো উচ্চ, যা অর্ডার প্রক্রিয়াকরণে কোনও বিলম্ব বা বিলম্ব হবে না তা নিশ্চিত করতে পারে। এটি 20 মিলিয়নেরও বেশি একযোগে অনলাইন ব্যবহারকারীদের সাথে প্ল্যাটফর্মগুলির মসৃণ এবং স্থিতিশীল অপারেশন বজায় রাখতে পারে। মাল্টি-লেয়ার এবং মাল্টি-ক্লাসার সিস্টেম ফ্রেমওয়ার্ক সিস্টেমের সুরক্ষা, স্থিতিশীলতা এবং প্রসারণযোগ্যতা নিশ্চিত করে। ফাংশন স্থাপন এবং সংস্করণ আপডেটগুলি ডাউনটাইম ছাড়াই সম্পাদন করা যেতে পারে, যা টার্মিনাল ব্যবহারকারীদের অপারেটিং অভিজ্ঞতার সর্বাধিক গ্যারান্টি দেয়। বর্তমানে, সিস্টেমটি wex.app সিমুলেটেড প্ল্যাটফর্মে অভিজ্ঞতা অর্জন করা যেতে পারে।