Mike Fishy and Automation System Programming (Bots)


#202

That’s correct, the Bot makes ICX by shorting ICX to buy more ICX. So when it trends down, it is making more ICX, but when it trends up, your more ICX is worth more. Either direction - you win.

The “gaps” or spread in the prices are cause by the order book. We get to this later, but you can see it on Binance by clicking the “Depth” button on the chart. We shall get to that later as well.

But this is good, you all appear to be learning :slight_smile:

My Bot:

Trading IOTABNB
V: Value
ST: Short Term Trend
MT: Medium Term Trend
LT: Long Term Trend
RSI: Relative Strength Indicator
1.82 is the spread.
Sell Ready, means it is ready to sell to BNB when the indicator rules are right.

This is where we are headed.

Stay Fishy


#203

Major Quodos Mike,

I am just tying to get my head around all the syntax of the code. Fundamentally I understand it but need to do some more homework. Certainly getting there. Reminds me a bit of my Fortran 77 days too!!!

Really enjoying this and I can see the potential for a great application. Amazing. I think I am doing the wrong job!! :wink:

Crash


#204

Thanks a lot man, this is so amazing!! All this knowledge sharing and learning is really very very awesome!! How about position sizing?! Until now the code assumes you go all in right? Maybe top soon to ask this question? Do you use specific indicators e.g. volatility related to decide when to run and stop your bot, manually or automatically? Thanks a lot man! :slight_smile: :slight_smile:


#205

Running percentage has turned the other way now. It’s not as bad as it looks, I had to restart the bots due to a power outage, the previous gains would offset these some of these losses. It would probably show something different if I left it running for a few days/weeks.


#206

This is some serious sapiosexual information Mike! I only use windows at work (and I don’t want to be fired for misusing company property :sweat_smile:) but everything at home is Mac. So I’ll do the same thing you did at the very beginning of your thread: I’ll get me a dedicated CPU to ensure a “sterile environment”.

I can’t thank you enough for your sharing your knowledge and keep that “carcass” of yours tuned up!

Staying Fishy, thankfully! :beers::beers: I’ll report results here.


#207

First thing first: @Mike_Fishy Most excellent seeing you bringing this to life. And yes, of course, I’m following along and looking to learn a few new tricks from you. Old dog can teach old dog new tricks, right? I fired up your 2nd version of the script and let it run this morning…is the math and decision direction right in that script?

This is what I get in the ICX1.txt file:

==========================
Runtime 13.2
Sell ICX at 0.24780000
==========================
==========================
Runtime 13.38
Buy ICX at 0.24780000
==========================
==========================
Runtime 13.38
TPC = 0 : RPC = -0.2 : Trade Completed
==========================
==========================
Runtime 23.25
Sell ICX at 0.24770000
==========================
==========================
Runtime 28.52
Buy ICX at 0.24750000
==========================
==========================
Runtime 28.52
TPC = 0.081 : RPC = -0.319 : Trade Completed
==========================
==========================
Runtime 28.88
Sell ICX at 0.24700000
==========================
==========================
Runtime 35.32
Buy ICX at 0.24780000
==========================
==========================
Runtime 35.32
TPC = -0.323 : RPC = -0.842 : Trade Completed
==========================
==========================
Runtime 46.55
Sell ICX at 0.24730000
==========================
==========================
Runtime 56.75
Buy ICX at 0.24710000
==========================
==========================
Runtime 56.75
TPC = 0.081 : RPC = -0.961 : Trade Completed
==========================
==========================
Runtime 58.92
Sell ICX at 0.24780000
==========================
==========================
Runtime 59.72
Buy ICX at 0.24760000
==========================
==========================
Runtime 59.72
TPC = 0.081 : RPC = -1.08 : Trade Completed
==========================
==========================
Runtime 67.63
Sell ICX at 0.24680000
==========================
==========================
Runtime 69.48
Buy ICX at 0.24900000
==========================
==========================
Runtime 69.48
TPC = -0.884 : RPC = -2.164 : Trade Completed
==========================
==========================
Runtime 89.6
Sell ICX at 0.24850000
==========================
==========================
Runtime 94.82
Buy ICX at 0.25130000
==========================
==========================
Runtime 94.82
TPC = -1.114 : RPC = -3.478 : Trade Completed
==========================
==========================
Runtime 125.38
Sell ICX at 0.26160000
==========================
==========================
Runtime 130.47
Buy ICX at 0.26150000
==========================
==========================
Runtime 130.47
TPC = 0.038 : RPC = -3.64 : Trade Completed
==========================
==========================
Runtime 131.6
Sell ICX at 0.25860000
==========================
==========================
Runtime 140.73
Buy ICX at 0.26300000
==========================
==========================
Runtime 140.73
TPC = -1.673 : RPC = -5.513 : Trade Completed
==========================
==========================
Runtime 150.9
Sell ICX at 0.26100000
==========================
==========================
Runtime 159.7
Buy ICX at 0.26490000
==========================
==========================
Runtime 159.7
TPC = -1.472 : RPC = -7.185 : Trade Completed
==========================
==========================
Runtime 167.8
Sell ICX at 0.26000000
==========================
==========================
Runtime 178.08
Buy ICX at 0.26310000
==========================
==========================
Runtime 178.08
TPC = -1.178 : RPC = -8.563 : Trade Completed
==========================
==========================
Runtime 206.87
Sell ICX at 0.26800000
==========================
==========================
Runtime 213.6
Buy ICX at 0.27210000
==========================
==========================
Runtime 213.6
TPC = -1.507 : RPC = -10.27 : Trade Completed
==========================
==========================
Runtime 225.9
Sell ICX at 0.26930000
==========================

