date_default_timezone_set('Europe/Berlin');
// MIT DB VERBINDEN --------------------------------------------------------------------------------------
// ######################################################################################################
function dbConnect()
{
global $conn;
$conn = mysqli_connect('localhost', 'cr_admin', 'gy@2Su61', 'crypto');
if (!$conn) die('DB-Connection failed');
mysqli_query($conn, "SET NAMES 'utf8'");
}
// LOGIN-HASH -------------------------------------------------------------------------------------------
// ######################################################################################################
// bekommt User-Daten aus DB übergeben
// generiert aus deren Bruchstücken eine eindeutige ID und verschlüsselt diese
function makeLoginHash($user)
{
$a = substr($user['username'], 0, 5);
$b = substr($user['email'], 2, 3);
$loginHash = hash('sha256', $a.$b.$user['user_ID']);
return $loginHash;
}
// GAIN DER ERWIRTSCHAFTETEN PREISDIFFERENZ BERECHNEN ---------------------------------------------------
// ######################################################################################################
function getGainDiff($position, $open, $close)
{
if ($open > 0 AND $close > 0 AND !empty($position))
{
if ($position == 'LONG' OR $position == 'Buy') $gain = $close - $open;
else if ($position == 'SHORT' OR $position == 'Sell') $gain = $open - $close;
return round($gain, 1);
}
else
{
$conn = dbConnect();
global $conn;
//protocol($conn, '999', 'cron-bb', 'Problem bei getGain', 'Pos: '.$position.' open: '.$open.' close: '.$close);
return (0);
}
}
// GAINDIFF FUER TELEGRAM FORMATIEREN -------------------------------------------------------------------
// ######################################################################################################
// funktioniert (warum auch immer) nur mit doppelten Anführungszeichen
function formatGainDiffTG($gain)
{
if ($gain <= 0) $gainTG = "$ ".$gain. " \u{1F630}"; // U+1F630
else $gainTG = "$ ".$gain. " \u{1F4B0}"; // U+1F4B0
return $gainTG;
}
// GAIN FUER TELEGRAM FORMATIEREN ------------------------------------------------------------------------
// ######################################################################################################
// funktioniert (warum auch immer) nur mit doppelten Anführungszeichen
function formatGainTG($gain)
{
$anzeige = 'BTC '.number_format($gain,8).' ($'.BTC2Dollar($gain, getPriceBybit()).')';
if ($gain <= 0) $anzeige = $anzeige. " \u{1F630}"; // U+1F630
else $anzeige = $anzeige. " \u{1F4B0}"; // U+1F4B0
return $anzeige;
}
// TELEGRAM-NACHRICHT SENDEN ----------------------------------------------------------------------------
// ######################################################################################################
function telegram($msg)
{
//global $telegrambot, $telegramchatid;
// Set your Bot ID and Chat ID.
$telegrambot = '1233342593:AAGt8M5668iaFpGuhvBFm232sImpE4Oopv4';
$telegramchatid = 462791002;
$url = 'https://api.telegram.org/bot'.$telegrambot.'/sendMessage';
$data = array('chat_id' => $telegramchatid, 'text' => $msg, 'parse_mode' => 'html');
$options = array('http' => array('method' => 'POST','header' => "Content-Type:application/x-www-form-urlencoded\r\n",'content' => http_build_query($data),),);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
return $result;
}
// PROTOKOLLIEREN ---------------------------------------------------------------------------------------
// ######################################################################################################
function protocol($conn, $trade_ID, $triggersource, $remark, $details)
{
$qs = "SELECT * From Protocol ORDER BY datetime DESC LIMIT 1 ";
$protocol = mysqli_fetch_assoc($mq = mysqli_query($conn, $qs));
if ($protocol['remark'] == $remark AND ($protocol['details'] == $details OR preg_match('/Preisdifferenz/', $details)))
{
$qs2 = "UPDATE Protocol SET datetime = NOW() WHERE p_ID = '".$protocol['p_ID']."' ";
if (!empty($qs2)) $mq2 = mysqli_query($conn, $qs2);
}
else
{
$qs2 = "INSERT INTO Protocol(trade_ID, triggersource, remark, details) ";
$qs2 .= "values('".$trade_ID."', '".$triggersource."', '".$remark."', '".addslashes($details)."' ) ";
}
if (! mysqli_query($conn, $qs2)) mail('kontakt@webdesire.de', 'Fehler beim Protokollieren', addslashes($qs2));
}
// HQ-UPDATE --------------------------------------------------------------------------------------------
// ######################################################################################################
function updateHQ($conn, $initiator_HQ, $pending_ID, $pending_position, $pending_status,
$current_ID, $current_position, $current_status, $current_peak, $current_SL,
$last_wait, $last_open, $last_SL)
{
$conn = dbConnect();
global $conn;
$qs .= "UPDATE HQ SET initiator_HQ = '".$initiator_HQ."', ";
// leere Werte werden ignoriert (kein Update), ERASE bedeutet: Wert loeschen (bei IDs Null setzen)
if (!empty($pending_ID)) { if ($pending_ID == 'ERASE') $pending_ID = 0; $qs .= "pending_ID = '".$pending_ID."', "; }
if (!empty($pending_position)) { if ($pending_position == 'ERASE') $pending_position = ''; $qs .= "pending_position = '".$pending_position."', "; }
if (!empty($pending_status)) { if ($pending_status == 'ERASE') $pending_status = ''; $qs .= "pending_status = '".$pending_status."', "; }
if (!empty($current_ID)) { if ($current_ID == 'ERASE') $current_ID = 0; $qs .= "current_ID = '".$current_ID."', "; }
if (!empty($current_position)) { if ($current_position == 'ERASE') $current_position = ''; $qs .= "current_position = '".$current_position."', "; }
if (!empty($current_status)) { if ($current_status == 'ERASE') $current_status = ''; $qs .= "current_status = '".$current_status."', "; }
if (!empty($current_peak)) { if ($current_peak == 'ERASE') $current_peak = 0; $qs .= "current_peak = '".$current_peak."', "; }
if (!empty($current_SL)) { if ($current_SL == 'ERASE') $current_SL = 0; $qs .= "current_SL = '".$current_SL."', "; }
if (!empty($last_wait)) { if ($last_wait == 'ERASE') $last_wait = 0; $qs .= "last_wait = '".$last_wait."', "; }
if (!empty($last_open)) { if ($last_open == 'ERASE') $last_open = 0; $qs .= "last_open = '".$last_open."', "; }
if (!empty($last_SL)) { if ($last_SL == 'ERASE') $last_SL = 0; $qs .= "last_SL = '".$last_SL."', "; }
$qs = substr($qs, 0, -2); // Komma hinten entfernen
if (! mysqli_query($conn, $qs)) mail('kontakt@webdesire.de', 'Fehler beim Trading: HQ1', $qs);
//telegram($qs);
}
// PEAK-UPDATE ------------------------------------------------------------------------------------------
// ######################################################################################################
// current_peak aktualisieren, wenn neuer Wert größer (bei LONG) oder kleiner (bei SHORT) als bisheriger
function updatePeak($conn, $BTCUSD)
{
$HQ = getHQ($conn);
if ($HQ['current_position'] == 'Buy' AND $BTCUSD > $HQ['current_peak'])
$qs .= "UPDATE HQ SET current_peak = '".$BTCUSD."' ";
else if ($HQ['current_position'] == 'Sell' AND $BTCUSD < $HQ['current_peak'] OR empty($HQ['current_peak']))
$qs .= "UPDATE HQ SET current_peak = '".$BTCUSD."' ";
if (!empty($qs)) $mq = mysqli_query($conn, $qs);
// protocol($conn, '999', 'Cron', 'Peak-Update', $BTCUSD);
}
// HQ-DATEN HOLEN ---------------------------------------------------------------------------------------
// ######################################################################################################
function getHQ($conn)
{
$qsHQ = "SELECT * FROM HQ ";
$HQ = mysqli_fetch_assoc($mq = mysqli_query($conn, $qsHQ));
return($HQ);
}
// HQ LOCK ----------------------------------------------------------------------------------------------
// ######################################################################################################
function setLock($conn, $mode, $initiator_lock)
{
$qs = "UPDATE HQ SET locked = '".$mode."', initiator_lock = '".$initiator_lock."' ";
if (!empty($qs)) $mq = mysqli_query($conn, $qs);
}
// GEGENTEIL DER POSITION ERMITTELN ---------------------------------------------------------------------
// ######################################################################################################
function getOpposite($side)
{
if($side == 'Buy') $opposite = 'Sell';
else if ($side == 'Sell') $opposite = 'Buy';
return($opposite);
}
// BOT EIN/AUSSCHALTEN ----------------------------------------------------------------------------------
// ######################################################################################################
function power($conn, $mode)
{
$qs = "UPDATE Settings SET status = '".$mode."' ";
if (!empty($qs)) $mq = mysqli_query($conn, $qs);
}
// BTC in Dollar umrechnen ------------------------------------------------------------------------------
// ######################################################################################################
function BTC2Dollar($sat, $btc)
{
$dollar = number_format($btc * $sat, 2);
return($dollar);
}
// BYBIT-CONNECT ----------------------------------------------------------------------------------------
// ######################################################################################################
$public_key = 'Bb97NFrGGNSNq145J0'; // MAIN
//$public_key = '2XUawXfEi1K2ruB4Ez'; // TRADEDESIRE
//$public_key = 'Et0G5yneqwyGYtLOed'; // TEST
$secret_key = '7nHJ4auYxB1LodwYQCeOJ9xF0r8nHNFhjbcx'; // MAIN
//$secret_key = 'PaT5E18cAzVYsxqvbb9y35NYoIn4U2r3GN89'; // TRADEDESIRE
//$secret_key = '8cPO2whHVpTkRZyxkkvZLWPL0KeKoBol6NOg'; // TEST
//$selector = '-testnet';
$selector = '';
function get_signed_params($params) {
global $public_key;
global $secret_key;
$params = array_merge(['api_key' => $public_key], $params);
ksort($params);
//decode return value of http_build_query to make sure signing by plain parameter string
$signature = hash_hmac('sha256', urldecode(http_build_query($params)), $secret_key);
return http_build_query($params) . "&sign=$signature";
}
// AKTUELLEN PREIS VON BYBIT HOLEN ----------------------------------------------------------------------
// ######################################################################################################
function getPriceBybit()
{
global $selector;
$bybit_json = file_get_contents('https://api'.$selector.'.bybit.com/v2/public/tickers');
$data = json_decode($bybit_json, true);
$BTCUSD = $data['result'][0]['last_price'];
global $conn;
$qs = "UPDATE Prices ";
$qs .= "SET BTCUSD = '".$BTCUSD."'";
$mq = mysqli_query($conn, $qs);
return ($BTCUSD);
}
// OPEN INTEREST VON BYBIT HOLEN ------------------------------------------------------------------------
// ######################################################################################################
function getOIBybit()
{
global $selector;
$bybit_json = file_get_contents('https://api'.$selector.'.bybit.com/v2/public/tickers');
$data = json_decode($bybit_json, true);
foreach($data['result'] as $a)
{
if ($a['symbol'] == 'BTCUSD') $OI = $a['open_interest'];
}
global $conn;
$qs = "INSERT INTO Open_Interest ";
$qs .= "SET symbol = 'BTSUSD', open_interest = '".$OI."' ";
$mq = mysqli_query($conn, $qs);
return ($OI);
}
// WALLET AUSLESEN --------------------------------------------------------------------------------------
// ######################################################################################################
function getWallet(){
$walletparams = ['symbol' => 'BTCUSD', 'timestamp' => time() * 1000];
global $selector;
$url = 'https://api'.$selector.'.bybit.com/v2/private/wallet/balance';
//$url = 'https://api-testnet.bybit.com/v2/private/wallet/balance';
return json_decode(file_get_contents($url . "?" . get_signed_params($walletparams)), true);
}
// LISTE DER TRADES AUSLESEN ----------------------------------------------------------------------------
// ######################################################################################################
function getPnL(){
$walletparams = ['symbol' => 'BTCUSD', 'timestamp' => time() * 1000];
global $selector;
$url = 'https://api'.$selector.'.bybit.com/v2/private/trade/closed-pnl/list';
return json_decode(file_get_contents($url . "?" . get_signed_params($walletparams)), true);
}
// LISTE DER ORDERS AUSLESEN ----------------------------------------------------------------------------
// ######################################################################################################
function getOrders(){
$walletparams = ['symbol' => 'BTCUSD', 'timestamp' => time() * 1000];
global $selector;
$url = 'https://api'.$selector.'.bybit.com/v2/private/execution/list';
return json_decode(file_get_contents($url . "?" . get_signed_params($walletparams)), true);
}
// LEVERAGE AUSLESEN ------------------------------------------------------------------------------------
// ######################################################################################################
function getLeverage()
{
global $selector;
$leverageParams = ['timestamp' => time() * 1000];
$url = 'https://api'.$selector.'.bybit.com/user/leverage';
return json_decode(file_get_contents($url . "?" . get_signed_params($leverageParams)), true);
}
// POSITION AUSLESEN ------------------------------------------------------------------------------------
// ######################################################################################################
function getPosition($symbol)
{
global $selector;
$positionParams = ['timestamp' => time() * 1000];
$positionParams = array_merge(['symbol' => $symbol], $positionParams);
$url = 'https://api'.$selector.'.bybit.com/v2/private/position/list';
return json_decode(file_get_contents($url . "?" . get_signed_params($positionParams)), true);
}
// LEVERAGE SETZEN --------------------------------------------------------------------------------------
// ######################################################################################################
function setLeverage($symbol, $leverage){
global $selector;
$leverageSetParams = ['timestamp' => time() * 1000];
$leverageSetParams = array_merge(['symbol' => $symbol, 'leverage' =>$leverage], $leverageSetParams);
$url = 'https://api'.$selector.'.bybit.com/user/leverage/save';
$params = get_signed_params($leverageSetParams);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => $params
)
);
$context = stream_context_create($opts);
return json_decode(file_get_contents($url, false, $context), true);
}
// ACTIVE BUY/SELL-ORDER --------------------------------------------------------------------------------
// ######################################################################################################
function trade_active($side, $symbol, $order_type, $qty, $stop_loss, $reduce_only)
{
$conn = dbConnect();
global $conn;
// auf bereits offene Position checken
if (!$reduce_only)
{
$pos = getPosition('BTCUSD');
if ($pos['ret_msg'] == 'OK' AND $pos['result']['size'] == 0) $posCheck = 'startbereit';
else $posCheck = json_encode($pos);
protocol($conn, '999', '', 'getPosition', $posCheck);
}
// wird nur ausgeführt, wenn bestätigtg ist, dass keine Position mehr offen ist
// oder es sich um eine Reduce-Only-Order handelt (dann muss ja Pos offen sein)
if ($pos['result']['entry_price'] == 0 OR $reduce_only)
{
global $selector;
$setParams = ['timestamp' => time() * 1000];
$setParams = array_merge(['side' => $side, 'symbol' => $symbol, 'order_type' => $order_type, 'qty' => $qty, 'reduce_only' => $reduce_only, 'time_in_force' => 'GoodTillCancel' ], $setParams);
if ($stop_loss > 0) $setParams = array_merge(['stop_loss' => ceil($stop_loss)], $setParams);
$url = 'https://api'.$selector.'.bybit.com/v2/private/order/create';
$params = get_signed_params($setParams);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => $params
)
);
$context = stream_context_create($opts);
$response = json_decode(file_get_contents($url, false, $context), true);
if ($reduce_only) $reduce_only = 1; else $reduce_only = 0; // Umwandlung von boolschem Wert zur besseren Protokollierung
protocol($conn, '888', '', 'trade_active Request', $side.' | '.$symbol.' | '.$order_type.' | '.$qty.' | '.$stop_loss.' | '.$reduce_only);
protocol($conn, '888', '', 'trade_active Response Status', $response['ret_msg']);
protocol($conn, '888', '', 'trade_active Full Response', json_encode($response));
}
return $response['result']['price'];
}
// CONDITIONAL BUY/SELL-ORDER ---------------------------------------------------------------------------
// ######################################################################################################
function trade_cond($side, $symbol, $order_type, $qty, $base_price, $stop_px)
{
global $selector;
$setParams = ['timestamp' => time() * 1000];
$setParams = array_merge(['side' => $side, 'symbol' => $symbol, 'order_type' => $order_type, 'qty' => $qty, 'base_price' => $base_price, 'stop_px' => $stop_px, 'time_in_force' => 'GoodTillCancel' ], $setParams);
$url = 'https://api'.$selector.'.bybit.com/open-api/stop-order/create';
$params = get_signed_params($setParams);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => $params
)
);
$context = stream_context_create($opts);
return json_decode(file_get_contents($url, false, $context), true);
}
// TP SETZEN --------------------------------------------------------------------------------------------
// ######################################################################################################
function setTP($symbol, $take_profit)
{
global $selector;
$setParams = ['timestamp' => time() * 1000];
$setParams = array_merge(['symbol' => $symbol, 'take_profit' => ceil($take_profit) ], $setParams);
$url = 'https://api'.$selector.'.bybit.com/open-api/position/trading-stop';
$params = get_signed_params($setParams);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => $params
)
);
$context = stream_context_create($opts);
return json_decode(file_get_contents($url, false, $context), true);
}
// SL SETZEN --------------------------------------------------------------------------------------------
// ######################################################################################################
function setSL($initiator_HQ, $symbol, $stop_loss)
{
global $selector;
$conn = dbConnect();
global $conn;
$setParams = ['timestamp' => time() * 1000];
$setParams = array_merge(['symbol' => $symbol, 'stop_loss' => intval($stop_loss) ], $setParams);
//$url = 'https://api'.$selector.'.bybit.com/open-api/position/trading-stop';
$url = 'https://api'.$selector.'.bybit.com/v2/private/position/trading-stop';
$params = get_signed_params($setParams);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => $params
)
);
$context = stream_context_create($opts);
$response = json_decode(file_get_contents($url, false, $context), true);
updateHQ($conn, 'setSAFE', '', '', '', '', '', '', '', $response['result']['stop_loss'], '', '', $response['result']['stop_loss']);
protocol($conn, 999, $initiator_HQ, 'SL gewollt: '.intval($stop_loss).', bekommen: '.$response['result']['stop_loss'], $response['ret_msg']);
protocol($conn, 999, $initiator_HQ, 'SL Full Response' , json_encode($response));
return($response['ret_msg']);
}
// TRAILING SETZEN --------------------------------------------------------------------------------------
// ######################################################################################################
function setTrailing($symbol, $trailing_stop, $new_trailing_active) // new_trailing_active = Trigger
{
global $selector;
$setParams = ['timestamp' => time() * 1000];
$setParams = array_merge(['symbol' => $symbol, 'trailing_stop' => $trailing_stop, 'new_trailing_active' => $new_trailing_active ], $setParams);
$url = 'https://api'.$selector.'.bybit.com/open-api/position/trading-stop';
$params = get_signed_params($setParams);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => $params
)
);
$context = stream_context_create($opts);
return json_decode(file_get_contents($url, false, $context), true);
}
?>