Mike Fishy and Automation System Programming (Bots)


#324

On the production bot, it is a capital gain.
I start the bot with 25 BTC, it moves the funds around from BTC to BNB to ALTS and back.
So it is basically accumulating BTC with a list of rules that are quite extensive.
Honestly, I dont care too much for USDT and I don’t really care what BTC is worth, just that I have more of them :slight_smile:

Isn’t that what the B90x is about, you need 90 of them right? :stuck_out_tongue:

Been running the code that does not have the stoploss and takes the money as soon as it signals and meets a bare minimum, it so far has done:

the ONT one has been running at a loss, the maximum it dropped to was -1.04% - but it keeps bouncing back and each time gets closer to a break even. This is what I mean by the rubber band effect and thus opens thought to rules around how we can take advantage of minimising a stop loss.

IE - track the loss value trend and decide to dump it at a minimum loss if possible.

The same should be true for the uptrend on a good trade - right?

IE - track the gain value trend and decide to dump it to get the maximum gain possible.

2 other things need to be tracked as well.

They are:

  1. RSI Trend
  2. How rapidly the price is going up or down in a time period

Edit: ONT has now bounced back to the break even:

Stay Fishy


#325

what does the acronym cda stand for?

You also have another called
cdarsgain…cda _rs_gain
cdarsloss…cda_rs_loss

Also as you get through the code you get to cdaprev… you haven’t dimensioned it yet;

The line If($cdaval == $cdaprev)
or dont you have to dimension it as zero? Does it inherit the related variables properties?

Sorry to ask you such stupid questions.

Here is the code:

// Calculate the Relative Strength Indicator on the Long Term Array
// A Low RSI indicates a buy opportunity
$rsitck = 0;
${$tick . “gain”} = array();
${$tick . “loss”} = array();
foreach(${$tick . “lt”} as $cdaval)
{
if($rsitck == 0)
{
$cdagain = 0;
$cdaloss = 0;
}
else
{
if($cdaval == $cdaprev)
{
$cdagain = 0;
$cdaloss = 0;
}
elseif($cdaval > $cdaprev)
{
$cdacalc = $cdaval - $cdaprev;
$cdagain = number_format($cdacalc,8);
$cdaloss = 0;
}
else
{
$cdacalc = $cdaprev - $cdaval;
$cdaloss = number_format($cdacalc,8);
$cdagain = 0;
}
}
array_push(${$tick . “gain”}, $cdagain);
array_push(${$tick . “loss”}, $cdaloss);
$cdaprev = $cdaval;
$rsitck++;
}
$cdarsgain = (array_sum(${$tick . “gain”})) / $ltrend;
$cdarsloss = (array_sum(${$tick . “loss”})) / $ltrend;
if($cdarsloss > 0)
{
${$tick . “rsi”} = round(100-(100/(1+($cdarsgain/$cdarsloss))),3);
if(${$tick . “rsi”} == 0) ${$tick . “rsi”} = 0;
}
else
{
${$tick . “rsi”} = 100;
}

Crash


#326

Criptographic Digital Asset instead of saying Token or Coin. See @Mike_Fishy’s absolute first post on this thread.


#327

whoot! yesterday’s version (with the stop/loss logic error):

image

I actually didn’t realize I had this version actively running in another terminal window until just now, so got quite a chuckle from that - 704k% loss.

Let’s try today’s! :slight_smile:

Thanks for talking more about the parameters and how to progressively improve the script (i.e. what to watch for). For me, this is the most valuable part of this journey.


#328

I just gave the latest a spin after adapting it for replay. This is essentially all data from yesterday:

5.8% up, so definitely confirms Fishy’s last post.

Last version with replay implemented:

<?php
require 'vendor/autoload.php';

// This bot will trade USDT to the other pairs and back to make more USDT
// It shall use all the trading pairs to make more UDST except the ones we tell it not to use

$strend = 50;             // Short Term Trend - must be less than $mtrend
$mtrend = 90;             // Medium Term Trend - must be less than $ltrend
$ltrend = 120;            // Long Term Trend
$tradefile = "USDT.txt";  // The Trade Logging file name
$minspread = 1;           // The minimum spread percentage needed for a trade
$minrsi = 46;             // Relative Strength must be below this number to buy
$sellbuffer = 1.003;      // Create a buffer to hold CDA if sell is not profitable

// Do not change any of the flags, we use this to signal the bot what to do and when
$buyready = 0;            // This flag signals the bot that the pair meets rules to buy
$buyprep = 1;             // This flag signals the bot to prepare to buy
$buyord = 2;              // This flag signals the bot to place an order
$sellok = 3;              // This flag signals the bot that the order was completed
$sellready = 4;           // This flag signals the bot to sell
$selldone = 5;            // This flag signals the bot the trade completed
$dontbuy = 6;             // This flag signals the bot we dont want to trade BCASH :P

// Standard variables and arrays we use
$replay = 1;
$i = 0;
$binance_prices = array();
$time_start = time();
$time_end = 0;
$run_time = 0;
$rpc = 0;
$tpc = 0;
$q = 0;

// API call to fetch pricing data from Binance
function getprices()
{
  global $replay;
  global $pricefh;
  
  if ($replay == 0) {
    $api = new Binance\API("<api key>","<secret>");
    $mp = $api->prices();

    $pricefh = fopen("USDT_prices.txt", "a") or die("Cannot open file");
    fwrite($pricefh, serialize($mp) . "\n");
    fclose($pricefh);
  }
  else
  {
    if (!$pricefh) {
      $pricefh = fopen("USDT_prices.txt", "r") or die("Cannot open replay file");
    }
    $mp = unserialize(fgets($pricefh));
    if ($mp == NULL) die("end of price data reached.\n");
  }
  return $mp;
}

if ($replay == 1) 
{
  $simulation_mode = "replaying"; 
}
else 
{
  $simulation_mode = "real-time";
  unlink("USDT_prices.txt");
}