And a screenshot in action…

Perhaps it’s just that it’s as you said in next post about having to start making decisions about whether the selling is happening for less than it was purchased, etc. I haven’t really started trying to tweak parameters, yet and just confirming all is well before I start messing with it.

@Criptomata, for macs, instructions are somewhat easier to get PHP installed and running, well, because it already is. And if you’re already on at least Sierra High, PHP 7.x is the version you’ll have.

If for some reason PHP isn’t working on your mac already, then best course of action is to install it with HomeBrew. Three useful links (and you may need to do some combination of these to get your system up to date):

  1. https://thewebtier.com/php/installing-php-7-2-osx-homebrew/
  2. https://medium.com/@romaninsh/install-php-7-2-xdebug-on-macos-high-sierra-with-homebrew-july-2018-d7968fe7e8b8
  3. https://thewebtier.com/php/installing-php-7-2-osx-homebrew/

In a nutshell: If you have Sierra High or later and PHP works, all you need to do next is Mike’s instructions for installing composer:

php -r “copy(‘https://getcomposer.org/installer’, ‘composer-setup.php’);”

After composer is installed, install the framework with a slightly modified version of his command:

composer require jaggedsoft/php-binance-api @dev

Basically, I had to remove the double-quotes to run the command but reflecting back as I write this, my error at the time may have been a copy and paste preserving curly double (a.k.a. fancy) quotes instead the standard keyboard typed double-quote character.

After that it should, "Just work"™


#208

Hi Team,

Glad to see you are progressing along.

This script is very basic and as I said, it’s not taking ALOT of things into account.

The reason you get negatives is because the long term trend is trending upwards, plus other reasons.
So when the short term trend crosses below the long term trend, it buys USDT, but as the long term trend is trending upwards, next time the short trend crosses over the long trend, the price of ICX has actually gone up, so you have gone backwards on that trade. Not to mention, we are buying at whatever the current value is, which could be above both trend lines, plus we are not taking into account the relative strength.

So this very basic strategy, really only works when the whole market is trending down (wait, hasn’t it been trending down all year?) and we should have an additional check to make sure the current value is also less or more than both trend lines.

The process of learning to code your own bot, is to see what goes wrong. We then learn from those mistakes and put code in to cater for such circumstances. The number of “what if” situations is quite extensive and you will likely iterate on your code for a long time. When you have all those rules coded in, the bot will run for many weeks without needing restarting, just basic attention to things that change, such as trading pairs being de-listed or new ones being listed.

The point being, the code has to be maintained, this is why you need to learn it, no one is going to maintain it for you. If you put the effort in and maintain your code, it will do work for you.

So right now, just play with this code and look how it is written and what it is doing, because right now it is super simple. Later on, it will be much more complex, so the best way to get you all up to speed is to start simple and play with it and learn. Just like learning a new spoken language, we start with Yes, No, Please, Thank you - before we try and put together more complex sentences.

I will put together the next iteration and post it after running tests - where we have 3 trend lines and some more rules around when we should switch. I will break it down better, so the code looks more logical rather than hacked together for speed.

Edit: Sorry, I have never use a MAC. I’m sure those who have might be able to help. I might own Apple Shares since 1999, but I have never bought any of their products as I don’t like them :stuck_out_tongue:

OK, since most of you have probably been using small numbers for the short and long trend, try using much larger numbers like a short trend of 500 and a long trend of 900, then let it run overnight. Learn what happens when you make it more conservative.

Stay Fishy


#209

My bots are running. When do they start to get data? This is what I get now:

Iteration = 58
Running Time: 5.23 mins
Current running percentage = 0

Loading arrays with the price data

UPDATE: Now I see. When the iterations hit the $long_trend it starts to give back / use the values.


#210

Is there a way to utilize the bot to add the profit to the starting amount to have the compound interest in effect? For example with 1 BTC and 2.4% profit/hour:

hour starting amount / hour starting amount + profit / hour profit
1 1.000 1.024 2.40%
2 1.024 1.049 4.86%
3 1.049 1.074 7.37%
4 1.074 1.100 9.95%
5 1.100 1.126 12.59%
6 1.126 1.153 15.29%
7 1.153 1.181 18.06%
8 1.181 1.209 20.89%
9 1.209 1.238 23.79%
10 1.238 1.268 26.77%
11 1.268 1.298 29.81%
12 1.298 1.329 32.92%
13 1.329 1.361 36.11%
14 1.361 1.394 39.38%
15 1.394 1.427 42.72%
16 1.427 1.462 46.15%
17 1.462 1.497 49.66%
18 1.497 1.532 53.25%
19 1.532 1.569 56.93%
20 1.569 1.607 60.69%
21 1.607 1.646 64.55%
22 1.646 1.685 68.50%
23 1.685 1.725 72.54%
24 1.725 1.767 76.68%

#211

Hi Mike,
I think the calculation for the running percentage seems to be flipped around. As the market has gone down, you have sold ICX to USDT then buy back as it turns so you actually gain more ICX.

$ctpc = round(((($value - $sellvalue)/$sellvalue)*100),3);
should be
$ctpc = round(((($sellvalue - $value)/$sellvalue)*100),3);

I see right at the moment ICXUSDT is going down but the bots are showing Current trade percent as negative. So the negative numbers we are getting should actually be positive?


#212

Yes, this is exactly what we will be doing, it compounds as it goes along. The more trades we do, the more funds we have to trade with.

Also yes, I didn’t check that previous code very well, it is likely to have some bad logic.

I’m working on the next iteration of code at the moment.

I am putting a whole swag of comments in the code, I’m sure you will see the gist of it and have the next iteration to play with soon.

To try and keep it as simple as I can, I decided to trade USDT and try and make as much USDT as I can.

People can more easily relate to USDT as we are so use to cash, but you could switch it to be BTC or BNB or ETH or all of them if you wanted.

We are only going to look at percentages right now, we will add quantities (which will show how it compounds) later on.

For a quick preview of the code so far, which will run and print stuff out, but doesn’t have any rules or logic yet, you can play with the below:

<?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 = 20;             // Short Term Trend - must be less than $mtrend
$mtrend = 40;             // Medium Term Trend - must be less than $ltrend
$ltrend = 70;             // Long Term Trend
$tradefile = "USDT.txt";  // The Trade Logging file name
$minspread = 1.4;         // The minimum spread percentage needed for a trade

// 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
$i = 0;
$binance_prices = array();
$time_start = time();
$time_end = 0;
$run_time = 0;
$rpc = 0;

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

// 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 \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 . "mspread"} = 0;          // Medium Term Spread
        ${$tick . "buyflag"} = $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 . "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 BCASH cause I dont like them :P

        if($key == "BCHABCUSDT") ${$tick . "buyflag"} = $dontbuy;
        if($key == "BCHSVUSDT") ${$tick . "buyflag"} = $dontbuy;
        if($key == "BCCUSDT") ${$tick . "buyflag"} = $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 . "mt"});
            $mhigh = max(${$tick . "mt"});
            ${$tick . "mspread"} = round(((1-($mlow/$mhigh))*100),3);

