আমি ২০২০ সালে একটি নিবন্ধ লিখেছিলাম উচ্চ ফ্রিকোয়েন্সি ট্রেডিং কৌশল প্রবর্তন (https://www.fmz.com/digest-topic/6228) যদিও এটি কিছু মনোযোগ পেয়েছে, তবে এটি খুব গভীর ছিল না। তখন থেকে আড়াই বছর কেটে গেছে, এবং বাজারটি পরিবর্তিত হয়েছে। আমি সেই নিবন্ধটি প্রকাশ করার পরে, আমার উচ্চ-ফ্রিকোয়েন্সি কৌশলটি দীর্ঘ সময়ের জন্য স্থিতিশীল মুনাফা অর্জন করতে সক্ষম হয়েছিল, তবে মুনাফা ধীরে ধীরে হ্রাস পেয়েছে এবং এমনকি এক পর্যায়ে বন্ধ হয়ে গেছে। সাম্প্রতিক মাসগুলিতে, আমি এটি পুনর্নির্মাণে সময় ব্যয় করেছি, এবং এটি এখনও কিছু ছোট মুনাফা করতে পারে। এই নিবন্ধটি আমার উচ্চ-ফ্রিকোয়েন্সি ট্রেডিং কৌশল এবং কিছু সরলীকৃত কোডের আরও বিশদ ভূমিকা প্রদান করবে, আলোচনা এবং প্রতিক্রিয়ার জন্য একটি সূচনা পয়েন্ট হিসাবে কাজ করবে।
কমিশনের রিবেট অ্যাকাউন্ট
উদাহরণস্বরূপ, বাইনারেন্স ব্যবহার করে, বর্তমানে প্রতি 100,000 ইউনিট ট্রেডিংয়ের জন্য 0.05% এর নির্মাতা ছাড় প্রদান করে। যদি দৈনিক ট্রেডিং ভলিউম 100 মিলিয়ন ইউ হয় তবে ছাড়টি 5,000 ইউ হয়। অবশ্যই, গ্রহণকারী ফি এখনও ভিআইপি হারের উপর নির্ভর করে, সুতরাং যদি কৌশলটি অর্ডার গ্রহণের প্রয়োজন না হয় তবে ভিআইপি স্তরের উচ্চ-ফ্রিকোয়েন্সি কৌশলটির উপর সামান্য প্রভাব পড়ে। বিভিন্ন এক্সচেঞ্জে কমিশন ছাড়ের বিভিন্ন স্তর উপলব্ধ রয়েছে, যার জন্য একটি উচ্চ ট্রেডিং ভলিউম প্রয়োজন। প্রাথমিক দিনগুলিতে, এখনও ছাড় ছাড়াই লাভ করা যায়, তবে প্রতিযোগিতা তীব্র হওয়ার সাথে সাথে ছাড়গুলি লাভের বৃহত্তর অনুপাতের জন্য দায়ী ছিল এবং উচ্চ-ফ্রিকোয়েন্সি ব্যবসায়ীরা শীর্ষ হারগুলি অনুসরণ করেছিল।
গতি
উচ্চ ফ্রিকোয়েন্সি ট্রেডিং এর দ্রুত গতির কারণে বলা হয়। একটি ট্রেডিং এক্সচেঞ্জের কোলোকেশন সার্ভারে যোগদান এবং সর্বনিম্ন বিলম্ব এবং সবচেয়ে স্থিতিশীল সংযোগ অর্জন প্রতিযোগিতার শর্তগুলির মধ্যে একটি হয়ে উঠেছে। কৌশলটির অভ্যন্তরীণ প্রক্রিয়াকরণের সময়ও যতটা সম্ভব কম হওয়া উচিত। এই নিবন্ধটি আমি ব্যবহার করা ওয়েবসকেট ফ্রেমওয়ার্কটি পরিচয় করিয়ে দেবে, যা সমান্তরাল সম্পাদন ব্যবহার করে।
উপযুক্ত বাজার
উচ্চ-ফ্রিকোয়েন্সি ট্রেডিংকে পরিমাণগত ব্যবসায়ের মুকুট হিসাবে বিবেচনা করা হয় এবং আমি বিশ্বাস করি যে অনেক অ্যালগরিদমিক ব্যবসায়ী এটি চেষ্টা করেছেন, তবে বেশিরভাগ লোকেরই এটি বন্ধ করা উচিত ছিল কারণ তারা অর্থ উপার্জন করতে পারেনি এবং উন্নতির উপায় খুঁজে পায়নি। মূল কারণটি সম্ভবত তারা ভুল ট্রেডিং বাজারটি বেছে নিয়েছে। কৌশলটির প্রাথমিক পর্যায়ে, লাভ অর্জনের জন্য তুলনামূলকভাবে সহজ বাজারগুলিকে ট্রেডিংয়ের জন্য লক্ষ্য করা উচিত এবং উন্নতির জন্য প্রতিক্রিয়া পাওয়া উচিত, যা কৌশলটির অগ্রগতির পক্ষে সহায়ক। আপনি যদি সবচেয়ে তীব্র প্রতিযোগিতামূলক বাজারে শুরু করেন এবং অনেক প্রতিপক্ষের সাথে প্রতিযোগিতা করেন তবে আপনি যতই চেষ্টা করুন না কেন আপনি অর্থ হারাবেন এবং আপনি দ্রুত ছেড়ে দেবেন। আমি নতুন চালু চিরস্থায়ী চুক্তি ট্রেডিং জোড়া দিয়ে শুরু করার পরামর্শ দিচ্ছি, যেখানে কম প্রতিযোগী রয়েছে, বিশেষত তুলনামূলকভাবে বড় ট্রেডিং ভলিউম সহ, যা এটি সহজ করে তোলে। বিটিসি এবং ইটিএইচ ট্রেডিংয়ের ভলিউম সর্বাধিক এবং সবচেয়ে সক্রিয়, তবে তারা বেঁচে থাকার সম্ভাবনাও সবচেয়ে কঠিন
প্রতিযোগিতার মুখোমুখি
যে কোনও ব্যবসায়ের জন্য বাজার ক্রমাগত পরিবর্তিত হচ্ছে, এবং কোনও ট্রেডিং কৌশল এককালীন সমাধান হতে পারে না। এটি উচ্চ-ফ্রিকোয়েন্সি ট্রেডিংয়ে আরও সুস্পষ্ট, যেখানে বাজারে প্রবেশের অর্থ সবচেয়ে স্মার্ট এবং সবচেয়ে অধ্যবসায়ী ব্যবসায়ীদের সাথে সরাসরি প্রতিযোগিতা করা। শূন্য-সমাবেশ গেম বাজারে, আপনি যত বেশি উপার্জন করবেন, অন্যরা তত কম উপার্জন করবেন। আপনি যত পরে প্রবেশ করবেন, ততই এটি আরও কঠিন হবে এবং ইতিমধ্যে বাজারে যারা আছেন তাদের ক্রমাগত উন্নতি করতে হবে এবং যে কোনও সময় নির্মূল করা যেতে পারে। তিন বা চার বছর আগে সম্ভবত সেরা সুযোগ ছিল, তবে ডিজিটাল মুদ্রা বাজারে সাম্প্রতিক সামগ্রিক ক্রিয়াকলাপের হ্রাসের সাথে, নতুনদের জন্য উচ্চ-ফ্রিকোয়েন্সি ট্রেডিং শুরু করা খুব কঠিন হয়ে উঠেছে।
বিভিন্ন উচ্চ-ফ্রিকোয়েন্সি ট্রেডিং কৌশল রয়েছে, যেমন উচ্চ-ফ্রিকোয়েন্সি আরবিট্রেজ, যা এই বা অন্যান্য এক্সচেঞ্জের মাধ্যমে আরবিট্রেজ সুযোগগুলি খুঁজে পাওয়া, অন্যের আগে অর্ডারগুলি খাওয়া এবং গতির সুবিধা নিয়ে মুনাফা অর্জনের সুযোগটি দখল করা; উচ্চ-ফ্রিকোয়েন্সি ট্রেন্ড ট্রেডিং, যা স্বল্পমেয়াদী প্রবণতা থেকে মুনাফা অর্জন জড়িত; এবং বাজার তৈরি, যা ক্রয় এবং বিক্রয় ব্যবসায়ের উভয় পক্ষের অর্ডার স্থাপন, অবস্থানগুলি ভালভাবে নিয়ন্ত্রণ করা এবং কমিশন ছাড়ের মাধ্যমে মুনাফা অর্জন জড়িত। আমার কৌশলটি প্রবণতা এবং বাজার তৈরির সংমিশ্রণ, প্রথমে প্রবণতা সনাক্তকরণ এবং তারপরে অর্ডার স্থাপন, কার্যকর হওয়ার পরে অবিলম্বে বিক্রয় এবং স্টক অবস্থানগুলি না রাখা। নীচে কৌশল কোডের একটি ভূমিকা রয়েছে।
নিম্নলিখিত কোডটি বিন্যান্স চিরস্থায়ী চুক্তির প্রাথমিক স্থাপত্যের উপর ভিত্তি করে এবং মূলত ওয়েবসকেট গভীরতা অর্ডার প্রবাহের বাণিজ্য এবং অবস্থান তথ্য সাবস্ক্রাইব করে। যেহেতু বাজার ডেটা এবং অ্যাকাউন্টের তথ্য আলাদাভাবে সাবস্ক্রাইব করা হয়, সর্বশেষ তথ্য পাওয়া গেছে কিনা তা নির্ধারণ করতে পাঠ্য (-1) অবিচ্ছিন্নভাবে ব্যবহার করা দরকার। এখানে, ইভেন্টলুপ (1000) সরাসরি মৃত লুপ এড়াতে এবং সিস্টেমের লোড হ্রাস করতে ব্যবহৃত হয়। ইভেন্টলুপ (1000) ব্লকগুলি 1000ms এর টাইমআউট সহ একটি wss বা সমান্তরাল টাস্ক রিটার্ন না হওয়া পর্যন্ত ব্লক করে।
var datastream = null
var tickerstream = null
var update_listenKey_time = 0
function ConncetWss(){
if (Date.now() - update_listenKey_time < 50*60*1000) {
return
}
if(datastream || tickerstream){
datastream.close()
tickerstream.close()
}
// need APIKEY
let req = HttpQuery(Base+'/fapi/v1/listenKey', {method: 'POST',data: ''}, null, 'X-MBX-APIKEY:' + APIKEY)
let listenKey = JSON.parse(req).listenKey
datastream = Dial("wss://fstream.binance.com/ws/" + listenKey + '|reconnect=true', 60)
// Symbols is the pair of symbol
let trade_symbols_string = Symbols.toLowerCase().split(',')
let wss_url = "wss://fstream.binance.com/stream?streams="+trade_symbols_string.join(Quote.toLowerCase()+"@aggTrade/")+Quote.toLowerCase()+"@aggTrade/"+trade_symbols_string.join(Quote.toLowerCase()+"@depth20@100ms/")+Quote.toLowerCase()+"@depth20@100ms"
tickerstream = Dial(wss_url+"|reconnect=true", 60)
update_listenKey_time = Date.now()
}
function ReadWss(){
let data = datastream.read(-1)
let ticker = tickerstream.read(-1)
while(data){
data = JSON.parse(data)
if (data.e == 'ACCOUNT_UPDATE') {
updateWsPosition(data)
}
if (data.e == 'ORDER_TRADE_UPDATE'){
updateWsOrder(data)
}
data = datastream.read(-1)
}
while(ticker){
ticker = JSON.parse(ticker).data
if(ticker.e == 'aggTrade'){
updateWsTrades(ticker)
}
if(ticker.e == 'depthUpdate'){
updateWsDepth(ticker)
}
ticker = tickerstream.read(-1)
}
makerOrder()
}
function main() {
while(true){
ConncetWss()
ReadWss()
worker()
updateStatus()
EventLoop(1000)
}
}
যেমনটি পূর্বে উল্লেখ করা হয়েছে, আমার উচ্চ-ফ্রিকোয়েন্সি কৌশলটি প্রথমে ক্রয় এবং বিক্রয় ব্যবসায় সম্পাদনের আগে প্রবণতা সনাক্ত করার প্রয়োজন। স্বল্পমেয়াদী প্রবণতা মূলত লেনদেনের ডেটা, অর্থাৎ, এগট্রেড সাবস্ক্রাইব করা, যার মধ্যে দিক, মূল্য, পরিমাণ এবং লেনদেনের সময় অন্তর্ভুক্ত রয়েছে তার উপর ভিত্তি করে বিচার করা হয়। ক্রয় এবং বিক্রয় ব্যবসায়গুলি মূলত গভীরতা এবং লেনদেনের পরিমাণকে বোঝায়। নিম্নলিখিতগুলি বিশদ সূচক যা বিবেচনা করা দরকার, যার বেশিরভাগই ক্রয় এবং বিক্রয়ের জন্য দুটি গ্রুপে বিভক্ত এবং একটি নির্দিষ্ট সময়ের উইন্ডোর মধ্যে গতিশীলভাবে গণনা করা হয়। আমার কৌশল
let bull = last_sell_price > avg_sell_price && last_buy_price > avg_buy_price &&
avg_buy_amount / avg_buy_time > avg_sell_amount / avg_sell_time;
let bear = last_sell_price < avg_sell_price && last_buy_price < avg_buy_price &&
avg_buy_amount / avg_buy_time < avg_sell_amount / avg_sell_time;
যদি সর্বশেষ বিড মূল্য গড় বিড মূল্যের চেয়ে বেশি হয় এবং সর্বশেষ বিড মূল্য গড় বিড মূল্যের চেয়ে বেশি হয় এবং একটি নির্দিষ্ট ব্যবধানে ক্রয় অর্ডারের মান বিক্রয় অর্ডারের মানের চেয়ে বেশি হয় তবে এটি একটি স্বল্পমেয়াদী উত্থান বাজার বলে বিবেচিত হয়। বিপরীতটি হ্রাস বাজারগুলির ক্ষেত্রে সত্য।
function updatePrice(depth, bid_amount, ask_amount) {
let buy_price = 0
let sell_price = 0
let acc_bid_amount = 0
let acc_ask_amount = 0
for (let i = 0; i < Math.min(depth.asks.length, depth.bids.length); i++) {
acc_bid_amount += parseFloat(depth.bids[i][1])
acc_ask_amount += parseFloat(depth.asks[i][1])
if (acc_bid_amount > bid_amount && buy_price == 0) {
buy_price = parseFloat(depth.bids[i][0]) + tick_size
}
if (acc_ask_amount > ask_amount && sell_price == 0) {
sell_price = parseFloat(depth.asks[i][0]) - tick_size
}
if (buy_price > 0 && sell_price > 0) {
break
}
}
return [buy_price, sell_price]
}
এখানে, প্রয়োজনীয় পরিমাণে গভীরতা পুনরাবৃত্তি পুরানো পদ্ধতি এখনও ব্যবহার করা হয়। অনুমান যে একটি কিনতে অর্ডার যে 1 সেকেন্ডের মধ্যে 10 কয়েন জন্য সম্পাদিত হতে পারে এবং নতুন আদেশের অবস্থা বিবেচনা না করে, বিক্রয় মূল্য অবস্থান যেখানে সেট করা হয়
১০টি মুদ্রার ভলিউম দিয়ে হিট করতে পারেন। নির্দিষ্ট সময় উইন্ডোর আকার নিজেকে সেট করতে হবে।
let buy_amount = Ratio * avg_sell_amount / avg_sell_time
let sell_amount = Ratio * avg_buy_amount / avg_buy_time
এই অনুপাতটি সর্বশেষ বিক্রয় আদেশের পরিমাণের একটি স্থির অনুপাতকে উপস্থাপন করে, যা সর্বশেষ বিক্রয় আদেশের পরিমাণের একটি স্থির অনুপাত হিসাবে ক্রয় আদেশের পরিমাণকে উপস্থাপন করে। এটি কৌশলকে বর্তমান ক্রয় এবং বিক্রয় ক্রিয়াকলাপ অনুযায়ী আদেশের আকার সামঞ্জস্য করতে দেয়।
if(bull && (sell_price-buy_price) > N * avg_diff) {
trade('buy', buy_price, buy_amount)
}else if(position.amount < 0){
trade('buy', buy_price, -position.amount)
}
if(bear && (sell_price-buy_price) > N * avg_diff) {
trade('sell', sell_price, sell_amount)
}else if(position.amount > 0){
trade('sell', sell_price, position.amount)
}
তাদের মধ্যে, avg_diff হল স্প্রেডের গড় পার্থক্য, এবং কেবলমাত্র যখন অর্ডার দেওয়ার ক্ষেত্রে ক্রয় এবং বিক্রয় পার্থক্য এই মানের একটি নির্দিষ্ট গুণের চেয়ে বেশি হয় এবং বাজারটি উত্থান হয় তখনই একটি ক্রয় অর্ডার স্থাপন করা হবে। যদি একটি শর্ট পজিশন ধরে রাখা হয় তবে অবস্থানটি দীর্ঘ সময়ের জন্য ধরে রাখা এড়ানোর জন্য অবস্থানটিও বন্ধ করা হবে। অর্ডারগুলি পূরণ করা নিশ্চিত করার জন্য কেবল-মেকার অর্ডার স্থাপন করা যেতে পারে এবং অর্ডার রিটার্নের জন্য অপেক্ষা এড়াতে কাস্টম অর্ডার আইডি ব্যবহার করা যেতে পারে।
var tasks = []
var jobs = []
function worker(){
let new_jobs = []
for(let i=0; i<tasks.length; i++){
let task = tasks[i]
jobs.push(exchange.Go.apply(this, task.param))
}
_.each(jobs, function(t){
let ret = t.wait(-1)
if(ret === undefined){
new_jobs.push(t)//未返回的任务下次继续等待
}
})
jobs = new_jobs
tasks = []
}
/*
tasks.push({'type':'order','param': ["IO", "api", "POST","/fapi/v1/order",
"symbol="+symbol+Quote+"&side="+side+"&type=LIMIT&timeInForce=GTX&quantity="+
amount+"&price="+price+"&newClientOrderId=" + UUID() +"×tamp="+Date.now()]})
*/