// Start of the Loop - can run for months - press CTRL-C to stop
for($i = 0; $i <= 2000000; $i++)
{
  $time_end = time();
  $run_time = round((($time_end - $time_start)/60),2);
  print "====================================\n";
  print "Iteration = $i ($simulation_mode) \n";
  print "Running Time: $run_time mins \n";
  print "Current running percentage = $rpc \n";
  print "====================================\n";

  // Fetch current prices from Binance
  $binance_prices = getprices();

  // Loop through the price data as key and value pairs
  foreach($binance_prices as $key => $value)
  {

    // Only process pairs with USDT
    if(strpos($key, "USDT"))
    {

      // Convert the pair name to lower case in varibale $tick
      // for example the name "BTCUSDT" will become "btcusdt"

      $tick = strtolower($key);

      // For the first iteration, create arrays and varibales for the bot
      if($i == 0)
      {

        // Use the lower case name to form the leading part of varibales and arrays
        // for exmaple, using "btcusdt" and adding "st" for the short term array
        // will initialise an array called "btcusdtst"
        // as we loop thorugh the pairs, each one gets created for each pair
        // for exmaple "NEOUSDT" will become "neousdtst"

        ${$tick . "st"} = array();           // Short Term Array
        ${$tick . "mt"} = array();           // Medium Term Array
        ${$tick . "lt"} = array();           // Long Term Array
        ${$tick . "stavg"} = 0;              // Short Term Moving Average
        ${$tick . "mtavg"} = 0;              // Medium Term Moving Average
        ${$tick . "ltavg"} = 0;              // Long Term Moving Average
        ${$tick . "strend"} = 0;             // Short Term Moving Trend
        ${$tick . "mtrend"} = 0;             // Medium Term Moving Trend
        ${$tick . "ltrend"} = 0;             // Long Term Moving Trend
        ${$tick . "lspread"} = 0;            // Long Term Spread
        ${$tick . "rsi"} = 0;                // Relative Strength Indicator for this pair
        ${$tick . "tradeflag"} = $buyready;  // Set this pair to buyready
        ${$tick . "buyvalue"} = 0;           // record what we buy for on this pair
        ${$tick . "sellvalue"} = 0;          // record what we sell for on this pair
        ${$tick . "lasttrade"} = 0;          // record we have had one trade done
        ${$tick . "lasttpc"} = 0;            // record what percentage last the trade was
        ${$tick . "isset"} = 1;              // used to signal we are initialised for this pair
      }

      // We are not on the first loop anymore, we proceed with processing the data
      else
      {

        // Exclude List - these ones we do not trade

        if($key == "BCHABCUSDT") ${$tick . "tradeflag"} = $dontbuy;
        if($key == "BCHSVUSDT") ${$tick . "tradeflag"} = $dontbuy;
        if($key == "BCCUSDT") ${$tick . "tradeflag"} = $dontbuy;
        if($key == "TUSDUSDT") ${$tick . "tradeflag"} = $dontbuy;
        if($key == "VENUSDT") ${$tick . "tradeflag"} = $dontbuy;
        if($key == "PAXUSDT") ${$tick . "tradeflag"} = $dontbuy;

        // Check if the trading pair has been initialised
        // this covers if Binance add a new trading pair on USDT while we are running
        // if Binance adds new trading pairs while bot is running, we shall
        // ignore them and only use the ones since the bot was started and initialised

        if(isset(${$tick . "isset"}))
        {

          // Push data into arrays and shift arrays once we have enough data
          array_push(${$tick . "st"}, $value);
          array_push(${$tick . "mt"}, $value);
          array_push(${$tick . "lt"}, $value);
          if($i > $strend) array_shift(${$tick . "st"});
          if($i > $mtrend) array_shift(${$tick . "mt"});
          if($i > $ltrend) array_shift(${$tick . "lt"});

          // Wait until we have all the arrays populated with data
          if($i <= $ltrend)
          {
            printf("%-9s",$key);
            print "\t:Loading Arrays with data\n";
          }

          // Arrays are populated, so on with the processing
          else
          {

            // Calculate the Moving Average for the 3 arrays
            ${$tick . "stavg"} = round((array_sum(${$tick . "st"})/$strend),8);
            ${$tick . "mtavg"} = round((array_sum(${$tick . "mt"})/$mtrend),8);
            ${$tick . "ltavg"} = round((array_sum(${$tick . "lt"})/$ltrend),8);

            // Check if the Short Term Trend is trending down, flat or up
            // We use the current price to see if it is above or below the short term moving average
            // We use "1" to signal it is trending down, "2" for flat, "3" for trending up
            if($value < ${$tick . "stavg"}) ${$tick . "strend"} = 1;
            if($value == ${$tick . "stavg"}) ${$tick . "strend"} = 2;
            if($value > ${$tick . "stavg"}) ${$tick . "strend"} = 3;

            // Check if the Medium Term Trend is trending down, flat or up
            // We use the short term moving average to see if it is above or below the medium term moving average
            // We use "1" to signal it is trending down, "2" for flat, "3" for trending up
            if(${$tick . "stavg"} < ${$tick . "mtavg"}) ${$tick . "mtrend"} = 1;
            if(${$tick . "stavg"} == ${$tick . "mtavg"}) ${$tick . "mtrend"} = 2;
            if(${$tick . "stavg"} > ${$tick . "mtavg"}) ${$tick . "mtrend"} = 3;

            // Check if the Long Term Trend is trending down, flat or up
            // We use the medium term moving average to see if it is above or below the long term moving average
            // We use "1" to signal it is trending down, "2" for flat, "3" for trending up
            if(${$tick . "mtavg"} < ${$tick . "ltavg"}) ${$tick . "ltrend"} = 1;
            if(${$tick . "mtavg"} == ${$tick . "ltavg"}) ${$tick . "ltrend"} = 2;
            if(${$tick . "mtavg"} > ${$tick . "ltavg"}) ${$tick . "ltrend"} = 3;

            // Calculate the Medium Term spread, which is the percentage difference between
            // the highest recorded price and the lowest recorded price in the Medium Term Array
            $mlow = min(${$tick . "lt"});
            $mhigh = max(${$tick . "lt"});
            ${$tick . "lspread"} = round(((1-($mlow/$mhigh))*100),3);
            
            // Calculate the Relative Strength Indicator on the Long Term Array
            // A Low RSI indicates a buy opportunity
            $rsitck = 0;
            ${$tick . "gain"} = array();
            ${$tick . "loss"} = array();
            foreach(${$tick . "lt"} as $cdaval)
            {
              if($rsitck == 0)
              {
                $cdagain = 0;
                $cdaloss = 0;
              }
              else
              {
                if($cdaval == $cdaprev)
                {
                  $cdagain = 0;
                  $cdaloss = 0;
                }
                elseif($cdaval > $cdaprev)
                {
                  $cdacalc = $cdaval - $cdaprev;
                  $cdagain = number_format($cdacalc,8);
                  $cdaloss = 0;
                }
                else
                {
                  $cdacalc = $cdaprev - $cdaval;
                  $cdaloss = number_format($cdacalc,8);
                  $cdagain = 0;
                }
              }
              array_push(${$tick . "gain"}, $cdagain);
              array_push(${$tick . "loss"}, $cdaloss);
              $cdaprev = $cdaval;
              $rsitck++;
            }
            $cdarsgain = (array_sum(${$tick . "gain"})) / $ltrend;
            $cdarsloss = (array_sum(${$tick . "loss"})) / $ltrend;
            if($cdarsloss > 0)
            {
              ${$tick . "rsi"} = round(100-(100/(1+($cdarsgain/$cdarsloss))),3);
            }
            else
            {
              ${$tick . "rsi"} = 100;
            }

            // Print out what we have so far so we can see what is going on
            printf("%-9s",$key);
            print "\tV:";
            printf("%-14.8F",$value);
            print "\t  ST:";
            printf("%-14.8F",${$tick . "stavg"});
            if(${$tick . "strend"} == 1) printf("%-5s",":DOWN");
            if(${$tick . "strend"} == 2) printf("%-5s",":FLAT");
            if(${$tick . "strend"} == 3) printf("%-5s",":UP");
            print "\t  MT:";
            printf("%-14.8F",${$tick . "mtavg"});
            if(${$tick . "mtrend"} == 1) printf("%-5s",":DOWN");
            if(${$tick . "mtrend"} == 2) printf("%-5s",":FLAT");
            if(${$tick . "mtrend"} == 3) printf("%-5s",":UP");
            print "\t  LT:";
            printf("%-14.8F",${$tick . "ltavg"});
            if(${$tick . "ltrend"} == 1) printf("%-5s",":DOWN");
            if(${$tick . "ltrend"} == 2) printf("%-5s",":FLAT");
            if(${$tick . "ltrend"} == 3) printf("%-5s",":UP");
            print "\t  SPREAD:";
            printf("%-03.3F",${$tick . "lspread"}); 
            print "%\t  RSI:";
            printf("%-06.3F",${$tick . "rsi"});
            if(${$tick . "tradeflag"} == $buyready) $cdastatus = "Buy Ready";
            if(${$tick . "tradeflag"} == $buyprep) $cdastatus = "Buy Prep";
            if(${$tick . "tradeflag"} == $buyord) $cdastatus = "Buy Order";
            if(${$tick . "tradeflag"} == $sellok) $cdastatus = "Sell OK";
            if(${$tick . "tradeflag"} == $sellready) $cdastatus = "Sell Ready";
            if(${$tick . "tradeflag"} == $selldone) $cdastatus = "Sell Done";
            if(${$tick . "tradeflag"} == $dontbuy) $cdastatus = "Dont Trade";
            if(${$tick . "tradeflag"} == $sellready)
            {
              $ctp = round(((($value - ${$tick . "buyvalue"})/${$tick . "buyvalue"})*100),3);
              print "\t S:$cdastatus \tBV:${$tick . "buyvalue"} CTP:$ctp";
            }
            else
            {
              print "\tS:$cdastatus";
            }
            if(${$tick . "lasttrade"} == 1)
            {
              print "   LastTPC:${$tick . "lasttpc"}";
            }
            print "\n";

            // Trading rules start here
            // ========================

            // CDA is trending up so set to buyprep
            if(${$tick . "tradeflag"} == $buyready AND ${$tick . "strend"}==3 AND ${$tick . "mtrend"}==3 AND ${$tick . "ltrend"}==3)
            {
              printf("%-9s",$key);
              print "Was Buyready, now Buyprep V:$value\n";
              ${$tick . "tradeflag"} = $buyprep;
            }

            // CDA was buyprep, now trending down, set to buyord if reasonable spread
            if(${$tick . "tradeflag"} == $buyprep AND ${$tick . "strend"}==1 AND ${$tick . "mtrend"}==1 AND ${$tick . "ltrend"}==1 AND ${$tick . "lspread"} >= $minspread)
            {
              printf("%-9s",$key);
              print "Was Buyprep, now Buyord V:$value\n";
              ${$tick . "tradeflag"} = $buyord;
            }

            // CDA stopped trending down and is ready to buy
            if(${$tick . "tradeflag"} == $buyord AND ${$tick . "strend"}!=1 AND ${$tick . "mtrend"}!=1)
            {
              if(${$tick . "rsi"} <= $minrsi)
              {
                printf("%-9s",$key);
                print "Was Buyord, now Buy V:$value\n";
                // Assume we buy at the current value
                ${$tick . "buyvalue"} = $value;
                ${$tick . "tradeflag"} = $sellok;
                $fh = fopen($tradefile, "a") or die("Cannot open file");
                fwrite($fh, "========================== \n");
                fwrite($fh, "Runtime $run_time \n");
                fwrite($fh, "Buy on $key BV:${$tick . "buyvalue"} \n");
                fwrite($fh, "========================== \n");
                fclose($fh);
              }
              else
              {
                printf("%-9s",$key);
                print "RSI Check not meeting Minimum, resetting back to Buy Prep\n";
                ${$tick . "tradeflag"} = $buyprep;
              }
            }

            // Buy Order on CDA placed, do order tracking here to make sure order completes
            if(${$tick . "tradeflag"} == $sellok)
            {
              // Since we are not placing an order, we just assume it completed
              ${$tick . "tradeflag"} = $sellready;
            }

            // CDA is sellready and is no longer trending upwards - time to sell
            if(${$tick . "tradeflag"} == $sellready AND ${$tick . "strend"}!=3 AND ${$tick . "mtrend"}!=3)
            {
              // Assume we sell at the current value and not sell if not meeting a minimum
              $cdabuff = ${$tick . "buyvalue"} * $sellbuffer;
              if($value > $cdabuff)
              {
                ${$tick . "sellvalue"} = $value;
                ${$tick . "tradeflag"} = $selldone;
              }
              else
              {
                printf("%-9s",$key);
                print "Did not meet minimum sell amount\n";
              }
            }

            // CDA is selldone
            if(${$tick . "tradeflag"} == $selldone)
            {
              // Sell Order on CDA placed, do order tracking here to make sure order completes
              // Since we are not placing an order, we just assume it completed
              $q = round((((${$tick . "sellvalue"} - ${$tick . "buyvalue"})/${$tick . "buyvalue"})*100),3);
              $tpc = $q - 0.2;
              $rpc = $rpc + $tpc;
              ${$tick . "lasttrade"} = 1;
              ${$tick . "lasttpc"} = $tpc;
              ${$tick . "tradeflag"} = $buyready;
              printf("%-9s",$key);
              print "Sell Done BV:${$tick . "buyvalue"} SV:${$tick . "sellvalue"} TPC:$tpc \n";
              $fh = fopen($tradefile, "a") or die("Cannot open file");
              fwrite($fh, "========================== \n");
              fwrite($fh, "Runtime $run_time \n");
              fwrite($fh, "Sell Done on $key BV:${$tick . "buyvalue"} SV:${$tick . "sellvalue"} TPC:$tpc RPC:$rpc \n");
              fwrite($fh, "========================== \n");
              fclose($fh);
            }
          }
        }
      }
    }
  }
  if ($replay == 0) sleep(5);
}
?>