// Print out what we have so far so we can see what is going on
            printf("%-9s",$key);
            print "\tV:";
            printf("%08.8F",$value);
            print "\tST:";
            printf("%08.8F",${$tick . "stavg"});
            if(${$tick . "strend"} == 1) print ":DOWN   ";
            if(${$tick . "strend"} == 2) print ":FLAT   ";
            if(${$tick . "strend"} == 3) print ":UP     ";
            print "\tMT:";
            printf("%08.8F",${$tick . "mtavg"});
            if(${$tick . "mtrend"} == 1) print ":DOWN   ";
            if(${$tick . "mtrend"} == 2) print ":FLAT   ";
            if(${$tick . "mtrend"} == 3) print ":UP     ";
            print "\tLT:";
            printf("%08.8F",${$tick . "ltavg"});
            if(${$tick . "ltrend"} == 1) print ":DOWN   ";
            if(${$tick . "ltrend"} == 2) print ":FLAT   ";
            if(${$tick . "ltrend"} == 3) print ":UP     ";
            print "\tSPREAD:${$tick . "mspread"}% \n";

// No rules or anything yet, just printing what we have to show you what is done so far.

          }
        }
      }
    }
  }
  sleep(5);
}
?>

Stay Fishy

Edit: No offence to BCASH, just using it as an example of how to do trading exceptions.
Edit2: ok, maybe a little biased :stuck_out_tongue:

