· 6 years ago · Nov 27, 2019, 05:28 PM
1<?php
2
3 // --------------------------------------------------------------------------------------------------------------------
4 // DERIBOT - 0.4
5 // --------------------------------------------------------------------------------------------------------------------
6 // Author: FrostyAF from the Krown's Crypto Cave discord group
7 // Version: 0.4
8 // Dedication: Dedicated to @christiaan's mom, what a classy lady!
9 // Disclaimer: Use this bot at your own risk, I accept no responsibility if you get rekt
10 // Usage: This bot is intended to be used with TradingView webhooks or via cli commands. Ensure that you have a
11 // PHP web server running and that you have cloned CCXT into the bot directory using:
12 // git clone https://github.com/ccxt/ccxt.git
13 // Ensure the web server is publicly accessible, and then configure your Trading View alerts to call the
14 // webhook using the appropriate commands:
15 // Webhook Example URLs:
16 // https://my.bot.com/webhooks/?command=LONGENTRY (will use the default ORDER_SIZE configured below)
17 // https://my.bot.com/webhooks/?command=LONGENTRY&size=1000&price=7600 (Limit buy for USD1000 at $7600)
18 // https://my.bot.com/webhooks/?command=LONGENTRY&size=200pct (Market buy 200% of current balance, ie. 2x)
19 // https://my.bot.com/webhooks/?command=LONGEXIT (Will exit the full current long position)
20 // https://my.bot.com/webhooks/?command=SHORTENTRY&size=20000 (Custom order size in request)
21 // https://my.bot.com/webhooks/?command=SHORTEXIT (Will exit the full current short position)
22 // https://my.bot.com/webhooks/?command=TAKEPROFIT&size=50pct (Take profit on 50% of the current position)
23 // CLI Examples:
24 // php bot.php LONGENTRY (Will use the default ORDER_SIZE specified below with a market order)
25 // php bot.php LONGENTRY 10000 (Will enter long position of USD 10000 with a market order)
26 // php bot.php LONGENTRY 1000 7600 (Will enter long position of USD 10000 with a limit order at $7600)
27 // php bot.php LONGENTRY 200pct (Will enter long position of 200% of balance (2x) at market price)
28 // php bot.php LONGEXIT (Will exit the full current long position)
29 // php bot.php SHORTENTRY 20000 (Will enter short position of USD 20000)
30 // php bot.php SHORTEXIT (Will exit the full current short position)
31 // php bot.php TAKEPROFIT 50pct (Take profit on 50% of the current position)
32 // php bot.php BALANCE (Current account balances)
33 // php bot.php TRADES (Recent trades, oldest listed first)
34 // php bot.php ORDERS (Open orders)
35 // php bot.php CANCEL (Cancel all open orders)
36 // php bot.php POSITION (Show current open position, if any)
37 // Changelog: 0.1 : Initial version
38 // 0.2 : Code cleanup
39 // Removed the FLIPLONG and FLIPSHORT commands. Incorporated into LONGENTRY and SHORTENTRY.
40 // Added POSITION command to show current position
41 // Added size parameter
42 // 0.3 : Added ORDERS and CANCEL command to show open orders and cancel orders (limit orders)
43 // Added price parameter (limit orders)
44 // Changed output of BALANCE, TRADES and POSITION commands to JSON
45 // Changed IP whitelist to const to prevent skullfuckery
46 // 0.4 : Added size parameter support for % of balance (ie. 200pct = 2x)
47 // Added TAKEPROFIT command with size parameter as % of open order (ie. 50pct)
48 // --------------------------------------------------------------------------------------------------------------------
49
50 // https://ccxt.readthedocs.io/en/latest/README.html
51 include('ccxt/ccxt.php');
52
53 // Script settings
54 const EXCHANGE = 'deribit'; // Any exchange supported by CCXT
55 const API_KEY = ''; // API key
56 const API_SECRET = ''; // API secret
57 const MARKET = 'BTC-PERPETUAL'; // Market to trade
58 const ORDER_SIZE = 100; // Default Order size in USD (if not specified in GET)
59 const CONTRACT_SIZE = 10; // Deribit is $10 per contract
60 const LOG_FILE = 'deribot.log'; // Log file
61 const WHITELIST = [ // GET request whitelist addresses (from TradingView)
62 '52.89.214.238',
63 '34.212.75.30',
64 '54.218.53.128',
65 '52.32.178.7'
66 ];
67
68 // Function to log messages to a log file
69 function logger($message) {
70 file_put_contents(LOG_FILE, date('Y-m-d H:i:s').' : '.$message.PHP_EOL, FILE_APPEND);
71 echo date('Y-m-d H:i:s').' : '.$message.PHP_EOL;
72 }
73
74 // Check that request is coming from an authorised Trading View IP
75 if (isset($_GET['command'])) {
76 if (!in_array($_SERVER['REMOTE_ADDR'], WHITELIST)) {
77 logger('Request received from invalid address');
78 // die;
79 }
80 }
81
82 // Connect to Exchange
83 $exchange_id = EXCHANGE;
84 $exchange_class = "\\ccxt\\$exchange_id";
85 $exchange = new $exchange_class (array (
86 'apiKey' => API_KEY,
87 'secret' => API_SECRET,
88 ));
89
90 // Get balance and market data
91 $ticker = $exchange->fetch_ticker(MARKET);
92 $balance = $exchange->fetch_balance();
93 $btcbalance = (round($balance['BTC']['total'] * 10000) / 10000);
94
95 // Get current position in market
96 $positions = $exchange->private_get_positions();
97 $position = false;
98 $isLong = false;
99 $isShort = false;
100 foreach($positions['result'] as $positionRaw) {
101 if ($positionRaw['instrument']=MARKET) {
102 $position = $positionRaw;
103 }
104 }
105 $isLong = (is_array($position) ? ($position['direction'] == 'buy') : false);
106 $isShort = (is_array($position) ? ($position['direction'] == 'sell') : false);
107
108 // Get bot commands and parameters from GET request or CLI
109 $command = isset($_GET['command']) ? $_GET['command'] : $argv[1];
110 $size = isset($_GET['size']) ? $_GET['size'] : ( isset($argv[2]) ? $argv[2] : ORDER_SIZE);
111 if (substr(strtolower($size),-3) == 'pct') {
112 $pctsize = str_replace('pct','',strtolower($size));
113 if (strtoupper($command) !== 'TAKEPROFIT') {
114 $size = round((($ticker['ask'] * $balance['BTC']['total']) * ($pctsize / 100)) / CONTRACT_SIZE) * CONTRACT_SIZE;
115 } else {
116 $size = round((($position['size'] * CONTRACT_SIZE) * ($pctsize / 100)) / CONTRACT_SIZE) * CONTRACT_SIZE;
117 if ($size > ($position['size'] * CONTRACT_SIZE)) {
118 $size = round((($position['size'] * CONTRACT_SIZE)) / CONTRACT_SIZE) * CONTRACT_SIZE;
119 }
120 }
121 }
122 $orderSize = $size / CONTRACT_SIZE;
123 $price = isset($_GET['price']) ? $_GET['price'] : ( isset($argv[3]) ? $argv[3] : null);
124
125 // Execute appropriate bot command on Exchange
126
127 $order = false;
128
129 switch(strtoupper($command)) {
130 case 'LONGENTRY' : $order = ($isShort && !$price) ? abs($position['size']) + $orderSize : $orderSize;
131 break;
132 case 'LONGEXIT' : $order = $isLong ? 0 - $position['size'] : 0;
133 break;
134 case 'SHORTENTRY' : $order = 0 - (($isLong && !$price) ? $position['size'] + $orderSize : $orderSize);
135 break;
136 case 'SHORTEXIT' : $order = $isShort ? abs($position['size']) : 0;
137 break;
138 case 'TAKEPROFIT' : $order = $isShort ? abs($orderSize) : ($isLong ? 0 - abs($orderSize) : 0);
139 break;
140 case 'TICKER' : echo json_encode((object) $ticker, JSON_PRETTY_PRINT).PHP_EOL;
141 break;
142 case 'BALANCE' : echo json_encode((object) $balance, JSON_PRETTY_PRINT).PHP_EOL;
143 break;
144 case 'TRADES' : $trades = $exchange->fetch_my_trades(MARKET);
145 echo json_encode((object) $trades, JSON_PRETTY_PRINT).PHP_EOL;
146 break;
147 case 'ORDERS' : $orders = $exchange->fetch_open_orders(MARKET);
148 echo json_encode((object) $orders, JSON_PRETTY_PRINT).PHP_EOL;
149 break;
150 case 'CANCEL' : $orders = $exchange->fetch_open_orders(MARKET);
151 foreach ($orders as $item)
152 $exchange->cancel_order($item['id']);
153 echo json_encode((object) $orders, JSON_PRETTY_PRINT).PHP_EOL;
154 break;
155 case 'POSITION' : echo json_encode((object) $position, JSON_PRETTY_PRINT).PHP_EOL;
156 break;
157 }
158
159 if ($order) {
160
161 $type = ((strtoupper($price) !== 'MARKET') && (is_numeric($price))) ? 'limit' : 'market';
162 $dir = $order > 0 ? 'buy' : ($order < 0 ? 'sell' : null);
163 $result = $exchange->create_order(MARKET, $type, $dir, abs($order), $price);
164
165 if ($result) {
166 echo json_encode((object) $result, JSON_PRETTY_PRINT).PHP_EOL;
167 logger('TRADE: USD '.str_pad(($order) * CONTRACT_SIZE, 5, " ", STR_PAD_LEFT).', BALANCE: BTC '.$btcbalance);
168 } else {
169 logger('FAILED TO EXECUTE TRADE!!!');
170 }
171 }
172
173?>