#329

Thanks Mike,

Had this running overnight and the results are:

========================== 
Runtime 43.23 
Buy on TRXUSDT BV:0.01381000 
========================== 
========================== 
Runtime 45.15 
Buy on ICXUSDT BV:0.24780000 
========================== 
========================== 
Runtime 62.98 
Sell Done on ICXUSDT BV:0.24780000 SV:0.24940000 TPC:0.446 RPC:0.446 
========================== 
========================== 
Runtime 72.22 
Sell Done on TRXUSDT BV:0.01381000 SV:0.01389000 TPC:0.379 RPC:0.825 
========================== 
========================== 
Runtime 90.13 
Buy on ONTUSDT BV:0.76000000 
========================== 
========================== 
Runtime 100.28 
Buy on EOSUSDT BV:2.59630000 
========================== 
========================== 
Runtime 100.73 
Buy on ETCUSDT BV:4.50850000 
========================== 
========================== 
Runtime 104.13 
Buy on LTCUSDT BV:30.92000000 
========================== 
========================== 
Runtime 147.22 
Sell Done on EOSUSDT BV:2.59630000 SV:2.61190000 TPC:0.401 RPC:1.226 
========================== 
========================== 
Runtime 151.27 
Sell Done on ETCUSDT BV:4.50850000 SV:4.59450000 TPC:1.708 RPC:2.934 
========================== 
========================== 
Runtime 155.78 
Sell Done on LTCUSDT BV:30.92000000 SV:31.09000000 TPC:0.35 RPC:3.284 
========================== 
========================== 
Runtime 215.08 
Buy on ICXUSDT BV:0.25190000 
========================== 
========================== 
Runtime 305.1 
Buy on EOSUSDT BV:2.54440000 
========================== 
========================== 
Runtime 331.1 
Buy on QTUMUSDT BV:1.92000000 
========================== 
========================== 
Runtime 344.65 
Buy on BNBUSDT BV:5.26550000 
========================== 
========================== 
Runtime 376.67 
Sell Done on QTUMUSDT BV:1.92000000 SV:1.92800000 TPC:0.217 RPC:3.501 
========================== 
========================== 
Runtime 430.3 
Sell Done on BNBUSDT BV:5.26550000 SV:5.29970000 TPC:0.45 RPC:3.951 
========================== 
========================== 
Runtime 510.23 
Buy on VETUSDT BV:0.00458000 
========================== 
========================== 
Runtime 526.68 
Sell Done on ICXUSDT BV:0.25190000 SV:0.25460000 TPC:0.872 RPC:4.823 
========================== 
========================== 
Runtime 527.6 
Sell Done on VETUSDT BV:0.00458000 SV:0.00467000 TPC:1.765 RPC:6.588 
========================== 
========================== 
Runtime 532.62 
Buy on ADAUSDT BV:0.03962000 
========================== 
========================== 
Runtime 558.57 
Buy on XRPUSDT BV:0.35736000 
========================== 
========================== 
Runtime 595.58 
Sell Done on EOSUSDT BV:2.54440000 SV:2.57390000 TPC:0.959 RPC:7.547 
========================== 
========================== 
Runtime 611.9 
Buy on NULSUSDT BV:0.51390000 
========================== 