After running for a little while, you should see something like this:

As you can see, the spread is only a small percentage. With low numbers on the ST, MT and LT, the potential trade area for that time period has only a small percentage possibility. We should increase the ST, MT and LT numbers until we start seeing a spread of 1.5% or so on a few of them (not BCASH as we are excluding them :stuck_out_tongue: ).

For those who manually trade and may have used the Bollinger indicator, the Medium Trend spread is sort of like the upper and lower lines of the Bollinger graph for that time period.
As MT in the code was set to 40, that is 40 x 5 seconds = 3.33 minutes.
The more conservative and longer periods, the more likely of a higher trade percentage (also, the more volatile the market is, the higher the percentages will be, so if the market is really bouncing, you can run a more aggressive strategy, but if the market is quiet, you can run a more conservative strategy).

Again, play with the numbers and watch what happens, see if you can spot and learn from what is being displayed to us.

Stay Fishy


#213

Hi everyone, after @mwlang’s great post I sent a private message to him about what exactly is github and composer doing? Just for everyone’s benefit it would be great to understand exactly how it all ties in to each other.

I am really enjoying doing this. More the side with programming and the ability to be able to pick up data and manipulate it! This is something I really like doing. :wink:

Cheers Crash.


#214

@Crash101 - thanks for reposting your questions publicly. This is a great exercise Mike’s started and your questions are ones I’m sure many others just getting started are wondering, too.

So, github is simply a cloud service that let’s software developers collaborate and share source code. Github is powered by an underlying software repository/version control open source tool called “git” of which there are many others such as Subversion, Mercurial, to name a couple other popular ones. The great thing about these tools is that they allow teams of developers to work on the same project, potentially editing the same source files, without clashing because the tool will alert each developer to the other developer’s changes and force them to resolve differences at the time they commit their changes back to the repository.

You can learn more about git here: https://www.atlassian.com/git/tutorials/what-is-version-control

Composer is what’s known as a dependency manager. Ruby has gems. Perl has PEAR. Python has PIP. So with composer, a developer is able to declare dependencies on external libraries such as Binance API as here and whenever external libraries are updated and improved, composer makes it easy to pull the latest updates into the project without having to keep track of each dependency ourselves. The other big benefit is that it makes it easy to distribute one’s code to another as all the new developer has to do is run compose to download and install all those dependencies.


#215

“Running percentage” is not variable ctpc. Running percentage is variable rpc.
From the screenshot below are you referring to the -0.813 (Current running percentage rpc) or the -2.553 (Current Trade Percent ctpc)?

Bot%20screenshot


#216

Yes, you’re right. I must have been using the first version of the code. I checked version 2 above and its correct. Sorry for the confusion.


#217

I used your code with different large numbers for ST, MT and LT. The spread increases with higher numbers. However the running percentage remains zero. Just wondering whether this is correct or not correct man! :slight_smile: :slight_smile:


#218

If you’re on the last version of the code posted earlier today, no trades are happening. It’s just printing information on prices and trends each iteration.


#219

Ok clear thanks a lot man! Really cant wait to get the first real bot up and running man! :slight_smile: :slight_smile:


#220

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 = 100;            // Short Term Trend - must be less than $mtrend
$mtrend = 180;            // Medium Term Trend - must be less than $ltrend
$ltrend = 280;            // Long Term Trend
$tradefile = "USDT.txt";  // The Trade Logging file name
$minspread = 1.4;         // The minimum spread percentage needed for a trade
$minrsi = 40;             // Relative Strength must be below this number to buy

// 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
$i = 0;
$binance_prices = array();
$time_start = time();
$time_end = 0;
$run_time = 0;
$rpc = 0;

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

