It was the Bitcointalk forum that inspired us to create Bitcointalksearch.org - Bitcointalk is an excellent site that should be the default page for anybody dealing in cryptocurrency, since it is a virtual gold-mine of data. However, our experience and user feedback led us create our site; Bitcointalk's search is slow, and difficult to get the results you need, because you need to log in first to find anything useful - furthermore, there are rate limiters for their search functionality.
The aim of our project is to create a faster website that yields more results and faster without having to create an account and eliminate the need to log in - your personal data, therefore, will never be in jeopardy since we are not asking for any of your data and you don't need to provide them to use our site with all of its capabilities.
We created this website with the sole purpose of users being able to search quickly and efficiently in the field of cryptocurrency so they will have access to the latest and most accurate information and thereby assisting the crypto-community at large.
// Trade API settings
$key = ''; // your API-key
$secret = ''; // your Secret-key
// Limits for trading size (BTC)
// Setting the increment too small will have a negative effect on speed
$min_amount = 0.1;
$max_amount = 0.6;
$increment = 0.02;
// Minimum profit in percent
// Must be higher than BTC-E fee * 3 to be profitable
$min_profit = 1.0;
// Margin of price
// Trades will be executed this much higher/lower to make "sure" they go through
// 1.05 = 5 % and so on
$price_margin = 1.05;
// Delay between requests (ms), check with BTC-E how high value they allow
// setting this too high could cause BTC-E to potentially block the bot.
$delay = 100;
// Specify a minimum time between 2 trades (s). Whenever an inbalance between prices exists
// we want to quickly execute the FIRST trade, but let other arbitrage bots (with bigger balances)
// clean up the rest. Otherwise there seems to be big risk for losing trades.
$time_between_trades = 10;
$last_trade_time = 0;
// Required for BTC-E API
$mt = explode(' ', microtime());
$nonce = $mt[1];
// http://pastebin.com/QyjS3U9M
function btce_query($method, array $req = array())
{
global $key, $secret, $nonce;
$req['method'] = $method;
$req['nonce'] = $nonce++;
// generate the POST data string
$post_data = http_build_query($req, '', '&');
$sign = hash_hmac("sha512", $post_data, $secret);
// generate the extra headers
$headers = array(
'Sign: '.$sign,
'Key: '.$key,
);
// our curl handle (initialize if required)
static $ch = null;
if (is_null($ch)) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; BTC-E PHP client; '.php_uname('s').'; PHP/'.phpversion().')');
}
curl_setopt($ch, CURLOPT_URL, 'https://btc-e.com/tapi/');
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
// run the query
$res = curl_exec($ch);
if ($res === false)
exit('Trade API error: Connection error: ' . curl_error($ch));
$dec = json_decode($res, true);
if (!$dec)
exit('Trade API error: Invalid JSON.');
return $dec;
}
function perform_trade($trade, $show_balance)
{
global $last_trade_time;
$last_trade_time = time();
$reply = btce_query('Trade', $trade);
if ($reply['success'] != 1)
exit('Trade error: ' . $reply['error']);
if ($show_balance)
print_balance($reply);
}
function print_balance($response = false)
{
if (!$response)
$response = btce_query('getInfo');
$str = "";
foreach ($response['return']['funds'] as $key => $val)
{
if ($val > 0)
{
if (strlen($str) > 0)
$str .= ",";
$str .= " " . $val . " " . strtoupper($key);
}
}
echo date("H:i:s") . ' Balance:' . $str . "\n";
}
// Fetch order book for a given currency pair
function order_book($pair)
{
$orders = file_get_contents('https://btc-e.com/api/2/' . $pair . '/depth');
if ($orders === false)
exit('Public API error: Connection error.');
$dec = json_decode($orders);
if (!$dec)
echo date("H:i:s") . " ERROR: Unable to fetch order book for " . $pair . ".\n";
return $dec;
}
// Return how big volume we can get with the given amount
function ask_volume($orders, $amount)
{
$vol = 0;
$value = 0;
for ($i = 0; $i < count($orders->asks) && $value < $amount; $i++)
{
$this_value = min($orders->asks[$i][0] * $orders->asks[$i][1], $amount - $value);
$this_vol = $this_value / $orders->asks[$i][0];
$value += $this_value;
$vol += $this_vol;
}
return $vol;
}
function bid_volume($orders, $amount)
{
$vol = 0;
$value = 0;
for ($i = 0; $i < count($orders->bids) && $value < $amount; $i++)
{
$this_value = min($orders->bids[$i][1], $amount - $value);
$this_vol = $this_value * $orders->bids[$i][0];
$value += $this_value;
$vol += $this_vol;
}
return $vol;
}
function best_bid($orders)
{
return $orders->bids[0][0];
}
function best_ask($orders)
{
return $orders->asks[0][0];
}
// The main function of the program
function main_loop()
{
global $min_amount, $max_amount, $increment, $min_profit, $delay, $price_margin, $time_between_trades, $last_trade_time;
// Print some starting information
echo "BTC-E Arbitrage Bot v0.1 (CTRL+C to exit)\n";
echo "Trade amount (min/increment/max): " . $min_amount . " / " . $increment . " / " . $max_amount . "\n";
echo "Minimum profit: " . $min_profit . " %\n";
echo "Price margin: " . $price_margin . "\n";
echo "Delay between checks: " . $delay . " ms\n";
echo "Min time between trades: " . $time_between_trades . " s\n";
print_balance();
// Loop indefinitely (press CTRL+C to exit)
while (true)
{
// Fetch order books for all currency pairs
$btc_usd_orders = order_book('btc_usd');
$ltc_btc_orders = order_book('ltc_btc');
$ltc_usd_orders = order_book('ltc_usd');
// Proceed if we have orders for all pairs
if ($btc_usd_orders && $ltc_btc_orders && $ltc_usd_orders)
{
$best_case = 0;
$best_profit = 0;
$best_amount = 0;
$best_trades = array();
// Loop through different order sizes to find the one with most profit
for ($amt = $min_amount; $amt <= $max_amount; $amt += $increment)
{
// Case 1: BTC -> LTC -> USD -> BTC
$c1_ltc = ask_volume($ltc_btc_orders, $amt);
$c1_usd = bid_volume($ltc_usd_orders, $c1_ltc);
$c1_btc = ask_volume($btc_usd_orders, $c1_usd);
$c1_profit = $c1_btc - $amt;
$c1_profit_percent = ($c1_profit * 100) / $amt;
if ($c1_profit > $best_profit && $c1_profit_percent > $min_profit)
{
$best_case = 1;
$best_profit = $c1_profit;
$best_amount = $amt;
$best_trades = array
(
array('pair' => 'ltc_btc', 'type' => 'buy', 'amount' => round($c1_ltc, 6), 'rate' => round(best_ask($ltc_btc_orders) * $price_margin, 3)),
array('pair' => 'ltc_usd', 'type' => 'sell', 'amount' => round($c1_ltc, 6), 'rate' => round(best_bid($ltc_usd_orders) / $price_margin, 3)),
array('pair' => 'btc_usd', 'type' => 'buy', 'amount' => round($c1_btc, 6), 'rate' => round(best_ask($btc_usd_orders) * $price_margin, 3))
);
}
// Case 2: BTC -> USD -> LTC -> BTC
$c2_usd = bid_volume($btc_usd_orders, $amt);
$c2_ltc = ask_volume($ltc_usd_orders, $c2_usd);
$c2_btc = bid_volume($ltc_btc_orders, $c2_ltc);
$c2_profit = $c2_btc - $amt;
$c2_profit_percent = ($c2_profit * 100) / $amt;
if ($c2_profit > $best_profit && $c2_profit_percent > $min_profit)
{
$best_case = 2;
$best_profit = $c2_profit;
$best_amount = $amt;
$best_trades = array
(
array('pair' => 'btc_usd', 'type' => 'sell', 'amount' => round($amt, 6), 'rate' => round(best_bid($btc_usd_orders) / $price_margin, 3)),
array('pair' => 'ltc_usd', 'type' => 'buy', 'amount' => round($c2_ltc, 6), 'rate' => round(best_ask($ltc_usd_orders) * $price_margin, 3)),
array('pair' => 'ltc_btc', 'type' => 'sell', 'amount' => round($c2_ltc, 6), 'rate' => round(best_bid($ltc_btc_orders) / $price_margin, 3))
);
}
}
// Execute the trades if we found one
if ($best_case > 0)
{
echo date("H:i:s") . ($best_case == 1 ? " LTC -> USD" : " USD -> LTC") . ", Amount " . $best_amount .
", Expected Profit " . number_format($best_profit, 4) .
" (" . number_format(($best_profit * 100) / $best_amount, 2) . " %)\n";
// Check that enough time has passed from the last trade
if ((time() - $last_trade_time) < $time_between_trades)
{
echo date("H:i:s") . " Rejected (not enough time passed from last trade.\n";
}
else
{
perform_trade($best_trades[0], false);
perform_trade($best_trades[1], false);
perform_trade($best_trades[2], true);
}
}
}
// Sleep for a bit
usleep($delay * 1000);
}
}
// Execute the main loop function
main_loop();