7.5% after 10 hours!

I unfortunately stopped the bot by mistake this morning so i’ve it started again.


#330

The PHP language is really loose, unlike C++ and others.

You don’t have to pre-define variables before you use them, when you use them, they get dynamically defined.

The down side is, they don’t know any bounds, which makes it one of the least secure languages to use. This means you have to wrap code around checking the bounds and state of every variable and array with PHP.

C++ on the other hand, must have the bounds and state pre-defined before you can use them in your code, which is why it is generally far more secure. The down side is it takes longer to write and debug the code.

PHP is great for prototyping ideas fast, C++ is great for real production solid and reliable code.

Also yes, CDA is Cryptographic Digital Asset. In a legal definition Crypto is neither a token, coin or currency. It is legally defined as an asset, just like a digital baseball card or digital photo would be considered an asset. This is kind of important if Crypto is to become mainstream, it really must be correctly defined with it’s own bounds and state, just like you would with your C++ code. The faster this becomes normal to call all Crypto a CDA, the faster it will achieve adoption as it avoids so many misconceptions and other legal issues.

Stay Fishy


#331

Don’t forget guys the true position is approx “Current running percentage” / 17.

Certainly a step in the right direction.
As a quick hack so we don’t get carried away we should perhaps change:

$rpc = $rpc + $tpc;

