مرحبا بالجميع! اليوم سنكتب أول روبوت تداول قتالي لدينا للعب في البورصة. تبادل العملات الرقمية. لماذا صرف العملات المشفرة؟
أ) موضوع الضجيج ؛
ب) أنها أبسط إلى حد ما.
أولاً ، أريد أن أحذر على الفور عشاق كازينو Three Axes: لن تكسب سيارة غدًا. المقالة أكثر عن كيفية البدء في كتابة الروبوتات الخاصة بك ، لذلك ستكون الخوارزمية بدائية ، ولكنها تعمل.
ثانيا ، سوف تكسب. فقط القليل.
C / f "لعبة السقوط" (2015)- هذه الرائحة ، ما هي؟ ما الروائح؟
- كولونيا؟
- لا ...
- الفرص؟
- كلا. المال.
- أوه ... كل شيء واضح
- رائحة المال!
- فهمت.
بالنسبة إلى الأكثر نفاد الصبر ، كل الشفرة على github exmo-exchange-trade-bot .
المرحلة 1: التبادل.
سنتداول في بورصة EXMO. هناك عدة أسباب. التبادل شائع في رابطة الدول المستقلة ، وهو يتحدث الروسية ويدعم إدخال الروبل ، ولديه القدرة على إنشاء أزواج للروبل.
من بين السلبيات العملية غير المريحة لإيداع الروبل ، والعمولة اللائقة ، وعدد قليل من الأزواج المتداولة.
بالنسبة لنا ، الشيء الرئيسي هو أن لديها حلول جاهزة للعمل مع واجهة برمجة التطبيقات الخاصة بهم. هذا سوف يسهل عملنا بالتأكيد.
لذلك دعونا نبدأ.
بالطبع ، تحتاج إلى التسجيل في البورصة وإيداع بعض المال. على سبيل المثال ، ساهمت بمبلغ 5 دولارات.
علاوة على ذلك ، في حسابك ، ستتلقى مفاتيح للوصول إلى واجهة برمجة التطبيقات.
سأستخدم العميل لـ NodeJS (لذا ستحتاج إلى تثبيت nodejs و npm).
على جهاز الكمبيوتر الخاص بك ، قم بإنشاء مجلد جديد وملف سيكون فيه روبوت التداول الخاص بنا (على سبيل المثال exmo / index.js) ، افتح وحدة التحكم وقم بإجراء آخر الاستعدادات القياسية.
نذهب إلى المجلد مع مشروعنا والكتابة - npm init ، ثم نضغط على زر الإدخال لجميع الأسئلة.
بعد ذلك نكتب
npm install exmo-api
أثناء تثبيت الحزم ، أنشئ ملفًا آخر ، واسمه exmo.js واملأه بهذا المحتوى.
مع هذه المحتويات var CryptoJS = require("crypto-js") http = require('http'), querystring = require('querystring'), request = require('request'), config = { url: 'https://api.exmo.me/v1/' }; function sign(message){ return CryptoJS.HmacSHA512(message, config.secret).toString(CryptoJS.enc.hex); } exports.init_exmo = function (cfg) { config.key = cfg.key; config.secret = cfg.secret; config.nonce = Math.floor(new Date().getTime()*1000); }; exports.api_query = function(method_name, data, callback){ data.nonce = config.nonce++; var post_data = querystring.stringify(data); var options = { url: config.url + method_name, method: 'POST', headers: { 'Key': config.key, 'Sign': sign(post_data) }, form:data }; request(options, function (error, response, body) { if (!error && response.statusCode == 200) { callback(body); }else{ callback(error); } }); }; exports.api_query2 = function(method_name, data, callback){ data.nonce = config.nonce++; var post_data = querystring.stringify(data); var post_options = { host: 'api.exmo.me', port: '80', path: '/v1/' + method_name, method: 'POST', headers: { 'Key': config.key, 'Sign': sign(post_data), 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(post_data) } }; var post_req = http.request(post_options, function(res) { res.setEncoding('utf8'); res.on('data', function (chunk) { callback(chunk); }); }); post_req.write(post_data); post_req.end(); }; exports.test = function(){ return config.key; };
يحتوي هذا الملف على عنوان API ، واتصال المكتبات الإضافية التي نحتاجها للعمل مع API ، والوظيفة الرئيسية لطلبات API.
هذا كل شيء ، لقد أعددنا كل شيء والآن يمكننا أن نبدأ مباشرة في إنشاء "آلة صنع المال" الشخصية ؛)
المرحلة 2: الرمز
افتح index.js الخاص بنا وقم بتوصيل ملف exmo.js:
const exmo = require("./exmo");
بعد ذلك ، انتقل إلى التبادل في حسابك الشخصي إلى المكان الذي أنشأنا فيه مفاتيحنا للوصول إلى واجهة برمجة التطبيقات. نقوم بنسخها وحفظها في المتغيرات:
const apiKey = ' '; const apiSecret = ' ';
الآن قم بإنشاء متغيرين:
العملة 1 هي ما نشتريه ؛
currency2 - العملة التي نشتري لها.
أريد شراء بيتكوين مقابل الدولار:
const currency1 = 'BTC'; const currency2 = 'USD';
بعد ذلك ، نقطة مهمة - نقوم بإنشاء متغير بحد أدنى من الرهان. لا يسمح التبادل بالشراء بأقل من هذا المبلغ.
نذهب إلى العنوان https://api.exmo.com/v1/pair_settings/ ابحث عن زوجك (بالنسبة لي هو BTC_USD) ونلقي نظرة على المعلمة الأولى - min_quantity - 0.001
const currency1MinQuantity = 0.001;
وبعض المتغيرات الأخرى:
عدد الدقائق التي يتم بعدها إلغاء أمر شراء غير مكتمل بالعملة 1
const orderLifeTime = 3;
عمولة الصرف (0.002 = 0.2٪)
const stockFee = 0.002;
الفترة الزمنية (بالدقائق) لحساب متوسط السعر (ستكون هذه ضرورية لخوارزميتنا)
const avgPricePeriod = 1;
مبلغ العملة 2 لشراء العملة 1 في معاملة لمرة واحدة (رميت 5 دولارات - سأعمل معهم)
const canSpend = 5;
مقدار الربح المطلوب من كل معاملة (0.001 = 0.1٪)
const profit = 0.001;
إذا اختلف وقت الصرف عن التيار
const stockTimeOffset = 0;
من أجل الراحة ، ندمج زوجنا من خلال _
let currentPair = currency1+'_'+currency2;
قم بتهيئة الاتصال.
exmo.init_exmo({key:apiKey, secret:apiSecret});
للاختبار ، يمكنك طلب معلومات عن نفسك:
exmo.api_query("user_info", { }, result => console.log(result););
انتقل إلى وحدة التحكم وتشغيل
node index.js
إذا تم كل شيء بشكل صحيح ، فسوف ترى معلومات عنك!
كل شيء يعمل ويمكنك الانتقال إلى الجزء الأكثر إثارة للاهتمام - الوظيفة التي ستولدها لنا الجدات.
لذلك ، سبق أن قلت أعلاه أن الخوارزمية لدينا ستكون غبية ، والآن ستفهم كم)
الحيلة هي أخذ تاريخ المعاملات المكتملة لأي فترة - لدينا المتغير avgPricePeriod المسؤول عن ذلك - وحساب متوسط السعر الذي تم بيع العملة 1 مقابله. لهذا السعر المتوسط ، سنضع طلبنا.
لذلك دعونا نبدأ. نكتب وظيفة التجارة () لدينا
function trade(){}
أولاً نحصل على قائمة بأوامرنا المفتوحة:
1) نتحقق مما إذا كان لدينا أوامر مفتوحة لزوجنا باستخدام طريقة user_open_order api. إذا كان هناك أيضا للبيع ،
ثم ننتظر أن يتم الوفاء بها (أحيانًا حتى نهاية الوقت). إذا كانت هناك أوامر شراء ، فقط تذكرها.
exmo.api_query("user_open_orders", { }, result => { let res = JSON.parse(result); if(res[currentPair] == undefined) console.log(' '); let buyOrders = []; for(let i in res[currentPair]){ console.log(res[currentPair][i]); if(res[currentPair][i].type == 'sell'){ console.log(', / '); }else{ buyOrders.push(res[currentPair][i]); } }
2) نتحقق مما إذا كان لدينا أوامر شراء مفتوحة.
نقوم بفرز جميع الطلبات والحصول على سجل لها باستخدام طريقة order_trades ، وتمرير معرف الطلب هناك.
يمكن أن يكون هناك 3 خيارات:
if(buyOrders.length > 0){ for(let key in buyOrders){ console.log(', ', buyOrders[key]['order_id']); exmo.api_query('order_trades', {"order_id": buyOrders[key]['order_id']}, result => { let res = JSON.parse(result);
1) يمكننا شراء العملة اللازمة ليس بالكامل ، ولكن في أجزاء من أوامر البائعين.
لذلك ، إذا اشترينا بالفعل بالسعر المطلوب ، فإننا ننتظر شراء المبلغ بالكامل.
if(res.result !== false){ console.log(', , '); }
2) مع الخيار الثاني ، نحتاج إلى التحقق مما إذا كان نظامنا معلقًا لفترة طويلة جدًا. تتغير الأسعار بسرعة وربما لم يعد متوسط السعر مناسبًا. للقيام بذلك ، أنشأنا orderLifeTime المتغير ، حيث نشير إلى مقدار تعليق النظام في غضون دقائق.
إذا انتهى الوقت ، فقم بإلغاء الطلب باستخدام طريقة order_cancel ، وقم بتمرير معرف الطلب.
let timePassed = (new Date().getTime() / 1000) + stockTimeOffset * 60 * 60 - (buyOrders[key]['created']); if(timePassed > orderLifeTime * 60){ exmo.api_query('order_cancel',{"order_id":buyOrders[key]['order_id']}, res => { let result = JSON.parse(res); if(result.error) console.log(result.error); console.log(` ${orderLifeTime} ${currency1}`); }); }else{
3) إذا لم يحن الوقت بعد ، فنحن نأمل فقط أن نتمكن من الشراء بسعرنا.
console.log(`, , ${timePassed} `); } } }); } }else{
كل شيء ، توصلنا إلى أوامر مفتوحة ، الآن يعرف الروبوت لدينا ما يجب القيام به مع الطلبات عندما ينشئها. تم إنجاز نصف المهمة.
لذا ، كتلة إذا لم يكن لدينا أوامر.
نحصل على معلومات حول حسابنا باستخدام طريقة user_info :
exmo.api_query('user_info',{},(result)=>{ let res = JSON.parse(result);
للراحة ، نقوم بتدوين أرصدة أزواجنا:
let balance = res.balances[currency1]; let balance2 = res.balances[currency2];
تحقق مما إذا كانت هناك عملة 1 يمكن بيعها؟
if(balance >= currency1MinQuantity){}
إذا كان الأمر كذلك ، فنحن بحاجة إلى حساب سعر البيع.
تحتاج إلى بيع جميع العملات التي اشتريتها والمبلغ الذي اشتريته بالإضافة إلى الربح ناقص عمولة الصرف.
نقطة مهمة! لدينا عملات أقل مما اشترينا - استغرق الصرف عمولة.
let wannaGet = canSpend + canSpend * (stockFee+profit); console.log('sell', balance, wannaGet, (wannaGet/balance));
عند إنشاء أوامر ، يجب تمرير طريقة order_create المعلمات:
- الزوج هو زوجنا الحالي للتداول ؛
- الكمية - الكمية ؛
- السعر - السعر
- النوع - نوع الأمر الذي تم إنشاؤه (شراء / بيع) ؛
نريد البيع - من النوع الذي نحدده البيع .
let options = { "pair": currentPair, "quantity": balance, "price": wannaGet / balance, "type": 'sell' };
وأرسل طلبًا ، إذا كان كل شيء صحيحًا ، فسترى الإدخال "تم إنشاء أمر بيع"
exmo.api_query("order_create", options,(result)=>{ if(result.error) console.log(result.error); console.log(" ", currency1, result.order_id); });
هذا كل شيء. إذا كان لدينا عملة ، فقد أنشأنا ببساطة أمرًا ببيعها.
ننتقل الآن إلى الكتلة الأكثر إثارة للاهتمام: الحالة إذا لم يكن لدينا currency1 (btc) ونريد شرائها لعملتنا 2 (usd).
أولاً ، تحقق مما إذا كان هناك ما يكفي من المال في الميزانية العمومية بالعملة 2.
if(balance2 >= canSpend){}
إذا كان هناك ، فنحن بحاجة إلى الحصول على متوسط السعر الذي تُباع به العملة 1 (btc) للفترة الزمنية التي حددناها في avgPricePeriod .
القليل من الكلمات:
لدى Exmo طريقة مؤشر مع الإحصائيات وأحجام التداول لأزواج العملات. تظهر الإحصائيات متوسط السعر لآخر 24 ساعة. ومع ذلك ، يمكن أن يكون الفرق بين متوسط السعر والسعر الذي يُعقد فيه المزاد حاليًا مختلفًا تمامًا.
ولهذا السبب ، يمكننا الانتظار لفترة طويلة لتنفيذ أمر بيع.
سوف نصنع دراجتنا.
لدى Exmo طريقة تداول ، تقوم بإرجاع قائمة الصفقات لزوج العملات.
سنأخذ الصفقة المثالية لـ avgPricePeriod التي نهتم بها ومنهم سنقوم بحساب متوسط السعر.
هذا ليس خيارًا مثاليًا ، ولكنه سيعرض الأسعار الحقيقية التي يبيعون ويشترون بها.
على سبيل المثال ، في وقت كتابة هذا التقرير ، كان متوسط سعر BTC_USD هو 8314 ، بينما يتم الشراء في البورصة بسعر 7970.
إذا وضعنا طلبًا بمتوسط سعر ، فسيتم تنفيذه على الفور بأقل سعر موضح في أوامر البيع.
ولكن بإضافة عمولة الربح والصرف ، من المرجح أن ننتظر فترة طويلة جدًا للبيع.
لذا ، دعنا ننتقل إلى طريقة الصفقات ونطلب منه إحصائيات حول زوجنا الحالي :
exmo.api_query("trades",{"pair":currentPair}, result => { let res = JSON.parse(result); let prices = []; let summ = 0;
سنستعرض جميع النتائج ونترك فقط تلك المناسبة لفترة زمنية لدينا.
for(deal in res[currentPair]){ let timePassed = (new Date().getTime() / 1000) + stockTimeOffset * 60 * 60 - res[currentPair][deal].date; if(timePassed < avgPricePeriod * 60){ summ += parseInt(res[currentPair][deal].price); prices.push(parseInt(res[currentPair][deal].price)); } }
وحساب متوسط السعر.
let avgPrice = summ2 / prices.length;
لدينا متوسط السعر ، ولكننا بحاجة إلى إصلاحه قليلاً - طرح عمولة بورصة stockFee وإضافة الربح المطلوب. وبالتالي ، بعد أن حصلنا على سعر أقل من متوسط سعر السوق ، سنشتري عملة أكثر قليلاً ، لأن البورصة جزء منها لاحقًا ؛
let needPrice = avgPrice - avgPrice * (stockFee + profit)
نحصل على المبلغ النهائي الذي نحتاج إلى شرائه.
let ammount = canSpend / needPrice; console.log('Buy', ammount, needPrice);
نتحقق مما إذا كان من الممكن شراء هذا المبلغ من العملة (هو الحد الأدنى لمبلغ الشراء الذي لم يتم انتهاكه).
if(ammount >= currency1MinQuantity){}
إذا كانت الكمية الخاصة بنا أكبر ، فنحن نشكل المعلمات لأسلوب order_create ، هذه المرة فقط مع نوع الشراء .
let options = { "pair": currentPair, "quantity": ammount, "price": needPrice, **"type": 'buy'** }; exmo.api_query('order_create', options, res => { let result = JSON.parse(res); if(result.error) console.log(result.error); console.log(' ', result.order_id); }); }else{ console.log(', '); } }); }else{ console.log(', '); }
نحتاج الآن إلى وضع وظيفتنا على المؤقت (النطاق مرة واحدة كل 5 ثوانٍ ، على سبيل المثال) ويمكننا تشغيله.
var timerId = setTimeout(function tick() { trade(); timerId = setTimeout(tick, 5000); }, 5000);
node index.js
مبروك ، لقد كتبت أول روبوت تداول لك: يمكنك إنهاء الخوارزمية وكسب الكثير من المال) أنا أمزح فقط .
أعتقد أن لديك سؤال معقول ، "كم من المال يمكنك أن تكسب بهذه الطريقة؟"
لعملية واحدة بخمسة دولارات ، أكسب حوالي 2-3 سنتات. هذا يرجع إلى بدائية الخوارزمية ، والتي تعمل إذا كان السعر يتقلب في نطاق معين (وهذا ليس هو الحال دائمًا في تبادل العملات المشفرة). تتم حوالي 10-20 عملية في اليوم (بأيد أمينة). يمكنك عد نفسك ؛)
لكننا لا نتقن الكود من أجل المال)
مرة أخرى ، رابط إلى جيثب مع النسخة الكاملة من البوت والتعليقات.
https://github.com/v-florinskiy/exmo-exchange-trade-bot
هذه مقالتي الأولى - لا تحكم بدقة)
كل الربح.
ملاحظة: بالنسبة لأولئك الذين لم يعملوا مع العقدة ، سيعمل البرنامج النصي الخاص بك بشكل طبيعي أثناء فتح وحدة التحكم.
لكي يعمل الروبوت الخاص بك على مدار الساعة طوال أيام الأسبوع ، تحتاج إلى نوع من أنواع vps: هناك تضع nodejs و npm ، على سبيل المثال ، pm2. باستخدام هذه الأداة ، سيستمر البرنامج النصي في العمل ، حتى إذا تم إغلاق وحدة التحكم.