// 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 \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 . "mspread"} = 0;          // Medium Term Spread
		${$tick . "rsi"} = 0;              // Relative Strength Indicator for this pair
        ${$tick . "buyflag"} = $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 . "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 BCASH cause I dont like them :P

        if($key == "BCHABCUSDT") ${$tick . "buyflag"} = $dontbuy;
        if($key == "BCHSVUSDT") ${$tick . "buyflag"} = $dontbuy;
        if($key == "BCCUSDT") ${$tick . "buyflag"} = $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 . "mt"});
            $mhigh = max(${$tick . "mt"});
            ${$tick . "mspread"} = 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);
              if(${$tick . "rsi"} == 0) ${$tick . "rsi"} = 0;
            }
            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 . "mspread"}); 
			print "%\t  RSI:${$tick . "rsi"}\n";

// No rules or anything yet, just printing what we have to show you what is done so far.

          }
        }
      }
    }
  }
  sleep(5);
}
?>

Now looks like:

No Rules yet, that is pretty much what is next.

So far, the only API call to Binance is to fetch the current prices.

With one simple API Call, we can gather a LOT of information by processing the data in a manner we can use.

Now that we have this data and processed it into a manner we can use, we can start adding logical rules to execute good trades.

Again, code to play with and to fiddle with the numbers, though in it’s current form, it could do quite well using the numbers that I have chosen.

Stay Fishy


#221

Last code chunk before the weekend. I will not be online over the weekend, I have parties to attend :slight_smile:

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 = 100;            // Short Term Trend - must be less than $mtrend
$mtrend = 180;            // Medium Term Trend - must be less than $ltrend
$ltrend = 280;            // Long Term Trend
$tradefile = "USDT.txt";  // The Trade Logging file name
$minspread = 0.6;         // The minimum spread percentage needed for a trade
$minrsi = 46;             // Relative Strength must be below this number to buy

// 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
$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()
{
  $api = new Binance\API("<api key>","<secret>");
  $mp = $api->prices();
  return $mp;
}

// 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 \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 . "mspread"} = 0;          // Medium Term Spread
        ${$tick . "rsi"} = 0;              // Relative Strength Indicator for this pair
        ${$tick . "buyflag"} = $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 . "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 . "buyflag"} = $dontbuy;
        if($key == "BCHSVUSDT") ${$tick . "buyflag"} = $dontbuy;
        if($key == "BCCUSDT") ${$tick . "buyflag"} = $dontbuy;
        if($key == "TUSDUSDT") ${$tick . "buyflag"} = $dontbuy;
        if($key == "VENUSDT") ${$tick . "buyflag"} = $dontbuy;
				if($key == "PAXUSDT") ${$tick . "buyflag"} = $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 . "mt"});
            $mhigh = max(${$tick . "mt"});
            ${$tick . "mspread"} = 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);
              if(${$tick . "rsi"} == 0) ${$tick . "rsi"} = 0;
            }
            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 . "mspread"}); 
            print "%\t  RSI:";
						printf("%-06.3F",${$tick . "rsi"});
						if(${$tick . "buyflag"} == $buyready) $cdastatus = "Buy Ready";
						if(${$tick . "buyflag"} == $buyprep) $cdastatus = "Buy Prep";
						if(${$tick . "buyflag"} == $buyord) $cdastatus = "Buy Order";
						if(${$tick . "buyflag"} == $sellok) $cdastatus = "Sell OK";
						if(${$tick . "buyflag"} == $sellready) $cdastatus = "Sell Ready";
						if(${$tick . "buyflag"} == $selldone) $cdastatus = "Sell Done";
						if(${$tick . "buyflag"} == $dontbuy) $cdastatus = "Dont Trade";
						print "\tS:$cdastatus \n";

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

// CDA is trending up so set to buyprep
            if(${$tick . "buyflag"} == $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 . "buyflag"} = $buyprep;
            }

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

// CDA stopped trending down and is ready to buy
            if(${$tick . "buyflag"} == $buyord AND ${$tick . "strend"}!=1 AND ${$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 . "buyflag"} = $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);
            }

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

// CDA is sellready and is no longer trending upwards - time to sell
            if(${$tick . "buyflag"} == $sellready AND ${$tick . "strend"}!=3 AND ${$tick . "mtrend"}!=3)
            {
// Assume we sell at the current value
              ${$tick . "sellvalue"} = $value;
              ${$tick . "buyflag"} = $selldone;
		        }

// CDA is selldone
            if(${$tick . "buyflag"} == $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 . "buyflag"} = $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 \n");
              fwrite($fh, "========================== \n");
              fclose($fh);
						}
          }
        }
      }
    }
  }
  sleep(5);
}
?>

Going to say, I have not really tested this out, but giving it anyway for you guys to play with over the weekend with something that actually does stuff. Sorry kind of rushed, so formatting is not great.

Enjoy.

Stay Fishy