to:

$rpc = $rpc + ($tpc / 17);

A cleaner hack is to have an integer variable such as:

$tickerstraded = 17;  // capital is split over this number of tickers
$rpc = $rpc + ($tpc / $tickerstraded);

#332

Do you use any tools for PHP to C++ conversion or do you do it freehand?

Are you familiar with Facebook’s opensource HipHop (PHP to C++) project?

Do you have experience with MCU’s including Arduino / ESP8266?


#333

I was gonna ask what CDA is, thank you very much for stating what it means along with your opinion of to call it such. You da Man!


#334

I do not use any conversion tools, I re-write it again from scratch, this often leads to better ideas on how I handle things.

I am familiar with HipHop, it’s been around for a while, it is like a cut down version of PHP so it can compile.

I don’t do any mobile coding or touch screens, I generally write automation, which run as services and have API’s you interact with.

Also, it is not always divided by 17. When we get to doing orders, you set a maximum number of concurrent orders for the cycle and the bot is responsible for picking the most likely ones, not every one. The maximum concurrent can also vary depending on the trade cycle.

After running test code for a while, you see at what times things are done and those timings are almost like clockwork (time between a buy and sell period is a cycle).

Things get a whole lot more interesting soon, you will see :slight_smile:

Cheers…

Mike Fishy


#335

@Nate1 one of my acronym’s for you.

CDAC Cryptographic Digital Asset Controller is the software / hardware which is more commonly called a “wallet”. The term wallet gives the wrong impression to people new to crypto. I have asked some of the teams (like Binance’s Trust devs) if they will change their product names to CDAC in the Apple and Google stores but they say the term wallet is now too well established.

Personally I don’t think it’s too late to adopt CDAC as 99% of the world’s population don’t really know what crypto is yet.


#336

Just quoting your post from above as it might have been missed by some readers as it was a heavily edited post.

In the current bot, with no stop loss to stop losing trades, we can be holding sizeable unrealised losses i.e. CRP (Current running percentage) not only needs to be divided by about 17 tickers it also needs to have deducted the unrealised losses to give “current trading position”.

Anyone have any thoughts on trading rules for:

  1. Principles for a good stop loss
  2. Sell (or buy) based on RSI changes
  3. Sell (or buy) based on how rapidly the price is going up or down in a time period

#337
  1. I’m still trying to work it out with these 5 second price feeds, but right now, I’m getting good results with trailing stop loss that activates after 1.005+ price change and tracks the $long_avg trend. in other words, current price falling below the long trend’s current average is the trigger for the stop loss.

  2. Have not messed with this, yet.

  3. This is the spread variable presently and I haven’t really fussed with it much in the latest script. It’s still at Fishy’s 1.0 setting, but one idea I do want to try is when prices tank 3% or more and then level off, buy! i.e. buy the dip. I do this in my Ruby-based bots and it works fairly well.


#338

I should probably add more info on the stop/loss metrics…

…I was getting poorer results trying to cap losses at -2%, -3%, etc. than just letting the bot run loose. I’m not really sure why, yet, but plan to spend some more time in this area later to see what exactly is happening during such a stop/loss exit. It seems to me that it’s awfully risky letting the bot just go w/o some stop/loss threshold in place as I’ve seen some of the trade positions dip as much as -8% and many to -5% and -6%.

I think the poorer results is because I stop out on the down trend and then wait at buy_ready for an extra cycle instead of being able to get in at the bottom of the current dip when it eventually turns back up. At least this is the hypothesis I plan to test when I get some more time to dig in on next go around.


#339

You state 1.005+ price change which is a 0.5% SL but for bot purposes the 1.005 is:

$stoplossbuffer = 0.995;  // plus code in the trading rules

I need to take a look at the latest logs / code because as we are taking profit from 0.3% gain and above with 0.2% fee it doesn’t give much margin of error.


#340

SL is essential. It’s just the mechanics that we need to evaluate.


#341

There’s two stop losses I’ve implemented…

Instead of instantly closing the positions as soon as I hit 1.003 (the sell_buffer setting), I instead am setting a trailing stop loss at the long trend’s average, which might or might not be a “losing proposition” at the time I set it, but it’s trailing the current price action by a decent margin on the upswings in most cases and it gives the current position room to grow – a few have gone as high as 4% before eventually falling back to the moving long trend average.

The other stop/loss I’m still working on and it’s the hard-line cutoff from initial buy value. I was experimenting with -2% and -3%, but net result in simulation was much worse than letting the bot run without such. Could be coding error on my part, or could be as I described above as possible hypothesis. Could also be other bots stop/loss hunting to flush me.


#342

Agree 100%. I’ll hack on it some more later, for sure.


#343

Hi All,

First up, new code :slight_smile:
(we got the Github sorted yet?)

Code:

<?php
require 'vendor/autoload.php';

// This bot will trade USDT to the other pairs and back to make more USDT
// It shall use all the trading pairs to make more UDST except the ones we tell it not to use

$strend = 50;                    // Short Term Trend - must be less than $mtrend
$mtrend = 90;                    // Medium Term Trend - must be less than $ltrend
$ltrend = 120;                   // Long Term Trend
$tradefile = "BTC.txt";          // The Trade Logging file name
$minspread = 1.1;                // The minimum spread percentage needed for a trade
$minrsi = 45;                    // Relative Strength must be below this number to buy
$sellbuffer = 1.003;             // Create a buffer to hold CDA if sell is not profitable
$maxorders = 10;                 // Maximum number of concurrent orders

// Do not change any of the flags, we use this to signal the bot what to do and when
$buyready = 0;            // This flag signals the bot that the pair meets rules to buy
$buyprep = 1;             // This flag signals the bot to prepare to buy
$buyord = 2;              // This flag signals the bot to place an order
$sellok = 3;              // This flag signals the bot that the order was completed
$sellready = 4;           // This flag signals the bot to sell
$selldone = 5;            // This flag signals the bot the trade completed
$dontbuy = 6;             // This flag signals the bot we dont want to trade BCASH :P

// Standard variables and arrays we use
$replay = 0;
$i = 0;
$binance_prices = array();
$time_start = time();
$time_end = 0;
$run_time = 0;
$rpc = 0;
$tpc = 0;
$q = 0;
$cdaorders = 0;
$btcprice = 0;
$btctrend = array();
$bttrend = "WAIT";

// API call to fetch pricing data from Binance
function getprices()
{
	global $replay;
	global $pricefh;
	
	if($replay == 0)
	{
		$api = new Binance\API("<api key>","<secret>");
		$mp = $api->prices();
		$pricefh = fopen("BTC-prices.txt","a") or die("Cannot open file");
		fwrite($pricefh, serialize($mp) . "\n");
		fclose($pricefh);
	}
	else
	{
		if (!$pricefh)
		{
			$pricefh = fopen("BTC-prices.txt","r") or die("Cannot open replay file");
		}
		$mp = unserialize(fgets($pricefh));
		if ($mp == NULL) die("end of price data reached.\n");
	}
	return $mp;
}

if ($replay == 1) 
{
	$simulation_mode = "replaying"; 
}
else 
{
	$simulation_mode = "real-time";
	if(file_exists("BTC-prices.txt"))
	{
		unlink("BTC-prices.txt");
	}
}

// Start of the Loop - can run for months - press CTRL-C to stop
for($i = 0; $i <= 2000000; $i++)
{
	$time_end = time();
	$run_time = round((($time_end - $time_start)/60),2);
	print "====================================\n";
	print "Iteration = $i ($simulation_mode) \n";
	print "Running Time: $run_time mins \n";
	print "Current BTC Price is: $btcprice T:$bttrend \n";
	print "Current Orders in progress = $cdaorders / $maxorders\n";
	print "Current running percentage = $rpc \n";
	print "====================================\n";

	// Fetch current prices from Binance
	$binance_prices = getprices();

	// Loop through the price data as key and value pairs
	foreach($binance_prices as $key => $value)
	{
		// Track BTC price for display
		if($key == "BTCUSDT")
		{
			$btcprice = $value;
			array_push($btctrend, $value);
			if($i >= $mtrend)
			{
				array_shift($btctrend);
				$btcavg = round((array_sum($btctrend)/$mtrend),8);
				if($value >= $btcavg)
				{
					$bttrend = "UP";
				}
				else
				{
					$bttrend = "DOWN";
				}
			}
		}
		// Only process pairs with BTC
		if(strpos($key, "BTC"))
		{

			// Convert the pair name to lower case in varibale $tick
			// for example the name "BTCUSDT" will become "btcusdt"

			$tick = strtolower($key);

			// For the first iteration, create arrays and varibales for the bot
			if($i == 0)
			{

				// Use the lower case name to form the leading part of varibales and arrays
				// for exmaple, using "btcusdt" and adding "st" for the short term array
				// will initialise an array called "btcusdtst"
				// as we loop thorugh the pairs, each one gets created for each pair
				// for exmaple "NEOUSDT" will become "neousdtst"

				${$tick . "st"} = array();           // Short Term Array
				${$tick . "mt"} = array();           // Medium Term Array
				${$tick . "lt"} = array();           // Long Term Array
				${$tick . "stavg"} = 0;              // Short Term Moving Average
				${$tick . "mtavg"} = 0;              // Medium Term Moving Average
				${$tick . "ltavg"} = 0;              // Long Term Moving Average
				${$tick . "strend"} = 0;             // Short Term Moving Trend
				${$tick . "mtrend"} = 0;             // Medium Term Moving Trend
				${$tick . "ltrend"} = 0;             // Long Term Moving Trend
				${$tick . "lspread"} = 0;            // Long Term Spread
				${$tick . "rsi"} = 0;                // Relative Strength Indicator for this pair
				${$tick . "tradeflag"} = $buyready;  // Set this pair to buyready
				${$tick . "buyvalue"} = 0;           // record what we buy for on this pair
				${$tick . "sellvalue"} = 0;          // record what we sell for on this pair
				${$tick . "lasttrade"} = 0;          // record we have had one trade done
				${$tick . "lasttpc"} = 0;            // record what percentage last the trade was
				${$tick . "isset"} = 1;              // used to signal we are initialised for this pair
			}

			// We are not on the first loop anymore, we proceed with processing the data
			else
			{

				// Exclude List - these ones we do not trade

				if($key == "BCHABCBTC") ${$tick . "tradeflag"} = $dontbuy;
				if($key == "BCHSVBTC") ${$tick . "tradeflag"} = $dontbuy;
				if($key == "BCCBTC") ${$tick . "tradeflag"} = $dontbuy;

				// Check if the trading pair has been initialised
				// this covers if Binance add a new trading pair on USDT while we are running
				// if Binance adds new trading pairs while bot is running, we shall
				// ignore them and only use the ones since the bot was started and initialised

				if(isset(${$tick . "isset"}))
				{

					// Push data into arrays and shift arrays once we have enough data
					array_push(${$tick . "st"}, $value);
					array_push(${$tick . "mt"}, $value);
					array_push(${$tick . "lt"}, $value);
					if($i > $strend) array_shift(${$tick . "st"});
					if($i > $mtrend) array_shift(${$tick . "mt"});
					if($i > $ltrend) array_shift(${$tick . "lt"});

					// Wait until we have all the arrays populated with data
					if($i <= $ltrend)
					{
						if($key == "BCHSVBTC") print "Loading Arrays with data until Iteration $ltrend - please wait...\n";
					}

					// Arrays are populated, so on with the processing
					else
					{

						// Calculate the Moving Average for the 3 arrays
						${$tick . "stavg"} = round((array_sum(${$tick . "st"})/$strend),8);
						${$tick . "mtavg"} = round((array_sum(${$tick . "mt"})/$mtrend),8);
						${$tick . "ltavg"} = round((array_sum(${$tick . "lt"})/$ltrend),8);

						// Check if the Short Term Trend is trending down, flat or up
						// We use the current price to see if it is above or below the short term moving average
						// We use "1" to signal it is trending down, "2" for flat, "3" for trending up
						if($value < ${$tick . "stavg"}) ${$tick . "strend"} = 1;
						if($value == ${$tick . "stavg"}) ${$tick . "strend"} = 2;
						if($value > ${$tick . "stavg"}) ${$tick . "strend"} = 3;

						// Check if the Medium Term Trend is trending down, flat or up
						// We use the short term moving average to see if it is above or below the medium term moving average
						// We use "1" to signal it is trending down, "2" for flat, "3" for trending up
						if(${$tick . "stavg"} < ${$tick . "mtavg"}) ${$tick . "mtrend"} = 1;
						if(${$tick . "stavg"} == ${$tick . "mtavg"}) ${$tick . "mtrend"} = 2;
						if(${$tick . "stavg"} > ${$tick . "mtavg"}) ${$tick . "mtrend"} = 3;

						// Check if the Long Term Trend is trending down, flat or up
						// We use the medium term moving average to see if it is above or below the long term moving average
						// We use "1" to signal it is trending down, "2" for flat, "3" for trending up
						if(${$tick . "mtavg"} < ${$tick . "ltavg"}) ${$tick . "ltrend"} = 1;
						if(${$tick . "mtavg"} == ${$tick . "ltavg"}) ${$tick . "ltrend"} = 2;
						if(${$tick . "mtavg"} > ${$tick . "ltavg"}) ${$tick . "ltrend"} = 3;

						// Calculate the Medium Term spread, which is the percentage difference between
						// the highest recorded price and the lowest recorded price in the Medium Term Array
						$mlow = min(${$tick . "lt"});
						$mhigh = max(${$tick . "lt"});
						${$tick . "lspread"} = round(((1-($mlow/$mhigh))*100),3);
						
						// Calculate the Relative Strength Indicator on the Long Term Array
						// A Low RSI indicates a buy opportunity
						$rsitck = 0;
						${$tick . "gain"} = array();
						${$tick . "loss"} = array();
						foreach(${$tick . "lt"} as $cdaval)
						{
							if($rsitck == 0)
							{
								$cdagain = 0;
								$cdaloss = 0;
							}
							else
							{
								if($cdaval == $cdaprev)
								{
									$cdagain = 0;
									$cdaloss = 0;
								}
								elseif($cdaval > $cdaprev)
								{
									$cdacalc = $cdaval - $cdaprev;
									$cdagain = number_format($cdacalc,8);
									$cdaloss = 0;
								}
								else
								{
									$cdacalc = $cdaprev - $cdaval;
									$cdaloss = number_format($cdacalc,8);
									$cdagain = 0;
								}
							}
							array_push(${$tick . "gain"}, $cdagain);
							array_push(${$tick . "loss"}, $cdaloss);
							$cdaprev = $cdaval;
							$rsitck++;
						}
						$cdarsgain = (array_sum(${$tick . "gain"})) / $ltrend;
						$cdarsloss = (array_sum(${$tick . "loss"})) / $ltrend;
						if($cdarsloss > 0)
						{
							${$tick . "rsi"} = round(100-(100/(1+($cdarsgain/$cdarsloss))),3);
						}
						else
						{
							${$tick . "rsi"} = 100;
						}

						// Print out only ones in Buy Order and Sell Ready
						if(${$tick . "tradeflag"} == $buyord OR ${$tick . "tradeflag"} == $sellready)
						{
							printf("%-9s",$key);
							print "\tV:";
							printf("%-14.8F",$value);
							print "\t  ST:";
							printf("%-14.8F",${$tick . "stavg"});
							if(${$tick . "strend"} == 1) printf("%-5s",":DOWN");
							if(${$tick . "strend"} == 2) printf("%-5s",":FLAT");
							if(${$tick . "strend"} == 3) printf("%-5s",":UP");
							print "\t  MT:";
							printf("%-14.8F",${$tick . "mtavg"});
							if(${$tick . "mtrend"} == 1) printf("%-5s",":DOWN");
							if(${$tick . "mtrend"} == 2) printf("%-5s",":FLAT");
							if(${$tick . "mtrend"} == 3) printf("%-5s",":UP");
							print "\t  LT:";
							printf("%-14.8F",${$tick . "ltavg"});
							if(${$tick . "ltrend"} == 1) printf("%-5s",":DOWN");
							if(${$tick . "ltrend"} == 2) printf("%-5s",":FLAT");
							if(${$tick . "ltrend"} == 3) printf("%-5s",":UP");
							print "\t  SPREAD:";
							printf("%-03.3F",${$tick . "lspread"}); 
							print "%\t  RSI:";
							printf("%-06.3F",${$tick . "rsi"});
							if(${$tick . "tradeflag"} == $buyord) $cdastatus = "Buy Order";
							if(${$tick . "tradeflag"} == $sellready) $cdastatus = "Sell Ready";
							if(${$tick . "tradeflag"} == $sellready)
							{
								$ctp = round(((($value - ${$tick . "buyvalue"})/${$tick . "buyvalue"})*100),3);
								print "\t S:$cdastatus \tBV:${$tick . "buyvalue"} CTP:$ctp";
							}
							else
							{
								print "\tS:$cdastatus";
							}
							if(${$tick . "lasttrade"} == 1)
							{
								print "   LastTPC:${$tick . "lasttpc"}";
							}
							print "\n";
						}

						// Trading rules start here
						// ========================

						// CDA is trending up so set to buyprep
						if(${$tick . "tradeflag"} == $buyready AND ${$tick . "strend"}==3 AND ${$tick . "mtrend"}==3 AND ${$tick . "ltrend"}==3)
						{
							printf("%-9s",$key);
							print "Was Buyready, now Buyprep V:$value\n";
							${$tick . "tradeflag"} = $buyprep;
						}

						// CDA was buyprep, now trending down, set to buyord if reasonable spread
						if(${$tick . "tradeflag"} == $buyprep AND ${$tick . "strend"}==1 AND ${$tick . "mtrend"}==1 AND ${$tick . "ltrend"}==1 AND ${$tick . "lspread"} >= $minspread)
						{
							printf("%-9s",$key);
							print "Was Buyprep, now Buyord V:$value\n";
							${$tick . "tradeflag"} = $buyord;
						}

						// CDA stopped trending down and is ready to buy
						if(${$tick . "tradeflag"} == $buyord AND ${$tick . "strend"}==3 AND ${$tick . "mtrend"}!=1)
						{
							if(${$tick . "rsi"} <= $minrsi)
							{
								if($cdaorders < $maxorders)
								{
									printf("%-9s",$key);
									print "Was Buyord, now Buy V:$value\n";
									// Assume we buy at the current value
									${$tick . "buyvalue"} = $value;
									${$tick . "tradeflag"} = $sellok;
									$cdaorders = $cdaorders + 1;
									$fh = fopen($tradefile, "a") or die("Cannot open file");
									fwrite($fh, "========================== \n");
									fwrite($fh, "Runtime $run_time \n");
									fwrite($fh, "Buy on $key BV:${$tick . "buyvalue"} \n");
									fwrite($fh, "========================== \n");
									fclose($fh);
								}
							}
							else
							{
								printf("%-9s",$key);
								print "RSI Check not meeting Minimum, resetting back to Buy Prep\n";
								${$tick . "tradeflag"} = $buyprep;
							}
						}

						// Buy Order on CDA placed, do order tracking here to make sure order completes
						if(${$tick . "tradeflag"} == $sellok)
						{
							// Since we are not placing an order, we just assume it completed
							${$tick . "tradeflag"} = $sellready;
						}

						// CDA is sellready and is no longer trending upwards - time to sell
						if(${$tick . "tradeflag"} == $sellready AND ${$tick . "strend"}!=3 AND ${$tick . "mtrend"}!=3)
						{
							// Assume we sell at the current value and not sell if not meeting a minimum
							$cdabuff = ${$tick . "buyvalue"} * $sellbuffer;
							if($value > $cdabuff)
							{
								${$tick . "sellvalue"} = $value;
								${$tick . "tradeflag"} = $selldone;
							}
							else
							{
								printf("%-9s",$key);
								print "Did not meet minimum sell amount\n";
							}
						}

						// CDA is selldone
						if(${$tick . "tradeflag"} == $selldone)
						{
							// Sell Order on CDA placed, do order tracking here to make sure order completes
							// Since we are not placing an order, we just assume it completed
							$q = round((((${$tick . "sellvalue"} - ${$tick . "buyvalue"})/${$tick . "buyvalue"})*100),3);
							$tpc = $q - 0.2;
							$rpc = round($rpc + ($tpc/$maxorders),3);
							${$tick . "lasttrade"} = 1;
							${$tick . "lasttpc"} = $tpc;
							${$tick . "tradeflag"} = $buyready;
							$cdaorders = $cdaorders - 1;
							printf("%-9s",$key);
							print "Sell Done BV:${$tick . "buyvalue"} SV:${$tick . "sellvalue"} TPC:$tpc \n";
							$fh = fopen($tradefile, "a") or die("Cannot open file");
							fwrite($fh, "========================== \n");
							fwrite($fh, "Runtime $run_time \n");
							fwrite($fh, "Sell Done on $key BV:${$tick . "buyvalue"} SV:${$tick . "sellvalue"} TPC:$tpc RPC:$rpc \n");
							fwrite($fh, "========================== \n");
							fclose($fh);
						}
					}
				}
			}
		}
	}
	if ($replay == 0) sleep(5);
}
?>

So, don’t know about you guys, but I love my Crypto a lot more than any love I might have for USDT.
Switched to trading BTC instead of USDT
Many more trading pairs, which allows me to be more picky on what I trade
Added maxorders
Fixed replay code
adjusted a bit of logic
Reduced output to only display things we should be interested in
No stop loss yet

For the stop loss, the answer is there and will tell you early if the CDA is probably headed for a loss.

RSI is calculated from which trend?
If RSI is trending down, probably not a good one to hold right?
Mind you, if the RSI was trending down, we probably wouldn’t have bought it - right?

Have not added RSI Trend in yet in above code, but think about it :slight_smile:

This code is not really tested, may have logic or other bugs which might need fixing.

Edit: been running it for a while, seems fairly bug free - should mention, the running percent is now based off the 10 maximum orders, so the tpc is divided by 10, but does not yet account for compounding, which I shall add soon.

Stay Fishy